mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-25 01:58:54 +02:00
fix: networth doesn't load if there aren't any transactions
This commit is contained in:
@@ -10,6 +10,7 @@ from django.db.models import Sum, Min, Max, Case, When, F, Value, DecimalField
|
|||||||
from django.db.models.functions import Coalesce
|
from django.db.models.functions import Coalesce
|
||||||
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.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from apps.accounts.models import Account
|
from apps.accounts.models import Account
|
||||||
@@ -88,18 +89,12 @@ def calculate_account_net_worth():
|
|||||||
|
|
||||||
|
|
||||||
def calculate_currency_net_worth():
|
def calculate_currency_net_worth():
|
||||||
# Calculate net worth and fetch currency details in a single query
|
# Subquery to calculate balance for each account
|
||||||
net_worth_data = (
|
balance_subquery = (
|
||||||
Transaction.objects.filter(is_paid=True)
|
Transaction.objects.filter(account=OuterRef("pk"), is_paid=True)
|
||||||
.values(
|
.values("account")
|
||||||
"account__currency__name",
|
|
||||||
"account__currency__code",
|
|
||||||
"account__currency__prefix",
|
|
||||||
"account__currency__suffix",
|
|
||||||
"account__currency__decimal_places",
|
|
||||||
)
|
|
||||||
.annotate(
|
.annotate(
|
||||||
amount=Sum(
|
balance=Sum(
|
||||||
Case(
|
Case(
|
||||||
When(type=Transaction.Type.INCOME, then=F("amount")),
|
When(type=Transaction.Type.INCOME, then=F("amount")),
|
||||||
When(type=Transaction.Type.EXPENSE, then=-F("amount")),
|
When(type=Transaction.Type.EXPENSE, then=-F("amount")),
|
||||||
@@ -108,19 +103,25 @@ def calculate_currency_net_worth():
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
.values("balance")
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create the net worth dictionary from the query results
|
# Main query to fetch all account data
|
||||||
|
accounts_data = Account.objects.annotate(
|
||||||
|
balance=Coalesce(Subquery(balance_subquery), Decimal("0"))
|
||||||
|
).select_related("currency")
|
||||||
|
|
||||||
net_worth = {}
|
net_worth = {}
|
||||||
for item in net_worth_data:
|
for item in accounts_data:
|
||||||
currency_name = item["account__currency__name"]
|
currency_name = item.currency.name
|
||||||
net_worth[currency_name] = {
|
net_worth[currency_name] = {
|
||||||
"amount": item["amount"] or Decimal("0"),
|
"amount": net_worth.get(currency_name, {}).get("amount", Decimal("0"))
|
||||||
"code": item["account__currency__code"],
|
+ item.balance,
|
||||||
|
"code": item.currency.code,
|
||||||
"name": currency_name,
|
"name": currency_name,
|
||||||
"prefix": item["account__currency__prefix"],
|
"prefix": item.currency.prefix,
|
||||||
"suffix": item["account__currency__suffix"],
|
"suffix": item.currency.suffix,
|
||||||
"decimal_places": item["account__currency__decimal_places"],
|
"decimal_places": item.currency.decimal_places,
|
||||||
}
|
}
|
||||||
|
|
||||||
return net_worth
|
return net_worth
|
||||||
@@ -134,8 +135,15 @@ def calculate_historical_currency_net_worth():
|
|||||||
)
|
)
|
||||||
currencies = list(Currency.objects.values_list("name", flat=True))
|
currencies = list(Currency.objects.values_list("name", flat=True))
|
||||||
|
|
||||||
start_date = aggregates["min_date"].replace(day=1)
|
if not aggregates.get("min_date"):
|
||||||
end_date = aggregates["max_date"].replace(day=1)
|
start_date = timezone.localdate(timezone.now())
|
||||||
|
else:
|
||||||
|
start_date = aggregates["min_date"].replace(day=1)
|
||||||
|
|
||||||
|
if not aggregates.get("max_date"):
|
||||||
|
end_date = timezone.localdate(timezone.now()) + relativedelta(months=1)
|
||||||
|
else:
|
||||||
|
end_date = aggregates["max_date"].replace(day=1)
|
||||||
|
|
||||||
# Calculate cumulative balances for each account, currency, and month
|
# Calculate cumulative balances for each account, currency, and month
|
||||||
cumulative_balances = (
|
cumulative_balances = (
|
||||||
@@ -184,7 +192,7 @@ def calculate_historical_currency_net_worth():
|
|||||||
if balance_change != Decimal("0.00"):
|
if balance_change != Decimal("0.00"):
|
||||||
totals_changed = True
|
totals_changed = True
|
||||||
|
|
||||||
if totals_changed:
|
if totals_changed or not historical_net_worth:
|
||||||
historical_net_worth[month_str] = running_totals.copy()
|
historical_net_worth[month_str] = running_totals.copy()
|
||||||
last_recorded_totals = running_totals.copy()
|
last_recorded_totals = running_totals.copy()
|
||||||
|
|
||||||
@@ -207,8 +215,16 @@ def calculate_historical_account_balance():
|
|||||||
date_range = Transaction.objects.filter(is_paid=True).aggregate(
|
date_range = Transaction.objects.filter(is_paid=True).aggregate(
|
||||||
min_date=Min("reference_date"), max_date=Max("reference_date")
|
min_date=Min("reference_date"), max_date=Max("reference_date")
|
||||||
)
|
)
|
||||||
start_date = date_range["min_date"].replace(day=1)
|
|
||||||
end_date = date_range["max_date"].replace(day=1)
|
if not date_range.get("min_date"):
|
||||||
|
start_date = timezone.localdate(timezone.now())
|
||||||
|
else:
|
||||||
|
start_date = date_range["min_date"].replace(day=1)
|
||||||
|
|
||||||
|
if not date_range.get("max_date"):
|
||||||
|
end_date = timezone.localdate(timezone.now()) + relativedelta(months=1)
|
||||||
|
else:
|
||||||
|
end_date = date_range["max_date"].replace(day=1)
|
||||||
|
|
||||||
# Calculate balances for each account and month
|
# Calculate balances for each account and month
|
||||||
balances = (
|
balances = (
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
from django.http import JsonResponse
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from apps.net_worth.utils.calculate_net_worth import (
|
from apps.net_worth.utils.calculate_net_worth import (
|
||||||
calculate_currency_net_worth,
|
calculate_currency_net_worth,
|
||||||
@@ -13,7 +9,6 @@ from apps.net_worth.utils.calculate_net_worth import (
|
|||||||
calculate_account_net_worth,
|
calculate_account_net_worth,
|
||||||
calculate_historical_account_balance,
|
calculate_historical_account_balance,
|
||||||
)
|
)
|
||||||
from apps.currencies.models import Currency
|
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
@@ -21,15 +16,24 @@ def net_worth_main(request):
|
|||||||
currency_net_worth = calculate_currency_net_worth()
|
currency_net_worth = calculate_currency_net_worth()
|
||||||
account_net_worth = calculate_account_net_worth()
|
account_net_worth = calculate_account_net_worth()
|
||||||
|
|
||||||
historical_net_worth = calculate_historical_currency_net_worth()
|
historical_currency_net_worth = calculate_historical_currency_net_worth()
|
||||||
|
|
||||||
labels = list(historical_net_worth.keys())
|
labels = (
|
||||||
currencies = list(historical_net_worth[labels[0]].keys())
|
list(historical_currency_net_worth.keys())
|
||||||
|
if historical_currency_net_worth
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
currencies = (
|
||||||
|
list(historical_currency_net_worth[labels[0]].keys())
|
||||||
|
if historical_currency_net_worth
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
|
||||||
datasets = []
|
datasets = []
|
||||||
for i, currency in enumerate(currencies):
|
for i, currency in enumerate(currencies):
|
||||||
data = [
|
data = [
|
||||||
float(month_data[currency]) for month_data in historical_net_worth.values()
|
float(month_data[currency])
|
||||||
|
for month_data in historical_currency_net_worth.values()
|
||||||
]
|
]
|
||||||
datasets.append(
|
datasets.append(
|
||||||
{
|
{
|
||||||
@@ -47,8 +51,14 @@ def net_worth_main(request):
|
|||||||
|
|
||||||
historical_account_balance = calculate_historical_account_balance()
|
historical_account_balance = calculate_historical_account_balance()
|
||||||
|
|
||||||
labels = list(historical_account_balance.keys())
|
labels = (
|
||||||
accounts = list(historical_account_balance[labels[0]].keys())
|
list(historical_account_balance.keys()) if historical_account_balance else []
|
||||||
|
)
|
||||||
|
accounts = (
|
||||||
|
list(historical_account_balance[labels[0]].keys())
|
||||||
|
if historical_account_balance
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
|
||||||
datasets = []
|
datasets = []
|
||||||
for i, account in enumerate(accounts):
|
for i, account in enumerate(accounts):
|
||||||
|
|||||||
Reference in New Issue
Block a user