mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-03-26 11:21:24 +01:00
feat: add account and currency info to monthly view
This commit is contained in:
@@ -19,4 +19,19 @@ urlpatterns = [
|
||||
views.monthly_summary,
|
||||
name="monthly_summary",
|
||||
),
|
||||
path(
|
||||
"monthly/<int:month>/<int:year>/summary/accounts/",
|
||||
views.monthly_account_summary,
|
||||
name="monthly_account_summary",
|
||||
),
|
||||
path(
|
||||
"monthly/<int:month>/<int:year>/summary/currencies/",
|
||||
views.monthly_currency_summary,
|
||||
name="monthly_currency_summary",
|
||||
),
|
||||
path(
|
||||
"monthly/summary/select/<str:selected>/",
|
||||
views.monthly_summary_select,
|
||||
name="monthly_summary_select",
|
||||
),
|
||||
]
|
||||
|
||||
@@ -2,6 +2,7 @@ from django.contrib.auth.decorators import login_required
|
||||
from django.db.models import (
|
||||
Q,
|
||||
)
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render, redirect
|
||||
from django.utils import timezone
|
||||
from django.views.decorators.http import require_http_methods
|
||||
@@ -16,6 +17,7 @@ from apps.transactions.models import Transaction
|
||||
from apps.transactions.utils.calculations import (
|
||||
calculate_currency_totals,
|
||||
calculate_percentage_distribution,
|
||||
calculate_account_totals,
|
||||
)
|
||||
from apps.transactions.utils.default_ordering import default_order
|
||||
|
||||
@@ -31,6 +33,7 @@ def index(request):
|
||||
@require_http_methods(["GET"])
|
||||
def monthly_overview(request, month: int, year: int):
|
||||
order = request.session.get("monthly_transactions_order", "default")
|
||||
summary_tab = request.session.get("monthly_summary_tab", "summary")
|
||||
|
||||
if month < 1 or month > 12:
|
||||
from django.http import Http404
|
||||
@@ -57,6 +60,7 @@ def monthly_overview(request, month: int, year: int):
|
||||
"previous_year": previous_year,
|
||||
"filter": f,
|
||||
"order": order,
|
||||
"summary_tab": summary_tab,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -131,3 +135,61 @@ def monthly_summary(request, month: int, year: int):
|
||||
"monthly_overview/fragments/monthly_summary.html",
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def monthly_account_summary(request, month: int, year: int):
|
||||
# Base queryset with all required filters
|
||||
base_queryset = Transaction.objects.filter(
|
||||
reference_date__year=year,
|
||||
reference_date__month=month,
|
||||
).exclude(Q(category__mute=True) & ~Q(category=None))
|
||||
|
||||
account_data = calculate_account_totals(transactions_queryset=base_queryset.all())
|
||||
account_percentages = calculate_percentage_distribution(account_data)
|
||||
|
||||
context = {
|
||||
"account_data": account_data,
|
||||
"account_percentages": account_percentages,
|
||||
}
|
||||
|
||||
return render(
|
||||
request,
|
||||
"monthly_overview/fragments/monthly_account_summary.html",
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def monthly_currency_summary(request, month: int, year: int):
|
||||
# Base queryset with all required filters
|
||||
base_queryset = Transaction.objects.filter(
|
||||
reference_date__year=year,
|
||||
reference_date__month=month,
|
||||
).exclude(Q(category__mute=True) & ~Q(category=None))
|
||||
|
||||
currency_data = calculate_currency_totals(base_queryset.all(), ignore_empty=True)
|
||||
currency_percentages = calculate_percentage_distribution(currency_data)
|
||||
|
||||
context = {
|
||||
"currency_data": currency_data,
|
||||
"currency_percentages": currency_percentages,
|
||||
}
|
||||
|
||||
return render(
|
||||
request, "monthly_overview/fragments/monthly_currency_summary.html", context
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def monthly_summary_select(request, selected):
|
||||
request.session["monthly_summary_tab"] = selected
|
||||
|
||||
return HttpResponse(
|
||||
status=204,
|
||||
)
|
||||
|
||||
@@ -11,6 +11,21 @@ urlpatterns = [
|
||||
views.transaction_all_summary,
|
||||
name="transactions_all_summary",
|
||||
),
|
||||
path(
|
||||
"transactions/summary/account/",
|
||||
views.transaction_all_account_summary,
|
||||
name="transaction_all_account_summary",
|
||||
),
|
||||
path(
|
||||
"transactions/summary/currency/",
|
||||
views.transaction_all_currency_summary,
|
||||
name="transaction_all_currency_summary",
|
||||
),
|
||||
path(
|
||||
"transactions/summary/select/<str:selected>/",
|
||||
views.transaction_all_summary_select,
|
||||
name="transaction_all_summary_select",
|
||||
),
|
||||
path(
|
||||
"transactions/actions/pay/",
|
||||
views.bulk_pay_transactions,
|
||||
|
||||
@@ -314,9 +314,13 @@ def transaction_pay(request, transaction_id):
|
||||
@require_http_methods(["GET"])
|
||||
def transaction_all_index(request):
|
||||
order = request.session.get("all_transactions_order", "default")
|
||||
summary_tab = request.session.get("transaction_all_summary_tab", "currency")
|
||||
|
||||
f = TransactionsFilter(request.GET)
|
||||
return render(
|
||||
request, "transactions/pages/transactions.html", {"filter": f, "order": order}
|
||||
request,
|
||||
"transactions/pages/transactions.html",
|
||||
{"filter": f, "order": order, "summary_tab": summary_tab},
|
||||
)
|
||||
|
||||
|
||||
@@ -382,16 +386,74 @@ def transaction_all_summary(request):
|
||||
account_percentages = calculate_percentage_distribution(account_data)
|
||||
|
||||
context = {
|
||||
"income_current": remove_falsey_entries(currency_data, "income_current"),
|
||||
"income_projected": remove_falsey_entries(currency_data, "income_projected"),
|
||||
"expense_current": remove_falsey_entries(currency_data, "expense_current"),
|
||||
"expense_projected": remove_falsey_entries(currency_data, "expense_projected"),
|
||||
"total_current": remove_falsey_entries(currency_data, "total_current"),
|
||||
"total_final": remove_falsey_entries(currency_data, "total_final"),
|
||||
"total_projected": remove_falsey_entries(currency_data, "total_projected"),
|
||||
"currency_data": currency_data,
|
||||
"currency_percentages": currency_percentages,
|
||||
"account_data": account_data,
|
||||
"account_percentages": account_percentages,
|
||||
}
|
||||
|
||||
return render(request, "transactions/fragments/summary.html", context)
|
||||
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def transaction_all_account_summary(request):
|
||||
transactions = Transaction.objects.prefetch_related(
|
||||
"account",
|
||||
"account__group",
|
||||
"category",
|
||||
"tags",
|
||||
"account__exchange_currency",
|
||||
"account__currency",
|
||||
"installment_plan",
|
||||
).all()
|
||||
|
||||
f = TransactionsFilter(request.GET, queryset=transactions)
|
||||
|
||||
account_data = calculate_account_totals(transactions_queryset=f.qs.all())
|
||||
account_percentages = calculate_percentage_distribution(account_data)
|
||||
|
||||
context = {
|
||||
"account_data": account_data,
|
||||
"account_percentages": account_percentages,
|
||||
}
|
||||
|
||||
return render(request, "transactions/fragments/all_account_summary.html", context)
|
||||
|
||||
|
||||
@only_htmx
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def transaction_all_currency_summary(request):
|
||||
transactions = Transaction.objects.prefetch_related(
|
||||
"account",
|
||||
"account__group",
|
||||
"category",
|
||||
"tags",
|
||||
"account__exchange_currency",
|
||||
"account__currency",
|
||||
"installment_plan",
|
||||
).all()
|
||||
|
||||
f = TransactionsFilter(request.GET, queryset=transactions)
|
||||
|
||||
currency_data = calculate_currency_totals(f.qs.all(), ignore_empty=True)
|
||||
currency_percentages = calculate_percentage_distribution(currency_data)
|
||||
|
||||
context = {
|
||||
"currency_data": currency_data,
|
||||
"currency_percentages": currency_percentages,
|
||||
}
|
||||
|
||||
return render(request, "transactions/fragments/all_currency_summary.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def transaction_all_summary_select(request, selected):
|
||||
request.session["transaction_all_summary_tab"] = selected
|
||||
|
||||
return HttpResponse(
|
||||
status=204,
|
||||
)
|
||||
|
||||
184
app/templates/cotton/ui/account_card.html
Normal file
184
app/templates/cotton/ui/account_card.html
Normal file
@@ -0,0 +1,184 @@
|
||||
{% load tools %}
|
||||
{% load i18n %}
|
||||
<div class="col card shadow">
|
||||
<div class="card-body">
|
||||
{% if account.account.group %}
|
||||
<div class="tw-text-sm mb-2">
|
||||
<span class="badge text-bg-primary ">{{ account.account.group }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<h5 class="card-title">
|
||||
{{ account.account.name }}
|
||||
</h5>
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="account.income_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.income_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.currency.income_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="account.expense_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.expense_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.expense_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_projected > 0 %}green{% elif account.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged.total_projected and account.exchanged.total_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="account.income_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.income_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.income_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="account.expense_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.expense_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.expense_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_current > 0 %}green{% elif account.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.total_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'final total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_final"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.total_final %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_final"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% with p=percentages|get_dict_item:account_id %}
|
||||
<div class="my-3">
|
||||
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
||||
</div>
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
182
app/templates/cotton/ui/currency_card.html
Normal file
182
app/templates/cotton/ui/currency_card.html
Normal file
@@ -0,0 +1,182 @@
|
||||
{% load tools %}
|
||||
{% load i18n %}
|
||||
<div class="col card shadow">
|
||||
<div class="card-body">
|
||||
<div class="tw-text-sm mb-2">
|
||||
<span class="badge text-bg-primary">{{ currency.currency.code }}</span>
|
||||
</div>
|
||||
<h5 class="card-title">
|
||||
{{ currency.currency.name }}
|
||||
</h5>
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="currency.income_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.income_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.currency.income_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="currency.expense_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.expense_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.expense_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="currency.total_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_projected > 0 %}green{% elif currency.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged.total_projected and currency.exchanged.total_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="currency.income_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.income_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.income_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="currency.expense_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.expense_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.expense_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="currency.total_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_current > 0 %}green{% elif currency.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.total_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'final total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="currency.total_final"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.total_final %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_final"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% with p=percentages|get_dict_item:currency_id %}
|
||||
<div class="my-3">
|
||||
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
||||
</div>
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,16 +1,18 @@
|
||||
{% load i18n %}
|
||||
<div class="tw-sticky tw-bottom-4 tw-left-0 tw-right-0 tw-z-50 tw-hidden mx-auto tw-w-fit" id="actions-bar"
|
||||
_="on change from #transactions-list or htmx:afterSettle from window
|
||||
if no <input[type='checkbox']:checked/> in #transactions-list
|
||||
if #actions-bar
|
||||
add .slide-in-bottom-reverse then settle
|
||||
then add .tw-hidden to #actions-bar
|
||||
then remove .slide-in-bottom-reverse
|
||||
end
|
||||
else
|
||||
if #actions-bar
|
||||
remove .tw-hidden from #actions-bar
|
||||
then trigger selected_transactions_updated
|
||||
if #actions-bar then
|
||||
if no <input[type='checkbox']:checked/> in #transactions-list
|
||||
if #actions-bar
|
||||
add .slide-in-bottom-reverse then settle
|
||||
then add .tw-hidden to #actions-bar
|
||||
then remove .slide-in-bottom-reverse
|
||||
end
|
||||
else
|
||||
if #actions-bar
|
||||
remove .tw-hidden from #actions-bar
|
||||
then trigger selected_transactions_updated
|
||||
end
|
||||
end
|
||||
end
|
||||
end">
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{% load tools %}
|
||||
{% load i18n %}
|
||||
{% load currency_display %}
|
||||
|
||||
<div class="row row-cols-1 g-4 mt-1 mb-3">
|
||||
{% for account_id, account in account_data.items %}
|
||||
<div class="col">
|
||||
<c-ui.account_card :account="account" :account_id="account_id"
|
||||
:percentages="account_percentages"></c-ui.account_card>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,16 @@
|
||||
{% load tools %}
|
||||
{% load i18n %}
|
||||
{% load currency_display %}
|
||||
<div class="row row-cols-1 g-4 mt-1 mb-3">
|
||||
{% for currency_id, currency in currency_data.items %}
|
||||
<div class="col">
|
||||
<c-ui.currency_card :currency="currency" :currency_id="currency_id"
|
||||
:percentages="currency_percentages"></c-ui.currency_card>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% load currency_display %}
|
||||
<div class="row row-cols-1 g-4 mb-3">
|
||||
<div class="row row-cols-1 g-4 mt-1 mb-3">
|
||||
{# Daily Spending#}
|
||||
<div class="col">
|
||||
<c-ui.info-card color="yellow" icon="fa-solid fa-calendar-day" title="{% trans 'Daily Spending Allowance' %}" help_text={% trans "This is the final total divided by the remaining days in the month" %}>
|
||||
@@ -252,6 +252,7 @@
|
||||
</div>
|
||||
</c-ui.info-card>
|
||||
</div>
|
||||
{% if percentages %}
|
||||
<div class="col">
|
||||
<c-ui.info-card color="yellow" icon="fa-solid fa-percent" title="{% trans 'Distribution' %}">
|
||||
{% for p in percentages.values %}
|
||||
@@ -260,4 +261,5 @@
|
||||
{% endfor %}
|
||||
</c-ui.info-card>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -13,89 +13,172 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container px-md-3 py-3 column-gap-5">
|
||||
<div class="row mb-3 gx-xl-4 gy-3 mb-4">
|
||||
{# Date picker#}
|
||||
<div class="col-12 col-xl-4 flex-row align-items-center d-flex">
|
||||
<div class="tw-text-base h-100 align-items-center d-flex">
|
||||
<a role="button"
|
||||
class="pe-4 py-2"
|
||||
hx-boost="true"
|
||||
hx-trigger="click, previous_month from:window"
|
||||
href="{% url 'monthly_overview' month=previous_month year=previous_year %}"><i
|
||||
class="fa-solid fa-chevron-left"></i></a>
|
||||
</div>
|
||||
<div class="tw-text-3xl fw-bold font-monospace tw-w-full text-center"
|
||||
hx-get="{% url 'month_year_picker' %}"
|
||||
hx-target="#generic-offcanvas-left"
|
||||
hx-trigger="click, date_picker from:window"
|
||||
hx-vals='{"month": {{ month }}, "year": {{ year }}, "for": "monthly_overview", "field": "reference_date"}' role="button">
|
||||
{{ month|month_name }} {{ year }}
|
||||
</div>
|
||||
<div class="tw-text-base mx-2 h-100 align-items-center d-flex">
|
||||
<a role="button"
|
||||
class="ps-3 py-2"
|
||||
hx-boost="true"
|
||||
hx-trigger="click, next_month from:window"
|
||||
href="{% url 'monthly_overview' month=next_month year=next_year %}">
|
||||
<i class="fa-solid fa-chevron-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{# Action buttons#}
|
||||
<div class="col-12 col-xl-8">
|
||||
<c-ui.quick-transactions-buttons
|
||||
:year="year"
|
||||
:month="month"
|
||||
></c-ui.quick-transactions-buttons>
|
||||
</div>
|
||||
</div>
|
||||
{# Monthly summary#}
|
||||
<div class="row gx-xl-4 gy-3">
|
||||
<div class="col-12 col-xl-4 order-0 order-xl-2">
|
||||
<div id="summary" hx-get="{% url 'monthly_summary' month=month year=year %}" class="show-loading"
|
||||
hx-trigger="load, updated from:window, selective_update from:window">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-8 order-2 order-xl-1">
|
||||
<div class="row mb-1">
|
||||
<div class="col-sm-6 col-12">
|
||||
{# Filter transactions button #}
|
||||
<button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-filter" aria-expanded="false" aria-controls="collapse-filter">
|
||||
<i class="fa-solid fa-filter fa-fw me-2"></i>{% translate 'Filter transactions' %}
|
||||
</button>
|
||||
<div class="container px-md-3 py-3 column-gap-5">
|
||||
<div class="row mb-3 gx-xl-4 gy-3 mb-4">
|
||||
{# Date picker#}
|
||||
<div class="col-12 col-xl-4 flex-row align-items-center d-flex">
|
||||
<div class="tw-text-base h-100 align-items-center d-flex">
|
||||
<a role="button"
|
||||
class="pe-4 py-2"
|
||||
hx-boost="true"
|
||||
hx-trigger="click, previous_month from:window"
|
||||
href="{% url 'monthly_overview' month=previous_month year=previous_year %}"><i
|
||||
class="fa-solid fa-chevron-left"></i></a>
|
||||
</div>
|
||||
{# Ordering button#}
|
||||
<div class="col-sm-6 col-12 tw-content-center my-3 my-sm-0">
|
||||
<div class="text-sm-end" _="on change trigger updated on window">
|
||||
<label for="order">{% translate "Order by" %}</label>
|
||||
<select class="tw-border-0 focus-visible:tw-outline-0 w-full pe-2 tw-leading-normal text-bg-tertiary tw-font-medium rounded" name="order" id="order">
|
||||
<option value="default" {% if order == 'default' %}selected{% endif %}>{% translate 'Default' %}</option>
|
||||
<option value="older" {% if order == 'older' %}selected{% endif %}>{% translate 'Oldest first' %}</option>
|
||||
<option value="newer" {% if order == 'newer' %}selected{% endif %}>{% translate 'Newest first' %}</option>
|
||||
</select>
|
||||
<div class="tw-text-3xl fw-bold font-monospace tw-w-full text-center"
|
||||
hx-get="{% url 'month_year_picker' %}"
|
||||
hx-target="#generic-offcanvas-left"
|
||||
hx-trigger="click, date_picker from:window"
|
||||
hx-vals='{"month": {{ month }}, "year": {{ year }}, "for": "monthly_overview", "field": "reference_date"}'
|
||||
role="button">
|
||||
{{ month|month_name }} {{ year }}
|
||||
</div>
|
||||
<div class="tw-text-base mx-2 h-100 align-items-center d-flex">
|
||||
<a role="button"
|
||||
class="ps-3 py-2"
|
||||
hx-boost="true"
|
||||
hx-trigger="click, next_month from:window"
|
||||
href="{% url 'monthly_overview' month=next_month year=next_year %}">
|
||||
<i class="fa-solid fa-chevron-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{# Action buttons#}
|
||||
<div class="col-12 col-xl-8">
|
||||
<c-ui.quick-transactions-buttons
|
||||
:year="year"
|
||||
:month="month"
|
||||
></c-ui.quick-transactions-buttons>
|
||||
</div>
|
||||
</div>
|
||||
{# Monthly summary#}
|
||||
<div class="row gx-xl-4 gy-3">
|
||||
<div class="col-12 col-xl-4 order-0 order-xl-2">
|
||||
<ul class="nav nav-tabs" id="monthly-summary" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link {% if summary_tab == 'summary' %}active{% endif %}"
|
||||
id="summary-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#summary-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="summary-tab-pane"
|
||||
_="on click fetch {% url 'monthly_summary_select' selected='summary' %}"
|
||||
aria-selected="{% if summary_tab == 'summary' or not summary_tab %}true{% else %}false{% endif %}">
|
||||
{% trans 'Summary' %}
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link {% if summary_tab == 'currency' %}active{% endif %}"
|
||||
id="currency-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#currency-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="currency-tab-pane"
|
||||
_="on click fetch {% url 'monthly_summary_select' selected='currency' %}"
|
||||
aria-selected="{% if summary_tab == 'currency' %}true{% else %}false{% endif %}">
|
||||
{% trans 'Currencies' %}
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link {% if summary_tab == 'account' %}active{% endif %}"
|
||||
id="account-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#account-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="account-tab-pane"
|
||||
_="on click fetch {% url 'monthly_summary_select' selected='account' %}"
|
||||
aria-selected="{% if summary_tab == 'account' %}true{% else %}false{% endif %}">
|
||||
{% trans 'Accounts' %}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" id="monthly-summary-content">
|
||||
<div class="tab-pane fade {% if summary_tab == 'summary' %}show active{% endif %}"
|
||||
id="summary-tab-pane"
|
||||
role="tabpanel"
|
||||
aria-labelledby="summary-tab"
|
||||
tabindex="0">
|
||||
<div id="summary"
|
||||
hx-get="{% url 'monthly_summary' month=month year=year %}"
|
||||
class="show-loading"
|
||||
hx-trigger="load, updated from:window, selective_update from:window">
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade {% if summary_tab == 'currency' %}show active{% endif %}"
|
||||
id="currency-tab-pane"
|
||||
role="tabpanel"
|
||||
aria-labelledby="currency-tab"
|
||||
tabindex="0">
|
||||
<div id="currency-summary"
|
||||
hx-get="{% url 'monthly_currency_summary' month=month year=year %}"
|
||||
class="show-loading"
|
||||
hx-trigger="load, updated from:window, selective_update from:window">
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade {% if summary_tab == 'account' %}show active{% endif %}"
|
||||
id="account-tab-pane"
|
||||
role="tabpanel"
|
||||
aria-labelledby="account-tab"
|
||||
tabindex="0">
|
||||
<div id="account-summary"
|
||||
hx-get="{% url 'monthly_account_summary' month=month year=year %}"
|
||||
class="show-loading"
|
||||
hx-trigger="load, updated from:window, selective_update from:window">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{# Filter transactions form#}
|
||||
<div class="collapse" id="collapse-filter">
|
||||
<div class="card card-body">
|
||||
<form _="on change or submit or search trigger updated on window end
|
||||
<div class="col-12 col-xl-8 order-2 order-xl-1">
|
||||
<div class="row mb-1">
|
||||
<div class="col-sm-6 col-12">
|
||||
{# Filter transactions button #}
|
||||
<button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#collapse-filter" aria-expanded="false"
|
||||
aria-controls="collapse-filter">
|
||||
<i class="fa-solid fa-filter fa-fw me-2"></i>{% translate 'Filter transactions' %}
|
||||
</button>
|
||||
</div>
|
||||
{# Ordering button#}
|
||||
<div class="col-sm-6 col-12 tw-content-center my-3 my-sm-0">
|
||||
<div class="text-sm-end" _="on change trigger updated on window">
|
||||
<label for="order">{% translate "Order by" %}</label>
|
||||
<select
|
||||
class="tw-border-0 focus-visible:tw-outline-0 w-full pe-2 tw-leading-normal text-bg-tertiary tw-font-medium rounded"
|
||||
name="order" id="order">
|
||||
<option value="default"
|
||||
{% if order == 'default' %}selected{% endif %}>{% translate 'Default' %}</option>
|
||||
<option value="older"
|
||||
{% if order == 'older' %}selected{% endif %}>{% translate 'Oldest first' %}</option>
|
||||
<option value="newer"
|
||||
{% if order == 'newer' %}selected{% endif %}>{% translate 'Newest first' %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{# Filter transactions form#}
|
||||
<div class="collapse" id="collapse-filter">
|
||||
<div class="card card-body">
|
||||
<form _="on change or submit or search trigger updated on window end
|
||||
install init_tom_select
|
||||
install init_datepicker"
|
||||
id="filter">
|
||||
{% crispy filter.form %}
|
||||
</form>
|
||||
<button class="btn btn-outline-danger btn-sm" _="on click call #filter.reset() then trigger change on #filter">{% translate 'Clear' %}</button>
|
||||
id="filter">
|
||||
{% crispy filter.form %}
|
||||
</form>
|
||||
<button class="btn btn-outline-danger btn-sm"
|
||||
_="on click call #filter.reset() then trigger change on #filter">{% translate 'Clear' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
{# Transactions list#}
|
||||
<div id="transactions"
|
||||
class="show-loading"
|
||||
hx-get="{% url 'monthly_transactions_list' month=month year=year %}"
|
||||
hx-trigger="load, updated from:window" hx-include="#filter, #order">
|
||||
</div>
|
||||
</div>
|
||||
{# Transactions list#}
|
||||
<div id="transactions"
|
||||
class="show-loading"
|
||||
hx-get="{% url 'monthly_transactions_list' month=month year=year %}"
|
||||
hx-trigger="load, updated from:window" hx-include="#filter, #order">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{% load tools %}
|
||||
{% load i18n %}
|
||||
{% load currency_display %}
|
||||
|
||||
<div class="row row-cols-1 g-4 mt-1 mb-3">
|
||||
{% for account_id, account in account_data.items %}
|
||||
<div class="col">
|
||||
<c-ui.account_card :account="account" :account_id="account_id"
|
||||
:percentages="account_percentages"></c-ui.account_card>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,16 @@
|
||||
{% load tools %}
|
||||
{% load i18n %}
|
||||
{% load currency_display %}
|
||||
<div class="row row-cols-1 g-4 mt-1 mb-3">
|
||||
{% for currency_id, currency in currency_data.items %}
|
||||
<div class="col">
|
||||
<c-ui.currency_card :currency="currency" :currency_id="currency_id"
|
||||
:percentages="currency_percentages"></c-ui.currency_card>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -1,431 +1,47 @@
|
||||
{% load tools %}
|
||||
{% load i18n %}
|
||||
{% load currency_display %}
|
||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||
<ul class="nav nav-tabs" id="all-trasactions-tab" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="currency-tab" data-bs-toggle="tab" data-bs-target="#currency-tab-pane" type="button" role="tab" aria-controls="currency-tab-pane" aria-selected="true">{% trans 'Currencies' %}</button>
|
||||
<button class="nav-link active" id="currency-tab" data-bs-toggle="tab" data-bs-target="#currency-tab-pane"
|
||||
type="button" role="tab" aria-controls="currency-tab-pane"
|
||||
aria-selected="true">{% trans 'Currencies' %}</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="account-tab" data-bs-toggle="tab" data-bs-target="#account-tab-pane" type="button" role="tab" aria-controls="account-tab-pane" aria-selected="false">{% trans 'Accounts' %}</button>
|
||||
<button class="nav-link" id="account-tab" data-bs-toggle="tab" data-bs-target="#account-tab-pane" type="button"
|
||||
role="tab" aria-controls="account-tab-pane" aria-selected="false">{% trans 'Accounts' %}</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" id="myTabContent">
|
||||
<div class="tab-pane fade show active" id="currency-tab-pane" role="tabpanel" aria-labelledby="currency-tab" tabindex="0">
|
||||
<div class="tab-content" id="all-transactions-content">
|
||||
<div class="tab-pane fade show active" id="currency-tab-pane" role="tabpanel" aria-labelledby="currency-tab"
|
||||
tabindex="0">
|
||||
<div class="row row-cols-1 g-4 mt-2">
|
||||
{# Income#}
|
||||
<div class="col">
|
||||
<c-ui.info-card color="green" icon="fa-solid fa-arrow-right-to-bracket" title="{% trans 'Income' %}">
|
||||
<div class="d-flex justify-content-between mt-3">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current' %}</div>
|
||||
</div>
|
||||
<div class="text-end font-monospace">
|
||||
{% for currency in income_current.values %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.income_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="green"></c-amount.display>
|
||||
</div>
|
||||
{% if currency.exchanged %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.income_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||
color="gray"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<div>-</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected' %}</div>
|
||||
</div>
|
||||
<div class="text-end font-monospace">
|
||||
{% for currency in income_projected.values %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.income_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="green"></c-amount.display>
|
||||
</div>
|
||||
{% if currency.exchanged %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.income_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||
color="gray"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<div>-</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</c-ui.info-card>
|
||||
</div>
|
||||
{# Expenses#}
|
||||
<div class="col">
|
||||
<c-ui.info-card color="red" icon="fa-solid fa-arrow-right-from-bracket" title="{% trans 'Expenses' %}">
|
||||
<div class="d-flex justify-content-between mt-3">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current' %}</div>
|
||||
</div>
|
||||
<div class="text-end font-monospace">
|
||||
{% for currency in expense_current.values %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.expense_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="red"></c-amount.display>
|
||||
</div>
|
||||
{% if currency.exchanged %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.expense_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||
color="gray"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<div>-</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected' %}</div>
|
||||
</div>
|
||||
<div class="text-end font-monospace">
|
||||
{% for currency in expense_projected.values %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.expense_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="red"></c-amount.display>
|
||||
</div>
|
||||
{% if currency.exchanged %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.expense_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||
color="gray"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<div>-</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</c-ui.info-card>
|
||||
</div>
|
||||
{# Total#}
|
||||
<div class="col">
|
||||
<c-ui.info-card color="blue" icon="fa-solid fa-scale-balanced" title="{% trans 'Total' %}">
|
||||
<div class="d-flex justify-content-between mt-3">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current' %}</div>
|
||||
</div>
|
||||
<div class="text-end font-monospace">
|
||||
{% for currency in total_current.values %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.total_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_current > 0 %}green{% elif currency.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
{% if currency.exchanged %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||
color="gray"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<div>-</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mt-3">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected' %}</div>
|
||||
</div>
|
||||
<div class="text-end font-monospace">
|
||||
{% for currency in total_projected.values %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.total_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_projected > 0 %}green{% elif currency.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
{% if currency.exchanged %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||
color="gray"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<div>-</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-1">
|
||||
<div class="d-flex justify-content-end">
|
||||
<div class="text-end font-monospace">
|
||||
{% for currency in total_final.values %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.total_final"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
{% if currency.exchanged %}
|
||||
<div>
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_final"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||
color="gray"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<div>-</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</c-ui.info-card>
|
||||
</div>
|
||||
<div class="col">
|
||||
<c-ui.info-card color="yellow" icon="fa-solid fa-percent" title="{% trans 'Distribution' %}">
|
||||
{% for p in currency_percentages.values %}
|
||||
<p class="tw-text-gray-400 mb-2 {% if not forloop.first %}mt-3{% endif %}">{{ p.currency.name }} ({{ p.currency.code }})</p>
|
||||
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
||||
{% endfor %}
|
||||
</c-ui.info-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="account-tab-pane" role="tabpanel" aria-labelledby="account-tab" tabindex="0">
|
||||
<div class="row row-cols-1 g-4 mt-2">
|
||||
<div class="col">
|
||||
{% for account_id, account in account_data.items %}
|
||||
{% if not single %}
|
||||
<div class="tw-text-xl {% if not forloop.first %}mt-4 mb-3{% endif %}">
|
||||
{% if account.account.group %}
|
||||
<span class="badge text-bg-primary me-2">{{ account.account.group }}</span>{% endif %}{{ account.account.name }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="account.income_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% for currency_id, currency in currency_data.items %}
|
||||
<div class="col">
|
||||
<c-ui.currency_card :currency="currency" :currency_id="currency_id"
|
||||
:percentages="currency_percentages"></c-ui.currency_card>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.income_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.currency.income_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="account.expense_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.expense_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.expense_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_projected > 0 %}green{% elif account.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged.total_projected and account.exchanged.total_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="account.income_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.income_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.income_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="account.expense_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.expense_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.expense_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_current > 0 %}green{% elif account.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.total_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'final total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_final"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.total_final %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_final"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% with p=account_percentages|get_dict_item:account_id %}
|
||||
<div class="my-3">
|
||||
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
||||
</div>
|
||||
{% endwith %}
|
||||
<hr>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="account-tab-pane" role="tabpanel" aria-labelledby="account-tab" tabindex="0">
|
||||
<div class="row row-cols-1 g-4 mt-2">
|
||||
{% for account_id, account in account_data.items %}
|
||||
<div class="col">
|
||||
<c-ui.account_card :account="account" :account_id="account_id"
|
||||
:percentages="account_percentages"></c-ui.account_card>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -45,10 +45,59 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-3 order-1 order-xl-2">
|
||||
<div id="transactions"
|
||||
class="show-loading"
|
||||
hx-get="{% url 'transactions_all_summary' %}"
|
||||
hx-trigger="load, updated from:window, change from:#filter, submit from:#filter, search from:#filter" hx-include="#filter">
|
||||
<ul class="nav nav-tabs" id="all-transactions-summary" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link {% if summary_tab == 'currency' %}active{% endif %}"
|
||||
id="currency-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#currency-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="currency-tab-pane"
|
||||
_="on click fetch {% url 'transaction_all_summary_select' selected='currency' %}"
|
||||
aria-selected="{% if summary_tab == 'currency' %}true{% else %}false{% endif %}">
|
||||
{% trans 'Currencies' %}
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link {% if summary_tab == 'account' %}active{% endif %}"
|
||||
id="account-tab"
|
||||
data-bs-toggle="tab"
|
||||
data-bs-target="#account-tab-pane"
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-controls="account-tab-pane"
|
||||
_="on click fetch {% url 'transaction_all_summary_select' selected='account' %}"
|
||||
aria-selected="{% if summary_tab == 'account' %}true{% else %}false{% endif %}">
|
||||
{% trans 'Accounts' %}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" id="all-transactions-content">
|
||||
<div class="tab-pane fade {% if summary_tab == 'currency' %}show active{% endif %}"
|
||||
id="currency-tab-pane"
|
||||
role="tabpanel"
|
||||
aria-labelledby="currency-tab"
|
||||
tabindex="0">
|
||||
<div id="currency-summary"
|
||||
hx-get="{% url 'transaction_all_currency_summary' %}"
|
||||
class="show-loading"
|
||||
hx-trigger="load, selective_update from:window, updated from:window, change from:#filter, submit from:#filter, search from:#filter"
|
||||
hx-include="#filter">
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade {% if summary_tab == 'account' %}show active{% endif %}"
|
||||
id="account-tab-pane"
|
||||
role="tabpanel"
|
||||
aria-labelledby="account-tab"
|
||||
tabindex="0">
|
||||
<div id="account-summary"
|
||||
hx-get="{% url 'transaction_all_account_summary' %}"
|
||||
class="show-loading"
|
||||
hx-trigger="load, selective_update from:window, updated from:window, change from:#filter, submit from:#filter, search from:#filter"
|
||||
hx-include="#filter">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,188 +1,15 @@
|
||||
{% load tools %}
|
||||
{% load i18n %}
|
||||
<div class="row row-cols-1 g-4 mb-3">
|
||||
{% for account_id, account in totals.items %}
|
||||
<div class="col">
|
||||
{% for account_id, account in totals.items %}
|
||||
{% if not single %}
|
||||
<div class="tw-text-xl {% if not forloop.first %}mt-4 mb-3{% endif %}">
|
||||
{% if account.account.group %}
|
||||
<span class="badge text-bg-primary me-2">{{ account.account.group }}</span>{% endif %}{{ account.account.name }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="account.income_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.income_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.currency.income_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="account.expense_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.expense_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.expense_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_projected"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_projected > 0 %}green{% elif account.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged.total_projected and account.exchanged.total_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_projected"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="account.income_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.income_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.income_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="account.expense_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.expense_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.expense_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_current"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_current > 0 %}green{% elif account.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.total_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_current"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'final total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="account.total_final"
|
||||
:prefix="account.currency.prefix"
|
||||
:suffix="account.currency.suffix"
|
||||
:decimal_places="account.currency.decimal_places"
|
||||
color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if account.exchanged and account.exchanged.total_final %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="account.exchanged.total_final"
|
||||
:prefix="account.exchanged.currency.prefix"
|
||||
:suffix="account.exchanged.currency.suffix"
|
||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% with p=percentages|get_dict_item:account_id %}
|
||||
<div class="my-3">
|
||||
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
||||
</div>
|
||||
{% endwith %}
|
||||
<hr>
|
||||
{% empty %}
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
{% endfor %}
|
||||
<c-ui.account_card :account="account" :account_id="account_id"
|
||||
:percentages="percentages"></c-ui.account_card>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
@@ -1,187 +1,15 @@
|
||||
{% load tools %}
|
||||
{% load month_name %}
|
||||
{% load i18n %}
|
||||
<div class="row row-cols-1 g-4 mb-3">
|
||||
{% for currency_id, currency in totals.items %}
|
||||
{% for currency_id, currency in totals.items %}
|
||||
<div class="col">
|
||||
{% if not single %}
|
||||
<div class="tw-text-xl {% if not forloop.first %}mt-4 mb-3{% endif %}">
|
||||
{{ currency.currency.name }} ({{ currency.currency.code }})
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="currency.income_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.income_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.currency.income_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="currency.expense_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.expense_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.expense_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'projected total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="currency.total_projected"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_projected > 0 %}green{% elif currency.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged.total_projected and currency.exchanged.total_projected %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_projected"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current income' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-green-400">
|
||||
<c-amount.display
|
||||
:amount="currency.income_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.income_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.income_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace tw-text-red-400">
|
||||
<c-amount.display
|
||||
:amount="currency.expense_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.expense_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.expense_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'current total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div
|
||||
class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="currency.total_current"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_current > 0 %}green{% elif currency.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.total_current %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_current"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<hr class="my-3">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw-text-gray-400">{% translate 'final total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="currency.total_final"
|
||||
:prefix="currency.currency.prefix"
|
||||
:suffix="currency.currency.suffix"
|
||||
:decimal_places="currency.currency.decimal_places"
|
||||
color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
{% if currency.exchanged and currency.exchanged.total_final %}
|
||||
<div class="text-end font-monospace tw-text-gray-500">
|
||||
<c-amount.display
|
||||
:amount="currency.exchanged.total_final"
|
||||
:prefix="currency.exchanged.currency.prefix"
|
||||
:suffix="currency.exchanged.currency.suffix"
|
||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% with p=percentages|get_dict_item:currency_id %}
|
||||
<div class="my-3">
|
||||
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% empty %}
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
<c-ui.currency_card :currency="currency" :currency_id="currency_id"
|
||||
:percentages="percentages"></c-ui.currency_card>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<c-msg.empty
|
||||
title="{% translate "No information to display" %}"></c-msg.empty>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user