Merge pull request #222

fix(net-worth): non-used currencies showing up on charts
This commit is contained in:
Herculino Trotta
2025-03-23 01:35:14 -03:00
committed by GitHub
2 changed files with 33 additions and 17 deletions

View File

@@ -2,25 +2,38 @@ from collections import OrderedDict, defaultdict
from decimal import Decimal from decimal import Decimal
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from django.db.models import Sum, Min, Max, Case, When, F, Value, DecimalField from django.db.models import Sum, Min, Max, Case, When, F, Value, DecimalField, Q
from django.db.models.functions import TruncMonth from django.db.models.functions import TruncMonth
from django.template.defaultfilters import date as date_filter from django.template.defaultfilters import date as date_filter
from django.utils import timezone from django.utils import timezone
from apps.accounts.models import Account from apps.accounts.models import Account
from apps.common.middleware.thread_local import get_current_user
from apps.currencies.models import Currency from apps.currencies.models import Currency
from apps.transactions.models import Transaction from apps.transactions.models import Transaction
def calculate_historical_currency_net_worth(is_paid=True): def calculate_historical_currency_net_worth(queryset):
transactions_params = {**{k: v for k, v in [("is_paid", True)] if is_paid}}
# Get all currencies and date range in a single query # Get all currencies and date range in a single query
aggregates = Transaction.objects.aggregate( aggregates = queryset.aggregate(
min_date=Min("reference_date"), min_date=Min("reference_date"),
max_date=Max("reference_date"), max_date=Max("reference_date"),
) )
currencies = list(Currency.objects.values_list("name", flat=True))
user = get_current_user()
currencies = list(
Currency.objects.filter(
Q(accounts__visibility="public")
| Q(accounts__owner=user)
| Q(accounts__shared_with=user)
| Q(accounts__visibility="private", accounts__owner=None),
accounts__is_archived=False,
accounts__isnull=False,
)
.values_list("name", flat=True)
.distinct()
)
if not aggregates.get("min_date"): if not aggregates.get("min_date"):
start_date = timezone.localdate(timezone.now()) start_date = timezone.localdate(timezone.now())
@@ -34,8 +47,7 @@ def calculate_historical_currency_net_worth(is_paid=True):
# Calculate cumulative balances for each account, currency, and month # Calculate cumulative balances for each account, currency, and month
cumulative_balances = ( cumulative_balances = (
Transaction.objects.filter(**transactions_params) queryset.annotate(month=TruncMonth("reference_date"))
.annotate(month=TruncMonth("reference_date"))
.values("account__currency__name", "month") .values("account__currency__name", "month")
.annotate( .annotate(
balance=Sum( balance=Sum(
@@ -94,15 +106,14 @@ def calculate_historical_currency_net_worth(is_paid=True):
return historical_net_worth return historical_net_worth
def calculate_historical_account_balance(is_paid=True): def calculate_historical_account_balance(queryset):
transactions_params = {**{k: v for k, v in [("is_paid", True)] if is_paid}}
# Get all accounts # Get all accounts
accounts = Account.objects.filter( accounts = Account.objects.filter(
is_archived=False, is_archived=False,
) )
# Get the date range # Get the date range
date_range = Transaction.objects.filter(**transactions_params).aggregate( date_range = queryset.aggregate(
min_date=Min("reference_date"), max_date=Max("reference_date") min_date=Min("reference_date"), max_date=Max("reference_date")
) )
@@ -118,8 +129,7 @@ def calculate_historical_account_balance(is_paid=True):
# Calculate balances for each account and month # Calculate balances for each account and month
balances = ( balances = (
Transaction.objects.filter(**transactions_params) queryset.annotate(month=TruncMonth("reference_date"))
.annotate(month=TruncMonth("reference_date"))
.values("account", "month") .values("account", "month")
.annotate( .annotate(
balance=Sum( balance=Sum(

View File

@@ -38,7 +38,9 @@ def net_worth_current(request):
transactions_queryset=transactions_account_queryset transactions_queryset=transactions_account_queryset
) )
historical_currency_net_worth = calculate_historical_currency_net_worth() historical_currency_net_worth = calculate_historical_currency_net_worth(
queryset=transactions_currency_queryset
)
labels = ( labels = (
list(historical_currency_net_worth.keys()) list(historical_currency_net_worth.keys())
@@ -71,7 +73,9 @@ def net_worth_current(request):
chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder) chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder)
historical_account_balance = calculate_historical_account_balance() historical_account_balance = calculate_historical_account_balance(
queryset=transactions_account_queryset
)
labels = ( labels = (
list(historical_account_balance.keys()) if historical_account_balance else [] list(historical_account_balance.keys()) if historical_account_balance else []
@@ -140,7 +144,7 @@ def net_worth_projected(request):
) )
historical_currency_net_worth = calculate_historical_currency_net_worth( historical_currency_net_worth = calculate_historical_currency_net_worth(
is_paid=False queryset=transactions_currency_queryset
) )
labels = ( labels = (
@@ -174,7 +178,9 @@ def net_worth_projected(request):
chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder) chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder)
historical_account_balance = calculate_historical_account_balance(is_paid=False) historical_account_balance = calculate_historical_account_balance(
queryset=transactions_account_queryset
)
labels = ( labels = (
list(historical_account_balance.keys()) if historical_account_balance else [] list(historical_account_balance.keys()) if historical_account_balance else []