From b074ef7929b923c8f599c397a1191ef4ab2e5fdb Mon Sep 17 00:00:00 2001 From: Herculino Trotta Date: Sat, 10 Jan 2026 02:52:46 -0300 Subject: [PATCH] feat: add late section to monthly and all views (w/ default ordering) --- app/apps/monthly_overview/views.py | 20 ++++++++- app/apps/transactions/views/transactions.py | 44 +++++++++++++++---- .../monthly_overview/fragments/list.html | 28 ++++++++++++ .../transactions/fragments/list_all.html | 27 ++++++++++++ 4 files changed, 110 insertions(+), 9 deletions(-) diff --git a/app/apps/monthly_overview/views.py b/app/apps/monthly_overview/views.py index 7529b27..b78da05 100644 --- a/app/apps/monthly_overview/views.py +++ b/app/apps/monthly_overview/views.py @@ -75,6 +75,8 @@ def transactions_list(request, month: int, year: int): if order != request.session.get("monthly_transactions_order", "default"): request.session["monthly_transactions_order"] = order + today = timezone.localdate(timezone.now()) + f = TransactionsFilter(request.GET) transactions_filtered = f.qs.filter( reference_date__year=year, @@ -92,12 +94,28 @@ def transactions_list(request, month: int, year: int): "dca_income_entries", ) + # Late transactions: date < today and is_paid = False (only shown for default ordering) + late_transactions = None + if order == "default": + late_transactions = transactions_filtered.filter( + date__lt=today, + is_paid=False, + ).order_by("date", "id") + # Exclude late transactions from the main list + transactions_filtered = transactions_filtered.exclude( + date__lt=today, + is_paid=False, + ) + transactions_filtered = default_order(transactions_filtered, order=order) return render( request, "monthly_overview/fragments/list.html", - context={"transactions": transactions_filtered}, + context={ + "transactions": transactions_filtered, + "late_transactions": late_transactions, + }, ) diff --git a/app/apps/transactions/views/transactions.py b/app/apps/transactions/views/transactions.py index e2d55fe..693a3c6 100644 --- a/app/apps/transactions/views/transactions.py +++ b/app/apps/transactions/views/transactions.py @@ -152,7 +152,9 @@ def transaction_simple_add(request): date_param = request.GET.get("date") if date_param: try: - initial_data["date"] = datetime.datetime.strptime(date_param, "%Y-%m-%d").date() + initial_data["date"] = datetime.datetime.strptime( + date_param, "%Y-%m-%d" + ).date() except ValueError: pass @@ -160,7 +162,9 @@ def transaction_simple_add(request): reference_date_param = request.GET.get("reference_date") if reference_date_param: try: - initial_data["reference_date"] = datetime.datetime.strptime(reference_date_param, "%Y-%m-%d").date() + initial_data["reference_date"] = datetime.datetime.strptime( + reference_date_param, "%Y-%m-%d" + ).date() except ValueError: pass @@ -172,7 +176,10 @@ def transaction_simple_add(request): except (ValueError, TypeError): # Try to find by name from apps.accounts.models import Account - account = Account.objects.filter(name__iexact=account_param, is_archived=False).first() + + account = Account.objects.filter( + name__iexact=account_param, is_archived=False + ).first() if account: initial_data["account"] = account.pk @@ -207,7 +214,10 @@ def transaction_simple_add(request): except (ValueError, TypeError): # Try to find by name from apps.transactions.models import TransactionCategory - category = TransactionCategory.objects.filter(name__iexact=category_param, active=True).first() + + category = TransactionCategory.objects.filter( + name__iexact=category_param, active=True + ).first() if category: initial_data["category"] = category.pk @@ -457,7 +467,7 @@ def transaction_pay(request, transaction_id): context={"transaction": transaction, **request.GET}, ) response.headers["HX-Trigger"] = ( - f'{"paid" if new_is_paid else "unpaid"}, selective_update' + f"{'paid' if new_is_paid else 'unpaid'}, selective_update" ) return response @@ -552,6 +562,8 @@ def transaction_all_list(request): if order != request.session.get("all_transactions_order", "default"): request.session["all_transactions_order"] = order + today = timezone.localdate(timezone.now()) + transactions = Transaction.objects.prefetch_related( "account", "account__group", @@ -565,12 +577,27 @@ def transaction_all_list(request): "dca_income_entries", ).all() - transactions = default_order(transactions, order=order) - f = TransactionsFilter(request.GET, queryset=transactions) + # Late transactions: date < today and is_paid = False (only shown for default ordering on first page) + late_transactions = None page_number = request.GET.get("page", 1) - paginator = Paginator(f.qs, 100) + if order == "default" and str(page_number) == "1": + late_transactions = f.qs.filter( + date__lt=today, + is_paid=False, + ).order_by("date", "id") + # Exclude late transactions from the main paginated list + main_transactions = f.qs.exclude( + date__lt=today, + is_paid=False, + ) + else: + main_transactions = f.qs + + main_transactions = default_order(main_transactions, order=order) + + paginator = Paginator(main_transactions, 100) page_obj = paginator.get_page(page_number) return render( @@ -579,6 +606,7 @@ def transaction_all_list(request): { "page_obj": page_obj, "paginator": paginator, + "late_transactions": late_transactions, }, ) diff --git a/app/templates/monthly_overview/fragments/list.html b/app/templates/monthly_overview/fragments/list.html index 30b200c..0227346 100644 --- a/app/templates/monthly_overview/fragments/list.html +++ b/app/templates/monthly_overview/fragments/list.html @@ -3,6 +3,31 @@ {% regroup transactions by date|customnaturaldate as transactions_by_date %}
+ {% if late_transactions %} +
+ +
+
+ {% for transaction in late_transactions %} + + {% endfor %} +
+
+
+ {% endif %} + {% for x in transactions_by_date %}
{% empty %} + {% if not late_transactions %} + {% endif %} {% endfor %} {# Floating bar #}
+ diff --git a/app/templates/transactions/fragments/list_all.html b/app/templates/transactions/fragments/list_all.html index cf3b362..196d4c0 100644 --- a/app/templates/transactions/fragments/list_all.html +++ b/app/templates/transactions/fragments/list_all.html @@ -3,6 +3,31 @@ {% regroup page_obj by date|customnaturaldate as transactions_by_date %}
+ {% if late_transactions %} +
+ +
+
+ {% for transaction in late_transactions %} + + {% endfor %} +
+
+
+ {% endif %} + {% for x in transactions_by_date %}
{% empty %} + {% if not late_transactions %} + {% endif %} {% endfor %} {# Floating bar #}