From 7d93a4be0abd99c824b7e8029f4b83b2438b01fa Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Sat, 30 Nov 2024 16:08:55 +0100 Subject: [PATCH] members/excursion: add V32 and improve texts --- .../finance/locale/de/LC_MESSAGES/django.po | 78 ++++----- .../jdav_web/settings/components/texts.py | 5 + jdav_web/jdav_web/settings/local.py | 13 ++ jdav_web/locale/de/LC_MESSAGES/django.po | 10 +- jdav_web/members/admin.py | 20 ++- .../members/locale/de/LC_MESSAGES/django.po | 156 ++++++++++-------- jdav_web/members/models.py | 68 +++++++- jdav_web/members/pdf.py | 48 ++++-- .../admin/generate_seminar_report.html | 6 +- ...1_Themenorientierte_Bildungsmassnahmen.pdf | Bin 0 -> 128108 bytes .../members/crisis_intervention_list.tex | 2 +- .../members/templates/members/notes_list.tex | 2 +- .../templates/members/seminar_report.tex | 2 +- .../freizeit/change_form_object_tools.html | 4 +- 14 files changed, 271 insertions(+), 143 deletions(-) create mode 100644 jdav_web/members/templates/members/V32-1_Themenorientierte_Bildungsmassnahmen.pdf diff --git a/jdav_web/finance/locale/de/LC_MESSAGES/django.po b/jdav_web/finance/locale/de/LC_MESSAGES/django.po index 8e561f5..d0f37a9 100644 --- a/jdav_web/finance/locale/de/LC_MESSAGES/django.po +++ b/jdav_web/finance/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: 2024-11-30 03:54+0100\n" +"POT-Creation-Date: 2024-11-30 15:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -132,165 +132,165 @@ msgstr "Bestätigung zurücknehmen" msgid "Finance" msgstr "Finanzen" -#: finance/models.py:20 +#: finance/models.py:21 msgid "Name" msgstr "Name" -#: finance/models.py:26 finance/models.py:466 finance/models.py:490 +#: finance/models.py:27 finance/models.py:472 finance/models.py:496 #: finance/templates/admin/confirmed_statement.html:38 #: finance/templates/admin/overview_submitted_statement.html:100 msgid "Ledger" msgstr "Geldtopf" -#: finance/models.py:27 +#: finance/models.py:28 msgid "Ledgers" msgstr "Geldtöpfe" -#: finance/models.py:47 finance/models.py:409 finance/models.py:489 +#: finance/models.py:48 finance/models.py:415 finance/models.py:495 msgid "Short description" msgstr "Kurzbeschreibung" -#: finance/models.py:50 finance/models.py:410 +#: finance/models.py:51 finance/models.py:416 msgid "Explanation" msgstr "Erklärung" -#: finance/models.py:52 +#: finance/models.py:53 msgid "Associated excursion" msgstr "Zugehörige Ausfahrt" -#: finance/models.py:57 +#: finance/models.py:58 msgid "Price per night" msgstr "Preis pro Nacht" -#: finance/models.py:59 +#: finance/models.py:60 msgid "Submitted" msgstr "Eingericht" -#: finance/models.py:60 +#: finance/models.py:61 msgid "Submitted on" msgstr "Eingereicht am" -#: finance/models.py:61 +#: finance/models.py:62 msgid "Confirmed" msgstr "Abgewickelt" -#: finance/models.py:62 finance/models.py:473 +#: finance/models.py:63 finance/models.py:479 msgid "Paid on" msgstr "Bezahlt am" -#: finance/models.py:64 +#: finance/models.py:65 msgid "Created by" msgstr "Erstellt von" -#: finance/models.py:69 +#: finance/models.py:70 msgid "Submitted by" msgstr "Eingereicht bei" -#: finance/models.py:74 finance/models.py:474 +#: finance/models.py:75 finance/models.py:480 msgid "Authorized by" msgstr "Autorisiert von" -#: finance/models.py:81 finance/models.py:408 finance/models.py:469 +#: finance/models.py:82 finance/models.py:414 finance/models.py:475 msgid "Statement" msgstr "Abrechnung" -#: finance/models.py:82 +#: finance/models.py:83 msgid "Statements" msgstr "Abrechnungen" -#: finance/models.py:97 +#: finance/models.py:98 #, python-format msgid "Statement: %(excursion)s" msgstr "Abrechnung: %(excursion)s" -#: finance/models.py:149 +#: finance/models.py:150 msgid "Ready to confirm" msgstr "Bereit zur Abwicklung" -#: finance/models.py:193 +#: finance/models.py:194 #, python-format msgid "Compensation for %(excu)s" msgstr "Entschädigung für %(excu)s" -#: finance/models.py:326 +#: finance/models.py:327 #: finance/templates/admin/overview_submitted_statement.html:78 msgid "Total" msgstr "Gesamtbetrag" -#: finance/models.py:363 +#: finance/models.py:369 msgid "Statement in preparation" msgstr "Abrechnung in Vorbereitung" -#: finance/models.py:364 +#: finance/models.py:370 msgid "Statements in preparation" msgstr "Abrechnungen in Vorbereitung" -#: finance/models.py:383 +#: finance/models.py:389 msgid "Submitted statement" msgstr "Eingereichte Abrechnung" -#: finance/models.py:384 +#: finance/models.py:390 msgid "Submitted statements" msgstr "Eingereichte Abrechnungen" -#: finance/models.py:400 +#: finance/models.py:406 msgid "Paid statement" msgstr "Bezahlte Abrechnung" -#: finance/models.py:401 +#: finance/models.py:407 msgid "Paid statements" msgstr "Bezahlte Abrechnungen" -#: finance/models.py:412 finance/models.py:426 finance/models.py:463 +#: finance/models.py:418 finance/models.py:432 finance/models.py:469 #: finance/templates/admin/confirmed_statement.html:36 #: finance/templates/admin/overview_submitted_statement.html:31 #: finance/templates/admin/overview_submitted_statement.html:98 msgid "Amount" msgstr "Betrag" -#: finance/models.py:413 +#: finance/models.py:419 msgid "Paid by" msgstr "Bezahlt von" -#: finance/models.py:415 +#: finance/models.py:421 msgid "Covered" msgstr "Übernommen" -#: finance/models.py:416 +#: finance/models.py:422 msgid "Refunded" msgstr "Ausgezahlt" -#: finance/models.py:418 +#: finance/models.py:424 msgid "Proof" msgstr "Beleg" -#: finance/models.py:429 finance/models.py:436 finance/models.py:449 +#: finance/models.py:435 finance/models.py:442 finance/models.py:455 msgid "Bill" msgstr "Ausgabe" -#: finance/models.py:430 finance/models.py:437 finance/models.py:450 +#: finance/models.py:436 finance/models.py:443 finance/models.py:456 #: finance/templates/admin/overview_submitted_statement.html:26 msgid "Bills" msgstr "Ausgaben" -#: finance/models.py:462 finance/templates/admin/confirmed_statement.html:37 +#: finance/models.py:468 finance/templates/admin/confirmed_statement.html:37 #: finance/templates/admin/overview_submitted_statement.html:99 msgid "Reference" msgstr "Verwendungszweck" -#: finance/models.py:464 +#: finance/models.py:470 msgid "Recipient" msgstr "Empfänger" -#: finance/models.py:472 +#: finance/models.py:478 msgid "Paid" msgstr "Bezahlt" -#: finance/models.py:484 +#: finance/models.py:490 msgid "Transaction" msgstr "Überweisung" -#: finance/models.py:485 +#: finance/models.py:491 #: finance/templates/admin/overview_submitted_statement.html:84 msgid "Transactions" msgstr "Überweisungen" diff --git a/jdav_web/jdav_web/settings/components/texts.py b/jdav_web/jdav_web/settings/components/texts.py index 0bb3ad3..577e348 100644 --- a/jdav_web/jdav_web/settings/components/texts.py +++ b/jdav_web/jdav_web/settings/components/texts.py @@ -162,3 +162,8 @@ Bei Fragen, wende dich gerne an %(RESPONSIBLE_MAIL)s. Viele Grüße Deine JDAV %(SEKTION)s""" % { 'SEKTION': SEKTION, 'RESPONSIBLE_MAIL': RESPONSIBLE_MAIL } + + +ADDRESS = """JDAV %(SEKTION)s +%(STREET)s +%(PLACE)s""" % { 'SEKTION': SEKTION, 'STREET': SEKTION_STREET, 'PLACE': SEKTION_TOWN } diff --git a/jdav_web/jdav_web/settings/local.py b/jdav_web/jdav_web/settings/local.py index d873429..a92da5e 100644 --- a/jdav_web/jdav_web/settings/local.py +++ b/jdav_web/jdav_web/settings/local.py @@ -8,10 +8,23 @@ SEKTION_TELEFAX = "06221 437338" SEKTION_CONTACT_MAIL = "geschaeftsstelle@alpenverein-heidelberg.de" SEKTION_BOARD_MAIL = "vorstand@alpenverein-heidelberg.de" SEKTION_CRISIS_INTERVENTION_MAIL = "krisenmanagement@alpenverein-heidelberg.de" +SEKTION_IBAN = "DE22 6729 0000 0000 1019 40" +SEKTION_ACCOUNT_HOLDER = "Deutscher Alpenverein Sektion Heidelberg 1869" RESPONSIBLE_MAIL = "jugendreferat@jdav-hd.de" DIGITAL_MAIL = "digitales@jdav-hd.de" +# LJP + +V32_HEAD_ORGANISATION = """JDAV Baden-Württemberg +Rotebühlstraße 59A +70178 Stuttgart + +info@jdav-bw.de +0711 - 49 09 46 00""" + +LJP_CONTRIBUTION_PER_DAY = 25 + # echo ECHO_PASSWORD_BIRTHDATE_FORMAT = '%d.%m.%Y' diff --git a/jdav_web/locale/de/LC_MESSAGES/django.po b/jdav_web/locale/de/LC_MESSAGES/django.po index 7ed7671..bb7020a 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: 2024-11-30 03:54+0100\n" +"POT-Creation-Date: 2024-11-30 15:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -258,17 +258,15 @@ msgstr "SJR Antrag erstellen" #: templates/admin/members/freizeit/change_form_object_tools.html:23 msgid "Generate overview" -msgstr "Übersicht erstellen" +msgstr "Hinweise für Jugendleiter:innen erstellen" #: templates/admin/members/freizeit/change_form_object_tools.html:30 msgid "Generate seminar report" -msgstr "Seminarbericht erstellen" +msgstr "Landesjugendplan Antrag erstellen" #: templates/admin/members/freizeit/change_form_object_tools.html:38 -#, fuzzy -#| msgid "Generate overview" msgid "Finance overview" -msgstr "Übersicht erstellen" +msgstr "Kostenübersicht" #: templates/admin/members/member/change_form_object_tools.html:8 msgid "Invite as user" diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index 0d24940..154d1cd 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -23,10 +23,10 @@ from django.utils.html import format_html from django.utils.translation import gettext_lazy as _ from django.db.models import TextField, ManyToManyField, ForeignKey, Count,\ Sum, Case, Q, F, When, Value, IntegerField, Subquery, OuterRef -from django.forms import Textarea, RadioSelect, TypedChoiceField +from django.forms import Textarea, RadioSelect, TypedChoiceField, CheckboxInput from django.shortcuts import render from django.core.exceptions import PermissionDenied -from .pdf import render_tex, fill_pdf_form +from .pdf import render_tex, fill_pdf_form, merge_pdfs, serve_pdf from contrib.admin import CommonAdminInlineMixin, CommonAdminMixin @@ -825,6 +825,9 @@ class GenerateSeminarReportForm(forms.Form): modes = (('full', _('Full report')), ('basic', _('Costs and participants only'))) mode = forms.ChoiceField(choices=modes, label=_('Mode')) + prepend_v32 = forms.BooleanField(label=_('Prepend V32'), initial=True, + widget=CheckboxInput(attrs={'style': 'display: inherit'}), + required=False) class FreizeitAdmin(CommonAdminMixin, nested_admin.NestedModelAdmin): @@ -904,12 +907,21 @@ class FreizeitAdmin(CommonAdminMixin, nested_admin.NestedModelAdmin): messages.error(request, _('Please select a mode.')) return self.render_seminar_report_options(request, memberlist, form) mode = form.cleaned_data['mode'] + prepend_v32 = form.cleaned_data['prepend_v32'] if mode == 'full' and not hasattr(memberlist, 'ljpproposal'): messages.error(request, _('Full mode is only available, if the seminar report section is filled out.')) return self.render_seminar_report_options(request, memberlist, form) - context = dict(memberlist=memberlist, settings=settings, mode=mode) title = memberlist.ljpproposal.title if hasattr(memberlist, 'ljpproposal') else memberlist.name - return render_tex(title + '_Seminarbericht', 'members/seminar_report.tex', context) + context = dict(memberlist=memberlist, settings=settings, mode=mode) + fp = render_tex(title + '_Seminarbericht', 'members/seminar_report.tex', context, save_only=True) + if prepend_v32: + context = memberlist.v32_fields() + v32_fp = fill_pdf_form(title + "_LJP_V32", + 'members/V32-1_Themenorientierte_Bildungsmassnahmen.pdf', + context, + save_only=True) + return merge_pdfs(title + 'LJP_Antrag', [v32_fp, fp]) + return serve_pdf(fp) return self.render_seminar_report_options(request, memberlist, GenerateSeminarReportForm()) seminar_report.short_description = _('Generate seminar report') diff --git a/jdav_web/members/locale/de/LC_MESSAGES/django.po b/jdav_web/members/locale/de/LC_MESSAGES/django.po index 08b248d..8871d4e 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: 2024-11-30 04:20+0100\n" +"POT-Creation-Date: 2024-11-30 15:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -109,7 +109,7 @@ msgstr "" msgid "activity" msgstr "Aktivität" -#: members/admin.py:374 members/models.py:54 members/models.py:1409 +#: members/admin.py:374 members/models.py:54 members/models.py:1475 msgid "Name" msgstr "Name" @@ -160,7 +160,7 @@ msgid "Successfully demoted %(name)s to waiter." msgstr "%(name)s zurück auf die Warteliste gesetzt." #: members/admin.py:542 members/models.py:389 members/models.py:733 -#: members/models.py:1154 +#: members/models.py:1220 msgid "Group" msgstr "Gruppe" @@ -273,7 +273,11 @@ msgstr "Nur Kosten und Teilnehmende" msgid "Mode" msgstr "Modus" -#: members/admin.py:841 +#: members/admin.py:828 +msgid "Prepend V32" +msgstr "V32 Formblatt einfügen" + +#: members/admin.py:844 msgid "" "General information on your excursion. These are partly relevant for the " "amount of financial compensation (means of transport, travel distance, etc.)." @@ -282,48 +286,48 @@ msgstr "" "teilweise relevant für die Zuschüsse aus dem Jugendetat (Verkehrsmittel, " "Fahrstrecke in km)." -#: members/admin.py:871 +#: members/admin.py:874 #, python-format msgid "You are not allowed to view all members on excursion %(name)s." msgstr "" "Du hast nicht die nötigen Rechte um alle Teilnehmer:innen der Ausfahrt " "%(name)s anzusehen." -#: members/admin.py:879 +#: members/admin.py:882 msgid "Generate crisis intervention list" msgstr "Kriseninterventionsliste erstellen" -#: members/admin.py:887 +#: members/admin.py:890 msgid "Generate overview" msgstr "Hinweise für Jugendleiter erstellen" -#: members/admin.py:891 members/admin.py:914 +#: members/admin.py:894 members/admin.py:926 #: members/templates/admin/generate_seminar_report.html:21 msgid "Generate seminar report" -msgstr "Seminarbericht erstellen" +msgstr "Landesjugendplan Antrag erstellen" -#: members/admin.py:904 +#: members/admin.py:907 msgid "Please select a mode." msgstr "Bitte wähle einen Modus aus." -#: members/admin.py:908 +#: members/admin.py:912 msgid "" "Full mode is only available, if the seminar report section is filled out." msgstr "" "Der vollständiger Modus ist nur verfügbar, wenn der Seminarbericht " "ausgefüllt ist. " -#: members/admin.py:926 +#: members/admin.py:938 msgid "Generate SJR application" msgstr "SJR Antrag erstellen" -#: members/admin.py:930 +#: members/admin.py:942 msgid "No statement found. Please add a statement and then retry." msgstr "" "Keine Abrechnung angelegt. Bitte lege eine Abrechnung and und versuche es " "erneut." -#: members/admin.py:934 +#: members/admin.py:946 msgid "" "Successfully submited statement. The finance department will notify you as " "soon as possible." @@ -331,7 +335,7 @@ msgstr "" "Abrechnung erfolgreich eingericht. Die Finanzabteilung wird sich bei dir so " "schnell wie möglich melden." -#: members/admin.py:937 +#: members/admin.py:949 #: members/templates/admin/freizeit_finance_overview.html:21 msgid "Finance overview" msgstr "Kostenübersicht" @@ -409,7 +413,7 @@ msgstr "Jugendleiter" msgid "week day" msgstr "Wochentag" -#: members/models.py:78 members/models.py:1236 +#: members/models.py:78 members/models.py:1302 msgid "Starting time" msgstr "Zeitpunkt" @@ -599,7 +603,7 @@ msgid "Set login data for Kompass" msgstr "Zugangsdaten für Kompass wählen" #: members/models.py:689 members/models.py:885 members/models.py:896 -#: members/models.py:1185 members/models.py:1192 +#: members/models.py:1251 members/models.py:1258 msgid "Member" msgstr "Teilnehmer" @@ -700,7 +704,7 @@ msgstr "Von der Warteliste abgemeldet" msgid "Comment" msgstr "Kommentar" -#: members/models.py:897 members/models.py:1193 +#: members/models.py:897 members/models.py:1259 msgid "Members" msgstr "Teilnehmer" @@ -748,7 +752,7 @@ msgstr "mittel" msgid "hard" msgstr "schwer" -#: members/models.py:966 members/models.py:1216 +#: members/models.py:966 members/models.py:1282 #: members/templates/admin/freizeit_finance_overview.html:26 msgid "Excursion" msgstr "Ausfahrt" @@ -757,163 +761,163 @@ msgstr "Ausfahrt" msgid "Excursions" msgstr "Ausfahrten" -#: members/models.py:1131 members/models.py:1207 members/models.py:1423 +#: members/models.py:1197 members/models.py:1273 members/models.py:1489 msgid "Title" msgstr "Titel" -#: members/models.py:1132 members/models.py:1150 members/models.py:1424 +#: members/models.py:1198 members/models.py:1216 members/models.py:1490 msgid "Date" msgstr "Datum" -#: members/models.py:1151 +#: members/models.py:1217 msgid "Location" msgstr "Ort" -#: members/models.py:1152 +#: members/models.py:1218 msgid "Topic" msgstr "Thema" -#: members/models.py:1176 +#: members/models.py:1242 msgid "Jugendleiter" msgstr "Jugendleiter" -#: members/models.py:1179 +#: members/models.py:1245 msgid "Klettertreff" msgstr "Klettertreff" -#: members/models.py:1180 +#: members/models.py:1246 msgid "Klettertreffs" msgstr "Klettertreffs" -#: members/models.py:1198 +#: members/models.py:1264 msgid "Password" msgstr "Passwort" -#: members/models.py:1201 +#: members/models.py:1267 msgid "registration password" msgstr "Registrierungspassort" -#: members/models.py:1202 +#: members/models.py:1268 msgid "registration passwords" msgstr "Registrierungspasswörter" -#: members/models.py:1209 +#: members/models.py:1275 msgid "Alpinistic goals" msgstr "Alpintechnische Ziele" -#: members/models.py:1210 +#: members/models.py:1276 msgid "Pedagogic goals" msgstr "Pädagogische Ziele" -#: members/models.py:1211 +#: members/models.py:1277 msgid "Content and methods" msgstr "Inhalte und Methoden" -#: members/models.py:1212 +#: members/models.py:1278 msgid "Evaluation" msgstr "Wertung" -#: members/models.py:1213 +#: members/models.py:1279 msgid "Experiences and possible improvements" msgstr "Erfahrungen und Verbesserungsvorschläge" -#: members/models.py:1222 members/models.py:1243 +#: members/models.py:1288 members/models.py:1309 msgid "LJP Proposal" msgstr "Seminarbericht" -#: members/models.py:1223 +#: members/models.py:1289 msgid "LJP Proposals" msgstr "Seminarberichte" -#: members/models.py:1237 +#: members/models.py:1303 msgid "Duration in hours" msgstr "Dauer in Stunden" -#: members/models.py:1240 +#: members/models.py:1306 msgid "Activity and method" msgstr "Art der Aktion inkl. Methode" -#: members/models.py:1248 +#: members/models.py:1314 msgid "Intervention" msgstr "Aktion" -#: members/models.py:1249 +#: members/models.py:1315 msgid "Interventions" msgstr "Aktionen" -#: members/models.py:1351 members/models.py:1381 +#: members/models.py:1417 members/models.py:1447 msgid "May list members" msgstr "Darf folgende Teilnehmer:innen listen" -#: members/models.py:1353 members/models.py:1383 +#: members/models.py:1419 members/models.py:1449 msgid "May view members" msgstr "Darf folgende Teilnehmer:innen anzeigen" -#: members/models.py:1355 members/models.py:1385 +#: members/models.py:1421 members/models.py:1451 msgid "May change members" msgstr "Darf folgende Teilnehmer:innen ändern" -#: members/models.py:1357 members/models.py:1387 +#: members/models.py:1423 members/models.py:1453 msgid "May delete members" msgstr "Darf folgende Teilnehmer:innen löschen" -#: members/models.py:1361 members/models.py:1391 +#: members/models.py:1427 members/models.py:1457 msgid "May list members of groups" msgstr "Darf Teilnehmer:innen folgender Gruppen listen" -#: members/models.py:1363 members/models.py:1393 +#: members/models.py:1429 members/models.py:1459 msgid "May view members of groups" msgstr "Darf Teilnehmer:innen folgender Gruppen anzeigen" -#: members/models.py:1365 members/models.py:1395 +#: members/models.py:1431 members/models.py:1461 msgid "May change members of groups" msgstr "Darf Teilnehmer:innen folgender Gruppen ändern" -#: members/models.py:1367 members/models.py:1397 +#: members/models.py:1433 members/models.py:1463 msgid "May delete members of groups" msgstr "Darf Teilnehmer:innen folgender Gruppen löschen" -#: members/models.py:1370 members/models.py:1371 members/models.py:1374 +#: members/models.py:1436 members/models.py:1437 members/models.py:1440 msgid "Permissions" msgstr "Berechtigungen" -#: members/models.py:1400 members/models.py:1401 members/models.py:1404 +#: members/models.py:1466 members/models.py:1467 members/models.py:1470 msgid "Group permissions" msgstr "Gruppenberechtigungen" -#: members/models.py:1410 +#: members/models.py:1476 msgid "Permission needed" msgstr "Freigabe erforderlich" -#: members/models.py:1413 +#: members/models.py:1479 msgid "Training category" msgstr "Fortbildungstyp" -#: members/models.py:1414 +#: members/models.py:1480 msgid "Training categories" msgstr "Fortbildungstypen" -#: members/models.py:1425 +#: members/models.py:1491 msgid "Category" msgstr "Kategorien" -#: members/models.py:1426 +#: members/models.py:1492 msgid "Comments" msgstr "Kommentar" -#: members/models.py:1427 +#: members/models.py:1493 msgid "Participated" msgstr "Teilgenommmen" -#: members/models.py:1428 +#: members/models.py:1494 msgid "Passed" msgstr "Bestanden" -#: members/models.py:1431 +#: members/models.py:1497 msgid "Training" msgstr "Fortbildung" -#: members/models.py:1432 +#: members/models.py:1498 msgid "Trainings" msgstr "Fortbildungen" @@ -943,7 +947,7 @@ msgstr "Zurück auf die Warteliste setzen" #: members/templates/admin/demote_to_waiter.html:46 #: members/templates/admin/freizeit_finance_overview.html:154 -#: members/templates/admin/generate_seminar_report.html:58 +#: members/templates/admin/generate_seminar_report.html:60 #: members/templates/admin/invite_as_user.html:37 #: members/templates/admin/invite_for_group.html:52 #: members/templates/admin/invite_selected_as_user.html:49 @@ -972,10 +976,8 @@ msgid "You listed the following expenses:" msgstr "Du hast die folgenden Ausgaben angegeben:" #: members/templates/admin/freizeit_finance_overview.html:39 -#, fuzzy -#| msgid "Evaluation" msgid "Explanation" -msgstr "Wertung" +msgstr "Erklärung" #: members/templates/admin/freizeit_finance_overview.html:40 msgid "Amount" @@ -1138,8 +1140,12 @@ msgid "" "Here you can generate a seminar report suitable for the LJP. A report\n" "always contains a head page with the basic information on the seminar." msgstr "" -"Hier kannst du einen Seminarbericht für den Landesjugendplan erstellen. Ein " -"Bericht enthält immer einen Kopf mit den Stammdaten des Seminars." +"Hier kannst du einen Zuschussantrag für den Landesjugendplan (LJP) " +"erstellen. Ein solcher Antrag besteht immer aus zwei Teilen: Einem Formblatt " +"und einem Seminarbericht. Ein Bericht enthält immer einen Kopf mit den " +"Stammdaten des Seminars. Darüber hinaus muss der Seminarbericht eine " +"Teilnehemendenliste, eine Kostenübersicht und eine detaillierte didaktische " +"Planung enthalten. " #: members/templates/admin/generate_seminar_report.html:31 msgid "" @@ -1147,8 +1153,8 @@ msgid "" "as one expense in the\n" "expense overview." msgstr "" -"Ausgaben mit der gleichen Kurzbeschreibung werden automatisch aufsummiert " -"und zu einer Ausgabe zusammengefasst." +"In der Kostenübersicht werden Ausgaben mit der gleichen Kurzbeschreibung " +"automatisch aufsummiert und zu einer Ausgabe zusammengefasst." #: members/templates/admin/generate_seminar_report.html:36 msgid "" @@ -1156,7 +1162,7 @@ msgid "" "schedule. This requires\n" "the seminar report section to be filled out." msgstr "" -"Vollständiger Bericht: Stelle Lernziele und einen detaillierte, tabellierten " +"Vollständiger Bericht: Stelle Lernziele und einen detaillierten, tabellierten " "Zeitplan dar. Dies benötigt, dass der Seminarbericht in der Ausfahrt " "ausgefüllt ist." @@ -1171,10 +1177,15 @@ msgstr "" "hinzufügen." #: members/templates/admin/generate_seminar_report.html:46 -msgid "Please choose one of the listed modes." -msgstr "Bitte wähle einen der obigen Modi." +msgid "You may also choose to include the V32 attachment." +msgstr "" +"Ein LJP Antrag benötigt immer ein Formblatt (in unserem Fall V32-1 " +"Themenorientierte Bildungsmaßnahmen). Dieses kannst du automatisch " +"vorausfüllen lassen und dem Antrag hinzufügen. " +"Bitte fülle die verbleibenden Felder im Formblatt selbst aus und " +"unterschreibe das PDF." -#: members/templates/admin/generate_seminar_report.html:57 +#: members/templates/admin/generate_seminar_report.html:59 msgid "Generate" msgstr "Erstellen" @@ -1636,6 +1647,9 @@ msgstr "abgelaufen" msgid "Invalid emergency contacts" msgstr "Ungültige Notfallkontakte" +#~ msgid "Please choose one of the listed modes." +#~ msgstr "Bitte wähle einen der obigen Modi." + #~ msgid "Good conduct certificate presentation needed" #~ msgstr "Vorlage Führungszeugnis notwendig" diff --git a/jdav_web/members/models.py b/jdav_web/members/models.py index 3b6739e..54d9f51 100644 --- a/jdav_web/members/models.py +++ b/jdav_web/members/models.py @@ -1024,9 +1024,21 @@ class Freizeit(CommonModel): jls = set(self.jugendleiter.distinct()) return len(ps - jls) + @property + def ljp_participant_count(self): + ps = set(map(lambda x: x.member, self.membersonlist.distinct())) + jls = set(self.jugendleiter.distinct()) + count = len(ps.union(jls)) + return count + #return count if count >= 5 else 0 + + @property + def maximal_ljp_contributions(self): + return cvt_to_decimal(settings.LJP_CONTRIBUTION_PER_DAY * self.ljp_participant_count * self.duration) + @property def potential_ljp_contributions(self): - return cvt_to_decimal(min(25 * self.participant_count * self.duration, + return cvt_to_decimal(min(self.maximal_ljp_contributions, 0.9 * float(self.statement.total_bills_theoretic) + float(self.statement.total_staff))) @property @@ -1113,6 +1125,60 @@ class Freizeit(CommonModel): base['Status' + suffix] = str(2) return base + def v32_fields(self): + title = self.ljpproposal.title if hasattr(self, 'ljpproposal') else self.name + base = { + # AntragstellerIn + 'Textfeld 2': settings.ADDRESS, + # Dachorganisation + 'Textfeld 3': settings.V32_HEAD_ORGANISATION, + # Datum der Maßnahme am/vom + 'Textfeld 20': self.date.strftime('%d.%m.%Y'), + # bis + 'Textfeld 28': self.end.strftime('%d.%m.%Y'), + # Thema der Maßnahme + 'Textfeld 22': title, + # IBAN + 'Textfeld 36': settings.SEKTION_IBAN, + # Kontoinhaber + 'Textfeld 37': settings.SEKTION_ACCOUNT_HOLDER, + # Zahl der zuwendungsfähigen Teilnehemr + 'Textfeld 43': str(self.ljp_participant_count), + # Teilnahmetage + 'Textfeld 46': str(round(self.duration * self.ljp_participant_count, 1)).replace('.', ','), + # Euro Tagessatz + 'Textfeld 48': str(settings.LJP_CONTRIBUTION_PER_DAY), + # Erbetener Zuschuss + 'Textfeld 50': str(self.maximal_ljp_contributions).replace('.', ','), + # Stunden Bildungsprogramm + 'Textfeld 52': '??', + # Tage + 'Textfeld 53': str(round(self.duration, 1)).replace('.', ','), + # Haushaltsjahr + 'Textfeld 54': str(datetime.now().year), + # nicht anrechenbare Teilnahmetage + 'Textfeld 55': '0', + # Gesamt-Teilnahmetage + 'Textfeld 56': str(round(self.duration * self.ljp_participant_count, 1)).replace('.', ','), + # Ort, Datum + 'DatumOrt 2': 'Heidelberg, ' + datetime.now().strftime('%d.%m.%Y') + } + if self.statement: + possible_contributions = self.maximal_ljp_contributions + total_contributions = min(self.statement.total_theoretic, possible_contributions) + self_participation = max(cvt_to_decimal(0), self.statement.total_theoretic - possible_contributions) + # Gesamtkosten von + base['Textfeld 62'] = str(self.statement.total_theoretic).replace('.', ',') + # Eigenmittel und Teilnahmebeiträge + base['Textfeld 59'] = str(self_participation).replace('.', ',') + # Drittmittel + base['Textfeld 60'] = '0,00' + # Erbetener Zuschuss + base['Textfeld 61'] = str(total_contributions).replace('.', ',') + # Ergibt wieder + base['Textfeld 58'] = base['Textfeld 62'] + return base + @staticmethod def filter_queryset_by_permissions(member, queryset=None): if queryset is None: diff --git a/jdav_web/members/pdf.py b/jdav_web/members/pdf.py index 00a9978..a273b95 100644 --- a/jdav_web/members/pdf.py +++ b/jdav_web/members/pdf.py @@ -31,7 +31,17 @@ def media_dir(): return os.path.join(settings.MEDIA_MEMBERLISTS, "memberlists") -def render_tex(name, template_path, context): +def serve_pdf(filename_pdf): + # provide the user with the resulting pdf file + with open(media_path(filename_pdf), 'rb') as pdf: + response = HttpResponse(FileWrapper(pdf))#, content='application/pdf') + response['Content-Type'] = 'application/pdf' + response['Content-Disposition'] = 'attachment; filename='+filename_pdf + + return response + + +def render_tex(name, template_path, context, save_only=False): filename = name + "_" + datetime.today().strftime("%d_%m_%Y") filename = filename.replace(' ', '_').replace('&', '').replace('/', '_') # drop umlauts, accents etc. @@ -64,16 +74,12 @@ def render_tex(name, template_path, context): os.chdir(oldwd) - # provide the user with the resulting pdf file - with open(media_path(filename_pdf), 'rb') as pdf: - response = HttpResponse(FileWrapper(pdf))#, content='application/pdf') - response['Content-Type'] = 'application/pdf' - response['Content-Disposition'] = 'attachment; filename='+filename_pdf - - return response + if save_only: + return filename_pdf + return serve_pdf(filename_pdf) -def fill_pdf_form(name, template_path, fields, attachments=[]): +def fill_pdf_form(name, template_path, fields, attachments=[], save_only=False): filename = name + "_" + datetime.today().strftime("%d_%m_%Y") filename = filename.replace(' ', '_').replace('&', '').replace('/', '_') # drop umlauts, accents etc. @@ -104,10 +110,22 @@ def fill_pdf_form(name, template_path, fields, attachments=[]): with open(media_path(filename_pdf), 'wb') as output_stream: writer.write(output_stream) - # provide the user with the resulting pdf file - with open(media_path(filename_pdf), 'rb') as pdf: - response = HttpResponse(FileWrapper(pdf))#, content='application/pdf') - response['Content-Type'] = 'application/pdf' - response['Content-Disposition'] = 'attachment; filename='+filename_pdf + if save_only: + return filename_pdf + return serve_pdf(filename_pdf) - return response + +def merge_pdfs(name, filenames, save_only=False): + merger = PdfWriter() + + for pdf in filenames: + merger.append(media_path(pdf)) + + filename = name + "_" + datetime.today().strftime("%d_%m_%Y") + filename_pdf = filename + ".pdf" + merger.write(media_path(filename_pdf)) + merger.close() + + if save_only: + return filename_pdf + return serve_pdf(filename_pdf) diff --git a/jdav_web/members/templates/admin/generate_seminar_report.html b/jdav_web/members/templates/admin/generate_seminar_report.html index 6a3e8e8..6a52699 100644 --- a/jdav_web/members/templates/admin/generate_seminar_report.html +++ b/jdav_web/members/templates/admin/generate_seminar_report.html @@ -43,12 +43,14 @@ have to add learning goals and a time schedule manually.{% endblocktrans %}
-

{% blocktrans %}Please choose one of the listed modes.{% endblocktrans %}

+

{% blocktrans %}You may also choose to include the V32 attachment.{% endblocktrans %}

{% csrf_token %}

- {{form}} + + {{ form }} +


diff --git a/jdav_web/members/templates/members/V32-1_Themenorientierte_Bildungsmassnahmen.pdf b/jdav_web/members/templates/members/V32-1_Themenorientierte_Bildungsmassnahmen.pdf new file mode 100644 index 0000000000000000000000000000000000000000..46a427aa0e550561f0d3e2cd6afa0168ff8eee5e GIT binary patch literal 128108 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