|
|
@@ -322,6 +322,145 @@ def listar_cuentas(request):
|
|
|
'fecha_fin': fecha_fin
|
|
|
})
|
|
|
|
|
|
+@login_required
|
|
|
+def listar_categorias(request):
|
|
|
+ categorias = Categoria.objects.all().order_by('nombre')
|
|
|
+
|
|
|
+ form_filtro = FiltroForm(request.GET or None)
|
|
|
+
|
|
|
+ if form_filtro.is_valid():
|
|
|
+ busqueda = form_filtro.cleaned_data.get('buscar')
|
|
|
+ if busqueda:
|
|
|
+ categorias = categorias.filter(
|
|
|
+ db_models.Q(nombre__icontains=busqueda)
|
|
|
+ )
|
|
|
+
|
|
|
+ return render(request, 'listar_categorias.html', {'categorias': categorias, 'form_filtro': form_filtro})
|
|
|
+
|
|
|
+@login_required
|
|
|
+def informe_categoria(request):
|
|
|
+ categoria_id = request.GET.get('categoria_id')
|
|
|
+
|
|
|
+ categoria = get_object_or_404(Categoria, id=categoria_id)
|
|
|
+
|
|
|
+ form = FiltroInformeCuentaForm(request.GET or None)
|
|
|
+
|
|
|
+ if form.is_valid():
|
|
|
+ # obtener fechas desde GET o establecer por defecto (mes actual)
|
|
|
+ hoy = timezone.localtime()
|
|
|
+ primer_dia = hoy.replace(day=1)
|
|
|
+
|
|
|
+ fecha_inicio_str = request.GET.get('fecha_inicio')
|
|
|
+ fecha_fin_str = request.GET.get('fecha_fin')
|
|
|
+
|
|
|
+ if fecha_inicio_str and fecha_fin_str:
|
|
|
+ fecha_inicio = datetime.strptime(fecha_inicio_str, '%Y-%m-%d').date()
|
|
|
+ fecha_fin = datetime.strptime(fecha_fin_str, '%Y-%m-%d').date()
|
|
|
+ else:
|
|
|
+ fecha_inicio = primer_dia
|
|
|
+ fecha_fin = hoy
|
|
|
+
|
|
|
+ # Convertir a datetime aware para evitar warnings
|
|
|
+ fecha_inicio_dt = timezone.make_aware(datetime.combine(fecha_inicio, time.min))
|
|
|
+ fecha_fin_dt = timezone.make_aware(datetime.combine(fecha_fin, time.max))
|
|
|
+
|
|
|
+ movimientos = Movimiento.objects.filter(
|
|
|
+ categoria=categoria,
|
|
|
+ usuario=request.user,
|
|
|
+ fecha__range=(fecha_inicio_dt, fecha_fin_dt)
|
|
|
+ ).order_by('fecha')
|
|
|
+
|
|
|
+ context = {
|
|
|
+ 'categoria': categoria,
|
|
|
+ 'movimientos': movimientos,
|
|
|
+ 'fecha_inicio': fecha_inicio_str,
|
|
|
+ 'fecha_fin': fecha_fin_str,
|
|
|
+ }
|
|
|
+
|
|
|
+ return render(request, 'informe_categoria.html', context)
|
|
|
+
|
|
|
+@login_required
|
|
|
+def informe_categoria_pdf(request):
|
|
|
+ categoria_id = request.GET.get('categoria_id')
|
|
|
+
|
|
|
+ categoria = get_object_or_404(Categoria, id=categoria_id)
|
|
|
+
|
|
|
+ # obtener fechas desde GET o establecer por defecto (mes actual)
|
|
|
+ hoy = timezone.localtime()
|
|
|
+ primer_dia = hoy.replace(day=1)
|
|
|
+
|
|
|
+ fecha_inicio_str = request.GET.get('fecha_inicio')
|
|
|
+ fecha_fin_str = request.GET.get('fecha_fin')
|
|
|
+
|
|
|
+ if fecha_inicio_str and fecha_fin_str:
|
|
|
+ fecha_inicio = datetime.strptime(fecha_inicio_str, '%Y-%m-%d').date()
|
|
|
+ fecha_fin = datetime.strptime(fecha_fin_str, '%Y-%m-%d').date()
|
|
|
+ else:
|
|
|
+ fecha_inicio = primer_dia
|
|
|
+ fecha_fin = hoy
|
|
|
+
|
|
|
+ # Convertir a datetime aware para evitar warnings
|
|
|
+ fecha_inicio_dt = timezone.make_aware(datetime.combine(fecha_inicio, time.min))
|
|
|
+ fecha_fin_dt = timezone.make_aware(datetime.combine(fecha_fin, time.max))
|
|
|
+
|
|
|
+ movimientos = Movimiento.objects.filter(
|
|
|
+ categoria=categoria,
|
|
|
+ usuario=request.user,
|
|
|
+ fecha__range=(fecha_inicio_dt, fecha_fin_dt)
|
|
|
+ ).order_by('fecha')
|
|
|
+
|
|
|
+ template = get_template('informe_categoria_pdf.html')
|
|
|
+ html = template.render({'categoria': categoria, 'fecha_inicio': fecha_inicio_str, 'fecha_fin': fecha_fin_str, 'movimientos': movimientos})
|
|
|
+
|
|
|
+ with tempfile.NamedTemporaryFile(delete=True) as output:
|
|
|
+ HTML(string=html).write_pdf(output.name)
|
|
|
+
|
|
|
+ output.seek(0)
|
|
|
+ response = HttpResponse(output.read(), content_type='application/pdf')
|
|
|
+ response['Content-Disposition'] = f'filename=informe_{categoria.nombre}.pdf'
|
|
|
+ return response
|
|
|
+
|
|
|
+@login_required
|
|
|
+def informe_categoria(request):
|
|
|
+ categoria_id = request.GET.get('categoria_id')
|
|
|
+
|
|
|
+ categoria = get_object_or_404(Categoria, id=categoria_id)
|
|
|
+
|
|
|
+ form = FiltroInformeCuentaForm(request.GET or None)
|
|
|
+
|
|
|
+ if form.is_valid():
|
|
|
+ # obtener fechas desde GET o establecer por defecto (mes actual)
|
|
|
+ hoy = timezone.localtime()
|
|
|
+ primer_dia = hoy.replace(day=1)
|
|
|
+
|
|
|
+ fecha_inicio_str = request.GET.get('fecha_inicio')
|
|
|
+ fecha_fin_str = request.GET.get('fecha_fin')
|
|
|
+
|
|
|
+ if fecha_inicio_str and fecha_fin_str:
|
|
|
+ fecha_inicio = datetime.strptime(fecha_inicio_str, '%Y-%m-%d').date()
|
|
|
+ fecha_fin = datetime.strptime(fecha_fin_str, '%Y-%m-%d').date()
|
|
|
+ else:
|
|
|
+ fecha_inicio = primer_dia
|
|
|
+ fecha_fin = hoy
|
|
|
+
|
|
|
+ # Convertir a datetime aware para evitar warnings
|
|
|
+ fecha_inicio_dt = timezone.make_aware(datetime.combine(fecha_inicio, time.min))
|
|
|
+ fecha_fin_dt = timezone.make_aware(datetime.combine(fecha_fin, time.max))
|
|
|
+
|
|
|
+ movimientos = Movimiento.objects.filter(
|
|
|
+ categoria=categoria,
|
|
|
+ usuario=request.user,
|
|
|
+ fecha__range=(fecha_inicio_dt, fecha_fin_dt)
|
|
|
+ ).order_by('fecha')
|
|
|
+
|
|
|
+ context = {
|
|
|
+ 'categoria': categoria,
|
|
|
+ 'movimientos': movimientos,
|
|
|
+ 'fecha_inicio': fecha_inicio_str,
|
|
|
+ 'fecha_fin': fecha_fin_str,
|
|
|
+ }
|
|
|
+
|
|
|
+ return render(request, 'informe_categoria.html', context)
|
|
|
|
|
|
# API
|
|
|
|