Merge pull request 'dav_events: Incorporated new rewards and fees' (#78) from money2025 into master
All checks were successful
Run tests / Execute tox to run the test suite (push) Successful in 3m19s

Reviewed-on: #78
This commit was merged in pull request #78.
This commit is contained in:
2024-09-12 08:51:16 +02:00
3 changed files with 230 additions and 156 deletions

View File

@@ -133,125 +133,149 @@ FORM_INITIALS = {
# EventCreateForm and sub classes # EventCreateForm and sub classes
# FORMS_DEVELOPMENT_INIT = False # FORMS_DEVELOPMENT_INIT = False
MATRIX_CONFIG = { MATRIX_CONFIG = {
'0': {'description': _(u'Keiner / direkte Abrechnung (Tageswanderung)'), '0': {'description': _(u'Keiner / direkte Abrechnung (Tageswanderung)'),
'trainer_fee': 0, 'orga_compensation': 0,
'trainer_day_fee': 0, 'pubtrans_compensation': 0,
'participant_fee': 0, 'trainer_compensation': 0,
'participant_day_fee': 0, 'trainer_daily_compensation': 0,
'pre_meeting_fee': 0, 'pre_meeting_compensation': 0,
'pubtrans_bonus': 0, 'participant_fee': 0,
'min_participants': 0, 'participant_daily_fee': 0,
'max_participants': 0, 'pubtrans_bonus': 0,
'min_participants': 0,
'max_participants': 0,
}, },
'A': {'description': _(u'A (Mehrtageswanderung Mittelgebirge)'), 'A': {'description': _(u'A (Mehrtageswanderung Mittelgebirge)'),
'trainer_fee': 40, 'orga_compensation': 30,
'trainer_day_fee': 50, 'pubtrans_compensation': 30,
'participant_fee': 10, 'trainer_compensation': 38,
'participant_day_fee': 10, 'trainer_daily_compensation': 48,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 20, 'participant_fee': 11,
'min_participants': 5, 'participant_daily_fee': 11,
'max_participants': 8, 'pubtrans_bonus': 20,
'min_participants': 5,
'max_participants': 8,
}, },
'B': {'description': _(u'B (Alpine Mehrtageswanderung)'), 'B': {'description': _(u'B (Alpine Mehrtageswanderung)'),
'trainer_fee': 50, 'orga_compensation': 30,
'trainer_day_fee': 75, 'pubtrans_compensation': 50,
'participant_fee': 10, 'trainer_compensation': 48,
'participant_day_fee': 20, 'trainer_daily_compensation': 73,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 11,
'min_participants': 3, 'participant_daily_fee': 21,
'max_participants': 6, 'pubtrans_bonus': 30,
'min_participants': 3,
'max_participants': 6,
}, },
'C': {'description': _(u'C (Tour/Kurs ohne Übernachtung)'), 'C': {'description': _(u'C (Tour/Kurs ohne Übernachtung)'),
'trainer_fee': 30, 'orga_compensation': 30,
'trainer_day_fee': 60, 'pubtrans_compensation': 30,
'participant_fee': 10, 'trainer_compensation': 28,
'participant_day_fee': 30, 'trainer_daily_compensation': 57,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 0, 'participant_fee': 11,
'min_participants': 3, 'participant_daily_fee': 32,
'max_participants': 5, 'pubtrans_bonus': 20,
'min_participants': 3,
'max_participants': 5,
}, },
'D': {'description': _(u'D (Tour/Kurs Mittelgebirge)'), 'D': {'description': _(u'D (Tour/Kurs Mittelgebirge)'),
'trainer_fee': 50, 'orga_compensation': 30,
'trainer_day_fee': 75, 'pubtrans_compensation': 30,
'participant_fee': 20, 'trainer_compensation': 48,
'participant_day_fee': 25, 'trainer_daily_compensation': 73,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 21,
'min_participants': 3, 'participant_daily_fee': 26,
'max_participants': 5, 'pubtrans_bonus': 20,
'min_participants': 3,
'max_participants': 5,
}, },
'E': {'description': _(u'E (Alpine Klettertour DE/AT)'), 'E': {'description': _(u'E (Alpine Klettertour DE/AT)'),
'trainer_fee': 80, 'orga_compensation': 40,
'trainer_day_fee': 75, 'pubtrans_compensation': 50,
'participant_fee': 40, 'trainer_compensation': 76,
'participant_day_fee': 40, 'trainer_daily_compensation': 73,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 42,
'min_participants': 2, 'participant_daily_fee': 42,
'max_participants': 3, 'pubtrans_bonus': 30,
'min_participants': 2,
'max_participants': 3,
}, },
'F': {'description': _(u'F (Alpine Klettertour CH/FR/IT/..)'), 'F': {'description': _(u'F (Alpine Klettertour CH/FR/IT/..)'),
'trainer_fee': 80, 'orga_compensation': 40,
'trainer_day_fee': 85, 'pubtrans_compensation': 50,
'participant_fee': 40, 'trainer_compensation': 76,
'participant_day_fee': 45, 'trainer_daily_compensation': 82,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 42,
'min_participants': 2, 'participant_daily_fee': 47,
'max_participants': 3, 'pubtrans_bonus': 30,
'min_participants': 2,
'max_participants': 3,
}, },
'G': {'description': _(u'G (Alpiner Kurs DE/AT)'), 'G': {'description': _(u'G (Alpiner Kurs DE/AT)'),
'trainer_fee': 100, 'orga_compensation': 50,
'trainer_day_fee': 75, 'pubtrans_compensation': 50,
'participant_fee': 35, 'trainer_compensation': 96,
'participant_day_fee': 30, 'trainer_daily_compensation': 73,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 37,
'min_participants': 3, 'participant_daily_fee': 32,
'max_participants': 4, 'pubtrans_bonus': 30,
'min_participants': 3,
'max_participants': 4,
}, },
'H': {'description': _(u'H (Alpiner Kurs CH/FR/IT/..)'), 'H': {'description': _(u'H (Alpiner Kurs CH/FR/IT/..)'),
'trainer_fee': 100, 'orga_compensation': 50,
'trainer_day_fee': 85, 'pubtrans_compensation': 50,
'participant_fee': 35, 'trainer_compensation': 96,
'participant_day_fee': 30, 'trainer_daily_compensation': 82,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 37,
'min_participants': 3, 'participant_daily_fee': 32,
'max_participants': 4, 'pubtrans_bonus': 30,
'min_participants': 3,
'max_participants': 4,
}, },
'I': {'description': _(u'I (Alpine MTB/Ski-Tour DE/AT)'), 'I': {'description': _(u'I (Alpine MTB/Ski-Tour DE/AT)'),
'trainer_fee': 80, 'orga_compensation': 40,
'trainer_day_fee': 75, 'pubtrans_compensation': 50,
'participant_fee': 25, 'trainer_compensation': 76,
'participant_day_fee': 25, 'trainer_daily_compensation': 73,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 26,
'min_participants': 3, 'participant_daily_fee': 26,
'max_participants': 6, 'pubtrans_bonus': 30,
'min_participants': 3,
'max_participants': 6,
}, },
'J': {'description': _(u'J (Alpine MTB/Ski-Tour CH/FR/IT/..)'), 'J': {'description': _(u'J (Alpine MTB/Ski-Tour CH/FR/IT/..)'),
'trainer_fee': 80, 'orga_compensation': 40,
'trainer_day_fee': 85, 'pubtrans_compensation': 50,
'participant_fee': 25, 'trainer_compensation': 76,
'participant_day_fee': 25, 'trainer_daily_compensation': 82,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 26,
'min_participants': 3, 'participant_daily_fee': 26,
'max_participants': 6, 'pubtrans_bonus': 30,
'min_participants': 3,
'max_participants': 6,
}, },
'K': {'description': _(u'K (Ski-Tour/-Kurs mit Liftbenutzung)'), 'K': {'description': _(u'K (Ski-Tour/-Kurs mit Liftbenutzung)'),
'trainer_fee': 80, 'orga_compensation': 40,
'trainer_day_fee': 130, 'pubtrans_compensation': 50,
'participant_fee': 40, 'trainer_compensation': 76,
'participant_day_fee': 40, 'trainer_daily_compensation': 124,
'pre_meeting_fee': 20, 'pre_meeting_compensation': 20,
'pubtrans_bonus': 30, 'participant_fee': 42,
'min_participants': 3, 'participant_daily_fee': 42,
'max_participants': 4, 'pubtrans_bonus': 30,
'min_participants': 3,
'max_participants': 4,
}, },
} }

View File

@@ -773,26 +773,35 @@ class ChargesForm(EventCreateForm):
_form_title = _(u'Kosten') _form_title = _(u'Kosten')
_next_form_name = 'DescriptionForm' _next_form_name = 'DescriptionForm'
pubtrans_planned = forms.BooleanField(disabled=True, required=False,
label=_(u'An-/Abreise mit Bahn/Bus geplant'),
)
charge_key = forms.CharField(disabled=True, charge_key = forms.CharField(disabled=True,
label=_(u'Kostenschlüssel'), label=_(u'Kostenschlüssel'),
) )
trainer_fee = forms.FloatField(disabled=True, orga_compensation = forms.FloatField(disabled=True,
label=_(u'Pauschale Trainer*in'), label=_(u'Aufwand für Tourenleitung'),
) )
trainer_day_fee = forms.FloatField(disabled=True, pubtrans_compensation = forms.FloatField(disabled=True,
label=_(u'Tagespauschale Trainer*in'), label=_(u'Aufwand für Organisation Bahn/Bus'),
) )
trainer_compensation = forms.FloatField(disabled=True,
label=_(u'Aufwand für Trainer*in'),
)
trainer_daily_compensation = forms.FloatField(disabled=True,
label=_(u'Täglicher Aufwand für Trainer*in'),
)
pre_meeting_compensation = forms.FloatField(disabled=True,
label=_(u'Aufwand pro Vortreffen'),
)
participant_fee = forms.FloatField(disabled=True, participant_fee = forms.FloatField(disabled=True,
label=_(u'Pauschale Teilnehmer*in'), label=_(u'Beitrag für Teilnehmer*in'),
)
participant_day_fee = forms.FloatField(disabled=True,
label=_(u'Tagespauschale Teilnehmer*in'),
)
pre_meeting_fee = forms.FloatField(disabled=True,
label=_(u'Pauschale pro Vortreffen'),
) )
participant_daily_fee = forms.FloatField(disabled=True,
label=_(u'Täglicher Beitrag für Teilnehmer*in'),
)
pubtrans_bonus = forms.FloatField(disabled=True, pubtrans_bonus = forms.FloatField(disabled=True,
label=_(u'Bonus bei Benutzung öffentlicher Verkehrsmittel'), label=_(u'Rückzahlung bei Benutzung Bahn/Bus'),
) )
trainer1_reward = forms.FloatField(disabled=True, trainer1_reward = forms.FloatField(disabled=True,
label=_(u'Aufwandsentschädigung Tourenleiter*in'), label=_(u'Aufwandsentschädigung Tourenleiter*in'),
@@ -832,6 +841,10 @@ class ChargesForm(EventCreateForm):
additional_costs_text = u'' additional_costs_text = u''
if transport != 'coach': if transport != 'coach':
additional_costs_text += ugettext(u'Fahrtkosten') additional_costs_text += ugettext(u'Fahrtkosten')
if transport == 'public':
pubtrans_planned = True
else:
pubtrans_planned = False
if last_day: if last_day:
timedelta = last_day - first_day timedelta = last_day - first_day
@@ -850,57 +863,83 @@ class ChargesForm(EventCreateForm):
else: else:
n_pre_meetings = 0 n_pre_meetings = 0
trainer_reward = ( trainer1_reward = (
matrix_config['trainer_fee'] matrix_config['orga_compensation']
+ ndays * matrix_config['trainer_day_fee'] + matrix_config['trainer_compensation']
+ n_pre_meetings * matrix_config['pre_meeting_fee'] + ndays * matrix_config['trainer_daily_compensation']
+ n_pre_meetings * matrix_config['pre_meeting_compensation']
)
trainer23_reward = (
matrix_config['trainer_compensation']
+ ndays * matrix_config['trainer_daily_compensation']
+ n_pre_meetings * matrix_config['pre_meeting_compensation']
) )
charge = ( charge = (
matrix_config['participant_fee'] matrix_config['participant_fee']
+ ndays * matrix_config['participant_day_fee'] + ndays * matrix_config['participant_daily_fee']
) )
if arrival_previous_day: if pubtrans_planned:
trainer_reward += matrix_config['trainer_day_fee'] / 2.0 trainer1_reward += matrix_config['pubtrans_compensation']
charge += matrix_config['participant_day_fee'] / 2.0
if arrival_previous_day:
trainer1_reward += matrix_config['trainer_daily_compensation'] / 2.0
trainer23_reward += matrix_config['trainer_daily_compensation'] / 2.0
charge += matrix_config['participant_daily_fee'] / 2.0
self.fields['pubtrans_planned'].initial = pubtrans_planned
self.fields['charge_key'].initial = matrix_config['description'] or matrix_key self.fields['charge_key'].initial = matrix_config['description'] or matrix_key
self.fields['trainer_fee'].initial = matrix_config['trainer_fee'] self.fields['orga_compensation'].initial = matrix_config['orga_compensation']
self.fields['trainer_day_fee'].initial = matrix_config['trainer_day_fee'] self.fields['pubtrans_compensation'].initial = matrix_config['pubtrans_compensation']
self.fields['trainer_compensation'].initial = matrix_config['trainer_compensation']
self.fields['trainer_daily_compensation'].initial = matrix_config['trainer_daily_compensation']
self.fields['pre_meeting_compensation'].initial = matrix_config['pre_meeting_compensation']
self.fields['participant_fee'].initial = matrix_config['participant_fee'] self.fields['participant_fee'].initial = matrix_config['participant_fee']
self.fields['participant_day_fee'].initial = matrix_config['participant_day_fee'] self.fields['participant_daily_fee'].initial = matrix_config['participant_daily_fee']
self.fields['pre_meeting_fee'].initial = matrix_config['pre_meeting_fee']
self.fields['pubtrans_bonus'].initial = matrix_config['pubtrans_bonus'] self.fields['pubtrans_bonus'].initial = matrix_config['pubtrans_bonus']
self.fields['charge'].initial = charge self.fields['charge'].initial = charge
self.fields['trainer1_reward'].initial = trainer_reward self.fields['trainer1_reward'].initial = trainer1_reward
self.fields['trainer23_reward'].initial = trainer_reward * 0.95 self.fields['trainer23_reward'].initial = trainer23_reward
self.fields['pubtrans_bonus'].widget.attrs['title'] = ugettext(u'Der Bonus wird nachträglich' self.fields['pubtrans_bonus'].widget.attrs['title'] = ugettext(u'Der Bonus wird nachträglich'
u' auf Meldung der Tourenleitung' u' auf Meldung der Tourenleitung'
u' verrechnet und ist noch nicht' u' verrechnet und ist noch nicht'
u' in den hier dargestellten Zahlen enthalten.') u' in den hier dargestellten Zahlen enthalten.')
self.fields['charge'].widget.attrs['title'] = (u'%dPauschale \n' self.fields['charge'].widget.attrs['title'] = (u'%dBeitrag \n'
u'+ %d Tage * %dTagespauschale \n' u'+ %d Tage * %dtäglicher Beitrag \n'
u'+ %d halben Anreisetag * %dTagespauschale / 2' u'+ %d halben Anreisetag * %dhalbtäglicher Beitrag'
% ( % (
matrix_config['participant_fee'], matrix_config['participant_fee'],
ndays, matrix_config['participant_day_fee'], ndays, matrix_config['participant_daily_fee'],
int(arrival_previous_day), matrix_config['participant_day_fee'], int(arrival_previous_day), matrix_config['participant_daily_fee']/2,
) )
) )
self.fields['trainer1_reward'].widget.attrs['title'] = (u'%dPauschale \n' self.fields['trainer1_reward'].widget.attrs['title'] = (u'%dAufwand für Tourenleitung\n'
u'+ %d Tage * %d € Tagespauschale \n' u'+ %d € Aufwand für Organisation Bahn/Bus\n'
u'+ %d halben Anreisetag * %d € Tagespauschale / 2 \n' u'+ %d € Aufwand für Trainer*in\n'
u'+ %d Vortreffen * %dVortreffenpauschale' u'+ %d Tage * %dtäglicher Aufwand \n'
u'+ %d halben Anreisetag * %d € halbtäglicher Aufwand\n'
u'+ %d Vortreffen * %d € Aufwand pro Vortreffen'
% ( % (
matrix_config['trainer_fee'], matrix_config['orga_compensation'],
ndays, matrix_config['trainer_day_fee'], int(pubtrans_planned)*matrix_config['pubtrans_compensation'],
int(arrival_previous_day), matrix_config['trainer_day_fee'], matrix_config['trainer_compensation'],
n_pre_meetings, matrix_config['pre_meeting_fee'] ndays, matrix_config['trainer_daily_compensation'],
int(arrival_previous_day), matrix_config['trainer_daily_compensation']/2,
n_pre_meetings, matrix_config['pre_meeting_compensation']
)
)
self.fields['trainer23_reward'].widget.attrs['title'] = (u'%d € Aufwand für Trainer*in\n'
u'+ %d Tage * %d € täglicher Aufwand \n'
u'+ %d halben Anreisetag * %d € halbtäglicher Aufwand\n'
u'+ %d Vortreffen * %d € Aufwand pro Vortreffen'
% (
matrix_config['trainer_compensation'],
ndays, matrix_config['trainer_daily_compensation'],
int(arrival_previous_day), matrix_config['trainer_daily_compensation']/2,
n_pre_meetings, matrix_config['pre_meeting_compensation']
) )
) )
self.fields['trainer23_reward'].widget.attrs['title'] = ugettext(u'95% der Aufwandsentschädigung'
u' Tourenleiter*in')
self.fields['additional_costs'].widget.attrs['placeholder'] = ugettext(u'Kann freigelassen werden') self.fields['additional_costs'].widget.attrs['placeholder'] = ugettext(u'Kann freigelassen werden')
self.fields['additional_costs'].initial = additional_costs_text self.fields['additional_costs'].initial = additional_costs_text

View File

@@ -11,21 +11,29 @@
{% bootstrap_field form.charge_key %} {% bootstrap_field form.charge_key %}
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
{% bootstrap_field form.trainer_fee %} {% bootstrap_field form.orga_compensation %}
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
{% bootstrap_field form.participant_fee %} {% bootstrap_field form.pubtrans_compensation %}
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-4"> <div class="col-sm-4">
{% bootstrap_field form.pre_meeting_fee %} {% bootstrap_field form.trainer_compensation %}
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
{% bootstrap_field form.trainer_day_fee %} {% bootstrap_field form.trainer_daily_compensation %}
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
{% bootstrap_field form.participant_day_fee %} {% bootstrap_field form.pre_meeting_compensation %}
</div>
</div>
<div class="row">
<div class="col-sm-4">
{% bootstrap_field form.participant_fee %}
</div>
<div class="col-sm-4">
{% bootstrap_field form.participant_daily_fee %}
</div> </div>
</div> </div>
</div> </div>
@@ -34,6 +42,9 @@
<div class="col-sm-8"> <div class="col-sm-8">
{% bootstrap_field form.pubtrans_bonus %} {% bootstrap_field form.pubtrans_bonus %}
</div> </div>
<div class="col-sm-4">
{% bootstrap_field form.pubtrans_planned %}
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">