Add monthly view
This commit is contained in:
parent
966100536e
commit
17e150032e
6 changed files with 102 additions and 6 deletions
|
@ -25,8 +25,6 @@
|
||||||
{% if transactions %}
|
{% if transactions %}
|
||||||
<h2>{% translate "Transactions" %}</h2>
|
<h2>{% translate "Transactions" %}</h2>
|
||||||
{% include "main/table/transaction.html" %}
|
{% include "main/table/transaction.html" %}
|
||||||
<h2>{% translate "History" %}</h2>
|
|
||||||
{% include "main/plot/history.html" %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if categories %}
|
{% if categories %}
|
||||||
<h2>{% translate "Categories" %}</h2>
|
<h2>{% translate "Categories" %}</h2>
|
||||||
|
@ -42,4 +40,8 @@
|
||||||
<h2>{% translate "Snapshots" %}</h2>
|
<h2>{% translate "Snapshots" %}</h2>
|
||||||
{% include "main/table/snapshot.html" %}
|
{% include "main/table/snapshot.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if history.data %}
|
||||||
|
<h2>{% translate "History" %}</h2>
|
||||||
|
{% include "main/plot/history.html" %}
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
27
nummi/main/templates/main/month/transaction.html
Normal file
27
nummi/main/templates/main/month/transaction.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{% extends "main/base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% load main_extras %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block link %}
|
||||||
|
{{ block.super }}
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="{% static 'main/css/table.css' %}"
|
||||||
|
type="text/css" />
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="{% static 'main/css/plot.css' %}"
|
||||||
|
type="text/css" />
|
||||||
|
{% endblock %}
|
||||||
|
{% block body %}
|
||||||
|
<h2>{% translate "Transactions" %} – {{ month|date:"F Y"|capfirst }}</h2>
|
||||||
|
{% if account %}
|
||||||
|
<p>
|
||||||
|
<a href="{% url "account" account.pk %}">{{ account.icon|remix }}{{ account }}</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if category %}
|
||||||
|
<p>
|
||||||
|
<a href="{% url "category" category.pk %}">{{ category.icon|remix }}{{ category }}</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% include "main/table/transaction.html" %}
|
||||||
|
{% endblock %}
|
|
@ -24,7 +24,19 @@
|
||||||
<td class="icon">
|
<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>
|
<span class="ri-{% if date.sum > 0 %}arrow-up-s-line green{% elif date.sum < 0 %}arrow-down-s-line red{% endif %}"></span>
|
||||||
</td>
|
</td>
|
||||||
<th class="date" scope="row">{{ date.month|date:"Y-m" }}</th>
|
<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="value">{{ date.sum_m|pmrvalue }}</td>
|
||||||
<td class="bar m">
|
<td class="bar m">
|
||||||
<div style="width: {% widthratio date.sum_m history.max -100 %}%"></div>
|
<div style="width: {% widthratio date.sum_m history.max -100 %}%"></div>
|
||||||
|
|
|
@ -80,4 +80,19 @@ urlpatterns = [
|
||||||
),
|
),
|
||||||
path("search", views.SearchFormView.as_view(), name="search"),
|
path("search", views.SearchFormView.as_view(), name="search"),
|
||||||
path("search/<search>", views.SearchView.as_view(), name="search"),
|
path("search/<search>", views.SearchView.as_view(), name="search"),
|
||||||
|
path(
|
||||||
|
"history/<int:year>/<int:month>",
|
||||||
|
views.TransactionMonthView.as_view(),
|
||||||
|
name="transaction_month",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"account/<account>/history/<int:year>/<int:month>",
|
||||||
|
views.TransactionMonthView.as_view(),
|
||||||
|
name="transaction_month",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"category/<category>/history/<int:year>/<int:month>",
|
||||||
|
views.TransactionMonthView.as_view(),
|
||||||
|
name="transaction_month",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -32,15 +32,20 @@ def history(transaction_set):
|
||||||
Now(output_field=models.DateField()),
|
Now(output_field=models.DateField()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.annotate(sum_m=Value(0), sum_p=Value(0), sum=Value(0))
|
.annotate(
|
||||||
|
sum_m=Value(0), sum_p=Value(0), sum=Value(0), has_transactions=Value(0)
|
||||||
|
)
|
||||||
.difference(
|
.difference(
|
||||||
_transaction_month.annotate(sum_m=Value(0), sum_p=Value(0), sum=Value(0))
|
_transaction_month.annotate(
|
||||||
|
sum_m=Value(0), sum_p=Value(0), sum=Value(0), has_transactions=Value(0)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
_history = _transaction_month.annotate(
|
_history = _transaction_month.annotate(
|
||||||
sum_p=Sum("value", filter=Q(value__gt=0)),
|
sum_p=Sum("value", filter=Q(value__gt=0)),
|
||||||
sum_m=Sum("value", filter=Q(value__lt=0)),
|
sum_m=Sum("value", filter=Q(value__lt=0)),
|
||||||
sum=Sum("value"),
|
sum=Sum("value"),
|
||||||
|
has_transactions=Value(1),
|
||||||
).order_by("-month")
|
).order_by("-month")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -21,6 +21,7 @@ from django.views.generic import (
|
||||||
TemplateView,
|
TemplateView,
|
||||||
UpdateView,
|
UpdateView,
|
||||||
)
|
)
|
||||||
|
from django.views.generic.dates import MonthArchiveView
|
||||||
from django.views.static import serve
|
from django.views.static import serve
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
|
@ -48,7 +49,7 @@ class IndexView(LoginRequiredMixin, TemplateView):
|
||||||
"transactions": _transactions[:_max],
|
"transactions": _transactions[:_max],
|
||||||
"categories": Category.objects.filter(user=self.request.user),
|
"categories": Category.objects.filter(user=self.request.user),
|
||||||
"snapshots": _snapshots[:_max],
|
"snapshots": _snapshots[:_max],
|
||||||
"history": history(_transactions.filter(category__budget=True)),
|
"history": history(_transactions.exclude(category__budget=False)),
|
||||||
}
|
}
|
||||||
if _transactions.count() > _max:
|
if _transactions.count() > _max:
|
||||||
res["transactions_url"] = reverse_lazy("transactions")
|
res["transactions_url"] = reverse_lazy("transactions")
|
||||||
|
@ -430,3 +431,37 @@ class MediaView(LoginRequiredMixin, View):
|
||||||
_res["Content-Type"] = ""
|
_res["Content-Type"] = ""
|
||||||
_res["X-Accel-Redirect"] = f"/internal/media/user/{_username}/{_path}"
|
_res["X-Accel-Redirect"] = f"/internal/media/user/{_username}/{_path}"
|
||||||
return _res
|
return _res
|
||||||
|
|
||||||
|
|
||||||
|
class TransactionMonthView(UserMixin, MonthArchiveView):
|
||||||
|
template_name = "main/month/transaction.html"
|
||||||
|
model = Transaction
|
||||||
|
date_field = "date"
|
||||||
|
context_object_name = "transactions"
|
||||||
|
month_format = "%m"
|
||||||
|
|
||||||
|
account = None
|
||||||
|
category = None
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
if self.account:
|
||||||
|
return super().get_queryset().filter(account=self.account)
|
||||||
|
if self.category:
|
||||||
|
return super().get_queryset().filter(category=self.category)
|
||||||
|
|
||||||
|
return super().get_queryset()
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
if "account" in self.kwargs:
|
||||||
|
self.account = get_object_or_404(
|
||||||
|
Account.objects.filter(user=self.request.user),
|
||||||
|
pk=self.kwargs["account"],
|
||||||
|
)
|
||||||
|
return super().get_context_data(**kwargs) | {"account": self.account}
|
||||||
|
if "category" in self.kwargs:
|
||||||
|
self.category = get_object_or_404(
|
||||||
|
Category.objects.filter(user=self.request.user),
|
||||||
|
pk=self.kwargs["category"],
|
||||||
|
)
|
||||||
|
return super().get_context_data(**kwargs) | {"category": self.category}
|
||||||
|
return super().get_context_data(**kwargs)
|
||||||
|
|
Loading…
Reference in a new issue