diff --git a/dav_registration/__init__.py b/dav_registration/__init__.py new file mode 100644 index 0000000..2d6cb8c --- /dev/null +++ b/dav_registration/__init__.py @@ -0,0 +1 @@ +default_app_config = 'dav_registration.apps.AppConfig' diff --git a/dav_registration/admin.py b/dav_registration/admin.py new file mode 100644 index 0000000..b7617c8 --- /dev/null +++ b/dav_registration/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin + +from .models import Registration + + +@admin.register(Registration) +class RegistrationAdmin(admin.ModelAdmin): + pass diff --git a/dav_registration/apps.py b/dav_registration/apps.py new file mode 100644 index 0000000..e121790 --- /dev/null +++ b/dav_registration/apps.py @@ -0,0 +1,17 @@ +from django.core.exceptions import ImproperlyConfigured + +from dav_base.config.apps import AppConfig as _AppConfig, DefaultSetting + +DEFAULT_SETTINGS = ( + DefaultSetting('privacy_policy', ImproperlyConfigured), +) + + +class AppConfig(_AppConfig): + name = 'dav_registration' + verbose_name = u'DAV Kurs-Anmeldungen' + default_settings = DEFAULT_SETTINGS + + def ready(self): + from . import signals + signals.registration_created.connect(signals.send_emails_on_registration) diff --git a/dav_registration/django_project_config/settings-dav_registration.py b/dav_registration/django_project_config/settings-dav_registration.py new file mode 100644 index 0000000..ea415aa --- /dev/null +++ b/dav_registration/django_project_config/settings-dav_registration.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +PRIVACY_POLICY = u"""Im Rahmen deiner Anmeldung werden eine Reihe von Daten erhoben, verarbeitet und gespeichert. +Wofür werden diese Daten benötigt? +Zunächst muss die Tourenleitung entscheiden, ob du die erforderlichen Anforderungen zur Teilnahme an der jeweiligen\ + Veranstaltung erfüllst. Dazu muss die Tourenleitung ein paar Informationen über dich haben und dich gegebenenfalls\ + für Rückfragen kontaktieren können. +Wenn für die Veranstaltung ein Teilnehmerbeitrag erhoben wird, dann benötigt auch die Geschäftstelle der Sektion\ + Karlsruhe eine Teilnehmerliste um die Zahlungseingänge zuordnen zu können. +Und für den unwahrscheinlichen Fall, dass bei der Veranstaltung etwas schief geht, kann eine Liste mit Teilnehmerdaten\ + und deren Notfall-Kontakten natürlich notwendig werden. +Letzlich müssen wir als Veranstalter irgendwie wissen, wer mit uns unterwegs ist. + +Wer verarbeitet die Daten? +Da die Anmeldedaten per E-Mail an die Tourenleitung übermittelt werden, sind in die Datenverarbeitung auch\ + EDV-Systeme privater Internetdiensteanbierter involviert. Hierauf haben wir keinen Einfluss. +Ebenso werden die Anmeldedaten an die von dir angegebene E-Mail-Adresse gesendet. Auch hierbei sind eventuell\ + Dritte beteiligt (z.B. dein E-Mail- oder Internetprovider). +Ansonsten erfolgt die Datenverarbeitung und Speicherung durch haupt- und ehrenamtliche Mitarbeiter der\ + Sektion Karlsruhe des Deutschen Alpenvereins (DAV) e.V. + +Was geschieht mit den Daten? +Die gespeicherten Daten werden ausschließlich zu Zwecken verwendet, die zur ordnungsgemäßen Durchführung der\ + jeweiligen Veranstaltung notwendig sind. +Nach Beendigung der Veranstaltung, Erfüllung aller Pflichten und organisatorischem Abschluss der Veranstaltung\ + werden die gespeicherten Daten gelöscht. +""" + diff --git a/dav_registration/emails.py b/dav_registration/emails.py new file mode 100644 index 0000000..74f6c9c --- /dev/null +++ b/dav_registration/emails.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +from dav_base.emails import AbstractMail + + +class AbstractRegistrationMail(AbstractMail): + def __init__(self, recipient, registration): + self._recipient = recipient + self._registration = registration + self._event = registration.event + + def _get_subject(self, subject_fmt=None, **kwargs): + if subject_fmt is None: + subject_fmt = self._subject + + if self._event.number: + subject_fmt = u'%s: %s' % (self._event.number, subject_fmt) + + return super(AbstractRegistrationMail, self)._get_subject(subject_fmt=subject_fmt, **kwargs) + + def _get_recipients(self): + if hasattr(self._recipient, 'get_full_name') and hasattr(self._recipient, 'email'): + r = u'"{fullname}" <{email}>'.format(fullname=self._recipient.get_full_name(), + email=self._recipient.email) + else: + r = self._recipient + return [r] + + def _get_context_data(self, extra_context=None): + context = super(AbstractRegistrationMail, self)._get_context_data(extra_context=extra_context) + context['recipient'] = self._recipient + context['registration'] = self._registration + context['event'] = self._event + return context + + +class InformTrainerRegistrationMail(AbstractRegistrationMail): + _subject = u'Anmeldung' + _template_name = 'dav_registration/emails/inform_trainer.txt' + + def _get_reply_to(self): + s = u'"{fullname}" <{email}>'.format(fullname=self._registration.get_full_name(), + email=self._registration.email_address) + return [s] + + +class InformSelfRegistrationMail(AbstractRegistrationMail): + _subject = u'Deine Anmeldung' + _template_name = 'dav_registration/emails/inform_self.txt' + + def _get_reply_to(self): + s = u'"{fullname}" <{email}>'.format(fullname=self._event.owner.get_full_name(), + email=self._event.owner.email) + return [s] diff --git a/dav_registration/forms.py b/dav_registration/forms.py new file mode 100644 index 0000000..e890d3b --- /dev/null +++ b/dav_registration/forms.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +import logging +from django import forms +from django.utils.translation import ugettext, ugettext_lazy as _ + +from .models import Registration + +logger = logging.getLogger(__name__) + + +class RegistrationForm(forms.ModelForm): + class Meta: + model = Registration + exclude = ['event', 'created_at', 'privacy_policy', 'purge_at'] + widgets = { + 'emergency_contact': forms.Textarea(attrs={'rows': 4}), + 'experience': forms.Textarea(attrs={'rows': 5}), + 'note': forms.Textarea(attrs={'rows': 5}), + } + + def clean_experience(self): + val = self.cleaned_data.get('experience') + if val == '': + need_experience = True + if self.instance.event.sport == 'W': + need_experience = False + if need_experience: + raise forms.ValidationError( + ugettext(u'Die Tourenleiter*innen brauchen ein paar Angaben,' + u' was du bereits kannst oder wie fit du bist.'), + code='need_experience', + ) + return val + + def clean_privacy_policy_accepted(self): + val = self.cleaned_data.get('privacy_policy_accepted') + if not val and self.instance.privacy_policy: + raise forms.ValidationError( + ugettext(u'Wir müssen deine Daten leider speichern können,' + u' damit wir wissen, dass du dich angemeldet hast.'), + code='privacy_policy_not_accepted', + ) + return val diff --git a/dav_registration/migrations/0001_initial.py b/dav_registration/migrations/0001_initial.py new file mode 100644 index 0000000..5eecf42 --- /dev/null +++ b/dav_registration/migrations/0001_initial.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.17 on 2019-02-08 15:35 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('dav_events', '0027_auto_20190207_1553'), + ] + + operations = [ + migrations.CreateModel( + name='Registration', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('personal_names', models.CharField(max_length=1024, verbose_name='Vorname(n)')), + ('family_names', models.CharField(max_length=1024, verbose_name='Familienname')), + ('address', models.CharField(help_text='Stra\xdfe, Hausnummer', max_length=1024, verbose_name='Anschrift')), + ('postal_code', models.CharField(max_length=254, verbose_name='Postleitzahl')), + ('city', models.CharField(max_length=1024, verbose_name='Ort')), + ('email_address', models.EmailField(max_length=254, verbose_name='E-Mail-Adresse')), + ('phone_number', models.CharField(help_text='Idealerweise eine Mobilfunk-Nummer', max_length=254, verbose_name='Telefonnummer')), + ('dav_number', models.CharField(help_text='Deine Mitgliedsnummer findest du unter dem Strichcode auf deinem DAV Ausweis.
Beispiel: 131/00/012345 (der Teil bis zum ersten * gen\xfcgt)', max_length=62, validators=[django.core.validators.RegexValidator(b'^([0-9]{1,10}/[0-9]{2,10}/)?[0-9]{1,10}(\\*[0-9]{1,10})?(\\*[0-9]{4}\\*[0-9]{4})?([* ][0-9]{8})?$', 'Ung\xfcltiges Format.')], verbose_name='DAV Mitgliednummer')), + ('emergency_contact', models.TextField(blank=True, help_text='Name und Telefonnummer bzw. Anschrift, die in Notf\xe4llen informiert werden soll.', verbose_name='Notfall-Kontakt')), + ('experience', models.TextField(blank=True, help_text='Welche Touren oder Kurse hast du bereits gemacht?', verbose_name='Erfahrung')), + ('note', models.TextField(blank=True, help_text='Wissenswertes f\xfcr den Tourenleiter, z.B. Allergien, gesundheitliche Einschr\xe4nkungen, ...
Kann frei gelassen werden.', verbose_name='Anmerkung')), + ('privacy_policy', models.TextField(blank=True, verbose_name='Erkl\xe4rung zur Datenspeicherung')), + ('privacy_policy_accepted', models.BooleanField(default=False, verbose_name='Einwilligung zur Datenspeicherung')), + ('purge_at', models.DateTimeField()), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='registrations', to='dav_events.Event')), + ], + options={ + 'ordering': ['created_at'], + 'verbose_name': 'Anmeldung', + 'verbose_name_plural': 'Anmeldungen', + }, + ), + ] diff --git a/dav_registration/migrations/__init__.py b/dav_registration/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dav_registration/models.py b/dav_registration/models.py new file mode 100644 index 0000000..510385c --- /dev/null +++ b/dav_registration/models.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +import datetime +import logging +from django.db import models +from django.urls import reverse +from django.utils import timezone +from django.utils.translation import ugettext_lazy as _ + +from dav_events.models.event import Event + +from . import signals +from .validators import DAVNumberValidator + +logger = logging.getLogger(__name__) + +midnight = datetime.time(00, 00, 00) +one_day = datetime.timedelta(1) + + +class Registration(models.Model): + event = models.ForeignKey(Event, related_name='registrations') + created_at = models.DateTimeField(auto_now_add=True) + + personal_names = models.CharField(max_length=1024, + verbose_name=_(u'Vorname(n)')) + family_names = models.CharField(max_length=1024, + verbose_name=_(u'Familienname')) + + address = models.CharField(max_length=1024, + verbose_name=_(u'Anschrift'), + help_text=_(u'Straße, Hausnummer')) + postal_code = models.CharField(max_length=254, + verbose_name=_(u'Postleitzahl')) + city = models.CharField(max_length=1024, + verbose_name=_(u'Ort')) + email_address = models.EmailField(verbose_name=_(u'E-Mail-Adresse')) + phone_number = models.CharField(max_length=254, + verbose_name=_(u'Telefonnummer'), + help_text=_(u'Idealerweise eine Mobilfunk-Nummer')) + dav_number = models.CharField(max_length=62, + validators=[DAVNumberValidator], + verbose_name=_(u'DAV Mitgliednummer'), + help_text=u'%s
%s %s' % ( + _(u'Deine Mitgliedsnummer findest du unter dem Strichcode' + u' auf deinem DAV Ausweis.'), + _(u'Beispiel: 131/00/012345'), + _(u'(der Teil bis zum ersten * genügt)'), + )) + emergency_contact = models.TextField(blank=True, + verbose_name=_(u'Notfall-Kontakt'), + help_text=_(u'Name und Telefonnummer bzw. Anschrift,' + u' die in Notfällen informiert werden soll.')) + experience = models.TextField(blank=True, + verbose_name=_(u'Erfahrung'), + help_text=_(u'Welche Touren oder Kurse hast du bereits gemacht?')) + note = models.TextField(blank=True, + verbose_name=_(u'Anmerkung'), + help_text=u'%s
%s' % ( + _(u'Wissenswertes für den Tourenleiter, z.B. Allergien,' + u' gesundheitliche Einschränkungen, ...'), + _(u'Kann frei gelassen werden.')) + ) + + privacy_policy = models.TextField(blank=True, + verbose_name=_(u'Erklärung zur Datenspeicherung')) + privacy_policy_accepted = models.BooleanField(default=False, + verbose_name=_(u'Einwilligung zur Datenspeicherung')) + purge_at = models.DateTimeField() + + class Meta: + verbose_name = _(u'Anmeldung') + verbose_name_plural = _(u'Anmeldungen') + ordering = ['created_at'] + + def __unicode__(self): + return u'{number} - {name} ({created} - {purge})'.format(number=self.event.get_number(), + name=self.get_full_name(), + created=self.created_at.strftime('%d.%m.%Y %H:%M'), + purge=self.purge_at.strftime('%d.%m.%Y %H:%M')) + + def get_absolute_url(self): + return reverse('dav_registration:registered') + + def get_full_name(self): + return u'{} {}'.format(self.personal_names, self.family_names) + + def save(self, **kwargs): + creating = False + if not self.id: + creating = True + + if self.event: + self.purge_at = self.__class__.calc_purge_at(self.event) + + super(Registration, self).save(**kwargs) + + if creating: + logger.info('Registration stored: %s', self) + signals.registration_created.send(sender=self.__class__, registration=self) + + @classmethod + def calc_purge_at(cls, event): + if event.alt_last_day: + last_day = event.alt_last_day + elif event.last_day: + last_day = event.last_day + elif event.alt_first_day: + last_day = event.alt_fisrt_day + else: + last_day = event.first_day + return timezone.make_aware(datetime.datetime.combine(last_day + one_day * 7, midnight)) diff --git a/dav_registration/module.json b/dav_registration/module.json new file mode 100644 index 0000000..544b4cf --- /dev/null +++ b/dav_registration/module.json @@ -0,0 +1,3 @@ +{ + "url_prefix": "registration" +} \ No newline at end of file diff --git a/dav_registration/signals.py b/dav_registration/signals.py new file mode 100644 index 0000000..032910a --- /dev/null +++ b/dav_registration/signals.py @@ -0,0 +1,20 @@ +from django.dispatch import Signal + +from . import emails + +registration_created = Signal(providing_args=['registration']) + + +def send_emails_on_registration(sender, **kwargs): + registration = kwargs.get('registration') + + # Inform the event owner (trainer) + recipient = registration.event.owner + email = emails.InformTrainerRegistrationMail(recipient=recipient, registration=registration) + email.send() + + # Inform the potential participant + recipient = u'"{fullname}" <{email}>'.format(fullname=registration.get_full_name(), + email=registration.email_address) + email = emails.InformSelfRegistrationMail(recipient=recipient, registration=registration) + email.send() diff --git a/dav_registration/static/dav_registration/img/sport_icons/B.png b/dav_registration/static/dav_registration/img/sport_icons/B.png new file mode 100644 index 0000000..4c0afaf Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/B.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/K.png b/dav_registration/static/dav_registration/img/sport_icons/K.png new file mode 100644 index 0000000..2bcebe7 Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/K.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/M.png b/dav_registration/static/dav_registration/img/sport_icons/M.png new file mode 100644 index 0000000..7eadb32 Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/M.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/S.png b/dav_registration/static/dav_registration/img/sport_icons/S.png new file mode 100644 index 0000000..cb7b49a Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/S.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/W.png b/dav_registration/static/dav_registration/img/sport_icons/W.png new file mode 100644 index 0000000..98d2e74 Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/W.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.black.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.black.png new file mode 100644 index 0000000..532d19a Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.black.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.dav-sommer.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.dav-sommer.png new file mode 100644 index 0000000..4c0afaf Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.dav-sommer.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.outdooractive.svg b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.outdooractive.svg new file mode 100644 index 0000000..8c9a617 --- /dev/null +++ b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/alpineTour.outdooractive.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.black.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.black.png new file mode 100644 index 0000000..35b4387 Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.black.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.dav-gelb.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.dav-gelb.png new file mode 100644 index 0000000..2bcebe7 Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.dav-gelb.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.outdooractive.svg b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.outdooractive.svg new file mode 100644 index 0000000..61e03f3 --- /dev/null +++ b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/climbing.outdooractive.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/hiking.outdooractive.svg b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/hiking.outdooractive.svg new file mode 100644 index 0000000..f963d20 --- /dev/null +++ b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/hiking.outdooractive.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.black.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.black.png new file mode 100644 index 0000000..039316c Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.black.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.dav-fruehling.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.dav-fruehling.png new file mode 100644 index 0000000..7eadb32 Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.dav-fruehling.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.outdooractive.svg b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.outdooractive.svg new file mode 100644 index 0000000..5952ada --- /dev/null +++ b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountainbiking.outdooractive.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.black.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.black.png new file mode 100644 index 0000000..14c38c4 Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.black.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.dav-herbst.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.dav-herbst.png new file mode 100644 index 0000000..98d2e74 Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.dav-herbst.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.outdooractive.svg b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.outdooractive.svg new file mode 100644 index 0000000..ca4efc3 --- /dev/null +++ b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/mountaineering.outdooractive.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.black.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.black.png new file mode 100644 index 0000000..fd6bb2e Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.black.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.dav-winter.png b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.dav-winter.png new file mode 100644 index 0000000..cb7b49a Binary files /dev/null and b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.dav-winter.png differ diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.outdooractive.svg b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.outdooractive.svg new file mode 100644 index 0000000..4bbd4cf --- /dev/null +++ b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/skitour.outdooractive.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/snowshoehiking.outdooractive.svg b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/snowshoehiking.outdooractive.svg new file mode 100644 index 0000000..36aa125 --- /dev/null +++ b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/snowshoehiking.outdooractive.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/dav_registration/static/dav_registration/img/sport_icons/outdooractive/viaferrata.outdooractive.svg b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/viaferrata.outdooractive.svg new file mode 100644 index 0000000..aaffdec --- /dev/null +++ b/dav_registration/static/dav_registration/img/sport_icons/outdooractive/viaferrata.outdooractive.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/dav_registration/templates/dav_registration/base.html b/dav_registration/templates/dav_registration/base.html new file mode 100644 index 0000000..89d8bf1 --- /dev/null +++ b/dav_registration/templates/dav_registration/base.html @@ -0,0 +1,3 @@ +{% extends "dav_base/base.html" %} + +{% block head-title %}Touren und Kurse - {{ block.super }}{% endblock %} diff --git a/dav_registration/templates/dav_registration/emails/inform_self.txt b/dav_registration/templates/dav_registration/emails/inform_self.txt new file mode 100644 index 0000000..31d9405 --- /dev/null +++ b/dav_registration/templates/dav_registration/emails/inform_self.txt @@ -0,0 +1,40 @@ +Hallo {{ registration.get_full_name }}, + +wir haben deine Anmeldung zur Veranstaltung + {{ event.number }} - {{ event.title }} +an den/die Tourenleiter/in {{ event.get_trainer_full_name }} weitergegeben. +{{ event.trainer_firstname }} wird sich bei dir melden und dir mitteilen, +ob du teilnehmen kannst oder nicht. + +======================================================================== +Veranstaltung: {{ event.number }} - {{ event.title }} +Datum: {{ event.get_formated_date }} +Tourenleitung: {{ event.get_trainer_full_name }} +Anmeldezeitpunkt: {{ registration.created_at|date:'l, d. F Y, G:i' }} +Anmeldenummer: {{ registration.id }} + +Personendaten +------------- +{{ registration.get_full_name }} +{{ registration.address }} +{{ registration.postal_code }} {{ registration.city }} +Telefon: {{ registration.phone_number }} +E-Mail: {{ registration.email_address }} +DAV Mitgliedsnummer: {{ registration.dav_number }} + +Notfall-Kontakt +--------------- +{% if registration.emergency_contact %}{{ registration.emergency_contact }}{% else %}-{% endif %} + +Erfahrung +--------- +{% if registration.experience %}{{ registration.experience }}{% else %}-{% endif %} + +Anmerkung +--------- +{% if registration.note %}{{ registration.note }}{% else %}-{% endif %} + +Erklärung zur Datenspeicherung +------------------------------ +{% if registration.privacy_policy %}{{ registration.privacy_policy }}{% else %}-{% endif %} +Zeitpunkt der Datenlöschung: {{ registration.purge_at|date:'l, d. F Y' }} diff --git a/dav_registration/templates/dav_registration/emails/inform_trainer.txt b/dav_registration/templates/dav_registration/emails/inform_trainer.txt new file mode 100644 index 0000000..9a5287f --- /dev/null +++ b/dav_registration/templates/dav_registration/emails/inform_trainer.txt @@ -0,0 +1,42 @@ +Hallo {{ recipient.first_name }}, + +Anmeldung zu deiner Veranstaltung {{ event.number }} +{{ event.title }} +======================================================================== +Anmeldezeitpunkt: {{ registration.created_at|date:'l, d. F Y, G:i' }} +Anmeldenummer: {{ registration.id }} + +Teilnehmer*in +------------- +{{ registration.get_full_name }} + +Telefonnummer und E-Mail-Adresse +-------------------------------- +{{ registration.phone_number }} +{{ registration.email_address }} + +Erfahrung +--------- +{% if registration.experience %}{{ registration.experience }}{% else %}-{% endif %} + +Anmerkung +--------- +{% if registration.note %}{{ registration.note }}{% else %}-{% endif %} + +Personendaten +------------- +{{ registration.get_full_name }} +{{ registration.address }} +{{ registration.postal_code }} {{ registration.city }} +Telefon: {{ registration.phone_number }} +E-Mail: {{ registration.email_address }} +DAV Mitgliedsnummer: {{ registration.dav_number }} + +Notfall-Kontakt +--------------- +{% if registration.emergency_contact %}{{ registration.emergency_contact }}{% else %}-{% endif %} + +Erklärung zur Datenspeicherung +------------------------------ +{% if registration.privacy_policy %}{{ registration.privacy_policy }}{% else %}-{% endif %} +Zeitpunkt der Datenlöschung: {{ registration.purge_at|date:'l, d. F Y' }} diff --git a/dav_registration/templates/dav_registration/event/facts.html b/dav_registration/templates/dav_registration/event/facts.html new file mode 100644 index 0000000..2e0bd6a --- /dev/null +++ b/dav_registration/templates/dav_registration/event/facts.html @@ -0,0 +1,119 @@ +{% load i18n %} + +{% if event.requirements %} + {% trans 'Anforderungen' %}: {{ event.requirements }}
+{% endif %} +{% if event.equipment %} + {% trans 'Ausrüstung' %}: {{ event.equipment }}
+{% endif %} +{% if event.location %} + {% trans 'Ort' %}: {{ event.location }} + {% if event.country and event.country != 'DE' and event.country != 'XX' %}({{ event.country }}){% endif %}
+{% endif %} +{% if event.basecamp %} + {% trans 'Stützpunkt' %}: {{ event.basecamp }}
+{% endif %} +{% if event.accommodation and event.accommodation != 'NONE' %} + {% trans 'Unterkunft' %}: + {% if event.accommodation == 'OTHER' %} + {{ event.accommodation_other }} + {% else %} + {{ event.get_accommodation_display }} + {% endif %} +
+{% endif %} +{% if event.meals and event.meals != 'NONE' %} + {% trans 'Verpflegung' %}: + {% if event.meals == 'OTHER' %} + {{ event.meals_other }} + {% else %} + {{ event.get_meals_display }} + {% endif %} +
+{% endif %} +{% if event.transport and event.transport != 'NONE' and event.transport != 'public' %} + {% trans 'Hin- / Rückfahrt' %}: + {% if event.transport == 'OTHER' %} + {{ event.transport_other }} + {% else %} + {{ event.get_transport_display }} + {% endif %} +
+{% endif %} +{% if event.meeting_point and event.meeting_point != 'NONE' %} + {% trans 'Treffpunkt' %}: + {% if event.meeting_time %} + {{ event.meeting_time|time:'G:i'|cut:':00' }} Uhr, + {% endif %} + {% if event.meeting_point == 'OTHER' %} + {{ event.meeting_point_other }} + {% else %} + {{ event.get_meeting_point_display }} + {% endif %} +
+{% endif %} +{% if event.transport == 'public' %} + {% if event.departure_time or event.departure_ride %} + {% trans 'Abfahrt' %}: + {% if event.departure_time %}{{ event.departure_time|time:'G:i'|cut:':00' }} Uhr{% endif %}{% if event.departure_time and event.departure_ride %}, {% endif %}{%if event.departure_ride %}{{ event.departure_ride }}{% endif %} +
+ {% endif %} +{% endif %} +{% if event.return_departure_time or event.return_arrival_time %} + {% trans 'Rückfahrt' %}: + {% if event.return_arrival_time %}{{ event.return_arrival_time|time:'G:i'|cut:':00' }} Uhr ({% trans 'Ankunft in' %} Karlsruhe) + {% elif event.return_departure_time %}{{ event.return_departure_time|time:'G:i'|cut:':00' }} Uhr ({% trans 'Abfahrt am Tourenort' %}) + {% endif %} +
+{% endif %} +{% if event.pre_meeting_1 %} + {% if event.pre_meeting_2 %} + {% trans 'Vortreffen' %} 1: {{ event.pre_meeting_1|date:'l, d. F Y, G:i'|cut:':00' }} {% trans 'Uhr' %}, DAV {% trans 'Sektionszentrum' %}
+ {% trans 'Vortreffen' %} 2: {{ event.pre_meeting_2|date:'l, d. F Y, G:i'|cut:':00' }} {% trans 'Uhr' %}, DAV {% trans 'Sektionszentrum' %}
+ {% else %} + {% trans 'Vortreffen' %}: {{ event.pre_meeting_1|date:'l, d. F Y, G:i'|cut:':00' }} {% trans 'Uhr' %}, DAV {% trans 'Sektionszentrum' %}
+ {% endif %} +{% endif %} +{% if event.min_participants > 0 or event.max_participants > 0 %} + {% trans 'Teilnehmerzahl' %}: + {% if event.min_participants == event.max_participants %} + {{ event.max_participants }} {% trans 'Teilnehmer' %} + {% elif event.min_participants > 0 and event.max_participants > 0 %} + {{ event.min_participants }} - {{ event.max_participants }} {% trans 'Teilnehmer' %} + {% elif event.min_participants > 0 %} + min. {{ event.min_participants }} {% trans 'Teilnehmer' %} + {% else %} + max. {{ event.max_participants }} {% trans 'Teilnehmer' %} + {% endif %} +
+{% endif %} +{% if event.charge > 0 or event.additional_costs %} +{% trans 'Kosten' %}: +{% if event.charge > 0 %} +{{ event.charge|floatformat:'-2' }} € {% trans 'Teilnahmegebühr' %} +{% endif %} +{% if event.additional_costs %} +{% if event.charge > 0 %}{% trans 'zzgl.' %}{% endif %} +{{ event.additional_costs }} +{% endif %} +
+{% endif %} +{% if event.registration_required and event.deadline %}{% trans 'Anmeldeschluss' %}: {{ event.deadline|date:'l, d. F Y' }}
{% endif %} +{% if event.trainer_2_fullname %} + {% if event.mode == 'training' %} + {% trans 'Ausbildungsteam' %}: + {% else %} + {% trans 'Team' %}: + {% endif %} + {{ event.trainer_firstname }} {{ event.trainer_familyname }}, + {{ event.trainer_2_fullname }}{% if event.trainer_3_fullname %}, + {{ event.trainer_3_fullname }}{% endif %} +
+{% endif %} +{% if event.trainer_familyname %} + {% trans 'Leitung' %}: + {{ event.trainer_firstname }} {{ event.trainer_familyname }} + {% if event.trainer_email or event.trainer_phone %} + ({% if event.trainer_email %}{{ event.trainer_email }}{% endif %}{% if event.trainer_email and event.trainer_phone %}, {% endif %}{% if event.trainer_phone %}{{ event.trainer_phone }}{% endif %}) + {% endif %} +{% endif %} \ No newline at end of file diff --git a/dav_registration/templates/dav_registration/event/paragraphs.html b/dav_registration/templates/dav_registration/event/paragraphs.html new file mode 100644 index 0000000..e325ae5 --- /dev/null +++ b/dav_registration/templates/dav_registration/event/paragraphs.html @@ -0,0 +1,52 @@ +{% load i18n %} +

+ {{ event.description|urlize|linebreaksbr }} +

+{% if event.mode == 'training' %} +
+

{% trans 'Kursinhalte' %}:

+ {% if event.course_topic_2 %} + + {% else %} +

{{ event.course_topic_1|urlize|linebreaksbr }}

+ {% endif %} +
+
+

{% trans 'Kursziele' %}:

+ {% if event.course_goal_2 %} + + {% else %} +

{{ event.course_goal_1|urlize|linebreaksbr }}

+ {% endif %} +
+{% endif %} diff --git a/dav_registration/templates/dav_registration/event_detail.html b/dav_registration/templates/dav_registration/event_detail.html new file mode 100644 index 0000000..3c999ca --- /dev/null +++ b/dav_registration/templates/dav_registration/event_detail.html @@ -0,0 +1,36 @@ +{% extends 'dav_registration/base.html' %} +{% load i18n %} +{% load dav_registration %} + +{% block head-title %}{{ event.number }} - {{ block.super }}{% endblock head-title %} + +{% block page-container-fluid %} +
+
+
+
+ {{ event.number }} - {{ event.title }} +
+
    +
  • + {{ event.get_formated_date }} + {% if event.get_alt_formated_date %} +
    + ({% trans 'Ersatztermin' %}: {{ event.get_alt_formated_date }}) + {% endif %} +
  • +
  • + {% render_event_paragraphs event %} +
  • +
  • + {% render_event_facts event %} +
  • +
  • + {% trans 'Anmelden' %} + {% trans 'Zurück' %} +
  • +
+
+
+
+{% endblock page-container-fluid %} \ No newline at end of file diff --git a/dav_registration/templates/dav_registration/event_list.html b/dav_registration/templates/dav_registration/event_list.html new file mode 100644 index 0000000..5d8a2d9 --- /dev/null +++ b/dav_registration/templates/dav_registration/event_list.html @@ -0,0 +1,103 @@ +{% extends 'dav_registration/base.html' %} +{% load static %} +{% load i18n %} +{% load dav_registration %} + +{% block page-container-fluid %} +
+

Touren & Kurse

+ + + + + + + + {% for event in event_list %} + + + + {% endfor %} + +
+
+ +
+ +
+ {% with event.sport as sport %} + {% with 'dav_registration/img/sport_icons/'|add:sport|add:'.png' as icon %} + {{ event.get_sport_display }} + + {% endwith %} + {% endwith %} +
+
+ + {{ event.get_number }} - {{ event.title }} + +

+ {{ event.get_formated_date }} + {% if event.get_alt_formated_date %} +
({% trans 'Ersatztermin' %}: {{ event.get_alt_formated_date }}) + {% endif %} +

+
+
    +
  • + {% render_event_paragraphs event %} +
  • +
  • + {% render_event_facts event %} +
  • +
  • + zur Anmeldung +
  • +
+
+
+ +
+ +
+{% endblock page-container-fluid %} \ No newline at end of file diff --git a/dav_registration/templates/dav_registration/registration_detail.html b/dav_registration/templates/dav_registration/registration_detail.html new file mode 100644 index 0000000..b9a9ba8 --- /dev/null +++ b/dav_registration/templates/dav_registration/registration_detail.html @@ -0,0 +1,44 @@ +{% extends 'dav_registration/base.html' %} +{% load bootstrap3 %} +{% load i18n %} +{% load dav_registration %} + +{% block head-title %}Anmeldung abgeschickt - {{ block.super }}{% endblock head-title %} + +{% block page-container-fluid %} +
+

+ Du solltest in Kürze eine E-Mail von uns mit deinen Anmeldedaten erhalten. +

+

+ Diese E-Mail gilt noch nicht als Zusage zur Teilnahme. +

+

+ Die Tourenleitung wurde über deine Anmeldung informiert und wird sich bei dir melden. +

+
+{% if object %} +
+
+ Anmeldung zu {{ object.event.number }} - {{ object.event.title }} +
+ +
+{% else %} + +{% endif %} + + {% bootstrap_icon 'list' %}  + {% trans 'zurück zur Tourenliste' %} + +{% endblock page-container-fluid %} \ No newline at end of file diff --git a/dav_registration/templates/dav_registration/registration_form.html b/dav_registration/templates/dav_registration/registration_form.html new file mode 100644 index 0000000..ed408a5 --- /dev/null +++ b/dav_registration/templates/dav_registration/registration_form.html @@ -0,0 +1,123 @@ +{% extends "dav_registration/base.html" %} +{% load bootstrap3 %} +{% load i18n %} + +{% block head-title %}{% block form-title %}{% trans 'Anmeldung' %} - {{ event.number }}{% endblock form-title %} - {{ block.super }}{% endblock head-title %} + +{% block page-container-fluid %} +

{% trans 'Anmeldung' %}

+
+
+ + +
+
+{% block form-errors %} +{% bootstrap_form_errors form %} +{% endblock form-errors %} +{% block form %} +
+ {% block form-content %} + {% csrf_token %} + {% block form-fields %} + {% block form-fields-hidden %} + {% for field in form.hidden_fields %} + {{ field }} + {% endfor %} + {% endblock form-fields-hidden %} + {% block form-fields-visible %} +
+
+ {% bootstrap_field form.personal_names %} +
+
+ {% bootstrap_field form.family_names %} +
+
+
+
+ {% bootstrap_field form.address %} +
+
+
+
+ {% bootstrap_field form.postal_code %} +
+
+ {% bootstrap_field form.city %} +
+
+
+
+ {% bootstrap_field form.email_address %} +
+
+ {% bootstrap_field form.phone_number %} +
+
+
+
+ {% bootstrap_field form.dav_number %} +
+
+ {% bootstrap_field form.emergency_contact %} +
+
+
+
+ {% bootstrap_field form.experience %} +
+
+ {% bootstrap_field form.note %} +
+
+
+
+
+ +
+

+ {{ privacy_policy|linebreaksbr }} +

+ {% trans 'Zeitpunkt der Löschung' %}: {{ purge_at|date:'l, d. F Y' }} +
+
+ {% if form.privacy_policy_accepted.errors %} +
+ {% endif %} +
+ +
+ {% if form.privacy_policy_accepted.errors %} +
+ {% for error in form.privacy_policy_accepted.errors %} +

{{ error }}

+ {% endfor %} +
+
+ {% endif %} + +
+
+ {% endblock form-fields-visible %} + {% endblock form-fields %} +
 
+ {% block form-buttons %} + {% buttons %} + + + {% bootstrap_icon 'remove' %}  + {% trans 'Zurück' %} + + {% endbuttons %} + {% endblock form-buttons %} + {% endblock form-content %} +
+{% endblock form %} +{% endblock page-container-fluid %} diff --git a/dav_registration/templatetags/__init__.py b/dav_registration/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dav_registration/templatetags/dav_registration.py b/dav_registration/templatetags/dav_registration.py new file mode 100644 index 0000000..0485408 --- /dev/null +++ b/dav_registration/templatetags/dav_registration.py @@ -0,0 +1,16 @@ +from django import template +from django.template.loader import render_to_string + +register = template.Library() + + +@register.simple_tag +def render_event_paragraphs(event): + return render_to_string('dav_registration/event/paragraphs.html', {'event': event}) + + +@register.simple_tag +def render_event_facts(event): + return render_to_string('dav_registration/event/facts.html', {'event': event}) + + diff --git a/dav_registration/urls.py b/dav_registration/urls.py new file mode 100644 index 0000000..62988b8 --- /dev/null +++ b/dav_registration/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls import url + +from . import views + +urlpatterns = [ + url(r'^$', views.RootView.as_view(), name='root'), + url(r'^finished', views.RegistrationSuccessView.as_view(), name='registered'), + url(r'^event/(?P\d+)/registration', views.RegistrationView.as_view(), name='register'), + url(r'^event/(?P\d+)/', views.EventDetailView.as_view(), name='event'), + url(r'^event', views.EventListView.as_view(), name='events'), +] diff --git a/dav_registration/utils.py b/dav_registration/utils.py new file mode 100644 index 0000000..f146bf3 --- /dev/null +++ b/dav_registration/utils.py @@ -0,0 +1,13 @@ +import logging +from django.utils import timezone + +from .models import Registration + +logger = logging.getLogger(__name__) + + +def purge_registrations(): + now = timezone.now() + for r in Registration.objects.filter(purge_at__lte=now): + logger.info('Purge registration \'%s\'', r) + r.delete() diff --git a/dav_registration/validators.py b/dav_registration/validators.py new file mode 100644 index 0000000..f8d0dad --- /dev/null +++ b/dav_registration/validators.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from django.core.validators import RegexValidator +from django.utils.translation import ugettext_lazy as _ + + +DAVNumberValidator = RegexValidator(r'^' + r'([0-9]{1,10}/[0-9]{2,10}/)?' + r'[0-9]{1,10}' + r'(\*[0-9]{1,10})?' + r'(\*[0-9]{4}\*[0-9]{4})?' + r'([* ][0-9]{8})?' + r'$', + _(u'Ungültiges Format.')) diff --git a/dav_registration/views.py b/dav_registration/views.py new file mode 100644 index 0000000..c7eaf57 --- /dev/null +++ b/dav_registration/views.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +import datetime +import logging +from django.apps import apps +from django.contrib import messages +from django.db.models import Q +from django.urls import reverse_lazy +from django.utils.translation import ugettext as _ +from django.views import generic + +from dav_events.models.event import Event + +from .forms import RegistrationForm +from .models import Registration +from .utils import purge_registrations + +app_config = apps.get_containing_app_config(__package__) +logger = logging.getLogger(__name__) + + +class RootView(generic.RedirectView): + url = reverse_lazy('dav_registration:events') + + def get(self, request, *args, **kwargs): + purge_registrations() + return super(RootView, self).get(request, *args, **kwargs) + + +class EventListView(generic.ListView): + model = Event + template_name = 'dav_registration/event_list.html' + + def get_queryset(self): + today = datetime.date.today() + + filter = Q(flags__status__code__in=('publishing', 'publishing_web', 'publishing_facebook', + 'published', 'published_web', 'published_facebook')) + filter &= Q(planned_publication_date__isnull=True) | Q(planned_publication_date__lte=today) + filter &= Q(first_day__gte=today) + filter &= Q(deadline__isnull=True) | Q(deadline__gte=today) + + qs = self.model.objects.filter(filter).order_by('first_day', 'number').distinct() + + return qs + + +class EventDetailView(generic.DetailView): + model = Event + template_name = 'dav_registration/event_detail.html' + + def get_queryset(self): + today = datetime.date.today() + + filter = Q(flags__status__code__in=('publishing', 'publishing_web', 'publishing_facebook', + 'published', 'published_web', 'published_facebook')) + filter &= Q(planned_publication_date__isnull=True) | Q(planned_publication_date__lte=today) + filter &= Q(first_day__gte=today) + filter &= Q(deadline__isnull=True) | Q(deadline__gte=today) + + qs = self.model.objects.filter(filter).distinct() + + return qs + + +class RegistrationView(generic.CreateView): + model = Registration + form_class = RegistrationForm + initial = { + 'personal_names': 'Jens', + 'family_names': 'Kleineheismann', + 'address': 'Marie-Alexandra-Str. 6', + 'postal_code': '76135', + 'city': 'Karlsruhe', + 'email_address': 'heinzel@heinzelwerk.de', + 'phone_number': '0178 143 2886', + 'note': 'Nur ein Test.', + 'dav_number': '131/00/007', + 'experience': 'Ich kann alles.', + 'privacy_policy_accepted': True, + } + + def get_queryset(self): + today = datetime.date.today() + + filter = Q(flags__status__code__in=('publishing', 'publishing_web', 'publishing_facebook', + 'published', 'published_web', 'published_facebook')) + filter &= Q(planned_publication_date__isnull=True) | Q(planned_publication_date__lte=today) + filter &= Q(first_day__gte=today) + filter &= Q(deadline__isnull=True) | Q(deadline__gte=today) + + qs = Event.objects.filter(filter).distinct() + + return qs + + def get_initial(self): + initials = super(RegistrationView, self).get_initial() + return initials + + def get_form(self, form_class=None): + form = super(RegistrationView, self).get_form(form_class) + + event = self.get_object() + + experience_label = form.fields['experience'].label + experience_help_text = form.fields['experience'].help_text + if event.sport == 'B': + experience_label = _(u'Eigene Bergerfahrung') + elif event.sport == 'K' and event.terrain == 'alpine': + experience_label = _(u'Eigene Fels- und Bergerfahrung') + if event.level == 'beginner': + experience_help_text = u'%s
%s
%s' % ( + _(u'Warst du schon mal im Gebirge klettern?'), + _(u'In welchem Schwierigkeitsgrad hast du Spaß?'), + _(u'Bist du schon mal vorgestiegen?') + ) + else: + experience_help_text = u'%s
%s
%s' % ( + _(u'In welchen Klettergebieten/Touren warst du bisher unterwegs?'), + _(u'In welchem Schwierigkeitsgrad hast du im Vorstieg Spaß?'), + _(u'Wie waren die Touren abgesichert, in denen du dich noch wohlgefühlt hast?') + ) + elif event.sport == 'K': + experience_label = _(u'Eigene Klettererfahrung') + if event.level == 'beginner': + experience_help_text = u'%s
%s
%s' % ( + _(u'Warst du schon mal am Fels klettern?'), + _(u'In welchem Schwierigkeitsgrad hast du Spaß?'), + _(u'Bist du schon mal vorgestiegen?') + ) + else: + experience_help_text = u'%s
%s
%s' % ( + _(u'In welchen Klettergebieten warst du bisher unterwegs?'), + _(u'In welchem Schwierigkeitsgrad hast du im Vorstieg Spaß?'), + _(u'Wie waren die Touren abgesichert, in denen du dich noch wohlgefühlt hast?') + ) + elif event.sport == 'M': + experience_label = _(u'Eigene MTB-Erfahrung') + experience_help_text = u'%s' % ( + _(u'Was für Touren bist du schon gefahren?') + ) + if event.level != 'beginner': + experience_help_text += u'
%s' % ( + _(u'Single-Trail-Schwierigkeit (S0-S5) bei der du dich wohl fühlst?') + ) + elif event.sport == 'S': + experience_label = _(u'Eigene Skitouren- und Bergerfahrung') + elif event.sport == 'W': + experience_help_text += u'
%s' % ( + _(u'Kann frei gelassen werden.') + ) + + form.fields['experience'].label = experience_label + form.fields['experience'].help_text = experience_help_text + + form.instance.event = event + form.instance.privacy_policy = app_config.settings.privacy_policy + return form + + def get_context_data(self, **kwargs): + context = super(RegistrationView, self).get_context_data(**kwargs) + event = self.get_object() + context['event'] = event + context['privacy_policy'] = app_config.settings.privacy_policy + context['purge_at'] = self.model.calc_purge_at(event) + return context + + def form_valid(self, form): + r = super(RegistrationView, self).form_valid(form) + self.request.session['registration_id'] = form.instance.pk + message = _(u'Deine Anmeldung wurde erfolgreich gespeichert.') + messages.success(self.request, message) + return r + + def post(self, request, *args, **kwargs): + if 'registration_id' in request.session: + del request.session['registration_id'] + return super(RegistrationView, self).post(request, *args, **kwargs) + + +class RegistrationSuccessView(generic.DetailView): + model = Registration + + def get_object(self, queryset=None): + try: + pk = self.request.session['registration_id'] + obj = self.model.objects.get(pk=pk) + except KeyError, self.model.DoesNotExist: + obj = None + return obj