feat: add group checklist

pull/154/head
mariusrklein 8 months ago
parent 11b92f72b1
commit 546f2a2dd4

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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"

@ -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):

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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"

@ -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}

@ -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

@ -7,6 +7,7 @@
<form method="post" action="{% url 'admin:members_group_action' %}">
{% csrf_token %}
<input type="submit" name="group_overview" value="{% trans 'Generate group overview' %}">
<input type="submit" name="group_checklist" value="{% trans 'Generate group checklist' %}">
</form>
</li>
{{block.super}}

Loading…
Cancel
Save