diff --git a/expenses_manager/expenses/models.py b/expenses_manager/expenses/models.py index 7316932..9c96007 100644 --- a/expenses_manager/expenses/models.py +++ b/expenses_manager/expenses/models.py @@ -1,8 +1,10 @@ +from datetime import date from decimal import Decimal from django.db import models from django.conf import settings from django.db.models import Sum from django.db.models.fields import related +from django.db.models.functions import ExtractMonth class Category(models.Model): name = models.CharField(max_length=100) @@ -58,6 +60,41 @@ class Account(models.Model): ) return self.initial_balance + income_total - expenses_total + def monthly_balance(self, year=None): + year = year or date.today().year + + incomes = ( + self.incomes + .filter(date__year=year) + .annotate(month=ExtractMonth('date')) + .values('month') + .annotate(total=Sum('amount')) + ) + + expenses = ( + self.expenses + .filter(date__year=year) + .annotate(month=ExtractMonth('date')) + .values('month') + .annotate(total=Sum('amount')) + ) + + income_map = {i['month']: i['total'] for i in incomes} + expenses_map = {e['month']: e['total'] for e in expenses} + + balance = self.initial_balance + data = [] + + for month in range(1, 13): + balance += income_map.get(month, 0) + balance -= expenses_map.get(month, 0) + + data.append({ + 'month': month, + 'balance': float(balance), + }) + return data + def __str__(self): return self.name diff --git a/expenses_manager/expenses/templates/expenses/dashboard.html b/expenses_manager/expenses/templates/expenses/dashboard.html index 78df8c6..1df92a9 100644 --- a/expenses_manager/expenses/templates/expenses/dashboard.html +++ b/expenses_manager/expenses/templates/expenses/dashboard.html @@ -225,7 +225,7 @@ -

Distribución mensual (año completo)

+

Distribución mensual (año completo)

@@ -249,5 +249,44 @@
+

Evolución anual por cuenta ({{ selected_year }})

+ +
+ {% for acc in accounts_charts %} +
+

{{ acc.name }}

+

Saldo actual: {{ acc.current_balance|floatformat:2 }} €

+ + +
+ {% endfor %} +
+ + + {% endblock %} \ No newline at end of file diff --git a/expenses_manager/expenses/views.py b/expenses_manager/expenses/views.py index fb04f49..095cdad 100644 --- a/expenses_manager/expenses/views.py +++ b/expenses_manager/expenses/views.py @@ -482,6 +482,21 @@ def dashboard(request): 'difference_abs': abs(difference), }) + # ------------------ + # Previous expenses by category + # ------------------ + accounts_charts = [] + for account in accounts: + monthly_data = account.monthly_balance(selected_year) + m_balance = [row['balance'] for row in monthly_data] + + accounts_charts.append({ + 'id': account.id, + 'name': account.name, + 'data': m_balance, + 'current_balance': account.current_balance(), + }) + # Send the data to the dashboard return render(request, 'expenses/dashboard.html', { 'by_category': by_category, @@ -506,6 +521,7 @@ def dashboard(request): 'selected_account': account_id, 'selected_account_obj': selected_account_obj, 'kpi_balance': kpi_balance, + 'accounts_charts': accounts_charts, })