From 546f2a2dd44d8cfe43f077c148e9daa30b494ea4 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Tue, 15 Apr 2025 23:08:00 +0200 Subject: [PATCH 01/18] feat: add group checklist --- jdav_web/locale/de/LC_MESSAGES/django.po | 6 +- jdav_web/members/admin.py | 28 ++++++ .../members/locale/de/LC_MESSAGES/django.po | 7 +- .../templates/members/group_checklist.tex | 92 +++++++++++++++++++ jdav_web/members/templatetags/tex_extras.py | 16 ++++ .../admin/members/group/change_list.html | 1 + 6 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 jdav_web/members/templates/members/group_checklist.tex diff --git a/jdav_web/locale/de/LC_MESSAGES/django.po b/jdav_web/locale/de/LC_MESSAGES/django.po index cafea14..52f0120 100644 --- a/jdav_web/locale/de/LC_MESSAGES/django.po +++ b/jdav_web/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-02-01 14:54+0100\n" +"POT-Creation-Date: 2025-04-15 23:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -272,6 +272,10 @@ msgstr "Kostenübersicht" msgid "Generate group overview" msgstr "Gruppenübersicht erstellen" +#: templates/admin/members/group/change_list.html +msgid "Generate group checklist" +msgstr "Gruppencheckliste erstellen" + #: templates/admin/members/member/change_form_object_tools.html msgid "Invite as user" msgstr "Als Kompassbenutzer*in einladen" diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index 71ee88d..f06a4ea 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -30,6 +30,7 @@ from django.shortcuts import render from django.core.exceptions import PermissionDenied, ValidationError from .pdf import render_tex, fill_pdf_form, merge_pdfs, serve_pdf, render_docx from .excel import generate_group_overview, generate_ljp_vbk +from .models import WEEKDAYS from contrib.admin import CommonAdminInlineMixin, CommonAdminMixin @@ -828,6 +829,8 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): def action_view(self, request): if "group_overview" in request.POST: return self.group_overview(request) + elif "group_checklist" in request.POST: + return self.group_checklist(request) def group_overview(self, request): @@ -841,6 +844,31 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): response = serve_media(filename=filename, content_type='application/xlsx') return response + + def group_checklist(self, request): + + if not request.user.has_perm('members.view_group'): + messages.error(request, + _("You are not allowed to create a group checklist.")) + return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name))) + + ensure_media_dir() + n_weeks = 17 # TODO: als variable in settings.toml? + + context = { + 'groups': self.model.objects.all(), + 'settings': settings, + 'range': range(n_weeks), + 'extras': range(4), + 'dates': mondays_until_nth(n_weeks), + 'weekdays': [long for i, long in WEEKDAYS], + } + return render_tex(f"Gruppen-Checkliste", 'members/group_checklist.tex', context) + +def mondays_until_nth(n): + today = datetime.today() + next_monday = today + timedelta(days=(7 - today.weekday()) % 7 or 7) + return [(next_monday + timedelta(weeks=i)).date() for i in range(n + 1)] class ActivityCategoryAdmin(admin.ModelAdmin): diff --git a/jdav_web/members/locale/de/LC_MESSAGES/django.po b/jdav_web/members/locale/de/LC_MESSAGES/django.po index 1187b87..45e52ea 100644 --- a/jdav_web/members/locale/de/LC_MESSAGES/django.po +++ b/jdav_web/members/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-03-08 16:16+0100\n" +"POT-Creation-Date: 2025-04-15 23:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -266,6 +266,11 @@ msgid "You are not allowed to create a group overview." msgstr "" "Du hast nicht die notwendigen Rechte um eine Gruppenübersicht zu erstellen." +#: members/admin.py +msgid "You are not allowed to create a group checklist." +msgstr "" +"Du hast nicht die notwendigen Rechte um eine Gruppencheckliste zu erstellen." + #: members/admin.py msgid "Difficulty" msgstr "Schwierigkeit" diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex new file mode 100644 index 0000000..bf6c1e4 --- /dev/null +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -0,0 +1,92 @@ +{% load static common tex_extras %} + +\documentclass[a4paper]{article} + +\usepackage[utf8]{inputenc} +% remove all undefined unicode characters instead of throwing an error +\makeatletter +\def\UTFviii@undefined@err#1{} +\makeatother +\usepackage{booktabs} +\usepackage{amssymb} +\usepackage{cmbright} +\usepackage{graphicx} +\usepackage{textpos} +\usepackage[colorlinks, breaklinks]{hyperref} +\usepackage{float} +\usepackage[margin=1cm]{geometry} +\usepackage{array} +\usepackage{tabularx} +\usepackage{rotating} + + +\newcommand{\picpos}[4]{ + \begin{textblock*}{#1}(#2, #3) + \includegraphics[width=\textwidth]{#4} + \end{textblock*} +} + +% custom url command for properly formatting emails +\DeclareUrlCommand\Email{\urlstyle{same}} +% allow linebreak after every character +\expandafter\def\expandafter\UrlBreaks\expandafter{\UrlBreaks +\do\/\do\a\do\b\do\c\do\d\do\e\do\f\do\g\do\h\do\i\do\j\do\k +\do\l\do\m\do\n\do\o\do\p\do\q\do\r\do\s\do\t\do\u\do\v +\do\w\do\x\do\y\do\z +\do\A\do\B\do\C\do\D\do\E\do\F\do\G\do\H\do\I\do\J\do\K +\do\L\do\M\do\N\do\O\do\P\do\Q\do\R\do\S\do\T\do\U\do\V +\do\W\do\X\do\Y\do\Z} + +\renewcommand{\arraystretch}{1.5} + +\newcolumntype{L}{>{\hspace{0pt}\raggedright\arraybackslash}X} +\newcolumntype{S}{>{\raggedright\arraybackslash\hsize=0.7\hsize}X} + +\newcommand{\tickedbox}{ + \makebox[0pt][l]{$\square$}\raisebox{.15ex}{\hspace{0.1em}$\checkmark$} +} +\newcommand{\checkbox}{ + \makebox[0pt][l]{$\square$} +} +\begin{document} +% HEADER RIGHT +{% settings_value 'DEFAULT_STATIC_PATH' as static_root %} + +{% for group in groups %} +\picpos{2.5cm}{15.5cm}{0cm}{% +{{ static_root }}/general/img/dav_logo_sektion.png% +} +% HEADLINE + +{\noindent\Large{Anmeldeliste {{ group.name }} }}\\[1mm] +\noindent {{ weekdays|index:group.weekday|esc_all }}, {{ group.start_time }} - {{ group.end_time }} Uhr\\ +\vspace{12pt} + +\begin{tabularx}{0.94\textwidth}{lXl|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} + \toprule + \textbf{\#} & \textbf{Name} & \textbf{JL} {% for i in range %} + & \begin{sideways} {{ dates|index:i|add:group.weekday|date_vs }} \end{sideways} + {% endfor %} \\ + + {% for m in group.member_set.all %} + \midrule + {{ forloop.counter }} & + {{ m.name|esc_all }} & + {% if m in group.leiters.all %} x {% endif %} + {% for i in range %} & {% endfor %}\\ + {% endfor %} + + {% for m in extras %} + \midrule + & + & + {% for i in range %} & {% endfor %}\\ + {% endfor %} + + \bottomrule +\end{tabularx} + +\clearpage +{% endfor %} + +\end{document} diff --git a/jdav_web/members/templatetags/tex_extras.py b/jdav_web/members/templatetags/tex_extras.py index 02169e7..8f3e9f6 100644 --- a/jdav_web/members/templatetags/tex_extras.py +++ b/jdav_web/members/templatetags/tex_extras.py @@ -1,5 +1,6 @@ from django import template from django.utils.safestring import mark_safe +from datetime import timedelta register = template.Library() @@ -14,6 +15,12 @@ def checked_if_true(name, value): def esc_all(val): return mark_safe(str(val).replace('_', '\\_').replace('&', '\\&').replace('%', '\\%')) +@register.filter +def index(sequence, position): + try: + return sequence[position] + except (IndexError, TypeError): + return '' @register.filter def datetime_short(date): @@ -24,7 +31,16 @@ def datetime_short(date): def date_short(date): return date.strftime('%d.%m.%y') +@register.filter +def date_vs(date): + return date.strftime('%d.%m.') @register.filter def time_short(date): return date.strftime('%H:%M') + +@register.filter +def add(date, days): + if days: + return date + timedelta(days=days) + return date diff --git a/jdav_web/templates/admin/members/group/change_list.html b/jdav_web/templates/admin/members/group/change_list.html index e688e94..081adcd 100644 --- a/jdav_web/templates/admin/members/group/change_list.html +++ b/jdav_web/templates/admin/members/group/change_list.html @@ -7,6 +7,7 @@
{% csrf_token %} +
{{block.super}} -- 2.38.4 From 649e35e26cc9bd9aff1bee4b1a0dec9b026c3b64 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Tue, 15 Apr 2025 23:25:15 +0200 Subject: [PATCH 02/18] fix: filter for published groups --- jdav_web/members/admin.py | 2 +- jdav_web/members/templates/members/group_checklist.tex | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index f06a4ea..295f9e2 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -856,7 +856,7 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): n_weeks = 17 # TODO: als variable in settings.toml? context = { - 'groups': self.model.objects.all(), + 'groups': self.model.objects.filter(show_website=True), 'settings': settings, 'range': range(n_weeks), 'extras': range(4), diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index bf6c1e4..ef11bdf 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -62,7 +62,7 @@ \noindent {{ weekdays|index:group.weekday|esc_all }}, {{ group.start_time }} - {{ group.end_time }} Uhr\\ \vspace{12pt} -\begin{tabularx}{0.94\textwidth}{lXl|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} +\begin{tabularx}{0.94\textwidth}{lX|c|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} \toprule \textbf{\#} & \textbf{Name} & \textbf{JL} {% for i in range %} & \begin{sideways} {{ dates|index:i|add:group.weekday|date_vs }} \end{sideways} @@ -72,7 +72,7 @@ \midrule {{ forloop.counter }} & {{ m.name|esc_all }} & - {% if m in group.leiters.all %} x {% endif %} + {% if m in group.leiters.all %} X {% endif %} {% for i in range %} & {% endfor %}\\ {% endfor %} -- 2.38.4 From f1398584cdf21ed541e4e51c72de0b8b4e64bd1e Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Tue, 15 Apr 2025 23:33:09 +0200 Subject: [PATCH 03/18] fix: sort members --- jdav_web/members/models.py | 5 +++++ jdav_web/members/templates/members/group_checklist.tex | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index d18b06f..85a910e 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -104,6 +104,11 @@ class Group(models.Model): class Meta: verbose_name = _('group') verbose_name_plural = _('groups') + + @property + def sorted_members(self): + """Returns the members of this group sorted by their last name.""" + return self.member_set.all().order_by('lastname') def has_time_info(self): # return if the group has all relevant time slot information filled diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index ef11bdf..696c067 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -68,7 +68,7 @@ & \begin{sideways} {{ dates|index:i|add:group.weekday|date_vs }} \end{sideways} {% endfor %} \\ - {% for m in group.member_set.all %} + {% for m in group.sorted_members %} \midrule {{ forloop.counter }} & {{ m.name|esc_all }} & -- 2.38.4 From eb0769b121d41a0a1f64fa40756e2f0135c18792 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Tue, 15 Apr 2025 23:37:56 +0200 Subject: [PATCH 04/18] fix page number --- jdav_web/members/templates/members/group_checklist.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index 696c067..c8978d4 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -14,7 +14,7 @@ \usepackage{textpos} \usepackage[colorlinks, breaklinks]{hyperref} \usepackage{float} -\usepackage[margin=1cm]{geometry} +\usepackage[margin=1cm, bottom=1.5cm]{geometry} \usepackage{array} \usepackage{tabularx} \usepackage{rotating} -- 2.38.4 From e16765e7af8318a7edd258d66eea19d6a005c069 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Wed, 23 Apr 2025 20:11:12 +0200 Subject: [PATCH 05/18] fixed margins, table layout --- .../templates/members/group_checklist.tex | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index c8978d4..59ce12b 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -53,38 +53,41 @@ {% settings_value 'DEFAULT_STATIC_PATH' as static_root %} {% for group in groups %} -\picpos{2.5cm}{15.5cm}{0cm}{% +\picpos{2.5cm}{16cm}{-0.4cm}{% {{ static_root }}/general/img/dav_logo_sektion.png% } % HEADLINE {\noindent\Large{Anmeldeliste {{ group.name }} }}\\[1mm] \noindent {{ weekdays|index:group.weekday|esc_all }}, {{ group.start_time }} - {{ group.end_time }} Uhr\\ -\vspace{12pt} -\begin{tabularx}{0.94\textwidth}{lX|c|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} +\noindent Anwesende Jugendleitende und Teilnehmende werden mit einem Kreuz markiert und die ausgefüllte +Liste zum Anfang der Gruppenstunde an der Kasse abgegeben. Zum Ende wird sie wieder abgeholt. Abgelaufene +Punktekarten werden von Kasse mit einem Kreis markiert.\\ +\begin{table}[htbp] + \centering +\begin{tabularx}{\textwidth}{lX|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} \toprule - \textbf{\#} & \textbf{Name} & \textbf{JL} {% for i in range %} + \textbf{\#} & \textbf{Name} {% for i in range %} & \begin{sideways} {{ dates|index:i|add:group.weekday|date_vs }} \end{sideways} {% endfor %} \\ {% for m in group.sorted_members %} \midrule {{ forloop.counter }} & - {{ m.name|esc_all }} & - {% if m in group.leiters.all %} X {% endif %} + {% if m in group.leiters.all %} \textbf{ {{ m.name|esc_all }} (JL) } {% else %} {{ m.name|esc_all }} {% endif %} {% for i in range %} & {% endfor %}\\ {% endfor %} {% for m in extras %} \midrule - & & {% for i in range %} & {% endfor %}\\ {% endfor %} \bottomrule \end{tabularx} +\end{table} \clearpage {% endfor %} -- 2.38.4 From 83ffd838304c672299df3a587991599d8ce09bb8 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sun, 27 Apr 2025 12:58:53 +0200 Subject: [PATCH 06/18] changed layout to always 25 rows --- jdav_web/members/admin.py | 2 +- .../templates/members/group_checklist.tex | 28 ++++++++++--------- jdav_web/members/templatetags/tex_extras.py | 6 ++++ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index 295f9e2..8f18f49 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -859,7 +859,7 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): 'groups': self.model.objects.filter(show_website=True), 'settings': settings, 'range': range(n_weeks), - 'extras': range(4), + 'n_members': range(25), 'dates': mondays_until_nth(n_weeks), 'weekdays': [long for i, long in WEEKDAYS], } diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index 59ce12b..e736077 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -48,6 +48,11 @@ \newcommand{\checkbox}{ \makebox[0pt][l]{$\square$} } + +\newenvironment{compacttext} + {\ignorespaces} + {\ignorespacesafterend} + \begin{document} % HEADER RIGHT {% settings_value 'DEFAULT_STATIC_PATH' as static_root %} @@ -61,10 +66,11 @@ {\noindent\Large{Anmeldeliste {{ group.name }} }}\\[1mm] \noindent {{ weekdays|index:group.weekday|esc_all }}, {{ group.start_time }} - {{ group.end_time }} Uhr\\ -\noindent Anwesende Jugendleitende und Teilnehmende werden mit einem Kreuz markiert und die ausgefüllte +\noindent Anwesende Jugendleitende und Teilnehmende werden mit einem Kreuz ($\times$) markiert und die ausgefüllte Liste zum Anfang der Gruppenstunde an der Kasse abgegeben. Zum Ende wird sie wieder abgeholt. Abgelaufene -Punktekarten werden von Kasse mit einem Kreis markiert.\\ -\begin{table}[htbp] +Punktekarten werden von Kasse mit einem Kreis ($\otimes$) markiert.\\ + +\begin{table}[H] \centering \begin{tabularx}{\textwidth}{lX|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} \toprule @@ -72,17 +78,13 @@ Punktekarten werden von Kasse mit einem Kreis markiert.\\ & \begin{sideways} {{ dates|index:i|add:group.weekday|date_vs }} \end{sideways} {% endfor %} \\ - {% for m in group.sorted_members %} - \midrule - {{ forloop.counter }} & - {% if m in group.leiters.all %} \textbf{ {{ m.name|esc_all }} (JL) } {% else %} {{ m.name|esc_all }} {% endif %} - {% for i in range %} & {% endfor %}\\ - {% endfor %} - - {% for m in extras %} + {% for j in n_members %} + {% with m=group.sorted_members|index:j %} \midrule - & - {% for i in range %} & {% endfor %}\\ + {{ j|plus:1 }} & \begin{compacttext} + {% if m in group.leiters.all %}{{ m.name|esc_all }} \textbf{(JL)} {% else %} {{ m.name|esc_all }} {% endif %} + \end{compacttext} {% for i in range %} & {% endfor %}\\ + {% endwith %} {% endfor %} \bottomrule diff --git a/jdav_web/members/templatetags/tex_extras.py b/jdav_web/members/templatetags/tex_extras.py index 8f3e9f6..cdc03a3 100644 --- a/jdav_web/members/templatetags/tex_extras.py +++ b/jdav_web/members/templatetags/tex_extras.py @@ -44,3 +44,9 @@ def add(date, days): if days: return date + timedelta(days=days) return date + +@register.filter +def plus(num1, num2): + if num2: + return num1 + num2 + return num1 -- 2.38.4 From 6388ccd15b46c54792de8a8b1142831cd0b14605 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sun, 27 Apr 2025 12:59:09 +0200 Subject: [PATCH 07/18] added badge no barcodes --- jdav_web/members/admin.py | 2 +- jdav_web/members/models.py | 6 ++++++ jdav_web/members/templates/members/group_checklist.tex | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index 8f18f49..7aa2aed 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -853,7 +853,7 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name))) ensure_media_dir() - n_weeks = 17 # TODO: als variable in settings.toml? + n_weeks = 12 # TODO: als variable in settings.toml? context = { 'groups': self.model.objects.filter(show_website=True), diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index 85a910e..5441693 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -361,6 +361,12 @@ class Member(Person): def place(self): """Returning the whole place (plz + town)""" return "{0} {1}".format(self.plz, self.town) + + @property + def dav_badge_no_tag(self): + """Returning the badge number stripped of strings and spaces""" + + return "{" + ''.join(re.findall(r'\d', self.dav_badge_no)) + "}" @property def iban_valid(self): diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index e736077..8275b35 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -18,6 +18,7 @@ \usepackage{array} \usepackage{tabularx} \usepackage{rotating} +\usepackage[code=Code39,X=.24mm,ratio=2.25,H=0.4cm]{makebarcode} \newcommand{\picpos}[4]{ @@ -82,7 +83,7 @@ Punktekarten werden von Kasse mit einem Kreis ($\otimes$) markiert.\\ {% with m=group.sorted_members|index:j %} \midrule {{ j|plus:1 }} & \begin{compacttext} - {% if m in group.leiters.all %}{{ m.name|esc_all }} \textbf{(JL)} {% else %} {{ m.name|esc_all }} {% endif %} + {% if m in group.leiters.all %}{{ m.name|esc_all }} \textbf{(JL)} {% else %} {{ m.name|esc_all }} {% endif %} {% if m.dav_badge_no_tag|length > 2 %}\barcode{{ m.dav_badge_no_tag }}{% endif %} \end{compacttext} {% for i in range %} & {% endfor %}\\ {% endwith %} {% endfor %} -- 2.38.4 From c3c207f64d98f45d70d1e1a35b2e72b4676492c3 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sat, 3 May 2025 14:19:54 +0200 Subject: [PATCH 08/18] test --- jdav_web/members/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index 5441693..fdaa7e2 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -366,7 +366,7 @@ class Member(Person): def dav_badge_no_tag(self): """Returning the badge number stripped of strings and spaces""" - return "{" + ''.join(re.findall(r'\d', self.dav_badge_no)) + "}" + return "{" + ''.join(re.findall(r'\d', self.dav_badge_no))[-6:] + "}" @property def iban_valid(self): -- 2.38.4 From 370b212597c44f38ebd67aadd1d6f21d82f2595d Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sat, 3 May 2025 15:22:59 +0200 Subject: [PATCH 09/18] reformat barcode --- jdav_web/members/admin.py | 4 +- .../templates/members/group_checklist.tex | 99 +++++-------------- 2 files changed, 29 insertions(+), 74 deletions(-) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index d94c7bf..9ccabcd 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -878,13 +878,13 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name))) ensure_media_dir() - n_weeks = 12 # TODO: als variable in settings.toml? + n_weeks = 15 context = { 'groups': self.model.objects.filter(show_website=True), 'settings': settings, 'range': range(n_weeks), - 'n_members': range(25), + 'n_members': range(24), 'dates': mondays_until_nth(n_weeks), 'weekdays': [long for i, long in WEEKDAYS], } diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index 8275b35..0415439 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -1,61 +1,16 @@ +{% extends "members/tex_base.tex" %} {% load static common tex_extras %} -\documentclass[a4paper]{article} +{% block headline %}{% endblock %} +{% block contact %}{% endblock %} -\usepackage[utf8]{inputenc} -% remove all undefined unicode characters instead of throwing an error -\makeatletter -\def\UTFviii@undefined@err#1{} -\makeatother -\usepackage{booktabs} -\usepackage{amssymb} -\usepackage{cmbright} -\usepackage{graphicx} -\usepackage{textpos} -\usepackage[colorlinks, breaklinks]{hyperref} -\usepackage{float} -\usepackage[margin=1cm, bottom=1.5cm]{geometry} -\usepackage{array} -\usepackage{tabularx} +{% block extra-preamble %} \usepackage{rotating} \usepackage[code=Code39,X=.24mm,ratio=2.25,H=0.4cm]{makebarcode} +\geometry{reset,margin=1cm, bottom=1.5cm} +{% endblock %} - -\newcommand{\picpos}[4]{ - \begin{textblock*}{#1}(#2, #3) - \includegraphics[width=\textwidth]{#4} - \end{textblock*} -} - -% custom url command for properly formatting emails -\DeclareUrlCommand\Email{\urlstyle{same}} -% allow linebreak after every character -\expandafter\def\expandafter\UrlBreaks\expandafter{\UrlBreaks -\do\/\do\a\do\b\do\c\do\d\do\e\do\f\do\g\do\h\do\i\do\j\do\k -\do\l\do\m\do\n\do\o\do\p\do\q\do\r\do\s\do\t\do\u\do\v -\do\w\do\x\do\y\do\z -\do\A\do\B\do\C\do\D\do\E\do\F\do\G\do\H\do\I\do\J\do\K -\do\L\do\M\do\N\do\O\do\P\do\Q\do\R\do\S\do\T\do\U\do\V -\do\W\do\X\do\Y\do\Z} - -\renewcommand{\arraystretch}{1.5} - -\newcolumntype{L}{>{\hspace{0pt}\raggedright\arraybackslash}X} -\newcolumntype{S}{>{\raggedright\arraybackslash\hsize=0.7\hsize}X} - -\newcommand{\tickedbox}{ - \makebox[0pt][l]{$\square$}\raisebox{.15ex}{\hspace{0.1em}$\checkmark$} -} -\newcommand{\checkbox}{ - \makebox[0pt][l]{$\square$} -} - -\newenvironment{compacttext} - {\ignorespaces} - {\ignorespacesafterend} - -\begin{document} -% HEADER RIGHT +{% block content %} {% settings_value 'DEFAULT_STATIC_PATH' as static_root %} {% for group in groups %} @@ -69,30 +24,30 @@ \noindent Anwesende Jugendleitende und Teilnehmende werden mit einem Kreuz ($\times$) markiert und die ausgefüllte Liste zum Anfang der Gruppenstunde an der Kasse abgegeben. Zum Ende wird sie wieder abgeholt. Abgelaufene -Punktekarten werden von Kasse mit einem Kreis ($\otimes$) markiert.\\ - +Punktekarten werden von der Kasse mit einem Kreis ($\otimes$) markiert. \begin{table}[H] - \centering -\begin{tabularx}{\textwidth}{lX|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} - \toprule - \textbf{\#} & \textbf{Name} {% for i in range %} - & \begin{sideways} {{ dates|index:i|add:group.weekday|date_vs }} \end{sideways} - {% endfor %} \\ - - {% for j in n_members %} - {% with m=group.sorted_members|index:j %} - \midrule - {{ j|plus:1 }} & \begin{compacttext} - {% if m in group.leiters.all %}{{ m.name|esc_all }} \textbf{(JL)} {% else %} {{ m.name|esc_all }} {% endif %} {% if m.dav_badge_no_tag|length > 2 %}\barcode{{ m.dav_badge_no_tag }}{% endif %} - \end{compacttext} {% for i in range %} & {% endfor %}\\ - {% endwith %} - {% endfor %} - - \bottomrule + \centering +%\begin{tabularx}{\textwidth}{lXX|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} +\begin{tabularx}{\textwidth}{lXl{% for i in range %}|l{% endfor%}} +\toprule + \textbf{\#} & \textbf{Name} & {% for i in range %} + & \begin{sideways} {{ dates|index:i|add:group.weekday|date_vs }} \end{sideways} +{% endfor %} \\ + + {% for j in n_members %} + {% with m=group.sorted_members|index:j %} + \midrule + {{ j|plus:1 }} & + {% if m in group.leiters.all %}{{ m.name|esc_all }} \textbf{(JL)} {% else %} {{ m.name|esc_all }} {% endif %} & {% if m.dav_badge_no_tag|length > 2 %}\barcode{{ m.dav_badge_no_tag }}{% endif %} + {% for i in range %} & {% endfor %}\\ + {% endwith %} + {% endfor %} + + \bottomrule \end{tabularx} \end{table} \clearpage {% endfor %} -\end{document} +{% endblock content %} -- 2.38.4 From 8192297c510b78a0b5bbbb232db5833ca05c2210 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sun, 22 Jun 2025 13:39:32 +0200 Subject: [PATCH 10/18] feat (members): add entry ticket field in members model --- jdav_web/members/admin.py | 2 +- .../members/locale/de/LC_MESSAGES/django.po | 12 ++++++++---- .../migrations/0041_member_ticket_no.py | 18 ++++++++++++++++++ jdav_web/members/models.py | 1 + 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 jdav_web/members/migrations/0041_member_ticket_no.py diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index 9ccabcd..3bcde34 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -196,7 +196,7 @@ class MemberAdmin(CommonAdminMixin, admin.ModelAdmin): ('join_date', 'leave_date'), 'comments', 'legal_guardians', - 'dav_badge_no', + ('dav_badge_no', 'ticket_no'), 'active', 'echoed', 'user', ] diff --git a/jdav_web/members/locale/de/LC_MESSAGES/django.po b/jdav_web/members/locale/de/LC_MESSAGES/django.po index 011eb30..3054b89 100644 --- a/jdav_web/members/locale/de/LC_MESSAGES/django.po +++ b/jdav_web/members/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-27 23:00+0200\n" +"POT-Creation-Date: 2025-06-22 13:36+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -675,6 +675,10 @@ msgstr "Hat Freikarte für Kletterhalle" msgid "DAV badge number" msgstr "DAV Mitgliedsnummer" +#: members/models.py +msgid "entrance ticket number" +msgstr "Eintrittskarten Nummer" + #: members/models.py msgid "Knows how to swim" msgstr "Kann schwimmen" @@ -1397,9 +1401,9 @@ msgid "" "%(total_org_fee_theoretical)s € is charged against the other transactions." msgstr "" "Achtung: %(old_participant_count)s Teilnehmende der Ausfahrt sind 27 oder " -"älter. Für diese Teilnehmende(n) ist ein Org-Beitrag von %(org_fee)s € pro Tag " -"fällig. Durch die Länge der Ausfahrt von %(duration)s Tagen werden insgesamt " -"%(total_org_fee_theoretical)s € mit den Zuschüssen und " +"älter. Für diese Teilnehmende(n) ist ein Org-Beitrag von %(org_fee)s € pro " +"Tag fällig. Durch die Länge der Ausfahrt von %(duration)s Tagen werden " +"insgesamt %(total_org_fee_theoretical)s € mit den Zuschüssen und " "Aufwandsentschädigungen verrechnet, sofern diese in Anspruch genommen werden." #: members/templates/admin/freizeit_finance_overview.html diff --git a/jdav_web/members/migrations/0041_member_ticket_no.py b/jdav_web/members/migrations/0041_member_ticket_no.py new file mode 100644 index 0000000..07b60b3 --- /dev/null +++ b/jdav_web/members/migrations/0041_member_ticket_no.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.20 on 2025-06-22 11:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('members', '0040_invitationtogroup_created_by'), + ] + + operations = [ + migrations.AddField( + model_name='member', + name='ticket_no', + field=models.CharField(blank=True, default='', max_length=20, verbose_name='entrance ticket number'), + ), + ] diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index 9a46501..666df7b 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -309,6 +309,7 @@ class Member(Person): has_key = models.BooleanField(_('Has key'), default=False) has_free_ticket_gym = models.BooleanField(_('Has a free ticket for the climbing gym'), default=False) dav_badge_no = models.CharField(max_length=20, verbose_name=_('DAV badge number'), default='', blank=True) + ticket_no = models.CharField(max_length=20, verbose_name=_('entrance ticket number'), default='', blank=True) swimming_badge = models.BooleanField(verbose_name=_('Knows how to swim'), default=False) climbing_badge = models.CharField(max_length=100, verbose_name=_('Climbing badge'), default='', blank=True) alpine_experience = models.TextField(verbose_name=_('Alpine experience'), default='', blank=True) -- 2.38.4 From ef7dac6d75b359ca71638f6d002338a805ee9c24 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sun, 22 Jun 2025 15:08:41 +0200 Subject: [PATCH 11/18] feat (members): change list layout to accomodate large ticket_no barcodes --- jdav_web/members/admin.py | 7 ++--- jdav_web/members/models.py | 6 ++--- .../templates/members/group_checklist.tex | 26 ++++++++++++------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index 3bcde34..ed9d070 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -878,13 +878,14 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name))) ensure_media_dir() - n_weeks = 15 + n_weeks = 18 + n_members = 20 context = { 'groups': self.model.objects.filter(show_website=True), 'settings': settings, - 'range': range(n_weeks), - 'n_members': range(24), + 'week_range': range(n_weeks), + 'member_range': range(n_members), 'dates': mondays_until_nth(n_weeks), 'weekdays': [long for i, long in WEEKDAYS], } diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index 666df7b..d697b04 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -373,10 +373,10 @@ class Member(Person): return "{0} {1}".format(self.plz, self.town) @property - def dav_badge_no_tag(self): - """Returning the badge number stripped of strings and spaces""" + def ticket_tag(self): + """Returning the ticket number stripped of strings and spaces""" - return "{" + ''.join(re.findall(r'\d', self.dav_badge_no))[-6:] + "}" + return "{" + ''.join(re.findall(r'\d', self.ticket_no)) + "}" @property def iban_valid(self): diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index 0415439..ed9a9fb 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -6,8 +6,9 @@ {% block extra-preamble %} \usepackage{rotating} -\usepackage[code=Code39,X=.24mm,ratio=2.25,H=0.4cm]{makebarcode} +\usepackage[code=Code39,X=.48mm,ratio=3.5,H=0.5cm]{makebarcode} \geometry{reset,margin=1cm, bottom=1.5cm} +\renewcommand{\arraystretch}{1} {% endblock %} {% block content %} @@ -23,23 +24,28 @@ \noindent {{ weekdays|index:group.weekday|esc_all }}, {{ group.start_time }} - {{ group.end_time }} Uhr\\ \noindent Anwesende Jugendleitende und Teilnehmende werden mit einem Kreuz ($\times$) markiert und die ausgefüllte -Liste zum Anfang der Gruppenstunde an der Kasse abgegeben. Zum Ende wird sie wieder abgeholt. Abgelaufene -Punktekarten werden von der Kasse mit einem Kreis ($\otimes$) markiert. +Liste zum Anfang der Gruppenstunde an der Kasse abgegeben. Zum Ende wird sie wieder abgeholt. Wenn die Punkte auf einer Karte fast aufgebraucht sind, notiert die Kasse die verbliebenen Eintritte (3, 2, 1) unter dem Kreuz. \begin{table}[H] \centering -%\begin{tabularx}{\textwidth}{lXX|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} -\begin{tabularx}{\textwidth}{lXl{% for i in range %}|l{% endfor%}} +%\begin{tabularx}{\textwidth}{lYY|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} +\begin{tabularx}{\textwidth}{X{% for i in week_range %}|l{% endfor%}} \toprule - \textbf{\#} & \textbf{Name} & {% for i in range %} + \textbf{Name} {% for i in week_range %} & \begin{sideways} {{ dates|index:i|add:group.weekday|date_vs }} \end{sideways} {% endfor %} \\ - {% for j in n_members %} + {% for j in member_range %} {% with m=group.sorted_members|index:j %} \midrule - {{ j|plus:1 }} & - {% if m in group.leiters.all %}{{ m.name|esc_all }} \textbf{(JL)} {% else %} {{ m.name|esc_all }} {% endif %} & {% if m.dav_badge_no_tag|length > 2 %}\barcode{{ m.dav_badge_no_tag }}{% endif %} - {% for i in range %} & {% endfor %}\\ + \begin{tabular}{@{}l} + {% if m.ticket_tag|length > 2 %}\barcode{{ m.ticket_tag }}{% else %}\rule{0pt}{5mm}{% endif %} + \vspace{-0.8ex} \\ + {\small {{ j|plus:1 }} {% if m in group.leiters.all %}\textbf{JL}{% endif %} + {{ m.name|esc_all }} {% if m.ticket_tag|length > 2 %} - {{ m.ticket_tag }}{% endif %} + \vspace{-3ex} } + \end{tabular} + + {% for i in week_range %} & {% endfor %}\\ {% endwith %} {% endfor %} -- 2.38.4 From 01b52feafecf6150f639f13b2163ad5daefa66a7 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sun, 22 Jun 2025 15:23:58 +0200 Subject: [PATCH 12/18] feat: abstracted parameters for group checklist into settings.toml --- jdav_web/jdav_web/settings/local.py | 8 ++++++++ jdav_web/members/admin.py | 5 +++-- jdav_web/members/templates/members/group_checklist.tex | 5 ++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/jdav_web/jdav_web/settings/local.py b/jdav_web/jdav_web/settings/local.py index 34dbe5c..a0753c2 100644 --- a/jdav_web/jdav_web/settings/local.py +++ b/jdav_web/jdav_web/settings/local.py @@ -50,6 +50,14 @@ SEND_FROM_ASSOCIATION_EMAIL = get_var('misc', 'send_from_association_email', def # domain for association email and generated urls DOMAIN = get_var('misc', 'domain', default='example.org') +GROUP_CHECKLIST_N_WEEKS = get_var('misc', 'group_checklist_n_weeks', default=18) +GROUP_CHECKLIST_N_MEMBERS = get_var('misc', 'group_checklist_n_members', default=20) +GROUP_CHECKLIST_TEXT = get_var('misc', 'group_checklist_text', + default="""Anwesende Jugendleitende und Teilnehmende werden mit einem +Kreuz ($\times$) markiert und die ausgefüllte Liste zum Anfang der Gruppenstunde an der Kasse +abgegeben. Zum Ende wird sie wieder abgeholt. Wenn die Punkte auf einer Karte fast aufgebraucht +sind, notiert die Kasse die verbliebenen Eintritte (3, 2, 1) unter dem Kreuz.""") + # finance ALLOWANCE_PER_DAY = get_var('finance', 'allowance_per_day', default=22) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index ed9d070..3733a78 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -878,8 +878,8 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name))) ensure_media_dir() - n_weeks = 18 - n_members = 20 + n_weeks = settings.GROUP_CHECKLIST_N_WEEKS + n_members = settings.GROUP_CHECKLIST_N_MEMBERS context = { 'groups': self.model.objects.filter(show_website=True), @@ -888,6 +888,7 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): 'member_range': range(n_members), 'dates': mondays_until_nth(n_weeks), 'weekdays': [long for i, long in WEEKDAYS], + 'header_text': settings.GROUP_CHECKLIST_TEXT, } return render_tex(f"Gruppen-Checkliste", 'members/group_checklist.tex', context) diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index ed9a9fb..fe50ae1 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -20,11 +20,10 @@ } % HEADLINE -{\noindent\Large{Anmeldeliste {{ group.name }} }}\\[1mm] +{\noindent\Large{Gruppenliste {{ group.name }} }}\\[1mm] \noindent {{ weekdays|index:group.weekday|esc_all }}, {{ group.start_time }} - {{ group.end_time }} Uhr\\ -\noindent Anwesende Jugendleitende und Teilnehmende werden mit einem Kreuz ($\times$) markiert und die ausgefüllte -Liste zum Anfang der Gruppenstunde an der Kasse abgegeben. Zum Ende wird sie wieder abgeholt. Wenn die Punkte auf einer Karte fast aufgebraucht sind, notiert die Kasse die verbliebenen Eintritte (3, 2, 1) unter dem Kreuz. +\noindent {{ header_text }} \begin{table}[H] \centering %\begin{tabularx}{\textwidth}{lYY|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l|l} -- 2.38.4 From b0fb7bcfce67cc7b39101b2314fdccc3e19e45e0 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sun, 22 Jun 2025 15:35:44 +0200 Subject: [PATCH 13/18] fix: escape backslash in default text --- jdav_web/jdav_web/settings/local.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdav_web/jdav_web/settings/local.py b/jdav_web/jdav_web/settings/local.py index a0753c2..a814484 100644 --- a/jdav_web/jdav_web/settings/local.py +++ b/jdav_web/jdav_web/settings/local.py @@ -54,7 +54,7 @@ GROUP_CHECKLIST_N_WEEKS = get_var('misc', 'group_checklist_n_weeks', default=18) GROUP_CHECKLIST_N_MEMBERS = get_var('misc', 'group_checklist_n_members', default=20) GROUP_CHECKLIST_TEXT = get_var('misc', 'group_checklist_text', default="""Anwesende Jugendleitende und Teilnehmende werden mit einem -Kreuz ($\times$) markiert und die ausgefüllte Liste zum Anfang der Gruppenstunde an der Kasse +Kreuz ($\\times$) markiert und die ausgefüllte Liste zum Anfang der Gruppenstunde an der Kasse abgegeben. Zum Ende wird sie wieder abgeholt. Wenn die Punkte auf einer Karte fast aufgebraucht sind, notiert die Kasse die verbliebenen Eintritte (3, 2, 1) unter dem Kreuz.""") -- 2.38.4 From eb2cd6c68cfca9eb3b5f5ac61e614725b6a09c31 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:57:06 +0200 Subject: [PATCH 14/18] fix(members): move util function, remove blank space --- jdav_web/members/admin.py | 5 ----- jdav_web/members/models.py | 1 - jdav_web/utils.py | 10 +++++++++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index 3733a78..f304c7b 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -892,11 +892,6 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin): } return render_tex(f"Gruppen-Checkliste", 'members/group_checklist.tex', context) -def mondays_until_nth(n): - today = datetime.today() - next_monday = today + timedelta(days=(7 - today.weekday()) % 7 or 7) - return [(next_monday + timedelta(weeks=i)).date() for i in range(n + 1)] - class ActivityCategoryAdmin(admin.ModelAdmin): fields = ['name', 'ljp_category', 'description'] diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index d697b04..a7e6d32 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -375,7 +375,6 @@ class Member(Person): @property def ticket_tag(self): """Returning the ticket number stripped of strings and spaces""" - return "{" + ''.join(re.findall(r'\d', self.ticket_no)) + "}" @property diff --git a/jdav_web/utils.py b/jdav_web/utils.py index 32db40b..f097aae 100644 --- a/jdav_web/utils.py +++ b/jdav_web/utils.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timedelta from django.db import models from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ @@ -80,3 +80,11 @@ def normalize_filename(filename, append_date=True, date=None): filename = filename.replace(' ', '_').replace('&', '').replace('/', '_') # drop umlauts, accents etc. return unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore').decode() + + +def mondays_until_nth(n): + """ Returns a list of dates for the next n Mondays, starting from the next Monday. + This functions aids in the generation of weekly schedules or reports.""" + today = datetime.today() + next_monday = today + timedelta(days=(7 - today.weekday()) % 7 or 7) + return [(next_monday + timedelta(weeks=i)).date() for i in range(n + 1)] -- 2.38.4 From 5978e6ab5b8432ba1dc94d28776ede600e97f885 Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Wed, 30 Jul 2025 08:53:10 +0200 Subject: [PATCH 15/18] fix(members): explain ticket_no field and move it+badge_no to others tab --- jdav_web/members/admin.py | 5 ++--- jdav_web/members/models.py | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index f304c7b..3072b49 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -196,7 +196,6 @@ class MemberAdmin(CommonAdminMixin, admin.ModelAdmin): ('join_date', 'leave_date'), 'comments', 'legal_guardians', - ('dav_badge_no', 'ticket_no'), 'active', 'echoed', 'user', ] @@ -214,8 +213,8 @@ class MemberAdmin(CommonAdminMixin, admin.ModelAdmin): ), (_("Others"), { - 'fields': ['allergies', 'tetanus_vaccination', 'medication', 'photos_may_be_taken', - 'may_cancel_appointment_independently'] + 'fields': ['dav_badge_no', 'ticket_no', 'allergies', 'tetanus_vaccination', + 'medication', 'photos_may_be_taken','may_cancel_appointment_independently'] } ), (_("Organizational"), diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index a7e6d32..f1a5ebf 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -309,6 +309,8 @@ class Member(Person): has_key = models.BooleanField(_('Has key'), default=False) has_free_ticket_gym = models.BooleanField(_('Has a free ticket for the climbing gym'), default=False) dav_badge_no = models.CharField(max_length=20, verbose_name=_('DAV badge number'), default='', blank=True) + + # use this to store a climbing gym customer or membership id, used to print on meeting checklists ticket_no = models.CharField(max_length=20, verbose_name=_('entrance ticket number'), default='', blank=True) swimming_badge = models.BooleanField(verbose_name=_('Knows how to swim'), default=False) climbing_badge = models.CharField(max_length=100, verbose_name=_('Climbing badge'), default='', blank=True) -- 2.38.4 From 7337cec025337651cc19faa66576ea8cfc69da5c Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Sun, 17 Aug 2025 18:42:00 +0200 Subject: [PATCH 16/18] fix migration --- .../{0041_member_ticket_no.py => 0042_member_ticket_no.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename jdav_web/members/migrations/{0041_member_ticket_no.py => 0042_member_ticket_no.py} (83%) diff --git a/jdav_web/members/migrations/0041_member_ticket_no.py b/jdav_web/members/migrations/0042_member_ticket_no.py similarity index 83% rename from jdav_web/members/migrations/0041_member_ticket_no.py rename to jdav_web/members/migrations/0042_member_ticket_no.py index 07b60b3..c1c28fb 100644 --- a/jdav_web/members/migrations/0041_member_ticket_no.py +++ b/jdav_web/members/migrations/0042_member_ticket_no.py @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('members', '0040_invitationtogroup_created_by'), + ('members', '0041_freizeit_crisis_intervention_list_sent_and_more'), ] operations = [ -- 2.38.4 From 1f4cb4125687e17ed0d1c59f9b8f46ca1b5c1d2a Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Sun, 17 Aug 2025 18:43:40 +0200 Subject: [PATCH 17/18] fix import --- jdav_web/members/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index 3072b49..5e2a3e7 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -45,7 +45,7 @@ from .models import (Member, Group, Freizeit, MemberNoteList, NewMemberOnList, K from finance.models import Statement, BillOnExcursionProxy from mailer.mailutils import send as send_mail, get_echo_link from django.conf import settings -from utils import get_member, RestrictedFileField +from utils import get_member, RestrictedFileField, mondays_until_nth from schwifty import IBAN from .pdf import media_path, media_dir -- 2.38.4 From eb3e45f016b22e9b363d746a8f48c1657ba14efb Mon Sep 17 00:00:00 2001 From: mariusrklein <47218379+mariusrklein@users.noreply.github.com> Date: Sat, 23 Aug 2025 15:17:26 +0200 Subject: [PATCH 18/18] fix missing time info and variable barcode length --- .../members/templates/members/group_checklist.tex | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/jdav_web/members/templates/members/group_checklist.tex b/jdav_web/members/templates/members/group_checklist.tex index fe50ae1..81ff72d 100644 --- a/jdav_web/members/templates/members/group_checklist.tex +++ b/jdav_web/members/templates/members/group_checklist.tex @@ -21,8 +21,7 @@ % HEADLINE {\noindent\Large{Gruppenliste {{ group.name }} }}\\[1mm] -\noindent {{ weekdays|index:group.weekday|esc_all }}, {{ group.start_time }} - {{ group.end_time }} Uhr\\ - +{% if group.has_time_info %} \noindent {{ weekdays|index:group.weekday|esc_all }}, {{ group.start_time }} - {{ group.end_time }} Uhr\\ {% endif %} \noindent {{ header_text }} \begin{table}[H] \centering @@ -35,17 +34,25 @@ {% for j in member_range %} {% with m=group.sorted_members|index:j %} + {% with codelength=m.ticket_tag|length %} \midrule \begin{tabular}{@{}l} - {% if m.ticket_tag|length > 2 %}\barcode{{ m.ticket_tag }}{% else %}\rule{0pt}{5mm}{% endif %} + {% if codelength > 2 %} + \barcode[ + X=\dimexpr 3.5mm / \numexpr {{ codelength }} \relax \relax + ]{{ m.ticket_tag }} + {% else %} + \rule{0pt}{5mm} + {% endif %} \vspace{-0.8ex} \\ {\small {{ j|plus:1 }} {% if m in group.leiters.all %}\textbf{JL}{% endif %} - {{ m.name|esc_all }} {% if m.ticket_tag|length > 2 %} - {{ m.ticket_tag }}{% endif %} + {{ m.name|esc_all }} {% if codelength > 2 %} - {{ m.ticket_tag }}{% endif %} \vspace{-3ex} } \end{tabular} {% for i in week_range %} & {% endfor %}\\ {% endwith %} + {% endwith %} {% endfor %} \bottomrule -- 2.38.4