mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-07-15 09:12:39 +02:00
feat(networth): add projected view
This commit is contained in:
@@ -3,5 +3,6 @@ from django.urls import path
|
|||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("net-worth/", views.net_worth_main, name="net_worth"),
|
path("net-worth/current/", views.net_worth_current, name="net_worth_current"),
|
||||||
|
path("net-worth/projected/", views.net_worth_projected, name="net_worth_projected"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ from apps.currencies.utils.convert import convert
|
|||||||
from apps.transactions.models import Transaction
|
from apps.transactions.models import Transaction
|
||||||
|
|
||||||
|
|
||||||
def calculate_historical_currency_net_worth():
|
def calculate_historical_currency_net_worth(is_paid=True):
|
||||||
|
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 = Transaction.objects.aggregate(
|
||||||
min_date=Min("reference_date"),
|
min_date=Min("reference_date"),
|
||||||
@@ -39,7 +41,7 @@ def calculate_historical_currency_net_worth():
|
|||||||
|
|
||||||
# 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(is_paid=True)
|
Transaction.objects.filter(**transactions_params)
|
||||||
.annotate(month=TruncMonth("reference_date"))
|
.annotate(month=TruncMonth("reference_date"))
|
||||||
.values("account__currency__name", "month")
|
.values("account__currency__name", "month")
|
||||||
.annotate(
|
.annotate(
|
||||||
@@ -99,12 +101,13 @@ def calculate_historical_currency_net_worth():
|
|||||||
return historical_net_worth
|
return historical_net_worth
|
||||||
|
|
||||||
|
|
||||||
def calculate_historical_account_balance():
|
def calculate_historical_account_balance(is_paid=True):
|
||||||
|
transactions_params = {**{k: v for k, v in [("is_paid", True)] if is_paid}}
|
||||||
# Get all accounts
|
# Get all accounts
|
||||||
accounts = Account.objects.filter(is_archived=False)
|
accounts = Account.objects.filter(is_archived=False)
|
||||||
|
|
||||||
# Get the date range
|
# Get the date range
|
||||||
date_range = Transaction.objects.filter(is_paid=True).aggregate(
|
date_range = Transaction.objects.filter(**transactions_params).aggregate(
|
||||||
min_date=Min("reference_date"), max_date=Max("reference_date")
|
min_date=Min("reference_date"), max_date=Max("reference_date")
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -120,7 +123,7 @@ def calculate_historical_account_balance():
|
|||||||
|
|
||||||
# Calculate balances for each account and month
|
# Calculate balances for each account and month
|
||||||
balances = (
|
balances = (
|
||||||
Transaction.objects.filter(is_paid=True)
|
Transaction.objects.filter(**transactions_params)
|
||||||
.annotate(month=TruncMonth("reference_date"))
|
.annotate(month=TruncMonth("reference_date"))
|
||||||
.values("account", "month")
|
.values("account", "month")
|
||||||
.annotate(
|
.annotate(
|
||||||
|
|||||||
+101
-1
@@ -14,7 +14,7 @@ from apps.transactions.utils.calculations import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def net_worth_main(request):
|
def net_worth_current(request):
|
||||||
transactions_currency_queryset = Transaction.objects.filter(
|
transactions_currency_queryset = Transaction.objects.filter(
|
||||||
is_paid=True, account__is_archived=False
|
is_paid=True, account__is_archived=False
|
||||||
).order_by(
|
).order_by(
|
||||||
@@ -110,3 +110,103 @@ def net_worth_main(request):
|
|||||||
"accounts": accounts,
|
"accounts": accounts,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def net_worth_projected(request):
|
||||||
|
transactions_currency_queryset = Transaction.objects.filter(
|
||||||
|
account__is_archived=False
|
||||||
|
).order_by(
|
||||||
|
"account__currency__name",
|
||||||
|
)
|
||||||
|
transactions_account_queryset = Transaction.objects.filter(
|
||||||
|
account__is_archived=False
|
||||||
|
).order_by(
|
||||||
|
"account__group__name",
|
||||||
|
"account__name",
|
||||||
|
)
|
||||||
|
|
||||||
|
currency_net_worth = calculate_currency_totals(
|
||||||
|
transactions_queryset=transactions_currency_queryset
|
||||||
|
)
|
||||||
|
account_net_worth = calculate_account_totals(
|
||||||
|
transactions_queryset=transactions_account_queryset
|
||||||
|
)
|
||||||
|
|
||||||
|
historical_currency_net_worth = calculate_historical_currency_net_worth(
|
||||||
|
is_paid=False
|
||||||
|
)
|
||||||
|
|
||||||
|
labels = (
|
||||||
|
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 = []
|
||||||
|
for i, currency in enumerate(currencies):
|
||||||
|
data = [
|
||||||
|
float(month_data[currency])
|
||||||
|
for month_data in historical_currency_net_worth.values()
|
||||||
|
]
|
||||||
|
datasets.append(
|
||||||
|
{
|
||||||
|
"label": currency,
|
||||||
|
"data": data,
|
||||||
|
"yAxisID": f"y{i}",
|
||||||
|
"fill": False,
|
||||||
|
"tension": 0.1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
chart_data_currency = {"labels": labels, "datasets": datasets}
|
||||||
|
|
||||||
|
chart_data_currency_json = json.dumps(chart_data_currency, cls=DjangoJSONEncoder)
|
||||||
|
|
||||||
|
historical_account_balance = calculate_historical_account_balance(is_paid=False)
|
||||||
|
|
||||||
|
labels = (
|
||||||
|
list(historical_account_balance.keys()) if historical_account_balance else []
|
||||||
|
)
|
||||||
|
accounts = (
|
||||||
|
list(historical_account_balance[labels[0]].keys())
|
||||||
|
if historical_account_balance
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
|
||||||
|
datasets = []
|
||||||
|
for i, account in enumerate(accounts):
|
||||||
|
data = [
|
||||||
|
float(month_data[account])
|
||||||
|
for month_data in historical_account_balance.values()
|
||||||
|
]
|
||||||
|
datasets.append(
|
||||||
|
{
|
||||||
|
"label": account,
|
||||||
|
"data": data,
|
||||||
|
"fill": False,
|
||||||
|
"tension": 0.1,
|
||||||
|
"yAxisID": f"y-axis-{i}", # Assign each dataset to its own Y-axis
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
chart_data_accounts = {"labels": labels, "datasets": datasets}
|
||||||
|
|
||||||
|
chart_data_accounts_json = json.dumps(chart_data_accounts, cls=DjangoJSONEncoder)
|
||||||
|
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"net_worth/net_worth.html",
|
||||||
|
{
|
||||||
|
"currency_net_worth": currency_net_worth,
|
||||||
|
"account_net_worth": account_net_worth,
|
||||||
|
"chart_data_currency_json": chart_data_currency_json,
|
||||||
|
"currencies": currencies,
|
||||||
|
"chart_data_accounts_json": chart_data_accounts_json,
|
||||||
|
"accounts": accounts,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|||||||
@@ -31,11 +31,19 @@
|
|||||||
href="{% url 'calendar_index' %}">{% translate 'Calendar' %}</a></li>
|
href="{% url 'calendar_index' %}">{% translate 'Calendar' %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link {% active_link views='net_worth' %}"
|
<a class="nav-link dropdown-toggle {% active_link views='net_worth_current||net_worth_projected' %}"
|
||||||
href="{% url 'net_worth' %}">
|
href="#" role="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false">
|
||||||
{% translate 'Net Worth' %}
|
{% translate 'Net Worth' %}
|
||||||
</a>
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a class="dropdown-item {% active_link views='net_worth_current' %}"
|
||||||
|
href="{% url 'net_worth_current' %}">{% translate 'Current' %}</a></li>
|
||||||
|
<li><a class="dropdown-item {% active_link views='net_worth_projected' %}"
|
||||||
|
href="{% url 'net_worth_projected' %}">{% translate 'Projected' %}</a></li>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle {% active_link views='installment_plans_index||recurring_trasanctions_index||transactions_all_index' %}"
|
<a class="nav-link dropdown-toggle {% active_link views='installment_plans_index||recurring_trasanctions_index||transactions_all_index' %}"
|
||||||
|
|||||||
Reference in New Issue
Block a user