diff --git a/TODO.txt b/TODO.txt index 2e90218..f21562b 100644 --- a/TODO.txt +++ b/TODO.txt @@ -2,7 +2,6 @@ - ApproachForm aufteilen - Anmeldungstext - Publish Status? -- Teilnehmerzahl und Trainerzahl kombinieren - Save as Draft - Copy Event - Tourenreferent managed Gruppen der Subreferenten diff --git a/dav_events/apps.py b/dav_events/apps.py index 2ef2c75..c983458 100644 --- a/dav_events/apps.py +++ b/dav_events/apps.py @@ -15,7 +15,7 @@ DEFAULT_SETTINGS = ( DefaultSetting('group_publish', None), DefaultSetting('group_publish_incremental', None), DefaultSetting('forms_development_init', False), - DefaultSetting('fee_matrix', ImproperlyConfigured), + DefaultSetting('matrix_config', ImproperlyConfigured), ) diff --git a/dav_events/choices.py b/dav_events/choices.py index 8451418..8167b8b 100644 --- a/dav_events/choices.py +++ b/dav_events/choices.py @@ -51,7 +51,11 @@ ACCOMMODATION_CHOICES = ChoiceSet([ ('NONE', _(u'Keine (tägliche Anreise)')), ('biwi', _(u'Biwak')), ('camp', _(u'Zelt')), + ('campsite', _(u'Campingplatz')), + ('hut_shelter', _(u'Winterraum')), ('hut', _(u'Alpenvereinshütte')), + ('hut_dorm', _(u'Alpenvereinshütte (Lager)')), + ('hut_room', _(u'Alpenvereinshütte (Zimmer)')), ('hotel', _(u'Hotel/Pension/Hostel')), ('OTHER', _(u'Andere Unterkunft (zusätzliches Feld)')), ]) @@ -111,9 +115,9 @@ TERRAIN_CHOICES = ChoiceSet([ TRANSPORT_CHOICES = ChoiceSet([ ('NONE', _(u'Keine Angabe')), - ('train', _(u'Bahn')), - ('bus', _(u'Bus')), - ('car', _(u'Fahrgemeinschaften')), + ('public', _(u'Bahn / Bus')), + ('coach', _(u'Reisebus')), + ('car', _(u'Fahrgemeinschaften / Stadtmobil')), ('self', _(u'Eigenverantwortlich')), ('OTHER', _(u'Anderes Verkehrsmittel (zusätzliches Feld)')), ]) diff --git a/dav_events/console_scripts/Resources/django.main.settings-dav_events.py b/dav_events/console_scripts/Resources/django.main.settings-dav_events.py index 3b127ff..997faec 100644 --- a/dav_events/console_scripts/Resources/django.main.settings-dav_events.py +++ b/dav_events/console_scripts/Resources/django.main.settings-dav_events.py @@ -18,13 +18,15 @@ GROUP_PUBLISH_INCREMENTAL = 'OnlineRedaktion' # EventCreateForm # FORMS_DEVELOPMENT_INIT = False -FEE_MATRIX = { +MATRIX_CONFIG = { '0': {'description': _(u'Keiner / direkte Abrechnung (Tageswanderung)'), 'trainer_fee': 0, 'pre_meeting_fee': 0, 'trainer_day_fee': 0, 'participant_fee': 0, 'participant_day_fee': 0, + 'min_participants': 0, + 'max_participants': 0, }, 'A': {'description': _(u'A (Mehrtageswanderung Mittelgebirge'), 'trainer_fee': 40, @@ -32,6 +34,8 @@ FEE_MATRIX = { 'participant_fee': 10, 'participant_day_fee': 10, 'pre_meeting_fee': 0, + 'min_participants': 5, + 'max_participants': 8, }, 'B': {'description': _(u'B (Alpine Mehrtageswanderung)'), 'trainer_fee': 50, @@ -39,6 +43,8 @@ FEE_MATRIX = { 'participant_fee': 10, 'participant_day_fee': 20, 'pre_meeting_fee': 0, + 'min_participants': 3, + 'max_participants': 6, }, 'C': {'description': _(u'C (Tour/Kurs ohne Übernachtung)'), 'trainer_fee': 30, @@ -46,6 +52,8 @@ FEE_MATRIX = { 'participant_fee': 10, 'participant_day_fee': 30, 'pre_meeting_fee': 0, + 'min_participants': 3, + 'max_participants': 5, }, 'D': {'description': _(u'D (Tour/Kurs Mittelgebirge)'), 'trainer_fee': 50, @@ -53,6 +61,8 @@ FEE_MATRIX = { 'participant_fee': 20, 'participant_day_fee': 25, 'pre_meeting_fee': 0, + 'min_participants': 3, + 'max_participants': 5, }, 'E': {'description': _(u'E (Alpine Klettertour DE/AT)'), 'trainer_fee': 80, @@ -60,6 +70,8 @@ FEE_MATRIX = { 'participant_fee': 40, 'participant_day_fee': 40, 'pre_meeting_fee': 0, + 'min_participants': 2, + 'max_participants': 3, }, 'F': {'description': _(u'F (Alpine Klettertour CH/FR/IT/..)'), 'trainer_fee': 80, @@ -67,6 +79,8 @@ FEE_MATRIX = { 'participant_fee': 40, 'participant_day_fee': 45, 'pre_meeting_fee': 0, + 'min_participants': 2, + 'max_participants': 3, }, 'G': {'description': _(u'G (Alpiner Kurs DE/AT)'), 'trainer_fee': 100, @@ -74,6 +88,8 @@ FEE_MATRIX = { 'participant_fee': 35, 'participant_day_fee': 30, 'pre_meeting_fee': 0, + 'min_participants': 3, + 'max_participants': 4, }, 'H': {'description': _(u'H (Alpiner Kurs CH/FR/IT/..)'), 'trainer_fee': 100, @@ -81,6 +97,8 @@ FEE_MATRIX = { 'participant_fee': 35, 'participant_day_fee': 30, 'pre_meeting_fee': 0, + 'min_participants': 3, + 'max_participants': 4, }, 'I': {'description': _(u'I (Alpine MTB/Ski-Tour DE/AT)'), 'trainer_fee': 80, @@ -88,6 +106,8 @@ FEE_MATRIX = { 'participant_fee': 25, 'participant_day_fee': 25, 'pre_meeting_fee': 0, + 'min_participants': 3, + 'max_participants': 6, }, 'J': {'description': _(u'J (Alpine MTB/Ski-Tour CH/FR/IT/..)'), 'trainer_fee': 80, @@ -95,6 +115,8 @@ FEE_MATRIX = { 'participant_fee': 25, 'participant_day_fee': 25, 'pre_meeting_fee': 0, + 'min_participants': 3, + 'max_participants': 6, }, 'K': {'description': _(u'K (Ski-Tour/-Kurs mit Liftbenutzung)'), 'trainer_fee': 80, @@ -102,5 +124,7 @@ FEE_MATRIX = { 'participant_fee': 40, 'participant_day_fee': 40, 'pre_meeting_fee': 0, + 'min_participants': 3, + 'max_participants': 4, }, } diff --git a/dav_events/forms/events.py b/dav_events/forms/events.py index 2a56dc7..a61848d 100644 --- a/dav_events/forms/events.py +++ b/dav_events/forms/events.py @@ -77,6 +77,41 @@ class EventCreateForm(ChainedForm): _model = models.Event _initial_form_name = 'ModeForm' + def _get_matrix_config(self, session_data): + mode = session_data.get('mode', None) + sport = session_data.get('sport', None) + ski_lift = session_data.get('ski_lift', False) + terrain = session_data.get('terrain', None) + country = session_data.get('country', None) + last_day = session_data.get('last_day', None) + + if sport == 'S' and ski_lift: + matrix_key = 'K' + elif sport == 'W' and not last_day: + matrix_key = '0' + elif sport == 'W' and terrain != 'alpine': + matrix_key = 'A' + elif sport == 'W': + matrix_key = 'B' + elif terrain != 'alpine' and not last_day: + matrix_key = 'C' + elif terrain != 'alpine': + matrix_key = 'D' + elif mode == 'training' and country in ('DE', 'AT'): + matrix_key = 'G' + elif mode == 'training': + matrix_key = 'H' + elif sport == 'K' and country in ('DE', 'AT'): + matrix_key = 'E' + elif sport == 'K': + matrix_key = 'F' + elif country in ('DE', 'AT'): + matrix_key = 'I' + else: + matrix_key = 'J' + + return matrix_key, app_config.settings.matrix_config[matrix_key] + class ModeForm(EventCreateForm): _form_title = _(u'Veranstaltungsmodus') @@ -374,7 +409,7 @@ class ApproachForm(EventCreateForm): if sport in ('M', 'W'): if country == 'DE' and terrain == 'submountains': - self.fields['transport'].initial = 'train' + self.fields['transport'].initial = 'public' self.fields['meeting_point'].initial = 'hbf' if not last_day: @@ -385,7 +420,7 @@ class ApproachForm(EventCreateForm): class RequirementsForm(EventCreateForm): - _form_title = _(u'Voraussetungen / Vorbedingungen') + _form_title = _(u'Voraussetzungen / Vorbedingungen') _next_form_name = 'DescriptionForm' requirements = forms.CharField(required=False, @@ -508,7 +543,7 @@ class RequirementsForm(EventCreateForm): class DescriptionForm(EventCreateForm): _form_title = _(u'Titel / Beschreibung') - _next_form_name = 'RegistrationForm' + _next_form_name = 'TrainerForm' title = forms.CharField(max_length=config.TITLE_MAX_LENGTH, label=_(u'Name/Titel der Veranstaltung'), @@ -550,70 +585,9 @@ class DescriptionForm(EventCreateForm): self.fields['title'].initial = title_prefix -class RegistrationForm(EventCreateForm): - _form_title = _(u'Teilnehmer / Anmeldung') - _next_form_name = 'TrainerForm' - - min_participants = forms.IntegerField(initial=0, - label=_(u'Min. Teilnehmer')) - max_participants = forms.IntegerField(initial=0, - label=_(u'Max. Teilnehmer')) - - deadline = forms.ChoiceField(choices=choices.DEADLINE_CHOICES, - initial='OTHER', - label=_(u'Anmeldeschluss'), - widget=forms.RadioSelect()) - - deadline_month = forms.DateField(widget=forms.HiddenInput()) - deadline_quarter = forms.DateField(widget=forms.HiddenInput()) - - deadline_other = forms.DateField(required=False, - label=_(u'Anderer Anmeldeschluss'), - help_text=u'%s - %s' % ( - _(u'Format: tt.mm.jjjj'), - _(u'Kann freigelassen werden') - ), - widget=DateWidget(attrs={'id': 'id_deadline_other_widget', - 'placeholder': _(u'Kann freigelassen werden'), - }, - # usel10n=True, - options={ - 'format': 'dd.mm.yyyy', - 'weekStart': 1, - 'pickerPosition': 'bottom-left', - }, - bootstrap_version=3)) - - def _proceed_session_data(self, session_data): - super(RegistrationForm, self)._proceed_session_data(session_data) - - first_day = session_data.get('first_day', None) - if first_day: - new_choices = [] - for key, desc in self.fields['deadline'].choices: - if key == 'month': - m = first_day.month - 1 - 1 - y = first_day.year + m / 12 - m = m % 12 + 1 - d = min(first_day.day, calendar.monthrange(y, m)[1]) - date = datetime.date(y, m, d) - desc += u' ({})'.format(format_date(date, 'EEEE, d. MMMM yyyy', locale=get_language()[0:2])) - self.fields['deadline_month'].initial = date.isoformat() - elif key == 'quarter': - m = first_day.month - 1 - 3 - y = first_day.year + m / 12 - m = m % 12 + 1 - d = min(first_day.day, calendar.monthrange(y, m)[1]) - date = datetime.date(y, m, d) - desc += u' ({})'.format(format_date(date, 'EEEE, d. MMMM yyyy', locale=get_language()[0:2])) - self.fields['deadline_quarter'].initial = date.isoformat() - new_choices.append((key, desc)) - self.fields['deadline'].choices = new_choices - - class TrainerForm(EventCreateForm): _form_title = _(u'Tourenleitung') - _next_form_name = 'ChargesForm' + _next_form_name = 'RegistrationForm' trainer_firstname = forms.CharField(label=_(u'Vorname'), max_length=config.TRAINER_NAME_MAX_LENGTH) @@ -680,6 +654,81 @@ class TrainerForm(EventCreateForm): self.fields['trainer_email'].initial = _(u'heinzel@alpenverein-karlsruhe.de') +class RegistrationForm(EventCreateForm): + _form_title = _(u'Teilnehmer / Anmeldung') + _next_form_name = 'ChargesForm' + + min_participants = forms.IntegerField(initial=0, + label=_(u'Min. Teilnehmer')) + max_participants = forms.IntegerField(initial=0, + label=_(u'Max. Teilnehmer')) + + deadline = forms.ChoiceField(choices=choices.DEADLINE_CHOICES, + initial='OTHER', + label=_(u'Anmeldeschluss'), + widget=forms.RadioSelect()) + + deadline_month = forms.DateField(widget=forms.HiddenInput()) + deadline_quarter = forms.DateField(widget=forms.HiddenInput()) + + deadline_other = forms.DateField(required=False, + label=_(u'Anderer Anmeldeschluss'), + help_text=u'%s - %s' % ( + _(u'Format: tt.mm.jjjj'), + _(u'Kann freigelassen werden') + ), + widget=DateWidget(attrs={'id': 'id_deadline_other_widget', + 'placeholder': _(u'Kann freigelassen werden'), + }, + # usel10n=True, + options={ + 'format': 'dd.mm.yyyy', + 'weekStart': 1, + 'pickerPosition': 'bottom-left', + }, + bootstrap_version=3)) + + def _proceed_session_data(self, session_data): + super(RegistrationForm, self)._proceed_session_data(session_data) + + first_day = session_data.get('first_day', None) + trainer_2_fullname = session_data.get('trainer_2_fullname', None) + trainer_3_fullname = session_data.get('trainer_3_fullname', None) + + matrix_key, matrix_config = self._get_matrix_config(session_data) + + n_trainer = 1 + if trainer_2_fullname: + n_trainer += 1 + if trainer_3_fullname: + n_trainer += 1 + + self.fields['min_participants'].initial = matrix_config['min_participants'] * n_trainer + self.fields['max_participants'].initial = matrix_config['max_participants'] * n_trainer + + if first_day: + new_choices = [] + for key, desc in self.fields['deadline'].choices: + if key == 'month': + m = first_day.month - 1 - 1 + y = first_day.year + m / 12 + m = m % 12 + 1 + d = min(first_day.day, calendar.monthrange(y, m)[1]) + date = datetime.date(y, m, d) + desc += u' ({})'.format(format_date(date, 'EEEE, d. MMMM yyyy', locale=get_language()[0:2])) + self.fields['deadline_month'].initial = date.isoformat() + elif key == 'quarter': + m = first_day.month - 1 - 3 + y = first_day.year + m / 12 + m = m % 12 + 1 + d = min(first_day.day, calendar.monthrange(y, m)[1]) + date = datetime.date(y, m, d) + desc += u' ({})'.format(format_date(date, 'EEEE, d. MMMM yyyy', locale=get_language()[0:2])) + self.fields['deadline_quarter'].initial = date.isoformat() + new_choices.append((key, desc)) + self.fields['deadline'].choices = new_choices + + class ChargesForm(EventCreateForm): _form_title = _(u'Kosten') _next_form_name = 'SummaryForm' @@ -718,11 +767,6 @@ class ChargesForm(EventCreateForm): def _proceed_session_data(self, session_data): super(ChargesForm, self)._proceed_session_data(session_data) - mode = session_data.get('mode', None) - sport = session_data.get('sport', None) - ski_lift = session_data.get('ski_lift', False) - terrain = session_data.get('terrain', None) - country = session_data.get('country', None) first_day = session_data.get('first_day', None) arrival_previous_day = session_data.get('arrival_previous_day', False) last_day = session_data.get('last_day', None) @@ -731,33 +775,10 @@ class ChargesForm(EventCreateForm): pre_meeting_1 = session_data.get('pre_meeting_1', None) pre_meeting_2 = session_data.get('pre_meeting_2', None) - if sport == 'S' and ski_lift: - charge_key = 'K' - elif sport == 'W' and not last_day: - charge_key = '0' - elif sport == 'W' and terrain != 'alpine': - charge_key = 'A' - elif sport == 'W': - charge_key = 'B' - elif terrain != 'alpine' and not last_day: - charge_key = 'C' - elif terrain != 'alpine': - charge_key = 'D' - elif mode == 'training' and country in ('DE', 'AT'): - charge_key = 'G' - elif mode == 'training': - charge_key = 'H' - elif sport == 'K' and country in ('DE', 'AT'): - charge_key = 'E' - elif sport == 'K': - charge_key = 'F' - elif country in ('DE', 'AT'): - charge_key = 'I' - else: - charge_key = 'J' + matrix_key, matrix_config = self._get_matrix_config(session_data) additional_costs_text = u'' - if transport != 'NONE': + if transport != 'coach': additional_costs_text += ugettext(u'Fahrtkosten') if last_day: @@ -777,37 +798,35 @@ class ChargesForm(EventCreateForm): else: n_pre_meetings = 0 - fees = app_config.settings.fee_matrix[charge_key] - trainer_reward = ( - fees['trainer_fee'] - + ndays * fees['trainer_day_fee'] - + n_pre_meetings * fees['pre_meeting_fee'] + matrix_config['trainer_fee'] + + ndays * matrix_config['trainer_day_fee'] + + n_pre_meetings * matrix_config['pre_meeting_fee'] ) charge = ( - fees['participant_fee'] - + ndays * fees['participant_day_fee'] + matrix_config['participant_fee'] + + ndays * matrix_config['participant_day_fee'] ) if arrival_previous_day: - trainer_reward += fees['trainer_day_fee'] / 2.0 - charge += fees['participant_day_fee'] / 2.0 + trainer_reward += matrix_config['trainer_day_fee'] / 2.0 + charge += matrix_config['participant_day_fee'] / 2.0 - self.fields['charge_key'].initial = fees['description'] or charge_key - self.fields['trainer_fee'].initial = fees['trainer_fee'] - self.fields['pre_meeting_fee'].initial = fees['pre_meeting_fee'] - self.fields['trainer_day_fee'].initial = fees['trainer_day_fee'] - self.fields['participant_fee'].initial = fees['participant_day_fee'] - self.fields['participant_day_fee'].initial = fees['participant_day_fee'] + self.fields['charge_key'].initial = matrix_config['description'] or matrix_key + self.fields['trainer_fee'].initial = matrix_config['trainer_fee'] + self.fields['pre_meeting_fee'].initial = matrix_config['pre_meeting_fee'] + self.fields['trainer_day_fee'].initial = matrix_config['trainer_day_fee'] + self.fields['participant_fee'].initial = matrix_config['participant_day_fee'] + self.fields['participant_day_fee'].initial = matrix_config['participant_day_fee'] self.fields['trainer_reward'].initial = trainer_reward self.fields['trainer_reward'].widget.attrs['title'] = (u'%d € Pauschale \n' u'+ %d Tage * %d € Tagespauschale \n' u'+ %d halben Anreisetag * %d € Tagespauschale / 2 \n' u'+ %d Vortreffen * %d € Vortreffenpauschale' % ( - fees['trainer_fee'], - ndays, fees['trainer_day_fee'], - int(arrival_previous_day), fees['trainer_day_fee'], - n_pre_meetings, fees['pre_meeting_fee'] + matrix_config['trainer_fee'], + ndays, matrix_config['trainer_day_fee'], + int(arrival_previous_day), matrix_config['trainer_day_fee'], + n_pre_meetings, matrix_config['pre_meeting_fee'] ) ) @@ -816,9 +835,9 @@ class ChargesForm(EventCreateForm): u'+ %d Tage * %d € Tagespauschale \n' u'+ %d halben Anreisetag * %d € Tagespauschale / 2' % ( - fees['participant_fee'], - ndays, fees['participant_day_fee'], - int(arrival_previous_day), fees['participant_day_fee'], + matrix_config['participant_fee'], + ndays, matrix_config['participant_day_fee'], + int(arrival_previous_day), matrix_config['participant_day_fee'], ) ) diff --git a/dav_events/migrations/0011_auto_20180219_1225.py b/dav_events/migrations/0011_auto_20180219_1225.py new file mode 100644 index 0000000..8939d50 --- /dev/null +++ b/dav_events/migrations/0011_auto_20180219_1225.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.9 on 2018-02-19 12:25 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dav_events', '0010_auto_20180207_1138'), + ] + + operations = [ + migrations.AlterField( + model_name='event', + name='accommodation', + field=models.CharField(choices=[(b'NONE', 'Keine (t\xe4gliche Anreise)'), (b'biwi', 'Biwak'), (b'camp', 'Zelt'), (b'campsite', 'Campingplatz'), (b'hut_shelter', 'Winterraum'), (b'hut', 'Alpenvereinsh\xfctte'), (b'hut_dorm', 'Alpenvereinsh\xfctte (Lager)'), (b'hut_room', 'Alpenvereinsh\xfctte (Zimmer)'), (b'hotel', 'Hotel/Pension/Hostel'), (b'OTHER', 'Andere Unterkunft (zus\xe4tzliches Feld)')], max_length=25), + ), + migrations.AlterField( + model_name='event', + name='transport', + field=models.CharField(choices=[(b'NONE', 'Keine Angabe'), (b'public', 'Bahn / Bus'), (b'coach', 'Reisebus'), (b'car', 'Fahrgemeinschaften / Stadtmobil'), (b'self', 'Eigenverantwortlich'), (b'OTHER', 'Anderes Verkehrsmittel (zus\xe4tzliches Feld)')], max_length=25), + ), + ]