From 4a003ed15e3b52bf7a0cd6dc55b3bde1948d02ec Mon Sep 17 00:00:00 2001 From: "marius.klein" Date: Sun, 30 Mar 2025 23:56:53 +0200 Subject: [PATCH 1/2] fix(members/freizeit): change age calculation to first day of excursion (#148) Reviewed-on: https://git.jdav-hd.merten.dev/digitales/kompass/pulls/148 Reviewed-by: Christian Merten Co-authored-by: marius.klein Co-committed-by: marius.klein --- jdav_web/members/models.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index 0ef6dc2..d18b06f 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import datetime, timedelta, date import uuid import math import pytz @@ -257,6 +257,10 @@ class Person(Contact): age.admin_order_field = 'birth_date' age.short_description = _('age') + def age_at(self, date: date): + """Age of member at a given date""" + return relativedelta(date.replace(tzinfo=None), self.birth_date).years + @property def birth_date_str(self): if self.birth_date is None: @@ -1252,7 +1256,7 @@ class Freizeit(CommonModel): # non-youth leader participants ps_only = ps - jls # participants of the correct age - ps_correct_age = {m for m in ps_only if m.age() >= 6 and m.age() < 27} + ps_correct_age = {m for m in ps_only if m.age_at(self.date) >= 6 and m.age_at(self.date) < 27} # m = the official non-youth-leader participant count # and, assuming there exist enough participants, unrounded m satisfies the equation # len(ps_correct_age) + 1/5 * m = m @@ -1340,9 +1344,9 @@ class Freizeit(CommonModel): jls = set(self.jugendleiter.distinct()) participants = members - jls b27_local = len([m for m in participants - if m.age() <= 27 and settings.SEKTION in m.town]) + if m.age_at(self.date) <= 27 and settings.SEKTION in m.town]) b27_non_local = len([m for m in participants - if m.age() <= 27 and not settings.SEKTION in m.town]) + if m.age_at(self.date) <= 27 and not settings.SEKTION in m.town]) staff = len(jls) total = b27_local + b27_non_local + len(jls) relevant_b27 = min(b27_local + b27_non_local, math.floor(3/2 * b27_local)) @@ -1387,7 +1391,7 @@ class Freizeit(CommonModel): suffix = str(i + 1) base['Vor- und Nachname' + suffix] = m.name base['Anschrift' + suffix] = m.address - base['Alter' + suffix] = str(m.age()) + base['Alter' + suffix] = str(m.age_at(self.date)) base['Status' + str(i+1)] = '2' if m in jls else 'Auswahl1' if settings.SEKTION in m.address else 'Auswahl2' return base From 11b92f72b1d183efe6cbf28b53c2c9f979fab923 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Mon, 31 Mar 2025 01:53:04 +0200 Subject: [PATCH 2/2] fix(members/tests): set date correctly --- jdav_web/members/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdav_web/members/tests.py b/jdav_web/members/tests.py index e11e291..3e90a67 100644 --- a/jdav_web/members/tests.py +++ b/jdav_web/members/tests.py @@ -634,7 +634,8 @@ class FreizeitTestCase(BasicMemberTestCase): self.ex = Freizeit.objects.create(name='Wild trip', kilometers_traveled=120, tour_type=GEMEINSCHAFTS_TOUR, tour_approach=MUSKELKRAFT_ANREISE, - difficulty=1) + difficulty=1, + date=timezone.localtime()) def _setup_test_sjr_application_numbers(self, n_yl, n_b27_local, n_b27_non_local): for i in range(n_yl):