members registration: send notification to group leiters when mails are confirmed

v1-0-stable
Christian Merten 3 years ago
parent eedb2ec862
commit 23770288f6
Signed by: christian.merten
GPG Key ID: D953D69721B948B3

@ -5,6 +5,8 @@ import os
NOT_SENT, SENT, PARTLY_SENT = 0, 1, 2 NOT_SENT, SENT, PARTLY_SENT = 0, 1, 2
HOST = os.environ.get('DJANGO_ALLOWED_HOST', 'localhost:8000').split(",")[0] HOST = os.environ.get('DJANGO_ALLOWED_HOST', 'localhost:8000').split(",")[0]
PROTOCOL = os.environ.get('DJANGO_PROTOCOL', 'https')
BASE_URL = os.environ.get('DJANGO_BASE_URL', HOST)
def send(subject, content, sender, recipients, message_id=None, reply_to=None, def send(subject, content, sender, recipients, message_id=None, reply_to=None,
@ -46,7 +48,7 @@ def send(subject, content, sender, recipients, message_id=None, reply_to=None,
def get_content(content, registration_complete=True): def get_content(content, registration_complete=True):
url = "https://{}/newsletter/unsubscribe".format(HOST) url = prepend_base_url("/newsletter/unsubscribe")
prepend = "WICHTIGE MITTEILUNG\n\n"\ prepend = "WICHTIGE MITTEILUNG\n\n"\
"Deine Anmeldung ist aktuell nicht vollständig. Bitte fülle umgehend das"\ "Deine Anmeldung ist aktuell nicht vollständig. Bitte fülle umgehend das"\
" Anmeldeformular aus und lasse es Deine*r Jugendleiter*in zukommen! Dieses"\ " Anmeldeformular aus und lasse es Deine*r Jugendleiter*in zukommen! Dieses"\
@ -62,16 +64,20 @@ def get_content(content, registration_complete=True):
def get_unsubscribe_link(member): def get_unsubscribe_link(member):
key = member.generate_key() key = member.generate_key()
return "https://{}/newsletter/unsubscribe?key={}".format(HOST, key) return prepend_base_url("/newsletter/unsubscribe?key={}".format(key))
def get_echo_link(member): def get_echo_link(member):
key = member.generate_echo_key() key = member.generate_echo_key()
return "https://{}/members/echo?key={}".format(HOST, key) return prepend_base_url("/members/echo?key={}".format(key))
def get_mail_confirmation_link(key): def get_mail_confirmation_link(key):
return "https://{}/members/mail/confirm?key={}".format(HOST, key) return prepend_base_url("/members/mail/confirm?key={}".format(key))
def prepend_base_url(absolutelink):
return "{protocol}://{base}{link}".format(protocol=PROTOCOL, base=BASE_URL, link=absolutelink)
mail_root = os.environ.get('EMAIL_SENDING_ADDRESS', 'christian@localhost') mail_root = os.environ.get('EMAIL_SENDING_ADDRESS', 'christian@localhost')

@ -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: 2022-10-03 23:57+0200\n" "POT-Creation-Date: 2022-10-06 11:38+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,7 +18,7 @@ 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:33 members/models.py:88 #: members/admin.py:33 members/models.py:89
msgid "Registration complete" msgid "Registration complete"
msgstr "Anmeldung vollständig" msgstr "Anmeldung vollständig"
@ -53,7 +53,7 @@ msgstr "Aktivität"
#: members/admin.py:190 #: members/admin.py:190
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."
#: members/admin.py:191 #: members/admin.py:191
msgid "Request mail confirmation from selected registrations" msgid "Request mail confirmation from selected registrations"
@ -104,242 +104,247 @@ msgstr "Hinweise für Jugendleiter erstellen"
msgid "Generate list for LJP" msgid "Generate list for LJP"
msgstr "LJP Liste erstellen" msgstr "LJP Liste erstellen"
#: members/apps.py:7 members/models.py:240 #: members/apps.py:7 members/models.py:256
msgid "members" msgid "members"
msgstr "Teilnehmer" msgstr "Teilnehmer"
#: members/models.py:27 #: members/models.py:28
msgid "Name" msgid "Name"
msgstr "Name" msgstr "Name"
#: members/models.py:28 #: members/models.py:29
msgid "Description" msgid "Description"
msgstr "Beschreibung" msgstr "Beschreibung"
#: members/models.py:34 members/models.py:285 members/models.py:364 #: members/models.py:35 members/models.py:301 members/models.py:380
#: members/templates/members/change_member.html:17 #: members/templates/members/change_member.html:17
msgid "Activity" msgid "Activity"
msgstr "Aktivität" msgstr "Aktivität"
#: members/models.py:35 #: members/models.py:36
msgid "Activities" msgid "Activities"
msgstr "Aktivitäten" msgstr "Aktivitäten"
#: members/models.py:43 #: members/models.py:44
msgid "name" msgid "name"
msgstr "Name" msgstr "Name"
#: members/models.py:44 #: members/models.py:45
msgid "lowest year" msgid "lowest year"
msgstr "Ab Jahrgang" msgstr "Ab Jahrgang"
#: members/models.py:45 #: members/models.py:46
msgid "highest year" msgid "highest year"
msgstr "Bis Jahrgang" msgstr "Bis Jahrgang"
#: members/models.py:46 #: members/models.py:47
msgid "youth leaders" msgid "youth leaders"
msgstr "Jugendleiter" msgstr "Jugendleiter"
#: members/models.py:54 members/models.py:81 #: members/models.py:55 members/models.py:82
msgid "group" msgid "group"
msgstr "Gruppe" msgstr "Gruppe"
#: members/models.py:55 #: members/models.py:56
msgid "groups" msgid "groups"
msgstr "Gruppen" msgstr "Gruppen"
#: members/models.py:68 #: members/models.py:69
msgid "prename" msgid "prename"
msgstr "Vorname" msgstr "Vorname"
#: members/models.py:69 #: members/models.py:70
msgid "last name" msgid "last name"
msgstr "Nachname" msgstr "Nachname"
#: members/models.py:62 #: members/models.py:71
msgid "street and house number" msgid "street and house number"
msgstr "Straße und Hausnummer" msgstr "Straße und Hausnummer"
#: members/models.py:71 #: members/models.py:72
msgid "Postcode" msgid "Postcode"
msgstr "PLZ" msgstr "PLZ"
#: members/models.py:73 #: members/models.py:74
msgid "town" msgid "town"
msgstr "Stadt" msgstr "Stadt"
#: members/models.py:74 #: members/models.py:75
msgid "phone number" msgid "phone number"
msgstr "Telefonnummer" msgstr "Telefonnummer"
#: members/models.py:75 #: members/models.py:76
msgid "parents phone number" msgid "parents phone number"
msgstr "Telefonnummer der Eltern" msgstr "Telefonnummer der Eltern"
#: members/models.py:78 #: members/models.py:79
msgid "Parents' Email" msgid "Parents' Email"
msgstr "Email der Eltern" msgstr "Email der Eltern"
#: members/models.py:79 #: members/models.py:80
msgid "Also send mails to parents" msgid "Also send mails to parents"
msgstr "Emails auch an Eltern schicken" msgstr "Emails auch an Eltern schicken"
#: members/models.py:80 #: members/models.py:81
msgid "birth date" msgid "birth date"
msgstr "Geburtsdatum" msgstr "Geburtsdatum"
#: members/models.py:82 #: members/models.py:83
msgid "receives newsletter" msgid "receives newsletter"
msgstr "Erhält den Newsletter" msgstr "Erhält den Newsletter"
#: members/models.py:86 #: members/models.py:87
msgid "comments" msgid "comments"
msgstr "Kommentare" msgstr "Kommentare"
#: members/models.py:87 #: members/models.py:88
msgid "created" msgid "created"
msgstr "erstellt" msgstr "erstellt"
#: members/models.py:89 #: members/models.py:90
msgid "Active" msgid "Active"
msgstr "Aktiv" msgstr "Aktiv"
#: members/models.py:90 #: members/models.py:91
msgid "Not waiting" msgid "Not waiting"
msgstr "NICHT Warteliste" msgstr "NICHT Warteliste"
#: members/models.py:91 #: members/models.py:92
msgid "registration form" msgid "registration form"
msgstr "Anmeldeformular" msgstr "Anmeldeformular"
#: members/models.py:101 #: members/models.py:102
msgid "Echoed" msgid "Echoed"
msgstr "Rückgemeldet" msgstr "Rückgemeldet"
#: members/models.py:102 #: members/models.py:103
msgid "Confirmed" msgid "Confirmed"
msgstr "Bestätigt" msgstr "Bestätigt"
#: members/models.py:103 #: members/models.py:104
msgid "Email confirmed" msgid "Email confirmed"
msgstr "Emailadresse bestätigt" msgstr "Emailadresse bestätigt"
#: members/models.py:104 #: members/models.py:105
msgid "Parents email confirmed" msgid "Parents email confirmed"
msgstr "Emailadresse der Eltern bestätigt" msgstr "Emailadresse der Eltern bestätigt"
#: members/models.py:137 members/models.py:147 #: members/models.py:138 members/models.py:148
msgid "Email confirmation" msgid "Email confirmation needed"
msgstr "Email Bestätigung" msgstr "Email Bestätigung erforderlich"
#: members/models.py:176
#, python-format
msgid "New unconfirmed registration for group %(group)s"
msgstr "Neue unbestätigte Registrierung für Gruppe %(group)s"
#: members/models.py:236 members/models.py:446 #: members/models.py:252 members/models.py:462
msgid "Group" msgid "Group"
msgstr "Gruppe" msgstr "Gruppe"
#: members/models.py:239 #: members/models.py:255
msgid "member" msgid "member"
msgstr "Teilnehmer" msgstr "Teilnehmer"
#: members/models.py:270 #: members/models.py:286
msgid "Unconfirmed registration" msgid "Unconfirmed registration"
msgstr "Unbestätigte Registrierung" msgstr "Unbestätigte Registrierung"
#: members/models.py:271 #: members/models.py:287
msgid "Unconfirmed registrations" msgid "Unconfirmed registrations"
msgstr "Unbestätigte Registrierungen" msgstr "Unbestätigte Registrierungen"
#: members/models.py:287 members/models.py:366 #: members/models.py:303 members/models.py:382
msgid "Place" msgid "Place"
msgstr "Ort" msgstr "Ort"
#: members/models.py:288 members/models.py:367 #: members/models.py:304 members/models.py:383
msgid "Destination (optional)" msgid "Destination (optional)"
msgstr "Ziel (optional)" msgstr "Ziel (optional)"
#: members/models.py:290 members/models.py:369 members/models.py:424 #: members/models.py:306 members/models.py:385 members/models.py:440
#: members/models.py:442 #: members/models.py:458
msgid "Date" msgid "Date"
msgstr "Datum" msgstr "Datum"
#: members/models.py:291 members/models.py:370 #: members/models.py:307 members/models.py:386
msgid "End (optional)" msgid "End (optional)"
msgstr "Ende" msgstr "Ende"
#: members/models.py:293 members/models.py:372 #: members/models.py:309 members/models.py:388
msgid "Groups" msgid "Groups"
msgstr "Gruppen" msgstr "Gruppen"
#: members/models.py:301 members/models.py:385 #: members/models.py:317 members/models.py:401
msgid "Categories" msgid "Categories"
msgstr "Kategorien" msgstr "Kategorien"
#: members/models.py:302 members/models.py:386 #: members/models.py:318 members/models.py:402
msgid "easy" msgid "easy"
msgstr "leicht" msgstr "leicht"
#: members/models.py:302 members/models.py:386 #: members/models.py:318 members/models.py:402
msgid "medium" msgid "medium"
msgstr "mittel" msgstr "mittel"
#: members/models.py:302 members/models.py:386 #: members/models.py:318 members/models.py:402
msgid "hard" msgid "hard"
msgstr "schwer" msgstr "schwer"
#: members/models.py:311 #: members/models.py:327
msgid "Memberlist" msgid "Memberlist"
msgstr "Teilnehmerliste" msgstr "Teilnehmerliste"
#: members/models.py:312 #: members/models.py:328
msgid "Memberlists" msgid "Memberlists"
msgstr "Teilnehmerlisten" msgstr "Teilnehmerlisten"
#: members/models.py:330 members/models.py:338 members/models.py:346 #: members/models.py:346 members/models.py:354 members/models.py:362
#: members/models.py:357 members/models.py:477 members/models.py:484 #: members/models.py:373 members/models.py:493 members/models.py:500
msgid "Member" msgid "Member"
msgstr "Teilnehmer" msgstr "Teilnehmer"
#: members/models.py:332 members/models.py:351 #: members/models.py:348 members/models.py:367
msgid "Comment" msgid "Comment"
msgstr "Kommentar" msgstr "Kommentar"
#: members/models.py:339 members/models.py:358 members/models.py:485 #: members/models.py:355 members/models.py:374 members/models.py:501
msgid "Members" msgid "Members"
msgstr "Teilnehmer" msgstr "Teilnehmer"
#: members/models.py:423 #: members/models.py:439
msgid "Title" msgid "Title"
msgstr "Titel" msgstr "Titel"
#: members/models.py:443 #: members/models.py:459
msgid "Location" msgid "Location"
msgstr "Ort" msgstr "Ort"
#: members/models.py:444 #: members/models.py:460
msgid "Topic" msgid "Topic"
msgstr "Thema" msgstr "Thema"
#: members/models.py:468 #: members/models.py:484
msgid "Jugendleiter" msgid "Jugendleiter"
msgstr "Jugendleiter" msgstr "Jugendleiter"
#: members/models.py:471 #: members/models.py:487
msgid "Klettertreff" msgid "Klettertreff"
msgstr "Klettertreff" msgstr "Klettertreff"
#: members/models.py:472 #: members/models.py:488
msgid "Klettertreffs" msgid "Klettertreffs"
msgstr "Klettertreffs" msgstr "Klettertreffs"
#: members/models.py:490 #: members/models.py:506
msgid "Password" msgid "Password"
msgstr "Passwort" msgstr "Passwort"
#: members/models.py:493 #: members/models.py:509
msgid "registration password" msgid "registration password"
msgstr "Registrierungspassort" msgstr "Registrierungspassort"
#: members/models.py:494 #: members/models.py:510
msgid "registration passwords" msgid "registration passwords"
msgstr "Registrierungspasswörter" msgstr "Registrierungspasswörter"
@ -467,8 +472,9 @@ msgstr "Ich bin Mitglied des DAV Ludwigsburg."
msgid "" msgid ""
"I agree that my data is stored and processed on the server of the JDAV " "I agree that my data is stored and processed on the server of the JDAV "
"Ludwigsburg." "Ludwigsburg."
msgstr "Ich bin einverstanden, dass meine Daten auf dem Server der JDAV " msgstr ""
"Ludwigsburg gespeichert und verarbeitet werden." "Ich bin einverstanden, dass meine Daten auf dem Server der JDAV Ludwigsburg "
"gespeichert und verarbeitet werden."
#: members/templates/members/register_password.html:13 #: members/templates/members/register_password.html:13
msgid "" msgid ""

@ -10,7 +10,8 @@ from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelatio
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from utils import RestrictedFileField from utils import RestrictedFileField
import os import os
from mailer.mailutils import send as send_mail, mail_root, get_mail_confirmation_link from mailer.mailutils import send as send_mail, mail_root, get_mail_confirmation_link,\
prepend_base_url
from django.contrib.auth.models import User from django.contrib.auth.models import User
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@ -134,7 +135,7 @@ class Member(models.Model):
self.confirmed_mail = False self.confirmed_mail = False
self.confirm_mail_key = uuid.uuid4().hex self.confirm_mail_key = uuid.uuid4().hex
group = ", ".join([g.name for g in self.group.all()]) group = ", ".join([g.name for g in self.group.all()])
send_mail(_('Email confirmation'), send_mail(_('Email confirmation needed'),
CONFIRM_MAIL_TEXT.format(name=self.prename, CONFIRM_MAIL_TEXT.format(name=self.prename,
group=group, group=group,
link=get_mail_confirmation_link(self.confirm_mail_key), link=get_mail_confirmation_link(self.confirm_mail_key),
@ -144,7 +145,7 @@ class Member(models.Model):
if self.email_parents: if self.email_parents:
self.confirmed_mail_parents = False self.confirmed_mail_parents = False
self.confirm_mail_parents_key = uuid.uuid4().hex self.confirm_mail_parents_key = uuid.uuid4().hex
send_mail(_('Email confirmation'), send_mail(_('Email confirmation needed'),
CONFIRM_MAIL_TEXT.format(name=self.prename, CONFIRM_MAIL_TEXT.format(name=self.prename,
group=group, group=group,
link=get_mail_confirmation_link(self.confirm_mail_parents_key), link=get_mail_confirmation_link(self.confirm_mail_parents_key),
@ -156,14 +157,29 @@ class Member(models.Model):
self.save() self.save()
def confirm_mail(self, key): def confirm_mail(self, key):
parents = False
email = None
if self.confirm_mail_key == key: if self.confirm_mail_key == key:
self.confirm_mail_key, self.confirmed_mail = "", True self.confirm_mail_key, self.confirmed_mail = "", True
self.save() email, parents = self.email, False
return (self.email, False)
elif self.confirm_mail_parents_key == key: elif self.confirm_mail_parents_key == key:
self.confirm_mail_parents_key, self.confirmed_mail_parents = "", True self.confirm_mail_parents_key, self.confirmed_mail_parents = "", True
self.save() email, parents = self.email_parents, True
return (self.email_parents, True) self.save()
if self.confirmed_mail_parents and self.confirmed_mail and not self.confirmed:
group = ", ".join([g.name for g in self.group.all()])
# notify jugendleiters of group of registration
jls = [jl for group in self.group.all() for jl in group.leiters.all()]
for jl in jls:
link = prepend_base_url(reverse('admin:members_memberunconfirmedproxy_change',
args=[str(self.id)]))
send_mail(_('New unconfirmed registration for group %(group)s') % {'group': group},
NEW_UNCONFIRMED_REGISTRATION.format(name=jl.prename,
group=group,
link=link),
mail_root,
jl.email)
return (email, parents)
def confirm(self): def confirm(self):
if not self.confirmed_mail or not self.confirmed_mail_parents: if not self.confirmed_mail or not self.confirmed_mail_parents:
@ -591,5 +607,16 @@ folgenden Link:
{link} {link}
Viele Grüße, Viele Grüße
Deine JDAV Ludwigsburg""" Deine JDAV Ludwigsburg"""
NEW_UNCONFIRMED_REGISTRATION = """Hallo {name},
für deine Gruppe {group} liegt eine neue unbestätigte Reservierung vor. Die Person hat bereits ihre
E-Mailadressen bestätigt. Bitte prüfe die Registrierung eingehend und bestätige falls möglich. Zu
der Registrierung kommst du hier:
{link}
Viele Grüße
Dein KOMPASS"""

@ -2,7 +2,7 @@ from django.shortcuts import render
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.forms import ModelForm, TextInput, DateInput from django.forms import ModelForm, TextInput, DateInput
from members.models import Member, RegistrationPassword from members.models import Member, RegistrationPassword, MemberUnconfirmedProxy
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
@ -137,7 +137,8 @@ def register(request):
def confirm_mail(request): def confirm_mail(request):
if request.method == 'GET' and 'key' in request.GET: if request.method == 'GET' and 'key' in request.GET:
key = request.GET['key'] key = request.GET['key']
res = Member.objects.filter(confirm_mail_key=key) | Member.objects.filter(confirm_mail_parents_key=key) res = MemberUnconfirmedProxy.objects.filter(confirm_mail_key=key) \
| MemberUnconfirmedProxy.objects.filter(confirm_mail_parents_key=key)
if len(res) != 1: if len(res) != 1:
return render_mail_confirmation_invalid(request) return render_mail_confirmation_invalid(request)
member = res[0] member = res[0]

Loading…
Cancel
Save