members/pdf: add numbering to participant listings (#119)

Also add a total participants and youth leaders count on the members on list inline tab.

Reviewed-on: #119
Reviewed-by: Christian Merten <christian@merten.dev>
Co-authored-by: marius.klein <marius.klein@alpenverein-heidelberg.de>
Co-committed-by: marius.klein <marius.klein@alpenverein-heidelberg.de>
docu-new-group
marius.klein 11 months ago committed by Christian Merten
parent d1a8e7f159
commit 678559fb4d

@ -951,6 +951,31 @@ class MemberOnListInline(CommonAdminInlineMixin, GenericTabularInline):
TextField: {'widget': Textarea(attrs={'rows': 1, 'cols': 40})} TextField: {'widget': Textarea(attrs={'rows': 1, 'cols': 40})}
} }
sortable_options = [] sortable_options = []
template = "admin/members/freizeit/memberonlistinline.html"
def people_count(self, obj):
if isinstance(obj, Freizeit):
# Number of organizers who are also in the Memberlist
organizer_count = obj.staff_on_memberlist_count
# Total number of people in the Memberlist
total_people = obj.head_count
else: # fallback if no activity was found
total_people = 0
organizer_count = 0
return dict(total_people=total_people, organizer_count=organizer_count)
def get_formset(self, request, obj=None, **kwargs):
"""Override get_formset to add extra context."""
formset = super().get_formset(request, obj, **kwargs)
if obj: # Ensure there is an Activity instance
formset.total_people = self.people_count(obj)['total_people']
formset.organizer_count = self.people_count(obj)['organizer_count']
return formset
class MemberNoteListAdmin(admin.ModelAdmin): class MemberNoteListAdmin(admin.ModelAdmin):

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-25 11:56+0100\n" "POT-Creation-Date: 2025-02-01 19:24+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -30,7 +30,7 @@ msgstr "Ja"
msgid "False" msgid "False"
msgstr "Nein" msgstr "Nein"
#: members/admin.py #: members/admin.py members/tests.py
msgid "All" msgid "All"
msgstr "Alle" msgstr "Alle"
@ -82,18 +82,18 @@ msgstr "%(name)s hat keine DAV360 E-Mail Adresse oder ist bereits registriert."
msgid "Successfully invited %(name)s as user." msgid "Successfully invited %(name)s as user."
msgstr "Erfolgreich %(name)s aufgefordert Zugangsdaten zu wählen." msgstr "Erfolgreich %(name)s aufgefordert Zugangsdaten zu wählen."
#: members/admin.py #: members/admin.py members/tests.py
msgid "Successfully invited selected members to join as users." msgid "Successfully invited selected members to join as users."
msgstr "" msgstr ""
"Erfolgreich ausgewählte Teilnehmer*innen aufgefordert Zugangsdaten zu wählen." "Erfolgreich ausgewählte Teilnehmer*innen aufgefordert Zugangsdaten zu wählen."
#: members/admin.py #: members/admin.py members/tests.py
msgid "Some members have been invited, others could not be invited." msgid "Some members have been invited, others could not be invited."
msgstr "" msgstr ""
"Manche Teilnehmer*innen wurden eingeladen, andere konnten nicht eingeladen " "Manche Teilnehmer*innen wurden eingeladen, andere konnten nicht eingeladen "
"werden." "werden."
#: members/admin.py #: members/admin.py members/tests.py
msgid "Permission denied." msgid "Permission denied."
msgstr "Fehlende Berechtigungen." msgstr "Fehlende Berechtigungen."
@ -105,21 +105,21 @@ msgstr "Kompass Zugangsdaten wählen lassen"
msgid "Invite selected members to join Kompass as users." msgid "Invite selected members to join Kompass as users."
msgstr "Ausgewählte Teilnehmer*innen Kompass Zugangsdaten wählen lassen." msgstr "Ausgewählte Teilnehmer*innen Kompass Zugangsdaten wählen lassen."
#: members/admin.py #: members/admin.py members/tests.py
msgid "Member not found." msgid "Member not found."
msgstr "Teilnehmer*in nicht gefunden." msgstr "Teilnehmer*in nicht gefunden."
#: members/admin.py #: members/admin.py members/tests.py
#, python-format #, python-format
msgid "%(name)s already has login data." msgid "%(name)s already has login data."
msgstr "%(name)s hat schon Zugangsdaten." msgstr "%(name)s hat schon Zugangsdaten."
#: members/admin.py #: members/admin.py members/tests.py
#, python-format #, python-format
msgid "The configured email address for %(name)s is not an internal one." msgid "The configured email address for %(name)s is not an internal one."
msgstr "Die für %(name)s eingestellte E-Mail Adresse ist keine DAV360 Adresse." msgstr "Die für %(name)s eingestellte E-Mail Adresse ist keine DAV360 Adresse."
#: members/admin.py #: members/admin.py members/tests.py
#, python-format #, python-format
msgid "%(name)s already has a pending invitation as user." msgid "%(name)s already has a pending invitation as user."
msgstr "" msgstr ""
@ -133,7 +133,7 @@ msgstr "Aktivität"
msgid "Name" msgid "Name"
msgstr "Name" msgstr "Name"
#: members/admin.py #: members/admin.py members/tests.py
msgid "Successfully requested mail confirmation from selected registrations." msgid "Successfully requested mail confirmation from selected registrations."
msgstr "Aufforderung zur Bestätigung der Email Adresse versendet." msgstr "Aufforderung zur Bestätigung der Email Adresse versendet."
@ -151,11 +151,11 @@ msgstr "Registrierung von %(name)s erfolgreich bestätigt."
msgid "Can't confirm. %(name)s has unconfirmed email addresses." msgid "Can't confirm. %(name)s has unconfirmed email addresses."
msgstr "Bestätigung nicht möglich. %(name)s hat unbestätigte Emailadressen." msgstr "Bestätigung nicht möglich. %(name)s hat unbestätigte Emailadressen."
#: members/admin.py #: members/admin.py members/tests.py
msgid "Successfully confirmed multiple registrations." msgid "Successfully confirmed multiple registrations."
msgstr "Erfolgreich mehrere Registrierungen bestätigt." msgstr "Erfolgreich mehrere Registrierungen bestätigt."
#: members/admin.py #: members/admin.py members/tests.py
msgid "" msgid ""
"Failed to confirm some registrations because of unconfirmed email addresses." "Failed to confirm some registrations because of unconfirmed email addresses."
msgstr "" msgstr ""
@ -170,7 +170,7 @@ msgstr "Ausgewählte Registrierungen bestätigen"
msgid "Demote selected registrations to waiters." msgid "Demote selected registrations to waiters."
msgstr "Ausgewählte Registrierungen zurück auf die Warteliste setzen." msgstr "Ausgewählte Registrierungen zurück auf die Warteliste setzen."
#: members/admin.py #: members/admin.py members/tests.py
msgid "Demote member to waiter" msgid "Demote member to waiter"
msgstr "Ausgewählte Registrierung zurück auf die Warteliste setzen." msgstr "Ausgewählte Registrierung zurück auf die Warteliste setzen."
@ -364,11 +364,11 @@ msgstr "Hinweise für Jugendleiter erstellen"
msgid "Generate seminar report" msgid "Generate seminar report"
msgstr "Landesjugendplan Antrag erstellen" msgstr "Landesjugendplan Antrag erstellen"
#: members/admin.py #: members/admin.py members/tests.py
msgid "Please select a mode." msgid "Please select a mode."
msgstr "Bitte wähle einen Modus aus." msgstr "Bitte wähle einen Modus aus."
#: members/admin.py #: members/admin.py members/tests.py
msgid "" msgid ""
"Full mode is only available, if the seminar report section is filled out." "Full mode is only available, if the seminar report section is filled out."
msgstr "" msgstr ""
@ -379,11 +379,11 @@ msgstr ""
msgid "Generate SJR application" msgid "Generate SJR application"
msgstr "SJR Antrag erstellen" msgstr "SJR Antrag erstellen"
#: members/admin.py #: members/admin.py members/tests.py
msgid "Please select an invoice." msgid "Please select an invoice."
msgstr "Bitte wähle einen Beleg aus." msgstr "Bitte wähle einen Beleg aus."
#: members/admin.py #: members/admin.py members/tests.py
msgid "No statement found. Please add a statement and then retry." msgid "No statement found. Please add a statement and then retry."
msgstr "" msgstr ""
"Keine Abrechnung angelegt. Bitte lege eine Abrechnung and und versuche es " "Keine Abrechnung angelegt. Bitte lege eine Abrechnung and und versuche es "
@ -1210,7 +1210,7 @@ msgstr ""
msgid "Summary" msgid "Summary"
msgstr "Zusammenfassung" msgstr "Zusammenfassung"
#: members/templates/admin/freizeit_finance_overview.html #: members/templates/admin/freizeit_finance_overview.html members/tests.py
msgid "This is the estimated cost and contribution summary:" msgid "This is the estimated cost and contribution summary:"
msgstr "Das ist die geschätzte Kosten- und Zuschussübersicht." msgstr "Das ist die geschätzte Kosten- und Zuschussübersicht."
@ -1327,7 +1327,7 @@ msgstr ""
"Kosten an. In diesem Fall musst du Lernziele und einen Zeitplan manuell " "Kosten an. In diesem Fall musst du Lernziele und einen Zeitplan manuell "
"hinzufügen." "hinzufügen."
#: members/templates/admin/generate_seminar_report.html #: members/templates/admin/generate_seminar_report.html members/tests.py
msgid "You may also choose to include the V32 attachment." msgid "You may also choose to include the V32 attachment."
msgstr "" msgstr ""
"Ein LJP Antrag benötigt immer ein Formblatt (in unserem Fall V32-1 " "Ein LJP Antrag benötigt immer ein Formblatt (in unserem Fall V32-1 "
@ -1340,7 +1340,7 @@ msgstr ""
msgid "Generate" msgid "Generate"
msgstr "Erstellen" msgstr "Erstellen"
#: members/templates/admin/generate_sjr_application.html #: members/templates/admin/generate_sjr_application.html members/tests.py
msgid "Here you can generate an allowance application for the SJR." msgid "Here you can generate an allowance application for the SJR."
msgstr "Hier kannst du einen SJR-Zuschussantrag erstellen." msgstr "Hier kannst du einen SJR-Zuschussantrag erstellen."
@ -1373,7 +1373,7 @@ msgstr ""
#: members/templates/admin/invite_as_user.html #: members/templates/admin/invite_as_user.html
#: members/templates/admin/invite_for_group.html #: members/templates/admin/invite_for_group.html
#: members/templates/admin/invite_selected_as_user.html #: members/templates/admin/invite_selected_as_user.html
#: members/templates/admin/invite_selected_for_group.html #: members/templates/admin/invite_selected_for_group.html members/tests.py
msgid "Invite" msgid "Invite"
msgstr "Einladen" msgstr "Einladen"
@ -1476,6 +1476,14 @@ msgstr ""
msgid "date" msgid "date"
msgstr "Datum" msgstr "Datum"
#: members/templates/admin/members/freizeit/memberonlistinline.html
msgid "Number of persons:"
msgstr "Anzahl Personen:"
#: members/templates/admin/members/freizeit/memberonlistinline.html
msgid "thereof leaders:"
msgstr "davon Leitung:"
#: members/templates/members/change_member.html #: members/templates/members/change_member.html
msgid "Participations:" msgid "Participations:"
msgstr "Ausfahrtteilnahmen:" msgstr "Ausfahrtteilnahmen:"

@ -1140,12 +1140,26 @@ class Freizeit(CommonModel):
def staff_count(self): def staff_count(self):
return self.jugendleiter.count() return self.jugendleiter.count()
@property
def staff_on_memberlist(self):
ps = set(map(lambda x: x.member, self.membersonlist.distinct()))
jls = set(self.jugendleiter.distinct())
return ps.intersection(jls)
@property
def staff_on_memberlist_count(self):
return len(self.staff_on_memberlist)
@property @property
def participant_count(self): def participant_count(self):
ps = set(map(lambda x: x.member, self.membersonlist.distinct())) ps = set(map(lambda x: x.member, self.membersonlist.distinct()))
jls = set(self.jugendleiter.distinct()) jls = set(self.jugendleiter.distinct())
return len(ps - jls) return len(ps - jls)
@property
def head_count(self):
return self.staff_on_memberlist_count + self.participant_count
@property @property
def approved_staff_count(self): def approved_staff_count(self):
"""Number of approved youth leaders for this excursion. The base number is calculated """Number of approved youth leaders for this excursion. The base number is calculated

@ -0,0 +1,10 @@
{% extends "admin/edit_inline/tabular.html" %}
{% load i18n admin_urls static %}
{% block extra_footer_content %}
<tfoot><tr class="inline-summary">
<td colspan="99" style="text-align: right; font-weight: bold;">
{% trans "Number of persons:" %} {{ inline_admin_formset.formset.total_people }}, {% trans "thereof leaders:" %} {{ inline_admin_formset.formset.organizer_count }}
</td>
</tr>
</tfoot>
{% endblock %}

@ -79,11 +79,12 @@
\end{tabular} \end{tabular}
\end{table} \end{table}
\begin{tabularx}{1\linewidth}{@{\extracolsep{\fill}}lLlLL} \begin{tabularx}{1\linewidth}{@{\extracolsep{\fill}}llLlLL}
\toprule \toprule
\textbf{Name} & \textbf{Anschrift} & \textbf{Telefon} & \textbf{Notfallkontakte} \\ & \textbf{Name} & \textbf{Anschrift} & \textbf{Telefon} & \textbf{Notfallkontakte} \\
\midrule \midrule
{% for m in memberlist.membersonlist.all %} {% for m in memberlist.membersonlist.all %}
{{ forloop.counter }} &
{{ m.member.name|esc_all }} & {{ m.member.name|esc_all }} &
{{ m.member.address|esc_all }} & {{ m.member.address|esc_all }} &
{{ m.member.contact_phone_number|esc_all }} & {{ m.member.contact_phone_number|esc_all }} &

@ -35,12 +35,12 @@
\end{table} \end{table}
\begin{table}[H] \begin{table}[H]
\begin{tabularx}{\textwidth}{@{} l l Y @{}} \begin{tabularx}{\textwidth}{@{} l l l Y @{}}
\toprule \toprule
\textbf{Name} & \textbf{Fähigkeiten (max. 100)} & \textbf{Kommentare} \\ & \textbf{Name} & \textbf{Fähigkeiten (max. 100)} & \textbf{Kommentare} \\
\midrule \midrule
{% for p in people %} {% for p in people %}
{{ p.name|esc_all }} & {{ p.qualities|esc_all }} & {{ p.comments|esc_all }} \\ {{ forloop.counter }} & {{ p.name|esc_all }} & {{ p.qualities|esc_all }} & {{ p.comments|esc_all }} \\
{% endfor %} {% endfor %}
\bottomrule \bottomrule
\end{tabularx} \end{tabularx}

@ -122,12 +122,12 @@
\section{Teilnehmer*innenliste} \section{Teilnehmer*innenliste}
\begin{table}[H] \begin{table}[H]
\begin{tabularx}{1\linewidth}{@{\extracolsep{\fill}}lLl|c|c|c} \begin{tabularx}{1\linewidth}{@{\extracolsep{\fill}}llLl|c|c|c}
\hline \hline
\textbf{Name} & \textbf{Anschrift} & \textbf{Geburtsdatum} & \textbf{m} & \textbf{w} & \textbf{d} \\ \hline & \textbf{Name} & \textbf{Anschrift} & \textbf{Geburtsdatum} & \textbf{m} & \textbf{w} & \textbf{d} \\ \hline
%\midrule %\midrule
{% for m in memberlist.membersonlist.all %} {% for m in memberlist.membersonlist.all %}
{{ m.member.name|esc_all }} & {{ m.member.address|esc_all }} & {{ m.member.birth_date_str|esc_all }} {{ forloop.counter }} & {{ m.member.name|esc_all }} & {{ m.member.address|esc_all }} & {{ m.member.birth_date_str|esc_all }}
& {% if m.member.gender == 0 %} x {% endif %} & {% if m.member.gender == 0 %} x {% endif %}
& {% if m.member.gender == 1 %} x {% endif %} & {% if m.member.gender == 1 %} x {% endif %}
& {% if m.member.gender == 2 %} x {% endif %} \\ & {% if m.member.gender == 2 %} x {% endif %} \\

@ -71,6 +71,7 @@
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
{% block extra_footer_content %}{% endblock %}
</table> </table>
{% if inline_admin_formset.is_collapsible %}</details>{% endif %} {% if inline_admin_formset.is_collapsible %}</details>{% endif %}
</fieldset> </fieldset>

Loading…
Cancel
Save