From 79f87779dd416859e8e50e40a19595ddf7077f77 Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart"
diff --git a/nummi/main/views.py b/nummi/main/views.py
index 2786ed9..0dc8b3f 100644
--- a/nummi/main/views.py
+++ b/nummi/main/views.py
@@ -105,4 +105,4 @@ class LogoutView(auth_views.LogoutView):
class NummiListView(UserMixin, ListView):
- paginate_by = 96
+ pass
diff --git a/nummi/statement/views.py b/nummi/statement/views.py
index 426436a..238d296 100644
--- a/nummi/statement/views.py
+++ b/nummi/statement/views.py
@@ -84,6 +84,7 @@ class StatementDetailView(NummiDetailView):
class StatementListView(NummiListView):
model = Statement
context_object_name = "statements"
+ paginate_by = 32
class StatementMixin:
diff --git a/nummi/transaction/views.py b/nummi/transaction/views.py
index 433177e..90e681d 100644
--- a/nummi/transaction/views.py
+++ b/nummi/transaction/views.py
@@ -124,6 +124,7 @@ class InvoiceDeleteView(NummiDeleteView):
class TransactionListView(NummiListView):
model = Transaction
context_object_name = "transactions"
+ paginate_by = 50
class TransactionACMixin:
From e8050fadb9600fc8f720038a7af7a05961855bca Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart"
@@ -14,7 +16,7 @@
{% endif %}
{{ trans.trader|default_if_none:"" }}
{% if not category %}
- {% if trans.category %}
-
+
+ {% if trans.category %}
{{ trans.category.icon|remix }}{{ trans.category }}
-
- {% else %}
-
- {% endif %}
+ {% endif %}
+
{% endif %}
{% if not account %}
- {{ trans.account.icon|remix }}{{ trans.account }}
+ {% if trans.account %}
+ {{ trans.account.icon|remix }}{{ trans.account|default_if_none:"" }}
+ {% endif %}
{% endif %}
From 57d5330d75619b664236dfaffbe72f095dbeed9b Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart"
+ {% for acc in accounts %}
+
diff --git a/nummi/account/templatetags/__init__.py b/nummi/account/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/nummi/account/templatetags/account_extras.py b/nummi/account/templatetags/account_extras.py
new file mode 100644
index 0000000..5e6c478
--- /dev/null
+++ b/nummi/account/templatetags/account_extras.py
@@ -0,0 +1,10 @@
+from django import template
+
+register = template.Library()
+
+
+@register.inclusion_tag("account/account_table.html")
+def account_table(accounts, **kwargs):
+ return kwargs | {
+ "accounts": accounts,
+ }
diff --git a/nummi/account/urls.py b/nummi/account/urls.py
index f6b4f2b..93713af 100644
--- a/nummi/account/urls.py
+++ b/nummi/account/urls.py
@@ -5,6 +5,7 @@ from transaction.views import TransactionMonthView, TransactionYearView
from . import views
urlpatterns = [
+ path("list", views.AccountListView.as_view(), name="accounts"),
path("new", views.AccountCreateView.as_view(), name="new_account"),
path("{% translate "Accounts" %}
-
- {% for acc in accounts %}
-
+ {% account_table accounts index=True total=accounts|balance %}
{% translate "Statements" %}
{% include "statement/statement_table.html" %}
{% translate "Categories" %}
{% spaceless %}
{{ object.icon|remix }}{{ object }}
{% translate "Statements" %}
- {% include "statement/statement_table.html" %}
+ {% statement_table statements statements_url=statements_url new_statement_url=new_statement_url %}
{% translate "Statements" %}
- {% include "statement/statement_table.html" %}
+ {% statement_table statements statements_url=statements_url %}
- {% for cat in categories %}
+ {% for cat in user.category_set.all %}
{{ cat.icon|remix }}{{ cat }}
{% endfor %}
{{ "add"|remix }}{% translate "Create category" %}
diff --git a/nummi/main/views.py b/nummi/main/views.py
index 0dc8b3f..df08d7c 100644
--- a/nummi/main/views.py
+++ b/nummi/main/views.py
@@ -1,5 +1,3 @@
-from account.models import Account
-from category.models import Category
from django.contrib import messages
from django.contrib.auth import views as auth_views
from django.contrib.auth.mixins import LoginRequiredMixin
@@ -15,33 +13,24 @@ from django.views.generic import (
UpdateView,
)
from history.utils import history
-from statement.models import Statement
-from transaction.models import Transaction
class IndexView(LoginRequiredMixin, TemplateView):
template_name = "main/index.html"
def get_context_data(self, **kwargs):
- _max = 8
- _transactions = Transaction.objects.filter(user=self.request.user)
- _accounts = Account.objects.filter(user=self.request.user)
+ _user = self.request.user
+ _transactions = _user.transaction_set.all()
_statements = (
- Statement.objects.filter(user=self.request.user)
- .exclude(account__archived=True)
+ _user.statement_set.exclude(account__archived=True)
.order_by("account__id", "-date")
.distinct("account__id")
)
res = {
- "accounts": _accounts,
- "categories": Category.objects.filter(user=self.request.user),
"statements": _statements,
"history": history(_transactions.exclude(category__budget=False)),
}
- if _transactions.count() > _max:
- res["transactions_url"] = reverse_lazy("transactions")
- res["statements_url"] = reverse_lazy("statements")
return super().get_context_data(**kwargs) | res
diff --git a/nummi/statement/templates/statement/statement_list.html b/nummi/statement/templates/statement/statement_list.html
index 6970a63..2b2d998 100644
--- a/nummi/statement/templates/statement/statement_list.html
+++ b/nummi/statement/templates/statement/statement_list.html
@@ -7,6 +7,6 @@
{% translate "Statements" %}
{% endblock h2 %}
{% block table %}
- {% url "new_statement" as new_statement_url %}
- {% statement_table statements new_statement_url=new_statement_url %}
+ {% url "new_statement" as ns_url %}
+ {% statement_table statements new_statement_url=ns_url %}
{% endblock table %}
diff --git a/nummi/statement/templatetags/statement_extras.py b/nummi/statement/templatetags/statement_extras.py
index 54eef80..d63dd6d 100644
--- a/nummi/statement/templatetags/statement_extras.py
+++ b/nummi/statement/templatetags/statement_extras.py
@@ -16,6 +16,11 @@ def check(s, diff):
@register.inclusion_tag("statement/statement_table.html")
def statement_table(statements, **kwargs):
+ if (n_max := kwargs.get("n_max")) is not None:
+ if statements.count() <= n_max:
+ del kwargs["statements_url"]
+ statements = statements[:n_max]
+
return kwargs | {
"statements": statements,
}
From 229033aac0d80774bf56d80c6e757dd56000869c Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart"
- {{ "edit"|remix }}{% translate "Edit account" %}
+ {{ "edit"|remix }}{% translate "Edit account" %}
- {{ "edit"|remix }}{% translate "Edit category" %}
+ {{ "edit"|remix }}{% translate "Edit category" %}
{{ object.icon|remix }}{{ object }}
+ {{ account.icon|remix }}{{ account }}
{% translate "Statements" %}
@@ -20,10 +20,8 @@
{% url "account_statements" account=account.pk as s_url %}
{% statement_table account.statement_set.all statements_url=s_url new_statement_url=ns_url n_max=6 %}
{% translate "History" %}
- {% include "history/plot.html" %}
- {% translate "History" %}
+ {% history_plot account.transactions %}
+ {{ object.icon|remix }}{{ object }}
+ {{ category.icon|remix }}{{ category }}
{% translate "Transactions" %}
{% include "transaction/transaction_table.html" %}
{% translate "History" %}
- {% include "history/plot.html" %}
- {% translate "History" %}
+ {% history_plot category.transaction_set.all %}
+
@@ -38,10 +38,12 @@
| {{ widget.initial_text }} | -- {% translate "File" %} [{{ widget.value|extension }}] - | -
|---|---|
| - - | -- - | -
| {{ widget.input_text }} | -- {% else %} - |
| - {% endif %} - - | -|
{{ field.errors }}
{% endif %}+ {{ "list-check"|remixnl }}{% translate "View all transactions" %} +
{% transaction_table category.transaction_set.all n_max=8 transactions_url=t_url %}- {% for page in paginator.page_range %} - {{ page }} - {% endfor %} -
+{% pagination_links page_obj %}
{% endif %} {% if month %}{% year_url month %}
diff --git a/nummi/main/templates/main/pagination_links.html b/nummi/main/templates/main/pagination_links.html new file mode 100644 index 0000000..fcd8531 --- /dev/null +++ b/nummi/main/templates/main/pagination_links.html @@ -0,0 +1,13 @@ +{% load i18n main_extras %} +{% if first.show %} + 1 + {% if first.dots %}…{% endif %} +{% endif %} +{% for page in pages %} + {{ page.number }} +{% endfor %} +{% if last.show %} + {% if last.dots %}…{% endif %} + {{ last.number }} +{% endif %} diff --git a/nummi/main/templatetags/main_extras.py b/nummi/main/templatetags/main_extras.py index c5eea6c..9dd97e4 100644 --- a/nummi/main/templatetags/main_extras.py +++ b/nummi/main/templatetags/main_extras.py @@ -89,3 +89,24 @@ def balance(accounts): return sum( statement.value for acc in accounts if (statement := acc.statement_set.first()) ) + + +@register.inclusion_tag("main/pagination_links.html") +def pagination_links(page_obj): + _n = 3 + return { + "pages": [ + {"number": p, "current": p == page_obj.number} + for p in page_obj.paginator.page_range + if abs(p - page_obj.number) < _n + ], + "first": { + "show": page_obj.number > _n, + "dots": page_obj.number > _n + 1, + }, + "last": { + "show": page_obj.number <= page_obj.paginator.num_pages - _n, + "dots": page_obj.number < page_obj.paginator.num_pages - _n, + "number": page_obj.paginator.num_pages, + }, + } diff --git a/nummi/statement/templates/statement/statement_detail.html b/nummi/statement/templates/statement/statement_detail.html index bb7c795..232b22f 100644 --- a/nummi/statement/templates/statement/statement_detail.html +++ b/nummi/statement/templates/statement/statement_detail.html @@ -56,8 +56,12 @@+ {{ "add-circle"|remix }}{% translate "Add transaction" %} + {{ "list-check"|remixnl }}{% translate "View all transactions" %} +
+ {% transaction_table statement.transaction_set.all n_max=8 transactions_url=t_url %}+ {{ "add-circle"|remix }}{% translate "Add transaction" %} +
+ {% transaction_table transactions %} {% endblock table %} diff --git a/nummi/transaction/templates/transaction/transaction_table.html b/nummi/transaction/templates/transaction/transaction_table.html index 4879d3f..7dbe47c 100644 --- a/nummi/transaction/templates/transaction/transaction_table.html +++ b/nummi/transaction/templates/transaction/transaction_table.html @@ -13,13 +13,6 @@ {% if not hide_account %}{{ "add-circle"|remix }}{% translate "Add transaction" %}
+ {% transaction_filters form=filter_form %} {% transaction_table transactions %} {% endblock table %} diff --git a/nummi/transaction/templatetags/transaction_extras.py b/nummi/transaction/templatetags/transaction_extras.py index e2311a0..e905a02 100644 --- a/nummi/transaction/templatetags/transaction_extras.py +++ b/nummi/transaction/templatetags/transaction_extras.py @@ -17,10 +17,8 @@ def transaction_table(context, transactions, n_max=None, **kwargs): del kwargs["transactions_url"] transactions = transactions[:n_max] - if "account" in context or "statement" in context: - kwargs.setdefault("hide_account", True) - if "category" in context: - kwargs.setdefault("hide_category", True) + kwargs.setdefault("hide_account", "account" in context or "statement" in context) + kwargs.setdefault("hide_category", "category" in context) ncol = 8 if kwargs.get("hide_account"): @@ -31,6 +29,12 @@ def transaction_table(context, transactions, n_max=None, **kwargs): return kwargs | {"transactions": transactions, "ncol": ncol} +@register.inclusion_tag("transaction/transaction_filters.html", takes_context=True) +def transaction_filters(context, **kwargs): + kwargs.setdefault("filters", context.get("filters")) + return kwargs + + @register.inclusion_tag("transaction/invoice_table.html") def invoice_table(transaction, **kwargs): return kwargs | { diff --git a/nummi/transaction/views.py b/nummi/transaction/views.py index ebf2238..41fd184 100644 --- a/nummi/transaction/views.py +++ b/nummi/transaction/views.py @@ -1,6 +1,13 @@ from account.models import Account from category.models import Category from django.contrib import messages +from django.contrib.postgres.search import ( + SearchQuery, + SearchRank, + SearchVector, + TrigramSimilarity, +) +from django.db import models from django.forms import ValidationError from django.shortcuts import get_object_or_404 from django.urls import reverse_lazy @@ -18,7 +25,12 @@ from main.views import ( UserMixin, ) -from .forms import InvoiceForm, MultipleInvoicesForm, TransactionForm +from .forms import ( + InvoiceForm, + MultipleInvoicesForm, + TransactionFiltersForm, + TransactionForm, +) from .models import Invoice, Transaction @@ -167,6 +179,49 @@ class TransactionListView(NummiListView): context_object_name = "transactions" paginate_by = 50 + def get_queryset(self, **kwargs): + queryset = super().get_queryset(**kwargs) + + if date := self.request.GET.get("start_date"): + queryset = queryset.filter(date__gte=date) + if date := self.request.GET.get("end_date"): + queryset = queryset.filter(date__lte=date) + if category := self.request.GET.get("category"): + queryset = queryset.filter(category=category) + if account := self.request.GET.get("account"): + queryset = queryset.filter(statement__account=account) + if search := self.request.GET.get("search"): + queryset = ( + queryset.annotate( + rank=SearchRank( + SearchVector("name", weight="A") + + SearchVector("description", weight="B") + + SearchVector("trader", weight="B") + + SearchVector("category__name", weight="C"), + SearchQuery(search, search_type="websearch"), + ), + similarity=TrigramSimilarity("name", search), + ) + .filter(models.Q(rank__gte=0.1) | models.Q(similarity__gte=0.3)) + .order_by("-rank", "-date") + ) + if sort_by := self.request.GET.get("sort_by"): + queryset = queryset.order_by(sort_by) + + return queryset + + def get_context_data(self, **kwargs): + data = super().get_context_data(**kwargs) + + filters = self.request.GET.copy() + filters.pop("page", None) + if filters: + data["filters"] = True + data["filter_form"] = TransactionFiltersForm( + initial=filters, user=self.request.user + ) + return data + class TransactionACMixin: model = Transaction From ccbf433ec0705b33f128c285e45dfd82530ee41b Mon Sep 17 00:00:00 2001 From: "Edgar P. Burkhart"$+Iv)^l<`dkU9K78Yra%WI_PQP>=)&fHW|JSquzJ
d6C34NL-I=!b2iR%W#k337##ER4zEmQ003vA76)k1``OeOk60p@u&+UyJKG7;gzWj
E0JmEaxBvhE
diff --git a/nummi/history/locale/fr_FR/LC_MESSAGES/django.po b/nummi/history/locale/fr_FR/LC_MESSAGES/django.po
index c0e51e2..ea07229 100644
--- a/nummi/history/locale/fr_FR/LC_MESSAGES/django.po
+++ b/nummi/history/locale/fr_FR/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-01-03 15:51+0100\n"
+"POT-Creation-Date: 2025-01-04 18:51+0100\n"
"PO-Revision-Date: 2023-04-22 15:18+0200\n"
"Last-Translator: Edgar P. Burkhart {{ transaction }}
- {% if statement %}
+ {% if transaction.statement %}
{{ "list-check"|remixnl }}{% translate "View all transactions" %}
diff --git a/nummi/category/templates/category/category_plot.html b/nummi/category/templates/category/category_plot.html index fd80fc3..1ffa4f7 100644 --- a/nummi/category/templates/category/category_plot.html +++ b/nummi/category/templates/category/category_plot.html @@ -22,9 +22,9 @@
{{ "add-circle"|remix }}{% translate "Add transaction" %}
diff --git a/nummi/transaction/forms.py b/nummi/transaction/forms.py
index 16110a0..a093bbc 100644
--- a/nummi/transaction/forms.py
+++ b/nummi/transaction/forms.py
@@ -172,6 +172,7 @@ class TransactionFiltersForm(forms.Form):
account = forms.ModelChoiceField(
queryset=None, required=False, widget=AccountSelect()
)
+ statement = forms.ModelChoiceField(queryset=None, required=False)
search = forms.CharField(label=_("Search"), required=False)
sort_by = forms.ChoiceField(
label=_("Sort by"),
@@ -191,6 +192,14 @@ class TransactionFiltersForm(forms.Form):
self.fields["category"].queryset = _user.category_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 |= {
"class": "category",
diff --git a/nummi/transaction/templates/transaction/transaction_filters.html b/nummi/transaction/templates/transaction/transaction_filters.html
index 907a14f..f29766d 100644
--- a/nummi/transaction/templates/transaction/transaction_filters.html
+++ b/nummi/transaction/templates/transaction/transaction_filters.html
@@ -1,19 +1,21 @@
{% load i18n %}
-{% translate "Filters" %}
-