feat(members/admin): button to (re)request registration form

pull/174/head
Christian Merten 3 months ago
parent 25dd1520c2
commit 9f7b7a9517
Signed by: christian.merten
GPG Key ID: D953D69721B948B3

@ -12,6 +12,26 @@ import rules.contrib.admin
from rules.permissions import perm_exists from rules.permissions import perm_exists
def decorate_admin_view(model, perm=None):
"""
Decorator for wrapping admin views.
"""
def decorator(fun):
def aux(self, request, object_id):
try:
obj = model.objects.get(pk=object_id)
except model.DoesNotExist:
messages.error(request, _('%(modelname)s not found.') % {'modelname': self.opts.verbose_name})
return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name)))
permitted = self.has_change_permission(request, obj) if not perm else request.user.has_perm(perm)
if not permitted:
messages.error(request, _('Insufficient permissions.'))
return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name)))
return fun(self, request, obj)
return aux
return decorator
class FieldPermissionsAdminMixin: class FieldPermissionsAdminMixin:
field_change_permissions = {} field_change_permissions = {}
field_view_permissions = {} field_view_permissions = {}

@ -32,7 +32,7 @@ from .pdf import render_tex, fill_pdf_form, merge_pdfs, serve_pdf, render_docx
from .excel import generate_group_overview, generate_ljp_vbk from .excel import generate_group_overview, generate_ljp_vbk
from .models import WEEKDAYS from .models import WEEKDAYS
from contrib.admin import CommonAdminInlineMixin, CommonAdminMixin from contrib.admin import CommonAdminInlineMixin, CommonAdminMixin, decorate_admin_view
import nested_admin import nested_admin
@ -513,6 +513,11 @@ class MemberUnconfirmedAdmin(CommonAdminMixin, admin.ModelAdmin):
wrap(self.demote_to_waiter_view), wrap(self.demote_to_waiter_view),
name="%s_%s_demote" % (self.opts.app_label, self.opts.model_name), name="%s_%s_demote" % (self.opts.app_label, self.opts.model_name),
), ),
path(
"<path:object_id>/request_registration_form/",
wrap(self.request_registration_form_view),
name="%s_%s_request_registration_form" % (self.opts.app_label, self.opts.model_name),
),
] ]
return custom_urls + urls return custom_urls + urls
@ -545,6 +550,18 @@ class MemberUnconfirmedAdmin(CommonAdminMixin, admin.ModelAdmin):
member.demote_to_waiter() member.demote_to_waiter()
messages.success(request, _("Successfully demoted %(name)s to waiter.") % {'name': member.name}) messages.success(request, _("Successfully demoted %(name)s to waiter.") % {'name': member.name})
@decorate_admin_view(MemberUnconfirmedProxy)
def request_registration_form_view(self, request, member):
if "apply" in request.POST:
member.request_registration_form()
messages.success(request, _("Requested registration form for %(name)s.") % {'name': member.name})
return HttpResponseRedirect(reverse('admin:members_memberunconfirmedproxy_change', args=(member.pk,)))
context = dict(self.admin_site.each_context(request),
title=_('Request upload registration form'),
opts=self.opts,
member=member)
return render(request, 'admin/request_registration_form.html', context=context)
def response_change(self, request, member): def response_change(self, request, member):
if "_confirm" in request.POST: if "_confirm" in request.POST:
if member.confirm(): if member.confirm():

@ -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-07-25 18:44+0200\n" "POT-Creation-Date: 2025-09-19 21:35+0200\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"
@ -18,22 +18,6 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: members/admin.py members/models.py
msgid "Registration complete"
msgstr "Anmeldung vollständig"
#: members/admin.py
msgid "True"
msgstr "Ja"
#: members/admin.py
msgid "False"
msgstr "Nein"
#: members/admin.py members/tests.py
msgid "All"
msgstr "Alle"
#: members/admin.py #: members/admin.py
msgid "The entered IBAN is not valid." msgid "The entered IBAN is not valid."
msgstr "Die eingegebene IBAN ist ungültig." msgstr "Die eingegebene IBAN ist ungültig."
@ -82,18 +66,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/tests.py #: members/admin.py members/tests/basic.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/tests.py #: members/admin.py members/tests/basic.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/tests.py #: members/admin.py members/tests/basic.py
msgid "Permission denied." msgid "Permission denied."
msgstr "Fehlende Berechtigungen." msgstr "Fehlende Berechtigungen."
@ -105,21 +89,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/tests.py #: members/admin.py members/tests/basic.py
msgid "Member not found." msgid "Member not found."
msgstr "Teilnehmer*in nicht gefunden." msgstr "Teilnehmer*in nicht gefunden."
#: members/admin.py members/tests.py #: members/admin.py members/tests/basic.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/tests.py #: members/admin.py members/tests/basic.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/tests.py #: members/admin.py members/tests/basic.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 ""
@ -143,7 +127,7 @@ msgid "Unconfirm selected members."
msgstr "" msgstr ""
"Ausgewählte Teilnehmer*innen zu unbestätigten Registrierungen zurücksetzen." "Ausgewählte Teilnehmer*innen zu unbestätigten Registrierungen zurücksetzen."
#: members/admin.py members/tests.py #: members/admin.py members/tests/basic.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,7 +135,7 @@ msgstr "Aufforderung zur Bestätigung der Email Adresse versendet."
msgid "Request mail confirmation from selected registrations" msgid "Request mail confirmation from selected registrations"
msgstr "Aufforderung zur Bestätigung der Email Adresse versenden" msgstr "Aufforderung zur Bestätigung der Email Adresse versenden"
#: members/admin.py #: members/admin.py members/tests/basic.py
msgid "" msgid ""
"Successfully re-requested missing mail confirmations from selected " "Successfully re-requested missing mail confirmations from selected "
"registrations." "registrations."
@ -175,11 +159,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/tests.py #: members/admin.py members/tests/basic.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/tests.py #: members/admin.py members/tests/basic.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 ""
@ -194,7 +178,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/tests.py #: members/admin.py members/tests/basic.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."
@ -203,6 +187,15 @@ msgstr "Ausgewählte Registrierung zurück auf die Warteliste setzen."
msgid "Successfully demoted %(name)s to waiter." msgid "Successfully demoted %(name)s to waiter."
msgstr "%(name)s zurück auf die Warteliste gesetzt." msgstr "%(name)s zurück auf die Warteliste gesetzt."
#: members/admin.py
#, python-format
msgid "Requested registration form for %(name)s."
msgstr "Anmeldeformular für %(name)s angefragt."
#: members/admin.py
msgid "Request upload registration form"
msgstr "Anmeldeformular anfragen"
#: members/admin.py members/models.py #: members/admin.py members/models.py
msgid "Group" msgid "Group"
msgstr "Gruppe" msgstr "Gruppe"
@ -257,7 +250,7 @@ msgstr ""
msgid "Offer waiter a place in a group." msgid "Offer waiter a place in a group."
msgstr "Personen auf der Warteliste einen Gruppenplatz anbieten." msgstr "Personen auf der Warteliste einen Gruppenplatz anbieten."
#: members/admin.py #: members/admin.py members/tests/basic.py
msgid "A waiter with this ID does not exist." msgid "A waiter with this ID does not exist."
msgstr "Es existiert keine wartende Person mit dieser ID." msgstr "Es existiert keine wartende Person mit dieser ID."
@ -379,11 +372,11 @@ msgstr "Übersicht erstellen"
msgid "Invoice" msgid "Invoice"
msgstr "Beleg" msgstr "Beleg"
#: members/admin.py members/tests.py #: members/admin.py members/tests/basic.py
msgid "Excursion not found." msgid "Excursion not found."
msgstr "Ausfahrt nicht gefunden." msgstr "Ausfahrt nicht gefunden."
#: members/admin.py members/tests.py #: members/admin.py members/tests/basic.py
msgid "" msgid ""
"This excursion does not have a LJP proposal. Please add one and try again." "This excursion does not have a LJP proposal. Please add one and try again."
msgstr "" msgstr ""
@ -412,7 +405,7 @@ msgstr ""
"nicht sichtbar für Standardbenutzer*innen, nur der Genehmigungszustand wird " "nicht sichtbar für Standardbenutzer*innen, nur der Genehmigungszustand wird "
"in der Übersicht alle Ausfahrten angezeigt." "in der Übersicht alle Ausfahrten angezeigt."
#: members/admin.py members/tests.py #: members/admin.py members/tests/basic.py
#, python-format #, python-format
msgid "You are not allowed to view all members on excursion %(name)s." msgid "You are not allowed to view all members on excursion %(name)s."
msgstr "" msgstr ""
@ -435,17 +428,17 @@ msgstr "Landesjugendplan Antrag erstellen"
msgid "Generate SJR application" msgid "Generate SJR application"
msgstr "SJR Antrag erstellen" msgstr "SJR Antrag erstellen"
#: members/admin.py members/tests.py #: members/admin.py members/tests/basic.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/tests.py #: members/admin.py members/tests/basic.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 "
"erneut." "erneut."
#: members/admin.py #: members/admin.py members/tests/basic.py
msgid "" msgid ""
"The configured recipients of the allowance don't match the regulations. " "The configured recipients of the allowance don't match the regulations. "
"Please correct this and try again." "Please correct this and try again."
@ -453,7 +446,7 @@ msgstr ""
"Die ausgewählten Empfänger*innen der Aufwandsentschädigung stimmen nicht mit " "Die ausgewählten Empfänger*innen der Aufwandsentschädigung stimmen nicht mit "
"den Richtlinien überein. Bitte korrigiere das und versuche es erneut. " "den Richtlinien überein. Bitte korrigiere das und versuche es erneut. "
#: members/admin.py #: members/admin.py members/tests/basic.py
msgid "" msgid ""
"The excursion is configured to claim LJP contributions. In that case, for " "The excursion is configured to claim LJP contributions. In that case, for "
"all bills, a proof must be uploaded. Please correct this and try again." "all bills, a proof must be uploaded. Please correct this and try again."
@ -474,15 +467,6 @@ msgstr ""
msgid "Finance overview" msgid "Finance overview"
msgstr "Kostenübersicht" msgstr "Kostenübersicht"
#: members/admin.py
msgid "Inform youth leaders about sending of crisis intervention list."
msgstr ""
"Informiere Jugendleiter:innen über Versand der Kriseninterventionsliste."
#: members/admin.py
msgid "Send crisis intervention list."
msgstr "Kriseninterventionsliste verschicken"
#: members/apps.py #: members/apps.py
msgid "member administration" msgid "member administration"
msgstr "Teilnehmer*innenverwaltung" msgstr "Teilnehmer*innenverwaltung"
@ -781,6 +765,10 @@ msgstr ""
msgid "Good conduct certificate valid" msgid "Good conduct certificate valid"
msgstr "Führungszeugnis gültig" msgstr "Führungszeugnis gültig"
#: members/models.py
msgid "Registration complete"
msgstr "Anmeldung vollständig"
#: members/models.py #: members/models.py
msgid "member" msgid "member"
msgstr "Teilnehmer*in" msgstr "Teilnehmer*in"
@ -846,15 +834,15 @@ msgstr "Gruppeneinladung"
msgid "Invitations to groups" msgid "Invitations to groups"
msgstr "Gruppeneinladungen" msgstr "Gruppeneinladungen"
#: members/models.py #: members/models.py members/tests/basic.py
msgid "Rejected" msgid "Rejected"
msgstr "Abgelehnt" msgstr "Abgelehnt"
#: members/models.py #: members/models.py members/tests/basic.py
msgid "Expired" msgid "Expired"
msgstr "Abgelaufen" msgstr "Abgelaufen"
#: members/models.py #: members/models.py members/tests/basic.py
msgid "Undecided" msgid "Undecided"
msgstr "Ausstehend" msgstr "Ausstehend"
@ -1021,6 +1009,7 @@ msgid "Excursions"
msgstr "Ausfahrten" msgstr "Ausfahrten"
#: members/models.py #: members/models.py
#, python-format
msgid "Crisis intervention list for %(excursion)s from %(start)s to %(end)s" msgid "Crisis intervention list for %(excursion)s from %(start)s to %(end)s"
msgstr "Kriseninterventionsliste für %(excursion)s vom %(start)s bis %(end)s" msgstr "Kriseninterventionsliste für %(excursion)s vom %(start)s bis %(end)s"
@ -1213,11 +1202,11 @@ msgstr "Darf Teilnehmer*innen folgender Gruppen ändern"
msgid "May delete members of groups" msgid "May delete members of groups"
msgstr "Darf Teilnehmer*innen folgender Gruppen löschen" msgstr "Darf Teilnehmer*innen folgender Gruppen löschen"
#: members/models.py #: members/models.py members/tests/basic.py
msgid "Permissions" msgid "Permissions"
msgstr "Berechtigungen" msgstr "Berechtigungen"
#: members/models.py #: members/models.py members/tests/basic.py
msgid "Group permissions" msgid "Group permissions"
msgstr "Gruppenberechtigungen" msgstr "Gruppenberechtigungen"
@ -1266,19 +1255,25 @@ msgstr "Fortbildungen"
#: members/templates/admin/invite_for_group_text.html #: members/templates/admin/invite_for_group_text.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/templates/admin/request_registration_form.html
#: members/templates/admin/request_registratoin_form.html
msgid "Home" msgid "Home"
msgstr "Start" msgstr "Start"
#: members/templates/admin/demote_to_waiter.html #: members/templates/admin/demote_to_waiter.html
#: members/templates/admin/request_registration_form.html
#: members/templates/admin/request_registratoin_form.html
msgid "Demote to waiter" msgid "Demote to waiter"
msgstr "Zurück auf die Warteliste setzen" msgstr "Zurück auf die Warteliste setzen"
#: members/templates/admin/demote_to_waiter.html #: members/templates/admin/demote_to_waiter.html
#: members/templates/admin/request_registratoin_form.html
msgid "" msgid ""
"Do you want to demote the following unconfirmed registrations to waiters?" "Do you want to demote the following unconfirmed registrations to waiters?"
msgstr "Möchtest du die folgenden Personen zurück auf die Warteliste setzen?" msgstr "Möchtest du die folgenden Personen zurück auf die Warteliste setzen?"
#: members/templates/admin/demote_to_waiter.html #: members/templates/admin/demote_to_waiter.html
#: members/templates/admin/request_registratoin_form.html
msgid "Demote" msgid "Demote"
msgstr "Zurück auf die Warteliste setzen" msgstr "Zurück auf die Warteliste setzen"
@ -1289,6 +1284,8 @@ msgstr "Zurück auf die Warteliste setzen"
#: 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/templates/admin/request_registration_form.html
#: members/templates/admin/request_registratoin_form.html
msgid "Cancel" msgid "Cancel"
msgstr "Abbrechen" msgstr "Abbrechen"
@ -1515,7 +1512,8 @@ msgstr ""
msgid "Summary" msgid "Summary"
msgstr "Zusammenfassung" msgstr "Zusammenfassung"
#: members/templates/admin/freizeit_finance_overview.html members/tests.py #: members/templates/admin/freizeit_finance_overview.html
#: members/tests/basic.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."
@ -1611,7 +1609,7 @@ msgstr ""
"notwendig. Aus den Informationen, die du in der Ausfahrt angegeben hast, " "notwendig. Aus den Informationen, die du in der Ausfahrt angegeben hast, "
"kann automatisch ein solcher Antrag erstellt werden." "kann automatisch ein solcher Antrag erstellt werden."
#: members/templates/admin/generate_seminar_report.html members/tests.py #: members/templates/admin/generate_seminar_report.html members/tests/basic.py
msgid "A seminar report consists of multiple components:" msgid "A seminar report consists of multiple components:"
msgstr "Ein LJP Antrag besteht aus verschiedenen Komponenten:" msgstr "Ein LJP Antrag besteht aus verschiedenen Komponenten:"
@ -1646,7 +1644,7 @@ msgstr ""
"Eine Kosten- und Teilnehmendenübersicht. Dies ist nicht notwendig für den " "Eine Kosten- und Teilnehmendenübersicht. Dies ist nicht notwendig für den "
"eigentlichen Bericht, muss aber langfristig aufbewahrt werden." "eigentlichen Bericht, muss aber langfristig aufbewahrt werden."
#: members/templates/admin/generate_sjr_application.html members/tests.py #: members/templates/admin/generate_sjr_application.html members/tests/basic.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."
@ -1683,7 +1681,8 @@ 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/tests.py #: members/templates/admin/invite_selected_for_group.html
#: members/tests/basic.py
msgid "Invite" msgid "Invite"
msgstr "Einladen" msgstr "Einladen"
@ -1794,6 +1793,18 @@ msgstr "Anzahl Personen:"
msgid "thereof leaders:" msgid "thereof leaders:"
msgstr "davon Leitung:" msgstr "davon Leitung:"
#: members/templates/admin/request_registration_form.html
msgid "Request registration form"
msgstr "Anmeldeformular anfragen"
#: members/templates/admin/request_registration_form.html
msgid "Do you want to ask %(member)s to upload their registration form?"
msgstr "Möchtest du %(member)s auffordern das Anmeldeformular hochzuladen?"
#: members/templates/admin/request_registration_form.html
msgid "Warning: %(member)s has already uploaded a registration form."
msgstr "Warnung: %(member)s hat bereits ein Anmeldeformular hochgeladen."
#: members/templates/members/change_member.html #: members/templates/members/change_member.html
msgid "Participations:" msgid "Participations:"
msgstr "Ausfahrtteilnahmen:" msgstr "Ausfahrtteilnahmen:"
@ -1815,11 +1826,12 @@ msgid "Confirm invitation"
msgstr "Teilnahme bestätigen" msgstr "Teilnahme bestätigen"
#: members/templates/members/confirm_invalid.html #: members/templates/members/confirm_invalid.html
#: members/templates/members/reject_invalid.html members/tests.py #: members/templates/members/reject_invalid.html members/tests/basic.py
#: members/tests/views.py
msgid "This invitation is invalid or expired." msgid "This invitation is invalid or expired."
msgstr "Diese Einladung ist ungültig oder abgelaufen." msgstr "Diese Einladung ist ungültig oder abgelaufen."
#: members/templates/members/confirm_invitation.html #: members/templates/members/confirm_invitation.html members/tests/views.py
msgid "Confirm trial group meeting invitation" msgid "Confirm trial group meeting invitation"
msgstr "Teilnahme bestätigen" msgstr "Teilnahme bestätigen"
@ -1841,7 +1853,7 @@ msgstr ""
msgid "Confirm trial group meeting" msgid "Confirm trial group meeting"
msgstr "Teilnahme bestätigen" msgstr "Teilnahme bestätigen"
#: members/templates/members/confirm_success.html #: members/templates/members/confirm_success.html members/tests/views.py
msgid "Invitation confirmed" msgid "Invitation confirmed"
msgstr "Teilnahme bestätigt" msgstr "Teilnahme bestätigt"
@ -1874,7 +1886,7 @@ msgstr ""
msgid "Echo" msgid "Echo"
msgstr "Rückmeldung" msgstr "Rückmeldung"
#: members/templates/members/echo.html members/tests.py #: members/templates/members/echo.html members/tests/basic.py
msgid "" msgid ""
"Here is your current data. Please check if it is up to date and change " "Here is your current data. Please check if it is up to date and change "
"accordingly." "accordingly."
@ -1882,7 +1894,7 @@ msgstr ""
"Hier siehst du deine aktuellen Daten. Bitte überprüfe alles und passe es bei " "Hier siehst du deine aktuellen Daten. Bitte überprüfe alles und passe es bei "
"Bedarf an." "Bedarf an."
#: members/templates/members/echo_failed.html members/tests.py #: members/templates/members/echo_failed.html members/tests/basic.py
msgid "Echo failed" msgid "Echo failed"
msgstr "Rückmeldung fehlgeschlagen" msgstr "Rückmeldung fehlgeschlagen"
@ -1903,7 +1915,7 @@ msgstr "Wenn du denkst, dass das ein Fehler ist, "
msgid "contact us." msgid "contact us."
msgstr "kontaktiere uns." msgstr "kontaktiere uns."
#: members/templates/members/echo_password.html members/tests.py #: members/templates/members/echo_password.html members/tests/basic.py
msgid "" msgid ""
"Thanks for echoing back. Please enter the password, which you can find in " "Thanks for echoing back. Please enter the password, which you can find in "
"the email we sent you.\n" "the email we sent you.\n"
@ -1925,7 +1937,7 @@ msgstr "Rückmeldung erfolgreich"
msgid "Thank you" msgid "Thank you"
msgstr "Danke" msgstr "Danke"
#: members/templates/members/echo_success.html members/tests.py #: members/templates/members/echo_success.html members/tests/basic.py
msgid "Your data was successfully updated." msgid "Your data was successfully updated."
msgstr "Deine Daten wurden erfolgreich aktualisiert." msgstr "Deine Daten wurden erfolgreich aktualisiert."
@ -1936,7 +1948,7 @@ msgstr ""
"Jugendleiter nach einem korrekten Passwort." "Jugendleiter nach einem korrekten Passwort."
#: members/templates/members/invited_registration_failed.html #: members/templates/members/invited_registration_failed.html
#: members/templates/members/register_failed.html #: members/templates/members/register_failed.html members/tests/basic.py
msgid "Registration failed" msgid "Registration failed"
msgstr "Registrierung fehlgeschlagen" msgstr "Registrierung fehlgeschlagen"
@ -1952,7 +1964,7 @@ msgstr "Registrierung fehlgeschlagen"
msgid "Registration" msgid "Registration"
msgstr "Registrierung" msgstr "Registrierung"
#: members/templates/members/leave_waitinglist.html members/tests.py #: members/templates/members/leave_waitinglist.html members/tests/basic.py
msgid "Leave waitinglist" msgid "Leave waitinglist"
msgstr "Warteliste verlassen" msgstr "Warteliste verlassen"
@ -1969,7 +1981,8 @@ msgstr ""
msgid "Yes, leave the waitinglist" msgid "Yes, leave the waitinglist"
msgstr "Ja, Warteliste verlassen" msgstr "Ja, Warteliste verlassen"
#: members/templates/members/leave_waitinglist_success.html members/tests.py #: members/templates/members/leave_waitinglist_success.html
#: members/tests/basic.py
msgid "Left waitinglist" msgid "Left waitinglist"
msgstr "Warteliste verlassen" msgstr "Warteliste verlassen"
@ -1984,16 +1997,19 @@ msgstr ""
"einem späteren Zeitpunkt wieder auf die Warteliste setzen lassen möchtest " "einem späteren Zeitpunkt wieder auf die Warteliste setzen lassen möchtest "
"kannst du das auf unserer Webseite machen.\n" "kannst du das auf unserer Webseite machen.\n"
#: members/templates/members/mail_confirmation_invalid.html members/tests.py #: members/templates/members/mail_confirmation_invalid.html
#: members/tests/basic.py
msgid "Mail confirmation failed" msgid "Mail confirmation failed"
msgstr "Emailbestätigung fehlgeschlagen" msgstr "Emailbestätigung fehlgeschlagen"
#: members/templates/members/mail_confirmation_invalid.html #: members/templates/members/mail_confirmation_invalid.html
#: members/templates/members/waiting_confirmation_invalid.html members/tests.py #: members/templates/members/waiting_confirmation_invalid.html
#: members/tests/basic.py
msgid "The supplied link is invalid." msgid "The supplied link is invalid."
msgstr "Der verwendete Link ist ungültig." msgstr "Der verwendete Link ist ungültig."
#: members/templates/members/mail_confirmation_success.html members/tests.py #: members/templates/members/mail_confirmation_success.html
#: members/tests/basic.py
msgid "Mail confirmed" msgid "Mail confirmed"
msgstr "Emailadresse bestätigt" msgstr "Emailadresse bestätigt"
@ -2066,7 +2082,7 @@ msgstr "Registrieren"
msgid "Here you can register for group" msgid "Here you can register for group"
msgstr "Hier kannst du dich registrieren für die Gruppe" msgstr "Hier kannst du dich registrieren für die Gruppe"
#: members/templates/members/register_failed.html members/tests.py #: members/templates/members/register_failed.html members/tests/basic.py
msgid "Something went wrong while processing your registration." msgid "Something went wrong while processing your registration."
msgstr "Etwas ist schief gelaufen, bei der Verarbeitung deiner Registrierung." msgstr "Etwas ist schief gelaufen, bei der Verarbeitung deiner Registrierung."
@ -2129,7 +2145,7 @@ msgid "Registration for waiting list."
msgstr "Registrierung für die Warteliste." msgstr "Registrierung für die Warteliste."
#: members/templates/members/register_waiting_list_success.html #: members/templates/members/register_waiting_list_success.html
#: members/tests.py #: members/tests/basic.py
msgid "Your registration for the waiting list was successful." msgid "Your registration for the waiting list was successful."
msgstr "Du wurdest auf die Warteliste gesetzt." msgstr "Du wurdest auf die Warteliste gesetzt."
@ -2227,7 +2243,8 @@ msgstr ""
"zustimmst, unterschreibe bitte das Formular und lade hier einen Scan oder " "zustimmst, unterschreibe bitte das Formular und lade hier einen Scan oder "
"ein Bild hoch." "ein Bild hoch."
#: members/templates/members/upload_registration_form.html members/tests.py #: members/templates/members/upload_registration_form.html
#: members/tests/basic.py
msgid "" msgid ""
"If you are not an adult yet, please let someone responsible for you sign the " "If you are not an adult yet, please let someone responsible for you sign the "
"agreement." "agreement."
@ -2240,7 +2257,7 @@ msgid "Upload"
msgstr "Hochladen" msgstr "Hochladen"
#: members/templates/members/upload_registration_form_invalid.html #: members/templates/members/upload_registration_form_invalid.html
#: members/tests.py #: members/tests/basic.py
msgid "The supplied key for uploading a registration form is invalid." msgid "The supplied key for uploading a registration form is invalid."
msgstr "Der verwendete Link zum Hochladen eines Anmeldeformulars ist ungültig." msgstr "Der verwendete Link zum Hochladen eines Anmeldeformulars ist ungültig."
@ -2249,7 +2266,7 @@ msgid "Thank you for uploading the registration form."
msgstr "Danke für das Hochladen des Anmeldeformulars." msgstr "Danke für das Hochladen des Anmeldeformulars."
#: members/templates/members/upload_registration_form_success.html #: members/templates/members/upload_registration_form_success.html
#: members/tests.py #: members/tests/basic.py
msgid "Our team will process your registration shortly." msgid "Our team will process your registration shortly."
msgstr "" msgstr ""
"Unser Jugendleiter*innenteam wird deine Registrierung so schnell wie möglich " "Unser Jugendleiter*innenteam wird deine Registrierung so schnell wie möglich "
@ -2267,11 +2284,13 @@ msgstr ""
"Leider hast du deinen Wartelistenplatz nicht rechtzeitig bestätigt und hast " "Leider hast du deinen Wartelistenplatz nicht rechtzeitig bestätigt und hast "
"somit deinen Platz verloren. Du kannst" "somit deinen Platz verloren. Du kannst"
#: members/templates/members/waiting_confirmation_invalid.html members/tests.py #: members/templates/members/waiting_confirmation_invalid.html
#: members/tests/basic.py
msgid "rejoin the waiting list" msgid "rejoin the waiting list"
msgstr "der Warteliste erneut beitreten" msgstr "der Warteliste erneut beitreten"
#: members/templates/members/waiting_confirmation_success.html members/tests.py #: members/templates/members/waiting_confirmation_success.html
#: members/tests/basic.py
msgid "Waiting confirmed" msgid "Waiting confirmed"
msgstr "Wartelistenplatz bestätigt" msgstr "Wartelistenplatz bestätigt"
@ -2293,19 +2312,19 @@ msgstr ""
"Danke %(prename)s für dein Interesse auf der Warteliste zu bleiben.\n" "Danke %(prename)s für dein Interesse auf der Warteliste zu bleiben.\n"
"Dein Platz wurde bestätigt." "Dein Platz wurde bestätigt."
#: members/tests.py #: members/tests/basic.py
msgid "This field is required." msgid "This field is required."
msgstr "" msgstr ""
#: members/tests.py members/views.py #: members/tests/basic.py members/views.py
msgid "The entered password is wrong." msgid "The entered password is wrong."
msgstr "Das eingegebene Passwort ist falsch." msgstr "Das eingegebene Passwort ist falsch."
#: members/tests.py members/views.py #: members/tests/basic.py members/views.py
msgid "invalid" msgid "invalid"
msgstr "ungültig" msgstr "ungültig"
#: members/tests.py members/views.py #: members/tests/basic.py members/views.py
msgid "expired" msgid "expired"
msgstr "abgelaufen" msgstr "abgelaufen"
@ -2335,6 +2354,22 @@ msgstr "Optionale zusätzliche E-Mailadresse"
msgid "Invalid emergency contacts" msgid "Invalid emergency contacts"
msgstr "Ungültige Notfallkontakte" msgstr "Ungültige Notfallkontakte"
#~ msgid "True"
#~ msgstr "Ja"
#~ msgid "False"
#~ msgstr "Nein"
#~ msgid "All"
#~ msgstr "Alle"
#~ msgid "Inform youth leaders about sending of crisis intervention list."
#~ msgstr ""
#~ "Informiere Jugendleiter:innen über Versand der Kriseninterventionsliste."
#~ msgid "Send crisis intervention list."
#~ msgstr "Kriseninterventionsliste verschicken"
#~ 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 "

@ -595,6 +595,11 @@ class Member(Person):
settings.UPLOAD_REGISTRATION_FORM_TEXT.format(name=self.prename, settings.UPLOAD_REGISTRATION_FORM_TEXT.format(name=self.prename,
link=link)) link=link))
def request_registration_form(self):
"""Ask the member to upload a registration form via email."""
self.generate_upload_registration_form_key()
self.send_upload_registration_form_link()
def notify_jugendleiters_about_confirmed_mail(self): def notify_jugendleiters_about_confirmed_mail(self):
group = ", ".join([g.name for g in self.group.all()]) group = ", ".join([g.name for g in self.group.all()])
# notify jugendleiters of group of registration # notify jugendleiters of group of registration

@ -0,0 +1,40 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static %}
{% block extrahead %}
{{ block.super }}
{{ media }}
<script src="{% static 'admin/js/cancel.js' %}" async></script>
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} invite-waiter
{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
&rsaquo; {% translate 'Demote to waiter' %}
</div>
{% endblock %}
{% block content %}
<h2>{% translate "Request registration form" %}</h2>
<p>
{% blocktrans %}Do you want to ask {{ member }} to upload their registration form?{% endblocktrans %}
</p>
<p>
{% if member.registration_form %}
{% blocktrans %}Warning: {{ member }} has already uploaded a registration form.{% endblocktrans %}
{% endif %}
</p>
<form action="" method="post">
{% csrf_token %}
<input class="default" style="color: $default-link-color" type="submit" name="apply" value="{% translate 'Request registration form' %}">
<a href="#" class="button cancel-link">{% translate "Cancel" %}</a>
</form>
{% endblock %}

@ -0,0 +1,48 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static %}
{% block extrahead %}
{{ block.super }}
{{ media }}
<script src="{% static 'admin/js/cancel.js' %}" async></script>
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} invite-waiter
{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
&rsaquo; {% translate 'Demote to waiter' %}
</div>
{% endblock %}
{% block content %}
<h2>{% translate "Demote to waiter" %}</h2>
<p>
{% trans "Do you want to demote the following unconfirmed registrations to waiters?" %}
</p>
<p>
<ul>
{% for member in queryset %}
<li>
<a href="{% url 'admin:members_memberunconfirmedproxy_change' 3 %}">{{ member }}</a>
</li>
{% endfor %}
</ul>
</p>
<form action="" method="post">
{% csrf_token %}
{% if form %}
{{form}}
{% endif %}
<input type="hidden" name="action" value="demote_to_waiter_action">
<input class="default" style="color: $default-link-color" type="submit" name="apply" value="{% translate 'Demote' %}">
<a href="#" class="button cancel-link">{% translate "Cancel" %}</a>
</form>
{% endblock %}

@ -1423,6 +1423,28 @@ class MemberUnconfirmedAdminTestCase(AdminTestCase):
qs = self.admin.get_queryset(request) qs = self.admin.get_queryset(request)
self.assertQuerysetEqual(qs, MemberUnconfirmedProxy.objects.none(), ordered=False) self.assertQuerysetEqual(qs, MemberUnconfirmedProxy.objects.none(), ordered=False)
def test_request_registration_form_invalid(self):
c = self._login('standard')
url = reverse('admin:members_memberunconfirmedproxy_request_registration_form', args=(124,))
response = c.get(url)
self.assertEqual(response.status_code, HTTPStatus.FOUND)
def test_request_registration_form_insuficient_permission(self):
c = self._login('standard')
url = reverse('admin:members_memberunconfirmedproxy_request_registration_form', args=(self.reg.pk,))
response = c.get(url, follow=True)
self.assertEqual(response.status_code, HTTPStatus.FORBIDDEN)
def test_request_registration_form(self):
c = self._login('superuser')
url = reverse('admin:members_memberunconfirmedproxy_request_registration_form', args=(self.reg.pk,))
response = c.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Request registration form'))
response = c.post(url, data={'apply': ''})
self.assertEqual(response.status_code, HTTPStatus.FOUND)
def test_demote_to_waiter(self): def test_demote_to_waiter(self):
c = self._login('superuser') c = self._login('superuser')
url = reverse('admin:members_memberunconfirmedproxy_demote', args=(self.reg.pk,)) url = reverse('admin:members_memberunconfirmedproxy_demote', args=(self.reg.pk,))

@ -183,8 +183,7 @@ def echo(request):
member.save() member.save()
if not member.registration_form: if not member.registration_form:
# If the member does not have a registration form, forward them to the upload page. # If the member does not have a registration form, forward them to the upload page.
member.generate_upload_registration_form_key() member.request_registration_form()
member.send_upload_registration_form_link()
return HttpResponseRedirect(reverse('members:upload_registration_form') + "?key=" + member.upload_registration_form_key) return HttpResponseRedirect(reverse('members:upload_registration_form') + "?key=" + member.upload_registration_form_key)
else: else:
return render_echo_success(request, member.prename) return render_echo_success(request, member.prename)

@ -3,6 +3,11 @@
{% block object-tools-items %} {% block object-tools-items %}
<li>
{% url opts|admin_urlname:'request_registration_form' original.pk|admin_urlquote as request_url %}
<a class="historylink" href="{% add_preserved_filters request_url %}">{% trans 'Request registration form' %}</a>
</li>
<li> <li>
{% url opts|admin_urlname:'demote' original.pk|admin_urlquote as demote_url %} {% url opts|admin_urlname:'demote' original.pk|admin_urlquote as demote_url %}
<a class="historylink" href="{% add_preserved_filters demote_url %}">{% trans 'Demote to waiter' %}</a> <a class="historylink" href="{% add_preserved_filters demote_url %}">{% trans 'Demote to waiter' %}</a>

Loading…
Cancel
Save