|
|
@@ -18,6 +18,8 @@ from django.http import HttpResponse
|
|
|
from weasyprint import HTML
|
|
|
import tempfile
|
|
|
from django.utils.dateparse import parse_date
|
|
|
+from decimal import Decimal
|
|
|
+from django.db.models import Sum
|
|
|
|
|
|
import logging
|
|
|
import re
|
|
|
@@ -429,14 +431,14 @@ def api_ejecutar_recurrentes(request):
|
|
|
|
|
|
@login_required
|
|
|
def resumen_saldos_mensuales(request):
|
|
|
- cuentas = Cuenta.objects.filter(usuario=request.user)
|
|
|
+ cuentas = Cuenta.objects.filter(usuario=request.user).order_by('nombre')
|
|
|
movimientos = Movimiento.objects.filter(usuario=request.user).order_by('fecha')
|
|
|
|
|
|
# Diccionario: {(cuenta_id, año, mes): saldo}
|
|
|
saldos_mensuales = defaultdict(lambda: 0)
|
|
|
|
|
|
# Diccionario para llevar el saldo acumulado
|
|
|
- saldos_acumulados = {cuenta.id: 0 for cuenta in cuentas}
|
|
|
+ saldos_acumulados = {cuenta.id: float(cuenta.saldo_inicial) for cuenta in cuentas}
|
|
|
|
|
|
# Obtener todos los meses presentes en movimientos
|
|
|
meses_presentes = set()
|
|
|
@@ -494,6 +496,22 @@ def informe_cuenta(request):
|
|
|
# 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))
|
|
|
+
|
|
|
+ # Saldo antes del periodo
|
|
|
+ movimientos_previos = Movimiento.objects.filter(
|
|
|
+ fecha__lt=fecha_inicio_dt,
|
|
|
+ ).filter(
|
|
|
+ cuenta_origen=cuenta
|
|
|
+ ).aggregate(total_origen=Sum('monto')) or {'total_origen': 0}
|
|
|
+
|
|
|
+ entradas_previas = Movimiento.objects.filter(
|
|
|
+ fecha__lt=fecha_inicio_dt,
|
|
|
+ ).filter(
|
|
|
+ cuenta_destino=cuenta
|
|
|
+ ).aggregate(total_destino=Sum('monto')) or {'total_destino': 0}
|
|
|
+
|
|
|
+ saldo_inicial = (entradas_previas['total_destino'] or 0) - (movimientos_previos['total_origen'] or 0)
|
|
|
+ saldo_inicial = saldo_inicial + cuenta.saldo_inicial
|
|
|
|
|
|
movimientos = Movimiento.objects.filter(
|
|
|
Q(cuenta_origen=cuenta) | Q(cuenta_destino=cuenta),
|
|
|
@@ -501,7 +519,8 @@ def informe_cuenta(request):
|
|
|
).order_by('fecha')
|
|
|
|
|
|
# Cálculo de saldos después de cada movimiento
|
|
|
- saldo = 0
|
|
|
+ saldo = saldo_inicial
|
|
|
+
|
|
|
movimientos_con_saldo = []
|
|
|
for mov in movimientos:
|
|
|
if mov.cuenta_origen == cuenta:
|
|
|
@@ -522,6 +541,7 @@ def informe_cuenta(request):
|
|
|
'movimientos_con_saldo': movimientos_con_saldo,
|
|
|
'fecha_inicio': fecha_inicio_str,
|
|
|
'fecha_fin': fecha_fin_str,
|
|
|
+ 'saldo_inicial': saldo_inicial,
|
|
|
}
|
|
|
|
|
|
return render(request, 'informe_cuenta.html', context)
|
|
|
@@ -551,12 +571,28 @@ def informe_cuenta_pdf(request):
|
|
|
fecha_inicio_dt = timezone.make_aware(datetime.combine(fecha_inicio, time.min))
|
|
|
fecha_fin_dt = timezone.make_aware(datetime.combine(fecha_fin, time.max))
|
|
|
|
|
|
+ # Saldo antes del periodo
|
|
|
+ movimientos_previos = Movimiento.objects.filter(
|
|
|
+ fecha__lt=fecha_inicio_dt,
|
|
|
+ ).filter(
|
|
|
+ cuenta_origen=cuenta
|
|
|
+ ).aggregate(total_origen=Sum('monto')) or {'total_origen': 0}
|
|
|
+
|
|
|
+ entradas_previas = Movimiento.objects.filter(
|
|
|
+ fecha__lt=fecha_inicio_dt,
|
|
|
+ ).filter(
|
|
|
+ cuenta_destino=cuenta
|
|
|
+ ).aggregate(total_destino=Sum('monto')) or {'total_destino': 0}
|
|
|
+
|
|
|
+ saldo_inicial = (entradas_previas['total_destino'] or 0) - (movimientos_previos['total_origen'] or 0)
|
|
|
+ saldo_inicial = saldo_inicial + cuenta.saldo_inicial
|
|
|
+
|
|
|
movimientos = Movimiento.objects.filter(
|
|
|
Q(cuenta_origen=cuenta) | Q(cuenta_destino=cuenta),
|
|
|
fecha__range=(fecha_inicio_dt, fecha_fin_dt)
|
|
|
).order_by('fecha')
|
|
|
|
|
|
- saldo = 0
|
|
|
+ saldo = saldo_inicial
|
|
|
historial = []
|
|
|
|
|
|
for mov in movimientos:
|
|
|
@@ -578,7 +614,7 @@ def informe_cuenta_pdf(request):
|
|
|
})
|
|
|
|
|
|
template = get_template('informe_cuenta_pdf.html')
|
|
|
- html = template.render({'cuenta': cuenta, 'historial': historial})
|
|
|
+ html = template.render({'cuenta': cuenta, 'saldo_inicial': saldo_inicial, 'historial': historial})
|
|
|
|
|
|
with tempfile.NamedTemporaryFile(delete=True) as output:
|
|
|
HTML(string=html).write_pdf(output.name)
|