From d8dec47c6a8b3ef484499e719ab5f0e7c8f33f39 Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Sat, 10 Aug 2024 17:51:30 +0200 Subject: [PATCH] add listfilter for filter bills in periods --- fet2020/finance/admin.py | 131 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 6 deletions(-) diff --git a/fet2020/finance/admin.py b/fet2020/finance/admin.py index 3276a747..6e234064 100644 --- a/fet2020/finance/admin.py +++ b/fet2020/finance/admin.py @@ -1,7 +1,11 @@ +import logging +from datetime import date, datetime + from django.conf import settings from django.contrib import admin, messages from django.http import HttpResponseRedirect from django.utils.html import format_html +from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext from segno import helpers @@ -17,6 +21,121 @@ from .forms import ( from .models import BankData, Bill, Resolution, Wiref from .utils import generate_pdf +logger = logging.getLogger(__name__) + + +class BillPeriodeFilter(admin.SimpleListFilter): + title = "Periode" + parameter_name = "period" + + __lst = () + + def choices(self, changelist): + # Current period. + yield { + "selected": self.value() is None, + "query_string": changelist.get_query_string(remove=[self.parameter_name]), + "display": self.__lst[0][1], + } + + # Add all other periods. + for lookup, title in self.__lst[1:]: + yield { + "selected": self.value() == str(lookup), + "query_string": changelist.get_query_string({self.parameter_name: lookup}), + "display": title, + } + + # 'All' choice. + yield { + "selected": self.value() == "All", + "query_string": changelist.get_query_string({self.parameter_name: "All"}), + "display": _("All"), + } + + def lookups(self, request, model_admin): + qs = model_admin.get_queryset(request).order_by("-date") + if qs.exists() is not True: + return None + + count = 0 + total_count = qs.count() + + # Get first period. + start_year = qs.first().date.year + + # Check if date of first bill is in first half of year. If yes, start of period is the + # year before. + if qs.first().date < date(start_year, 7, 1): + start_year -= 1 + + start_date = date(start_year, 7, 1) + end_date = date(start_year + 1, 6, 30) + entry_qs = qs.filter(date__range=(start_date, end_date)) + + # Go through all bills to get the periods. + while count != total_count: + # Set period if a bill exists. + if entry_qs.exists(): + self.__lst += ( + ( + f"{start_year}-{start_year + 1}", + f"Periode {start_year}-{start_year + 1}", + ), + ) + count += entry_qs.count() + + # Get bills from next period. + start_year -= 1 + start_date = date(start_year, 7, 1) + end_date = date(start_year + 1, 6, 30) + entry_qs = qs.filter(date__range=(start_date, end_date)) + + # If you are searching bills from 90's, something went wrong. + if start_year < 2000: + logger.info( + "Something went wrong while counting. Count: %s. Totalcounter: %s", + count, + total_count, + ) + break + + return self.__lst + + def queryset(self, request, queryset): + qs = queryset + + if self.value(): + try: + period = datetime.strptime(self.value()[:4], "%Y") + except Exception: + # If choice is 'All', return all bills. + qs = queryset + else: + # Return bills from specific old period. + start_year = period.year + start_date = date(start_year, 7, 1) + end_date = date(start_year + 1, 6, 30) + qs = queryset.filter(date__range=(start_date, end_date)) + + # Return bills from current period. + else: + tmp_qs = queryset.order_by("-date") + + # Get first period. + start_year = tmp_qs.first().date.year + + # Check if date of first bill is in first half of year. If yes, start of period is the + # year before. + if tmp_qs.first().date < date(start_year, 7, 1): + start_year -= 1 + + start_date = date(start_year, 7, 1) + end_date = date(start_year + 1, 6, 30) + qs = queryset.filter(date__range=(start_date, end_date)) + + return qs + class BillInline(admin.TabularInline): form = BillInlineForm @@ -80,7 +199,7 @@ class BillAdmin(admin.ModelAdmin): ] actions = ["make_cleared", "make_finished"] - list_filter = ["status", "affiliation", "payer"] + list_filter = ["status", "affiliation", "payer", BillPeriodeFilter] ordering = ["-id"] search_fields = ["purpose"] @@ -167,7 +286,7 @@ class BillAdmin(admin.ModelAdmin): except Exception: return "-" - return f"{ tmp.name }" + return f"{tmp.name}" @admin.display(description="IBAN") def get_bankdata_iban(self, obj): @@ -176,7 +295,7 @@ class BillAdmin(admin.ModelAdmin): except Exception: return "-" - return f"{ tmp.iban }" + return f"{tmp.iban}" @admin.display(description="BIC") def get_bankdata_bic(self, obj): @@ -185,7 +304,7 @@ class BillAdmin(admin.ModelAdmin): except Exception: return "-" - return f"{ tmp.bic }" + return f"{tmp.bic}" @admin.display(description="QR Code") def get_qrcode(self, obj): @@ -336,7 +455,7 @@ class ResolutionAdmin(admin.ModelAdmin): for elem in bills: total += elem.amount - return f"{ total }" + return f"{total}" @admin.display(description="Fachschaftssitzung") def fetmeeting(self, obj): @@ -422,7 +541,7 @@ class WirefAdmin(admin.ModelAdmin): for elem in bills: total += elem.amount - return f"{ total }" + return f"{total}" @admin.action(description="Als 'Überwiesen' markieren.") def make_finished(self, request, queryset):