Refactor transaction URL handling and enhance filter form functionality

Close #43
This commit is contained in:
Edgar P. Burkhart 2025-01-04 21:14:46 +01:00
parent 02c53c7dab
commit d44407d9ab
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227
9 changed files with 73 additions and 22 deletions

View file

@ -15,7 +15,7 @@
</p> </p>
<section> <section>
<h3>{% translate "Transactions" %}</h3> <h3>{% translate "Transactions" %}</h3>
{% url "category_transactions" category.id as t_url %} {% url_get "transactions" category=category.id as t_url %}
<p> <p>
<a class="big-link" href="{{ t_url }}">{{ "list-check"|remixnl }}{% translate "View all transactions" %}</a> <a class="big-link" href="{{ t_url }}">{{ "list-check"|remixnl }}{% translate "View all transactions" %}</a>
</p> </p>

View file

@ -22,9 +22,9 @@
<th scope="row" class="l wi"> <th scope="row" class="l wi">
{% if cat.category %} {% if cat.category %}
{% if month %} {% if month %}
<a href="{% url "category_transaction_month" cat.category month.year month.month %}">{{ cat.category__icon|remix }}{{ cat.category__name }}</a> <a href="{% url_get "transactions" category=cat.category start_date=month end_date=month|end_of_month %}">{{ cat.category__icon|remix }}{{ cat.category__name }}</a>
{% elif year %} {% elif year %}
<a href="{% url "category_transaction_year" cat.category year.year %}">{{ cat.category__icon|remix }}{{ cat.category__name }}</a> <a href="{% url_get "transactions" category=cat.category start_date=year end_date=year|end_of_year %}">{{ cat.category__icon|remix }}{{ cat.category__name }}</a>
{% else %} {% else %}
{{ cat.category__icon|remix }}{{ cat.category__name }} {{ cat.category__icon|remix }}{{ cat.category__name }}
{% endif %} {% endif %}

View file

@ -153,9 +153,27 @@ if (accounts) {
const filterForm = document.querySelector("form.filter"); const filterForm = document.querySelector("form.filter");
if (filterForm) { if (filterForm) {
const accountSelect = filterForm.querySelector("[name='account']");
const statementSelect = filterForm.querySelector("[name='statement']");
if (!statementSelect.disabled) {
accountSelect.addEventListener("input", (event) => {
statementSelect.value = "";
statementSelect.disabled = true;
});
filterForm.addEventListener("reset", (event) => {
statementSelect.disabled = false;
});
}
let disableStatement = false;
filterForm.addEventListener("submit", (event) => { filterForm.addEventListener("submit", (event) => {
for (element of filterForm.elements) { for (element of filterForm.elements) {
if (element.value == "") { if (
element.value == "" ||
(disableStatement && element.name == "statement")
) {
if (element.name == "account") {
disableStatement = true;
}
element.disabled = true; element.disabled = true;
} }
} }

View file

@ -1,5 +1,9 @@
from urllib import parse
from dateutil.relativedelta import relativedelta
from django import template from django import template
from django.templatetags.static import static from django.templatetags.static import static
from django.urls import reverse
from django.utils import formats from django.utils import formats
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -118,3 +122,18 @@ def page_url(context, page):
query = context["request"].GET.copy() query = context["request"].GET.copy()
query["page"] = page query["page"] = page
return query.urlencode() return query.urlencode()
@register.simple_tag
def url_get(name, **kwargs):
return f"{reverse(name)}?{parse.urlencode(kwargs)}"
@register.filter
def end_of_month(month):
return month + relativedelta(months=1, days=-1)
@register.filter
def end_of_year(year):
return year + relativedelta(years=1, days=-1)

View file

@ -55,7 +55,7 @@
</div> </div>
<section> <section>
<h3>{% translate "Transactions" %}</h3> <h3>{% translate "Transactions" %}</h3>
{% url "statement_transactions" statement.id as t_url %} {% url_get "transactions" account=account.id statement=statement.id as t_url %}
<p> <p>
<a class="big-link" <a class="big-link"
href="{% url "new_transaction" statement=statement.id %}">{{ "add-circle"|remix }}{% translate "Add transaction" %}</a> href="{% url "new_transaction" statement=statement.id %}">{{ "add-circle"|remix }}{% translate "Add transaction" %}</a>

View file

@ -172,6 +172,7 @@ class TransactionFiltersForm(forms.Form):
account = forms.ModelChoiceField( account = forms.ModelChoiceField(
queryset=None, required=False, widget=AccountSelect() queryset=None, required=False, widget=AccountSelect()
) )
statement = forms.ModelChoiceField(queryset=None, required=False)
search = forms.CharField(label=_("Search"), required=False) search = forms.CharField(label=_("Search"), required=False)
sort_by = forms.ChoiceField( sort_by = forms.ChoiceField(
label=_("Sort by"), label=_("Sort by"),
@ -191,6 +192,14 @@ class TransactionFiltersForm(forms.Form):
self.fields["category"].queryset = _user.category_set self.fields["category"].queryset = _user.category_set
self.fields["account"].queryset = _user.account_set self.fields["account"].queryset = _user.account_set
print(kwargs.get("initial"))
if acc_id := kwargs.get("initial", {}).get("account"):
self.fields["statement"].queryset = (
self.fields["account"].queryset.get(id=acc_id).statement_set
)
else:
self.fields["statement"].queryset = _user.statement_set.none()
self.fields["statement"].disabled = True
self.fields["category"].widget.attrs |= { self.fields["category"].widget.attrs |= {
"class": "category", "class": "category",

View file

@ -1,19 +1,21 @@
{% load i18n %} {% load i18n %}
<details {% if filters %}open{% endif %}> {% if form %}
<summary>{% translate "Filters" %}</summary> <details {% if filters %}open{% endif %}>
<form class="filter" method="get"> <summary>{% translate "Filters" %}</summary>
{% for field in form %} <form class="filter" method="get">
<div class="field"> {% for field in form %}
<label>{{ field.label }}</label> <div class="field">
{{ field }} <label>{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
<div class="buttons">
<input type="submit" value="{% translate "Filter" %}">
<input type="reset" value="{% translate "Reset" %}">
{% if filters %}
<a href="?" class="del">{% translate "Clear" %}</a>
{% endif %}
</div> </div>
{% endfor %} </form>
<div class="buttons"> </details>
<input type="submit" value="{% translate "Filter" %}"> {% endif %}
<input type="reset" value="{% translate "Reset" %}">
{% if filters %}
<a href="?" class="del">{% translate "Clear" %}</a>
{% endif %}
</div>
</form>
</details>

View file

@ -190,6 +190,8 @@ class TransactionListView(NummiListView):
queryset = queryset.filter(category=category) queryset = queryset.filter(category=category)
if account := self.request.GET.get("account"): if account := self.request.GET.get("account"):
queryset = queryset.filter(statement__account=account) queryset = queryset.filter(statement__account=account)
if statement := self.request.GET.get("statement"):
queryset = queryset.filter(statement=statement)
if search := self.request.GET.get("search"): if search := self.request.GET.get("search"):
queryset = ( queryset = (
queryset.annotate( queryset.annotate(

View file

@ -10,6 +10,7 @@ depends=(
"python-django" "python-django"
"python-toml" "python-toml"
"python-psycopg" "python-psycopg"
"python-dateutil"
) )
makedepends=("git") makedepends=("git")
optdepends=("postgresql: database") optdepends=("postgresql: database")