diff --git a/app/apps/insights/utils/category_explorer.py b/app/apps/insights/utils/category_explorer.py index 639750c..f7dc401 100644 --- a/app/apps/insights/utils/category_explorer.py +++ b/app/apps/insights/utils/category_explorer.py @@ -3,7 +3,7 @@ from django.db.models.functions import Coalesce from django.utils.translation import gettext_lazy as _ -def get_category_sums_by_account(queryset, category): +def get_category_sums_by_account(queryset, category=None): """ Returns income/expense sums per account for a specific category. """ @@ -11,10 +11,11 @@ def get_category_sums_by_account(queryset, category): queryset.filter(category=category) .values("account__name") .annotate( - income=Coalesce( + current_income=Coalesce( Sum( Case( When(type="IN", then="amount"), + When(is_paid=True, then="amount"), default=Value(0), output_field=DecimalField(max_digits=42, decimal_places=30), ) @@ -22,10 +23,35 @@ def get_category_sums_by_account(queryset, category): Value(0), output_field=DecimalField(max_digits=42, decimal_places=30), ), - expense=Coalesce( + current_expense=Coalesce( Sum( Case( When(type="EX", then=-F("amount")), + When(is_paid=True, then="amount"), + default=Value(0), + output_field=DecimalField(max_digits=42, decimal_places=30), + ) + ), + Value(0), + output_field=DecimalField(max_digits=42, decimal_places=30), + ), + projected_income=Coalesce( + Sum( + Case( + When(type="IN", then="amount"), + When(is_paid=False, then="amount"), + default=Value(0), + output_field=DecimalField(max_digits=42, decimal_places=30), + ) + ), + Value(0), + output_field=DecimalField(max_digits=42, decimal_places=30), + ), + projected_expense=Coalesce( + Sum( + Case( + When(type="EX", then=-F("amount")), + When(is_paid=False, then="amount"), default=Value(0), output_field=DecimalField(max_digits=42, decimal_places=30), ) @@ -41,18 +67,26 @@ def get_category_sums_by_account(queryset, category): "labels": [item["account__name"] for item in sums], "datasets": [ { - "label": _("Income"), - "data": [float(item["income"]) for item in sums], + "label": _("Current Income"), + "data": [float(item["current_income"]) for item in sums], }, { - "label": _("Expenses"), - "data": [float(item["expense"]) for item in sums], + "label": _("Current Expenses"), + "data": [float(item["current_expense"]) for item in sums], + }, + { + "label": _("Projected Income"), + "data": [float(item["projected_income"]) for item in sums], + }, + { + "label": _("Projected Expenses"), + "data": [float(item["projected_expense"]) for item in sums], }, ], } -def get_category_sums_by_currency(queryset, category): +def get_category_sums_by_currency(queryset, category=None): """ Returns income/expense sums per currency for a specific category. """ @@ -60,10 +94,11 @@ def get_category_sums_by_currency(queryset, category): queryset.filter(category=category) .values("account__currency__name") .annotate( - income=Coalesce( + current_income=Coalesce( Sum( Case( When(type="IN", then="amount"), + When(is_paid=True, then="amount"), default=Value(0), output_field=DecimalField(max_digits=42, decimal_places=30), ) @@ -71,10 +106,35 @@ def get_category_sums_by_currency(queryset, category): Value(0), output_field=DecimalField(max_digits=42, decimal_places=30), ), - expense=Coalesce( + current_expense=Coalesce( Sum( Case( When(type="EX", then=-F("amount")), + When(is_paid=True, then="amount"), + default=Value(0), + output_field=DecimalField(max_digits=42, decimal_places=30), + ) + ), + Value(0), + output_field=DecimalField(max_digits=42, decimal_places=30), + ), + projected_income=Coalesce( + Sum( + Case( + When(type="IN", then="amount"), + When(is_paid=False, then="amount"), + default=Value(0), + output_field=DecimalField(max_digits=42, decimal_places=30), + ) + ), + Value(0), + output_field=DecimalField(max_digits=42, decimal_places=30), + ), + projected_expense=Coalesce( + Sum( + Case( + When(type="EX", then=-F("amount")), + When(is_paid=False, then="amount"), default=Value(0), output_field=DecimalField(max_digits=42, decimal_places=30), ) @@ -90,12 +150,20 @@ def get_category_sums_by_currency(queryset, category): "labels": [item["account__currency__name"] for item in sums], "datasets": [ { - "label": _("Income"), - "data": [float(item["income"]) for item in sums], + "label": _("Current Income"), + "data": [float(item["current_income"]) for item in sums], }, { - "label": _("Expenses"), - "data": [float(item["expense"]) for item in sums], + "label": _("Current Expenses"), + "data": [float(item["current_expense"]) for item in sums], + }, + { + "label": _("Projected Income"), + "data": [float(item["projected_income"]) for item in sums], + }, + { + "label": _("Projected Expenses"), + "data": [float(item["projected_expense"]) for item in sums], }, ], } diff --git a/app/templates/insights/fragments/category_explorer/charts/account.html b/app/templates/insights/fragments/category_explorer/charts/account.html index a3b91f3..5ed053a 100644 --- a/app/templates/insights/fragments/category_explorer/charts/account.html +++ b/app/templates/insights/fragments/category_explorer/charts/account.html @@ -1,83 +1,100 @@ {% load i18n %} {% if account_data.labels %} -