more changes

This commit is contained in:
Herculino Trotta
2024-10-13 12:10:50 -03:00
parent 1717d8a94e
commit d20897a28a
33 changed files with 1552 additions and 153 deletions
+2 -6
View File
@@ -41,9 +41,7 @@
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'account_edit' pk=account.id %}"
hx-target="#generic-offcanvas"
_="on click send action_clicked to .tag-action in the closest parent .tag end
on action_clicked call bootstrap.Tooltip.getOrCreateInstance(me).dispose() end
install tooltip">
_="install tooltip">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="text-danger text-decoration-none p-1 tag-action"
role="button"
@@ -51,9 +49,7 @@
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'account_delete' pk=account.id %}"
hx-trigger='delete_confirmed'
_="on click send action_clicked to .tag-action in the closest parent .tag end
on action_clicked call bootstrap.Tooltip.getOrCreateInstance(me).dispose() end
install tooltip
_="install tooltip
on click
if event.ctrlKey trigger delete_confirmed
else
+2 -6
View File
@@ -39,9 +39,7 @@
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'currency_edit' pk=currency.id %}"
hx-target="#generic-offcanvas"
_="on click send action_clicked to .tag-action in the closest parent .tag end
on action_clicked call bootstrap.Tooltip.getOrCreateInstance(me).dispose() end
install tooltip">
_="install tooltip">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="text-danger text-decoration-none p-1 tag-action"
role="button"
@@ -49,9 +47,7 @@
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'currency_delete' pk=currency.id %}"
hx-trigger='delete_confirmed'
_="on click send action_clicked to .tag-action in the closest parent .tag end
on action_clicked call bootstrap.Tooltip.getOrCreateInstance(me).dispose() end
install tooltip
_="install tooltip
on click
if event.ctrlKey trigger delete_confirmed
else
+2 -1
View File
@@ -10,7 +10,7 @@
<div class="collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0 nav-underline" hx-push-url="true">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% active_link views='monthly_overview' %}"
<a class="nav-link dropdown-toggle {% active_link views='monthly_overview||yearly_overview' %}"
href="#"
role="button"
data-bs-toggle="dropdown"
@@ -19,6 +19,7 @@
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item {% active_link views='monthly_overview' %}" href="{% url 'monthly_index' %}">{%translate 'Monthly' %}</a></li>
<li><a class="dropdown-item {% active_link views='yearly_overview' %}" href="{% url 'yearly_index' %}">{%translate 'Yearly' %}</a></li>
</ul>
</li>
<li class="nav-item">
+1
View File
@@ -10,6 +10,7 @@
{% include 'includes/scripts/hyperscript/htmx_error_handler.html' %}
{% javascript_pack 'htmx' attrs="defer" %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
@@ -14,7 +14,7 @@
<div class="text-end font-monospace">
<div class="tw-text-gray-400">{% translate 'today' %}</div>
</div>
<div class="text-start font-monospace">
<div class="text-end font-monospace">
{% for entry in totals.daily_spending_allowance %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
@@ -38,7 +38,7 @@
<div class="text-end font-monospace">
<div class="tw-text-gray-400">{% translate 'current' %}</div>
</div>
<div class="d-flex justify-content-between text-start font-monospace">
<div class="text-end font-monospace">
{% for entry in totals.paid_income %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
@@ -51,7 +51,7 @@
<div class="text-end font-monospace">
<div class="tw-text-gray-400">{% translate 'projected' %}</div>
</div>
<div class="text-start font-monospace">
<div class="text-end font-monospace">
{% for entry in totals.projected_income %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
@@ -75,7 +75,7 @@
<div class="text-end font-monospace">
<div class="tw-text-gray-400">{% translate 'current' %}</div>
</div>
<div class="text-start font-monospace">
<div class="text-end font-monospace">
{% for entry in totals.paid_expenses %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
@@ -88,7 +88,7 @@
<div class="text-end font-monospace">
<div class="tw-text-gray-400">{% translate 'projected' %}</div>
</div>
<div class="text-start font-monospace">
<div class="text-end font-monospace">
{% for entry in totals.projected_expenses %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
@@ -112,7 +112,7 @@
<div class="text-end font-monospace">
<div class="tw-text-gray-400">{% translate 'current' %}</div>
</div>
<div class="text-start font-monospace">
<div class="text-end font-monospace">
{% for entry in totals.total_current %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
@@ -124,7 +124,7 @@
<div class="text-end font-monospace">
<div class="tw-text-gray-400">{% translate 'projected' %}</div>
</div>
<div class="text-start font-monospace">
<div class="text-end font-monospace">
{% for entry in totals.total_projected %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
@@ -134,7 +134,7 @@
</div>
<hr class="my-1">
<div class="d-flex justify-content-end">
<div class="text-start font-monospace">
<div class="text-end font-monospace">
{% for entry in totals.total_final %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
@@ -5,7 +5,7 @@
{% load static %}
{% load webpack_loader %}
{% block title %}Monthly Overview :: {{ month|month_name }}/{{ year }}{% endblock %}
{% block title %}{% translate 'Monthly Overview' %} :: {{ month|month_name }}/{{ year }}{% endblock %}
{% block body_hyperscript %}
on keyup[code is 'KeyE' and target.nodeName is 'BODY'] from body trigger 'add_expense' end
@@ -95,7 +95,7 @@
<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="sticky-sidebar"
hx-trigger="load, transaction_updated from:window, monthly_summary_update from:window">
hx-trigger="load, updated from:window, monthly_summary_update from:window">
</div>
</div>
<div class="col-12 col-xl-8 order-2 order-xl-1">
@@ -118,7 +118,7 @@
</div>
<div id="transactions"
hx-get="{% url 'monthly_transactions_list' month=month year=year %}"
hx-trigger="load, transaction_updated from:window" hx-include="#filter"></div>
hx-trigger="load, updated from:window" hx-include="#filter"></div>
</div>
</div>
</div>
+141 -15
View File
@@ -10,28 +10,154 @@
{% block content %}
<div class="container px-md-3 py-3 column-gap-5">
<div class="row">
<div class="col-6 row-gap-5">
{% for currency in currency_net_worth %}
<div class="row">
<div class="row gx-xl-4 gy-3">
<div class="col-12 col-xl-5">
<div class="row row-cols-1 g-4 mb-3">
<div class="col">
<div class="card tw-relative h-100 shadow">
<div class="tw-absolute tw-h-8 tw-w-8 tw-right-2 tw-top-2 tw-bg-yellow-300 tw-text-yellow-800 text-center
align-items-center d-flex justify-content-center rounded-2">
<i class="fa-solid fa-coins"></i>
</div>
<div class="card-body">
<div class="card-title">
<div class="row">
<div class="col-6">
{{ currency.name }}
<h5 class="tw-text-yellow-400 fw-bold mb-3">{% translate 'By currency' %}</h5>
{% for currency in currency_net_worth %}
<div class="d-flex justify-content-between mt-2">
<div class="d-flex align-items-baseline w-100">
<div class="currency-name text-start font-monospace tw-text-gray-300">{{ currency.name }}</div>
<div class="dotted-line flex-grow-1"></div>
<div class="amount text-end font-monospace" data-original-value="{% currency_display amount=currency.amount prefix=currency.prefix suffix=currency.suffix decimal_places=currency.decimal_places %}"></div>
</div>
<div class="col-6 text-end">
<div class="amount" data-original-value="{% currency_display amount=currency.amount prefix=currency.prefix suffix=currency.suffix decimal_places=currency.decimal_places %}"></div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
<div class="col">
<div class="card tw-relative h-100 shadow">
<div class="tw-absolute tw-h-8 tw-w-8 tw-right-2 tw-top-2 tw-bg-blue-300 tw-text-blue-800 text-center
align-items-center d-flex justify-content-center rounded-2">
<i class="fa-solid fa-wallet"></i>
</div>
<div class="card-body">
<h5 class="tw-text-blue-400 fw-bold mb-3">{% translate 'By account' %}</h5>
{% for group_id, group_data in account_net_worth.items %}
{% if group_id %}
<div class="d-flex justify-content-between mt-2">
<div class="d-flex align-items-baseline w-100">
<div class="text-start font-monospace tw-text-gray-300"><span class="badge !tw-bg-blue-300
!tw-text-blue-800">
{{ group_data.name }}</span></div>
</div>
</div>
{% for account_id, account_data in group_data.accounts.items %}
<div class="d-flex justify-content-between mt-2">
<div class="d-flex align-items-baseline w-100">
<div class="text-start font-monospace tw-text-gray-300">
<span class="hierarchy-line-icon-4"></span>{{ account_data.name }}</div>
<div class="dotted-line flex-grow-1"></div>
<div class="amount" data-original-value="{% currency_display amount=account_data.balance prefix=account_data.currency.prefix suffix=account_data.currency.suffix decimal_places=account_data.currency.decimal_places%}"></div>
</div>
</div>
{% if account_data.exchange %}
<div class="amount text-end tw-text-gray-400" data-original-value=
"{% currency_display amount=account_data.exchange.amount prefix=account_data.exchange.prefix suffix=account_data.exchange.suffix decimal_places=account_data.exchange.decimal_places%}"></div>
{% endif %}
{% endfor %}
{% else %}
{% for account_id, account_data in group_data.accounts.items %}
<div class="d-flex justify-content-between mt-2">
<div class="d-flex align-items-baseline w-100">
<div class="currency-name text-start font-monospace tw-text-gray-300">{{ account_data.name }}</div>
<div class="dotted-line flex-grow-1"></div>
<div class="amount" data-original-value="{% currency_display amount=account_data.balance prefix=account_data.currency.prefix suffix=account_data.currency.suffix decimal_places=account_data.currency.decimal_places%}"></div>
{% if account_data.exchange %}
<div class="amount text-end tw-text-gray-400" data-original-value=
"{% currency_display amount=account_data.balance prefix=account_data.currency.prefix suffix=account_data.currency.suffix decimal_places=account_data.currency.decimal_places%}"></div>
{% endif %}
</div>
</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-7 h-100">
<canvas id="historicalNetWorthChart"></canvas>
</div>
<div class="col-6">oi</div>
</div>
<script>
var historicalData = {{ historical_data_json|safe }};
var currencies = [
{% for currency in currencies %}
"{{ currency.code }}",
{% endfor %}
];
var labels = Object.keys(historicalData);
var datasets = currencies.map((currency, index) => ({
label: currency,
data: labels.map(date => parseFloat(historicalData[date][currency])),
color: `hsl(${index * 360 / currencies.length}, 70%, 50%)`,
yAxisID: `y-axis-${index}`,
}));
var ctx = document.getElementById('historicalNetWorthChart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: datasets
},
options: {
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
scales: {
x: {
type: 'category',
title: {
display: true,
text: 'Date'
}
},
...currencies.reduce((acc, currency, index) => {
acc[`y-axis-${index}`] = {
type: 'linear',
beginAtZero: true,
grace: '50%',
display: true,
grid: {
drawOnChartArea: false,
},
ticks: {
display: false // This hides the tick labels (numbers)
},
};
return acc;
}, {})
},
plugins: {
title: {
display: true,
text: 'Historical Net Worth by Currency'
},
tooltip: {
mode: 'index',
intersect: false,
}
}
}
});
</script>
</div>
</div>
{#<canvas id="chart" width="500" height="300"></canvas>#}
{##}
+2 -6
View File
@@ -38,9 +38,7 @@
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'tag_edit' tag_id=tag.id %}"
hx-target="#generic-offcanvas"
_="on click send action_clicked to .tag-action in the closest parent .tag end
on action_clicked call bootstrap.Tooltip.getOrCreateInstance(me).dispose() end
install tooltip">
_="install tooltip">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="text-danger text-decoration-none p-1 tag-action"
role="button"
@@ -48,9 +46,7 @@
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'tag_delete' tag_id=tag.id %}"
hx-trigger='delete_confirmed'
_="on click send action_clicked to .tag-action in the closest parent .tag end
on action_clicked call bootstrap.Tooltip.getOrCreateInstance(me).dispose() end
install tooltip
_="install tooltip
on click
if event.ctrlKey trigger delete_confirmed
else
@@ -0,0 +1,39 @@
{% load natural %}
{% load i18n %}
{% regroup transactions by date|customnaturaldate as transactions_by_date %}
<div>
{% for x in transactions_by_date %}
<div>
<div class="my-3 w-100 tw-text-base border-bottom bg-body">
<a class="text-decoration-none d-inline-block w-100"
role="button"
data-bs-toggle="collapse"
data-bs-target="#{{ x.grouper|slugify }}"
id="#{{ x.grouper|slugify }}-collapsible"
aria-expanded="true"
aria-controls="collapseExample">
{{ x.grouper }}
</a>
</div>
<div class="collapse show" id="{{ x.grouper|slugify }}">
<div class="ps-3">
{% for trans in x.list %}
{% include 'transactions/fragments/item.html' with transaction=trans %}
{% endfor %}
</div>
</div>
</div>
{% empty %}
<div class="row p-5">
<div class="col p-5">
<div class="text-center">
<i class="fa-solid fa-circle-xmark tw-text-6xl"></i>
<p class="lead mt-4 mb-0">{% translate "No transactions this month" %}</p>
<p class="tw-text-gray-500">{% translate "Try adding one" %}</p>
</div>
</div>
</div>
{% endfor %}
</div>
@@ -0,0 +1,51 @@
{% extends 'extends/offcanvas.html' %}
{% load month_name %}
{% load i18n %}
{% block title %}{% translate 'Pick a month' %}{% endblock %}
{% block body %}
{% regroup month_year_data by year as years_list %}
<ul class="nav nav-pills nav-fill" id="yearTabs" role="tablist">
{% for x in years_list %}
<li class="nav-item" role="presentation">
<button class="nav-link{% if x.grouper == current_year %} active{% endif %}"
id="{{ x.grouper }}"
data-bs-toggle="tab"
data-bs-target="#{{ x.grouper }}-pane"
type="button"
role="tab"
aria-controls="{{ x.grouper }}-pane"
aria-selected="{% if x.grouper == current_year %}true{% else %}false{% endif %}">
{{ x.grouper }}
</button>
</li>
{% endfor %}
</ul>
<div class="tab-content" id="yearTabsContent" hx-boost="true">
{% for x in years_list %}
<div class="tab-pane fade{% if x.grouper == current_year %} show active{% endif %} mt-2"
id="{{ x.grouper }}-pane"
role="tabpanel"
aria-labelledby="{{ x.grouper }}"
tabindex="0">
<ul class="list-group list-group-flush" id="month-year-list">
{% for month_data in x.list %}
<li class="list-group-item hover:tw-bg-zinc-900
{% if month_data.month == current_month and month_data.year == current_year %} disabled bg-primary{% endif %}"
{% if month_data.month == current_month and month_data.year == current_year %}aria-disabled="true"{% endif %}>
<div class="d-flex justify-content-between">
<a class="text-decoration-none stretched-link {% if month_data.month == current_month and month_data.year == current_year %} text-black{% endif %}"
href="{% url "monthly_overview" month=month_data.month year=month_data.year %}">
{{ month_data.month|month_name }}</a>
<span class="badge text-bg-secondary">{{ month_data.transaction_count }}</span>
</div>
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</div>
{% endblock %}
@@ -0,0 +1,166 @@
{% load i18n %}
{% load currency_display %}
<div class="row row-cols-1 g-4 mb-3">
{# Daily Spending#}
<div class="col">
<div class="card tw-relative h-100 shadow">
<div class="tw-absolute tw-h-8 tw-w-8 tw-right-2 tw-top-2 tw-bg-yellow-300 tw-text-yellow-800 text-center
align-items-center d-flex justify-content-center rounded-2">
<i class="fa-solid fa-calendar-day"></i>
</div>
<div class="card-body">
<h5 class="tw-text-yellow-400 fw-bold">{% translate 'Daily Spending Allowance' %}{% include 'includes/help_icon.html' with content=_('This is the final total divided by the remaining days in the month') %}</h5>
<div class="d-flex justify-content-between mt-3">
<div class="text-end font-monospace">
<div class="tw-text-gray-400">{% translate 'today' %}</div>
</div>
<div class="text-end font-monospace">
{% for entry in totals.daily_spending_allowance %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{# Income#}
<div class="col">
<div class="card tw-relative h-100 shadow">
<div class="tw-absolute tw-h-8 tw-w-8 tw-right-2 tw-top-2 tw-bg-green-300 tw-text-green-800 text-center
align-items-center d-flex justify-content-center rounded-2">
<i class="fa-solid fa-arrow-right-to-bracket"></i>
</div>
<div class="card-body">
<h5 class="tw-text-green-400 fw-bold">{% translate 'Income' %}</h5>
<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 entry in totals.paid_income %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% 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 entry in totals.projected_income %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{# Expenses#}
<div class="col">
<div class="card tw-relative h-100 shadow">
<div class="tw-absolute tw-h-8 tw-w-8 tw-right-2 tw-top-2 tw-bg-red-300 tw-text-red-800 text-center
align-items-center d-flex justify-content-center rounded-2">
<i class="fa-solid fa-arrow-right-from-bracket"></i>
</div>
<div class="card-body">
<h5 class="tw-text-red-400">{% translate 'Expenses' %}</h5>
<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 entry in totals.paid_expenses %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% 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 entry in totals.projected_expenses %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{# Total#}
<div class="col">
<div class="card tw-relative h-100 shadow">
<div class="tw-absolute tw-h-8 tw-w-8 tw-right-2 tw-top-2 tw-bg-blue-300 tw-text-blue-800 text-center
align-items-center d-flex justify-content-center rounded-2">
<i class="fa-solid fa-scale-balanced"></i>
</div>
<div class="card-body">
<h5 class="tw-text-blue-400">{% translate 'Total' %}</h5>
<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 entry in totals.total_current %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% 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 entry in totals.total_projected %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</div>
</div>
<hr class="my-1">
<div class="d-flex justify-content-end">
<div class="text-end font-monospace">
{% for entry in totals.total_final %}
<div class="amount" data-original-value="{% entry_amount entry %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{#<div class="p-2 rounded-2 shadow tw-text-sm card mt-4">#}
{# <p class="font-monospace text-light text-uppercase text-center fw-bold m-0 tw-text-base">#}
{# {% translate "Account Overview" %}</p>#}
{# <hr class="my-1">#}
{# <div>#}
{# {% for account in account_summary %}#}
{# <div class="row">#}
{# <div class="col-6">#}
{# <div class="font-monospace text-primary text-start align-self-end fw-bold m-0">{{ account.name }}</div>#}
{# </div>#}
{# <div class="col-6 text-end font-monospace">#}
{# <div class="amount" data-original-value="{% currency_display amount=account.balance prefix=account.currency__prefix suffix=account.currency__suffix decimal_places=account.currency__decimal_places %}"></div>#}
{# </div>#}
{# </div>#}
{# <div class="my-1"></div>#}
{# {% endfor %}#}
{# </div>#}
{#</div>#}
@@ -0,0 +1,197 @@
{% extends "layouts/base.html" %}
{% load currency_display %}
{% load crispy_forms_tags %}
{% load i18n %}
{% load month_name %}
{% load static %}
{% load webpack_loader %}
{% block title %}{% translate 'Yearly Overview' %} :: {{ year }}{% endblock %}
{% block body_hyperscript %}
on keyup[code is 'KeyE' and target.nodeName is 'BODY'] from body trigger 'add_expense' end
on keyup[code is 'KeyI' and target.nodeName is 'BODY'] from body trigger 'add_income' end
on keyup[code is 'KeyB' and target.nodeName is 'BODY'] from body trigger 'balance' end
on keyup[code is 'KeyT' and target.nodeName is 'BODY'] from body trigger 'add_transfer' end
on keyup[code is 'KeyN' and target.nodeName is 'BODY'] from body trigger 'installment' end
on keyup[code is 'ArrowLeft' and target.nodeName is 'BODY'] from body trigger 'previous_month' end
on keyup[code is 'ArrowRight' and target.nodeName is 'BODY'] from body trigger 'next_month' end
{% 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 'available_dates' %}"#}
{# hx-target="#generic-offcanvas-left"#}
{# hx-trigger="click, date_picker from:window"#}
{# hx-vals='{"month": {{ month }}, "year": {{ year }}}' 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">#}
{# <div class="d-grid gap-2 d-xl-flex justify-content-xl-end">#}
{# <button class="btn btn-sm btn-outline-success"#}
{# hx-get="{% url 'transaction_add' %}"#}
{# hx-target="#generic-offcanvas"#}
{# hx-trigger="click, add_income from:window"#}
{# hx-vals='{"year": {{ year }}, "month": {{ month }}, "type": "IN"}'>#}
{# <i class="fa-solid fa-arrow-right-to-bracket me-2"></i>#}
{# {% translate "Income" %}#}
{# </button>#}
{# <button class="btn btn-sm btn-outline-danger"#}
{# hx-get="{% url 'transaction_add' %}"#}
{# hx-target="#generic-offcanvas"#}
{# hx-trigger="click, add_expense from:window"#}
{# hx-vals='{"year": {{ year }}, "month": {{ month }}, "type": "EX"}'>#}
{# <i class="fa-solid fa-arrow-right-from-bracket me-2"></i>#}
{# {% translate "Expense" %}#}
{# </button>#}
{# <button class="btn btn-sm btn-outline-warning"#}
{# hx-get="{% url 'installments_add' %}"#}
{# hx-trigger="click, installment from:window"#}
{# hx-target="#generic-offcanvas">#}
{# <i class="fa-solid fa-divide me-2"></i>#}
{# {% translate "Installment" %}#}
{# </button>#}
{# <button class="btn btn-sm btn-outline-info"#}
{# hx-get="{% url 'transactions_transfer' %}"#}
{# hx-target="#generic-offcanvas"#}
{# hx-trigger="click, add_transfer from:window"#}
{# hx-vals='{"year": {{ year }}, "month": {{ month }}}'>#}
{# <i class="fa-solid fa-money-bill-transfer me-2"></i>#}
{# {% translate "Transfer" %}#}
{# </button>#}
{# <button class="btn btn-sm btn-outline-info"#}
{# hx-get="{% url 'account_reconciliation' %}"#}
{# hx-trigger="click, balance from:window"#}
{# hx-target="#generic-offcanvas">#}
{# <i class="fa-solid fa-scale-balanced me-2"></i>#}
{# {% translate "Balance" %}#}
{# </button>#}
{# </div>#}
{# </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="sticky-sidebar"#}
{# hx-trigger="load, updated from:window, monthly_summary_update from:window">#}
{# </div>#}
{# </div>#}
<div class="col-12">
{# Filter transactions#}
{# <div class="row mb-1">#}
{# <div class="col-12">#}
{# <div class="dropdown">#}
{# <button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown"#}
{# aria-expanded="false" data-bs-auto-close="false">#}
{# <i class="fa-solid fa-filter fa-fw me-2"></i>{% translate 'Filter transactions' %}#}
{# </button>#}
{# <form hx-get="{% url 'monthly_transactions_list' month=month year=year %}" hx-trigger="change, submit, search"#}
{# hx-target="#transactions" id="filter" hx-indicator="#transactions"#}
{# class="dropdown-menu p-4 w-lg-50 tw-w-full lg:tw-w-2/4"#}
{# _="install init_tom_select">#}
{# {% crispy filter.form %}#}
{# </form>#}
{# </div>#}
{# </div>#}
{# </div>#}
<div class="row">
<div class="no-more-tables">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">{% translate 'Month' %}</th>
<td>{% translate 'Projected Income' %}</td>
<td>{% translate 'Projected Expenses' %}</td>
<td>{% translate 'Projected Total' %}</td>
<td>{% translate 'Current Income' %}</td>
<td>{% translate 'Current Expenses' %}</td>
<td>{% translate 'Current Total' %}</td>
<td>{% translate 'Final Total' %}</td>
</tr>
</thead>
<tbody>
{% for date, x in totals.items %}
<tr>
<th scope="row">{{ date.month|month_name }}</th>
<td class="!tw-text-green-400">
{% for data in x.income_unpaid %}
<div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</td>
<td class="!tw-text-red-400">
{% for data in x.expense_unpaid %}
<div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</td>
<td>
{% for data in x.balance_unpaid %}
<div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</td>
<td class="!tw-text-green-400">
{% for data in x.income_paid %}
<div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</td>
<td class="!tw-text-red-400">
{% for data in x.expense_paid %}
<div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</td>
<td>
{% for data in x.balance_paid %}
<div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</td>
<td>
{% for data in x.balance_total %}
<div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>
{% empty %}
<div>-</div>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
@@ -0,0 +1,203 @@
{% extends "layouts/base.html" %}
{% load currency_display %}
{% load crispy_forms_tags %}
{% load i18n %}
{% load month_name %}
{% load static %}
{% load webpack_loader %}
{% block title %}{% translate 'Yearly Overview' %} :: {{ year }}{% endblock %}
{% block body_hyperscript %}
on keyup[code is 'ArrowLeft' and target.nodeName is 'BODY'] from body trigger 'previous_month' end
on keyup[code is 'ArrowRight' and target.nodeName is 'BODY'] from body trigger 'next_month' end
{% 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 'available_dates' %}"#}
{# hx-target="#generic-offcanvas-left"#}
{# hx-trigger="click, date_picker from:window"#}
{# hx-vals='{"month": {{ month }}, "year": {{ year }}}' 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">#}
{# <div class="d-grid gap-2 d-xl-flex justify-content-xl-end">#}
{# <button class="btn btn-sm btn-outline-success"#}
{# hx-get="{% url 'transaction_add' %}"#}
{# hx-target="#generic-offcanvas"#}
{# hx-trigger="click, add_income from:window"#}
{# hx-vals='{"year": {{ year }}, "month": {{ month }}, "type": "IN"}'>#}
{# <i class="fa-solid fa-arrow-right-to-bracket me-2"></i>#}
{# {% translate "Income" %}#}
{# </button>#}
{# <button class="btn btn-sm btn-outline-danger"#}
{# hx-get="{% url 'transaction_add' %}"#}
{# hx-target="#generic-offcanvas"#}
{# hx-trigger="click, add_expense from:window"#}
{# hx-vals='{"year": {{ year }}, "month": {{ month }}, "type": "EX"}'>#}
{# <i class="fa-solid fa-arrow-right-from-bracket me-2"></i>#}
{# {% translate "Expense" %}#}
{# </button>#}
{# <button class="btn btn-sm btn-outline-warning"#}
{# hx-get="{% url 'installments_add' %}"#}
{# hx-trigger="click, installment from:window"#}
{# hx-target="#generic-offcanvas">#}
{# <i class="fa-solid fa-divide me-2"></i>#}
{# {% translate "Installment" %}#}
{# </button>#}
{# <button class="btn btn-sm btn-outline-info"#}
{# hx-get="{% url 'transactions_transfer' %}"#}
{# hx-target="#generic-offcanvas"#}
{# hx-trigger="click, add_transfer from:window"#}
{# hx-vals='{"year": {{ year }}, "month": {{ month }}}'>#}
{# <i class="fa-solid fa-money-bill-transfer me-2"></i>#}
{# {% translate "Transfer" %}#}
{# </button>#}
{# <button class="btn btn-sm btn-outline-info"#}
{# hx-get="{% url 'account_reconciliation' %}"#}
{# hx-trigger="click, balance from:window"#}
{# hx-target="#generic-offcanvas">#}
{# <i class="fa-solid fa-scale-balanced me-2"></i>#}
{# {% translate "Balance" %}#}
{# </button>#}
{# </div>#}
{# </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="sticky-sidebar"#}
{# hx-trigger="load, updated from:window, monthly_summary_update from:window">#}
{# </div>#}
{# </div>#}
<div class="col-12">
{# Filter transactions#}
{# <div class="row mb-1">#}
{# <div class="col-12">#}
{# <div class="dropdown">#}
{# <button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown"#}
{# aria-expanded="false" data-bs-auto-close="false">#}
{# <i class="fa-solid fa-filter fa-fw me-2"></i>{% translate 'Filter transactions' %}#}
{# </button>#}
{# <form hx-get="{% url 'monthly_transactions_list' month=month year=year %}" hx-trigger="change, submit, search"#}
{# hx-target="#transactions" id="filter" hx-indicator="#transactions"#}
{# class="dropdown-menu p-4 w-lg-50 tw-w-full lg:tw-w-2/4"#}
{# _="install init_tom_select">#}
{# {% crispy filter.form %}#}
{# </form>#}
{# </div>#}
{# </div>#}
{# </div>#}
<div class="row">
{{ year }}
{% for date, x in data.items %}
<div class="card shadow mb-3 mt-3">
<div class="card-body">
<h5 class="card-title">{{ date.month|month_name }}</h5>
{{ x }}
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
{% endfor %}
{# <div class="no-more-tables">#}
{# <table class="table table-hover">#}
{# <thead>#}
{# <tr>#}
{# <th scope="col">{% translate 'Month' %}</th>#}
{# <td>{% translate 'Projected Income' %}</td>#}
{# <td>{% translate 'Projected Expenses' %}</td>#}
{# <td>{% translate 'Projected Total' %}</td>#}
{# <td>{% translate 'Current Income' %}</td>#}
{# <td>{% translate 'Current Expenses' %}</td>#}
{# <td>{% translate 'Current Total' %}</td>#}
{# <td>{% translate 'Final Total' %}</td>#}
{# </tr>#}
{# </thead>#}
{# <tbody>#}
{# {% for date, x in totals.items %}#}
{# <tr>#}
{# <th scope="row">{{ date.month|month_name }}</th>#}
{# <td class="!tw-text-green-400">#}
{# {% for data in x.income_unpaid %}#}
{# <div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>#}
{# {% empty %}#}
{# <div>-</div>#}
{# {% endfor %}#}
{# </td>#}
{# <td class="!tw-text-red-400">#}
{# {% for data in x.expense_unpaid %}#}
{# <div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>#}
{# {% empty %}#}
{# <div>-</div>#}
{# {% endfor %}#}
{# </td>#}
{# <td>#}
{# {% for data in x.balance_unpaid %}#}
{# <div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>#}
{# {% empty %}#}
{# <div>-</div>#}
{# {% endfor %}#}
{# </td>#}
{# <td class="!tw-text-green-400">#}
{# {% for data in x.income_paid %}#}
{# <div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>#}
{# {% empty %}#}
{# <div>-</div>#}
{# {% endfor %}#}
{# </td>#}
{# <td class="!tw-text-red-400">#}
{# {% for data in x.expense_paid %}#}
{# <div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>#}
{# {% empty %}#}
{# <div>-</div>#}
{# {% endfor %}#}
{# </td>#}
{# <td>#}
{# {% for data in x.balance_paid %}#}
{# <div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>#}
{# {% empty %}#}
{# <div>-</div>#}
{# {% endfor %}#}
{# </td>#}
{# <td>#}
{# {% for data in x.balance_total %}#}
{# <div class="amount" data-original-value="{% currency_display amount=data.amount prefix=data.prefix suffix=data.suffix decimal_places=data.decimal_places %}"></div>#}
{# {% empty %}#}
{# <div>-</div>#}
{# {% endfor %}#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
{# </tbody>#}
{# </table>#}
{# </div>#}
</div>
</div>
</div>
</div>
{% endblock %}