Reduce computations in history generation

This commit is contained in:
Edgar P. Burkhart 2023-12-28 16:31:13 +01:00
parent 9dbbd3d48e
commit 6f631607b8
Signed by: edpibu
GPG Key ID: 9833D3C5A25BD227
5 changed files with 63 additions and 69 deletions

View File

@ -11,7 +11,7 @@
{% block tables %}
<h3>{% translate "Transactions" %}</h3>
{% include "transaction/transaction_table.html" %}
{% if history.data %}
{% if history %}
<h3>{% translate "History" %}</h3>
{% include "history/plot.html" %}
{% endif %}

View File

@ -19,43 +19,51 @@
</thead>
<tbody>
{% spaceless %}
{% for date in history.data %}
<tr>
<td class="icon">
<span class="ri-{% if date.sum > 0 %}arrow-up-s-line green{% elif date.sum < 0 %}arrow-down-s-line red{% endif %}"></span>
</td>
<th class="date" scope="row">
{% if date.has_transactions %}
{% if account %}
<a href="{% url "transaction_month" account=account.pk year=date.month.year month=date.month.month %}">{{ date.month|date:"Y-m" }}</a>
{% elif category %}
<a href="{% url "transaction_month" category=category.pk year=date.month.year month=date.month.month %}">{{ date.month|date:"Y-m" }}</a>
{% else %}
<a href="{% url "transaction_month" year=date.month.year month=date.month.month %}">{{ date.month|date:"Y-m" }}</a>
{% endif %}
{% else %}
{{ date.month|date:"Y-m" }}
{% endif %}
</th>
<td class="value">{{ date.sum_m|pmrvalue }}</td>
<td class="bar m">
<div style="width: {% widthratio date.sum_m history.max -100 %}%"></div>
{% if date.sum < 0 %}
<div class="tot" style="width:{% widthratio date.sum history.max -100 %}%">
<span>{{ date.sum|pmrvalue }}</span>
</div>
{% endif %}
</td>
<td class="bar p">
<div style="width: {% widthratio date.sum_p history.max 100 %}%"></div>
{% if date.sum > 0 %}
<div class="tot" style="width:{% widthratio date.sum history.max 100 %}%">
<span>{{ date.sum|pmrvalue }}</span>
</div>
{% endif %}
</td>
<td class="value">{{ date.sum_p|pmrvalue }}</td>
</tr>
{% for y in history.years reversed %}
{% for date in y.d reversed %}
{% if date %}
<tr>
<td class="icon">
<span class="ri-{% if date.sum > 0 %}arrow-up-s-line green{% elif date.sum < 0 %}arrow-down-s-line red{% endif %}"></span>
</td>
<th class="date" scope="row">
{% if date.has_transactions %}
{% if account %}
<a href="{% url "transaction_month" account=account.pk year=date.month.year month=date.month.month %}">{{ date.month|date:"Y-m" }}</a>
{% elif category %}
<a href="{% url "transaction_month" category=category.pk year=date.month.year month=date.month.month %}">{{ date.month|date:"Y-m" }}</a>
{% else %}
<a href="{% url "transaction_month" year=date.month.year month=date.month.month %}">{{ date.month|date:"Y-m" }}</a>
{% endif %}
{% else %}
{{ date.month|date:"Y-m" }}
{% endif %}
</th>
<td class="value">{{ date.sum_m|pmrvalue }}</td>
<td class="bar m">
<div style="width: {% widthratio date.sum_m history.max -100 %}%"></div>
{% if date.sum < 0 %}
<div class="tot" style="width:{% widthratio date.sum history.max -100 %}%">
<span>{{ date.sum|pmrvalue }}</span>
</div>
{% endif %}
</td>
<td class="bar p">
<div style="width: {% widthratio date.sum_p history.max 100 %}%"></div>
{% if date.sum > 0 %}
<div class="tot" style="width:{% widthratio date.sum history.max 100 %}%">
<span>{{ date.sum|pmrvalue }}</span>
</div>
{% endif %}
</td>
<td class="value">{{ date.sum_p|pmrvalue }}</td>
</tr>
{% else %}
<tr class="empty">
<td colspan="5" class="empty"></td>
</tr>
{% endif %}
{% endfor %}
{% endfor %}
{% endspaceless %}
</tbody>
@ -82,7 +90,7 @@
</thead>
<tbody>
{% spaceless %}
{% for year in history.years %}
{% for year in history.years reversed %}
<tr>
<th>{{ year.y }}</th>
{% for m in year.d %}
@ -100,3 +108,4 @@
</tbody>
</table>
</div>
{{ history.years|json_script }}

View File

@ -1,8 +1,7 @@
import datetime
from django.db import models
from django.db.models import Func, Max, Min, Q, Sum, Value
from django.db.models.functions import Abs, Now, TruncMonth
from django.db.models.functions import Abs, TruncMonth
class GenerateMonth(Func):
@ -13,31 +12,13 @@ class GenerateMonth(Func):
def history(transaction_set):
if not transaction_set.exists():
return None
_transaction_month = transaction_set.values(month=TruncMonth("date")).order_by(
"-date"
)
_months = (
transaction_set.values(
month=GenerateMonth(
_transaction_month.last()["month"],
Now(output_field=models.DateField()),
)
)
.annotate(
sum_m=Value(0),
sum_p=Value(0),
sum=Value(0),
has_transactions=Value(0),
)
.difference(
_transaction_month.annotate(
sum_m=Value(0),
sum_p=Value(0),
sum=Value(0),
has_transactions=Value(0),
)
)
)
_first_month = _transaction_month.last()["month"]
_last_month = _transaction_month.first()["month"]
_history = _transaction_month.annotate(
sum_p=Sum("value", filter=Q(value__gt=0)),
sum_m=Sum("value", filter=Q(value__lt=0)),
@ -46,19 +27,20 @@ def history(transaction_set):
).order_by("-month")
return {
"data": _history.union(_months).order_by("-month"),
"years": [
{
"y": y,
"d": [
_history.filter(month=datetime.date(y, m + 1, 1)).first()
for m in range(12)
for m in range(
0,
_last_month.month if _last_month.year == y else 12,
)
],
}
for y in range(
_transaction_month.first()["month"].year,
_transaction_month.last()["month"].year - 1,
-1,
_first_month.year,
_last_month.year + 1,
)
],
"max": max(

View File

@ -63,6 +63,9 @@ table.full-width col.bar {
.plot td.bar.m div.tot span {
right: 0;
}
.plot tr.empty {
height: 0.5rem;
}
@media (width < 720px) {
.plot .bar {

View File

@ -40,7 +40,7 @@
<h2>{% translate "Statements" %}</h2>
{% include "statement/statement_table.html" %}
{% endif %}
{% if history.data %}
{% if history %}
<h2>{% translate "History" %}</h2>
{% include "history/plot.html" %}
{% endif %}