Merge pull request 'FIX #15 and more' (#32) from heinzel into master

Reviewed-on: #32
This commit was merged in pull request #32.
This commit is contained in:
2020-12-18 15:38:24 +01:00
17 changed files with 351 additions and 74 deletions

View File

@@ -210,6 +210,17 @@
<form action="" method="post" class="form-inline">
{% csrf_token %}
<input type="hidden" name="id" value="{{ participant.id }}">
{% if event.charge and has_permission_payment %}
<button name="action" value="toggle_reduced_fee"
title="{% trans 'Hier klicken, um zwischen voller und reduzierter Teilnahmegebühr umzuschalten' %}"
class="btn btn-link no-padding">
<span class="text-primary">
{% if participant.apply_reduced_fee %}{% bootstrap_icon 'check' %}{% else %}{% bootstrap_icon 'unchecked' %}{% endif %}
Reduzierte Teilnamegebühr
</span>
</button>
&nbsp;
{% endif %}
{% if has_permission_update_participants %}
<button name="action" value="moveup_participant"
title="{% trans 'Nach oben verschieben' %}"
@@ -229,30 +240,35 @@
{% endif %}
{% if event.charge and participant.paid and has_permission_payment %}
&nbsp;
<span class="text-success"><strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong></span><button
<span class="text-success {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><button
name="action" value="revoke_payment"
title="{% trans 'Geldeingang wurde bestätigt' %} - {% trans 'Bestätigung des Geldeingangs zurückziehen' %}"
class="btn btn-link no-padding"><span class="text-success">{% bootstrap_icon 'piggy-bank' %}</span></button>
{% elif event.charge and participant.paid %}
&nbsp;
<span class="text-success" title="{% trans 'Geldeingang bestätigt' %}">
<strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="text-success {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="text-success"
title="{% trans 'Geldeingang bestätigt' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% elif event.charge and has_permission_payment %}
&nbsp;
<span class="text-danger"><strong>{% if participant.apply_reduced_fee %}%{% elif participant.created_at|date:'U' < '1608764400' %}? {% else %}&emsp;{% endif %}</strong></span><button
<span class="text-danger {% if not participant.apply_reduced_fee and participant.created_at|date:'U' > '1608764400' %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>{% if participant.apply_reduced_fee %}%{% else %}? {% endif %}</strong></span><button
name="action" value="confirm_payment"
title="{% trans 'Geldeingang bestätigen' %}"
class="btn btn-link no-padding"><span class="text-danger">{% bootstrap_icon 'piggy-bank' %}</span></button>
{% elif event.charge %}
&nbsp;
<span class="text-danger" title="{% trans 'Geldeingang unbestätigt' %}">
<strong>{% if participant.apply_reduced_fee %}%{% elif participant.created_at|date:'U' < '1608764400' %}? {% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="text-danger {% if not participant.apply_reduced_fee and participant.created_at|date:'U' > '1608764400' %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>{% if participant.apply_reduced_fee %}%{% else %}? {% endif %}</strong></span><span
class="text-danger"
title="{% trans 'Geldeingang unbestätigt' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% else %}
<span class="hidden" title="{% trans 'Keine Teilnehmergebühr gefordert' %}">
<strong>&emsp;</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="hidden {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="hidden"
title="{% trans 'Keine Teilnehmergebühr gefordert' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% endif %}
</form>
</div>
@@ -287,6 +303,11 @@
</div>
</div>
{% endif %}
<div class="panel panel-default">
<div class="panel-body">
<strong title="Summe der bestätigten Geldeingänge (theoretisch!, da wir hier nur die Gebühren, aber nicht die tatsächlich überwiesenen Beträge kennen)">{% trans 'Gebuchte Teilnahmegebühren' %}:</strong> {{ earnings|floatformat:2 }} €
</div>
</div>
{% if participant_emails %}
<div class="panel panel-default">
<div class="panel-body">
@@ -380,14 +401,16 @@
</span>
{% if event.charge and participant.paid %}
&nbsp;
<span class="text-success" title="{% trans 'Geldeingang bestätigt' %}">
<strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="text-success {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="text-success"
title="{% trans 'Geldeingang bestätigt' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% elif event.charge %}
&nbsp;
<span class="text-danger" title="{% trans 'Geldeingang unbestätigt' %}">
<strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="text-danger {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="text-danger"
title="{% trans 'Geldeingang unbestätigt' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% endif %}
</span>
</div>

View File

@@ -71,24 +71,37 @@
<form action="" method="post" class="form-inline">
{% csrf_token %}
<input type="hidden" name="id" value="{{ participant.id }}">
{% if event.charge %}
<button name="action" value="toggle_reduced_fee"
title="{% trans 'Hier klicken, um zwischen voller und reduzierter Teilnahmegebühr umzuschalten' %}"
class="btn btn-link no-padding">
<span class="text-primary">
{% if participant.apply_reduced_fee %}{% bootstrap_icon 'check' %}{% else %}{% bootstrap_icon 'unchecked' %}{% endif %}
</span>
</button>
&nbsp;
{% endif %}
{% if event.charge and participant.paid %}
<span class="text-success"><strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong></span><button
<span class="text-success {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><button
name="action" value="revoke_payment"
title="{% trans 'Geldeingang wurde bestätigt' %} - {% trans 'Bestätigung des Geldeingangs zurückziehen' %}"
class="btn btn-link no-padding"><span class="text-success">{% bootstrap_icon 'piggy-bank' %}</span></button>
&nbsp;
({{ event.charge|floatformat:'-2' }}{% if participant.apply_reduced_fee %} / 2{% endif %} €)
{% elif event.charge %}
<span class="text-danger"><strong>{% if participant.apply_reduced_fee %}%{% elif participant.created_at|date:'U' < '1608764400' %}? {% else %}&emsp;{% endif %}</strong></span><button
<span class="text-danger {% if not participant.apply_reduced_fee and participant.created_at|date:'U' > '1608764400' %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>{% if participant.apply_reduced_fee %}%{% else %}? {% endif %}</strong></span><button
name="action" value="confirm_payment"
title="{% trans 'Geldeingang bestätigen' %}"
class="btn btn-link no-padding"><span class="text-danger">{% bootstrap_icon 'piggy-bank' %}</span></button>
&nbsp;
({{ event.charge|floatformat:'-2' }}{% if participant.apply_reduced_fee %} / 2{% endif %} €)
{% else %}
<span class="text-muted" title="{% trans 'Keine Teilnehmergebühr gefordert' %}">
<strong>&emsp;</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="hidden {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="hidden"
title="{% trans 'Keine Teilnehmergebühr gefordert' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% endif %}
</form>
</td>

View File

@@ -53,6 +53,11 @@ class ParticipantListView(generic.ListView):
participant = get_object_or_404(Participant, pk=participant_id)
participant.paid = False
participant.save()
elif action == 'toggle_reduced_fee':
participant_id = request.POST.get('id')
participant = get_object_or_404(Participant, pk=participant_id)
participant.apply_reduced_fee = not participant.apply_reduced_fee
participant.save()
else:
messages.error(request, 'unsupported action: {}'.format(action))
return HttpResponseRedirect(reverse('dav_event_office:participant-list'))

View File

@@ -1,3 +1,4 @@
from . import generic
from . import events
from . import participant
from . import registration

View File

@@ -7,7 +7,9 @@ from ..models import Participant
class ParticipantForm(forms.ModelForm):
class Meta:
model = Participant
exclude = ['event', 'created_at', 'position', 'purge_at']
exclude = ['event', 'created_at', 'position',
'privacy_policy', 'privacy_policy_accepted',
'paid', 'purge_at']
widgets = {
'emergency_contact': forms.Textarea(attrs={'rows': 4}),
'experience': forms.Textarea(attrs={'rows': 5}),

View File

@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from django import forms
from django.utils.translation import ugettext_lazy as _
class RegistrationResponseForm(forms.Form):
apply_reduced_fee = forms.BooleanField(required=False,
label=_(u'Reduzierte Teilnahmegebühr'))

View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-12-15 10:55
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dav_events', '0038_auto_20201209_1542'),
]
operations = [
migrations.AlterField(
model_name='participant',
name='apply_reduced_fee',
field=models.BooleanField(default=False, help_text='Für Jugendliche und Junioren (bis zum vollendeten 25. Lebensjahr), sowie Mitglieder mit geringen finanziellen Mitteln (Nachweis durch "Karlsruher Pass"), wird die Teilnahmegebühr auf 50% ermäßigt.', verbose_name='Antrag auf reduzierte Teilnahmegebühr'),
),
migrations.AlterField(
model_name='participant',
name='year_of_birth',
field=models.IntegerField(help_text='Vierstellige Jahreszahl', verbose_name='Geburtsjahr'),
),
migrations.AlterField(
model_name='trashedparticipant',
name='apply_reduced_fee',
field=models.BooleanField(default=False, help_text='Für Jugendliche und Junioren (bis zum vollendeten 25. Lebensjahr), sowie Mitglieder mit geringen finanziellen Mitteln (Nachweis durch "Karlsruher Pass"), wird die Teilnahmegebühr auf 50% ermäßigt.', verbose_name='Antrag auf reduzierte Teilnahmegebühr'),
),
migrations.AlterField(
model_name='trashedparticipant',
name='year_of_birth',
field=models.IntegerField(help_text='Vierstellige Jahreszahl', verbose_name='Geburtsjahr'),
),
]

View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-12-16 16:12
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dav_events', '0039_auto_20201215_1155'),
]
operations = [
migrations.AddField(
model_name='participant',
name='privacy_policy',
field=models.TextField(blank=True, verbose_name='Erklärung zur Datenspeicherung'),
),
migrations.AddField(
model_name='participant',
name='privacy_policy_accepted',
field=models.BooleanField(default=False, verbose_name='Einwilligung zur Datenspeicherung'),
),
migrations.AddField(
model_name='trashedparticipant',
name='privacy_policy',
field=models.TextField(blank=True, verbose_name='Erklärung zur Datenspeicherung'),
),
migrations.AddField(
model_name='trashedparticipant',
name='privacy_policy_accepted',
field=models.BooleanField(default=False, verbose_name='Einwilligung zur Datenspeicherung'),
),
]

View File

@@ -53,6 +53,11 @@ class AbstractParticipant(models.Model):
verbose_name=_('Anmerkung'),
help_text=_('Kann frei gelassen werden.'))
privacy_policy = models.TextField(blank=True,
verbose_name=_('Erklärung zur Datenspeicherung'))
privacy_policy_accepted = models.BooleanField(default=False,
verbose_name=_('Einwilligung zur Datenspeicherung'))
paid = models.BooleanField('Teilnehmerbeitrag bezahlt', default=False)
purge_at = models.DateTimeField()

View File

@@ -40,11 +40,9 @@
{% bootstrap_icon 'remove' %}&thinsp;
{% trans 'Abbrechen' %}
</a>
<!--
<button id="btn-form-save" type="submit" name="save" class="btn btn-info">
{% bootstrap_icon 'hdd' %}&thinsp;
{% trans 'Als Entwurf speichern' %}
</button>
-->
{% endbuttons %}
{% endblock form-buttons %}

View File

@@ -272,10 +272,17 @@ Das musst du selbst (per E-Mail oder telefonisch) machen.
{% csrf_token %}
<input type="hidden" name="registration" value="{{ registration.id }}">
{% if has_permission_update_participants %}
{% if registration.apply_reduced_fee %}
<a href="{% url 'dav_events:respond_registration' registration.pk %}"
class="btn btn-link no-padding" title="zur Teilnehmerliste hinzufügen">
<span class="text-success">{% bootstrap_icon 'plus-sign' %}</span>
</a>
{% else %}
<button type="submit" name="action" value="accept_registration"
class="btn btn-link no-padding" title="zur Teilnehmerliste hinzufügen">
<span class="text-success">{% bootstrap_icon 'plus-sign' %}</span>
</button>
{% endif %}
&nbsp;
<button type="submit" name="action" value="reject_registration"
class="btn btn-link no-padding" title="Anmeldung löschen">
@@ -298,7 +305,7 @@ Das musst du selbst (per E-Mail oder telefonisch) machen.
{% if registration.apply_reduced_fee %}
&nbsp;
<span class="text-info">
<strong>%</strong>{% bootstrap_icon 'piggy-bank' %} (reduzierte Gebühr)
<strong title="{% trans 'reduzierte Teilnahmegebühr' %}">%</strong>{% bootstrap_icon 'piggy-bank' %} (reduzierte Gebühr)
</span>
{% endif %}
</form>
@@ -392,30 +399,35 @@ Wichtig: das System verschickt keine Bestätigung an dich oder den neuen Teilneh
{% endif %}
{% if event.charge and participant.paid and has_permission_payment %}
&nbsp;
<span class="text-success"><strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong></span><button
<span class="text-success {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><button
name="action" value="revoke_payment"
title="{% trans 'Geldeingang wurde bestätigt' %} - {% trans 'Bestätigung des Geldeingangs zurückziehen' %}"
class="btn btn-link no-padding"><span class="text-success">{% bootstrap_icon 'piggy-bank' %}</span></button>
{% elif event.charge and participant.paid %}
&nbsp;
<span class="text-success" title="{% trans 'Geldeingang bestätigt' %}">
<strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="text-success {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="text-success"
title="{% trans 'Geldeingang bestätigt' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% elif event.charge and has_permission_payment %}
&nbsp;
<span class="text-danger"><strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong></span><button
<span class="text-danger {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><button
name="action" value="confirm_payment"
title="{% trans 'Geldeingang bestätigen' %}"
class="btn btn-link no-padding"><span class="text-danger">{% bootstrap_icon 'piggy-bank' %}</span></button>
{% elif event.charge %}
&nbsp;
<span class="text-danger" title="{% trans 'Geldeingang unbestätigt' %}">
<strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="text-danger {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="text-danger"
title="{% trans 'Geldeingang unbestätigt' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% else %}
<span class="hidden" title="{% trans 'Keine Teilnehmergebühr gefordert' %}">
<strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="hidden {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="hidden"
title="{% trans 'Keine Teilnehmergebühr gefordert' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% endif %}
</form>
</div>
@@ -580,14 +592,16 @@ von Position {{ participant.position }} der Teilnehmerliste entfernt.
</span>
{% if event.charge and participant.paid %}
&nbsp;
<span class="text-success" title="{% trans 'Geldeingang bestätigt' %}">
<strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="text-success {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="text-success"
title="{% trans 'Geldeingang bestätigt' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% elif event.charge %}
&nbsp;
<span class="text-danger" title="{% trans 'Geldeingang unbestätigt' %}">
<strong>{% if participant.apply_reduced_fee %}%{% else %}&emsp;{% endif %}</strong>{% bootstrap_icon 'piggy-bank' %}
</span>
<span class="text-danger {% if not participant.apply_reduced_fee %}invisible{% endif %}"
title="{% trans 'Reduzierte Teilnahmegebühr' %}"><strong>%</strong></span><span
class="text-danger"
title="{% trans 'Geldeingang unbestätigt' %}">{% bootstrap_icon 'piggy-bank' %}</span>
{% endif %}
</span>

View File

@@ -0,0 +1,45 @@
{% extends 'dav_events/base.html' %}
{% load bootstrap3 %}
{% load i18n %}
{% block head-title %}
{% trans 'Anmeldung' %} {{ registration.get_full_name }} - {{ registration.event.number }} - {{ block.super }}
{% endblock head-title %}
{% block page-container %}
<div class="well">
<p>
Hallo {{ registration.event.trainer_firstname }},
</p>
<p>
du hast sicherlich schon gesehen, dass {{ registration.get_full_name }} angekreuzt hat,
die reduzierte Teilnahmegebühr zahlen zu wollen.
</p>
<p>
Für Jugendliche und Junioren sowie Mitglieder mit geringen finanziellen Mitteln (Nachweis durch Karlsruher Paß)
wird die Teilnahmegebühr auf 50% ermäßigt.
</p>
<p>
Wenn ihr bereits darüber gesprochen habt und ihr übereingekommen seid,
dass {{ registration.personal_names }} doch den vollen Betrag zahlen soll,
dann kannst du unten den Haken entfernen.
</p>
</div>
<div class="well">
<h6>
{{ registration.event.number }} - {{ registration.event.title }}<br />
{% trans 'Anmeldung' %} {{ registration.get_full_name }}
</h6>
<form action="" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" name="action" value="accept_registration"
class="btn btn-success">
{% bootstrap_icon 'plus-sign' %} zur Teilnehmerliste hinzufügen
</button>
<a href="{% url 'dav_events:registrations' registration.event.pk %}" class="btn btn-danger">
{% bootstrap_icon 'remove' %} Zurück
</a>
</form>
</div>
{% endblock page-container %}

View File

@@ -12,6 +12,7 @@ urlpatterns = [
views.events.EventUpdateStatusView.as_view(), name='updatestatus'),
url(r'^(?P<pk>\d+)/edit', views.events.EventUpdateView.as_view(), name='update'),
url(r'^(?P<pk>\d+)/', views.events.EventDetailView.as_view(), name='detail'),
url(r'^registration/(?P<pk>\d+)/', views.events.RespondRegistrationView.as_view(), name='respond_registration'),
url(r'^action/(?P<pk>[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12})/',
views.actions.OneClickActionRunView.as_view(), name='action_run'),
]

View File

@@ -2,6 +2,7 @@
import datetime
import logging
import os
from django.apps import apps
from django.contrib import messages
from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
@@ -218,6 +219,16 @@ class EventRegistrationsView(EventPermissionMixin, generic.DetailView):
participants_trash = event.trashed_participants.all()
context['participants_trash'] = participants_trash
earnings = 0
if event.charge:
for participant in participants:
if participant.paid:
if participant.apply_reduced_fee:
earnings += event.charge / 2
else:
earnings += event.charge
context['earnings'] = earnings
if participants.count() > 1:
email_list = [u'"{}" <{}>'.format(p.get_full_name(), p.email_address) for p in participants]
email_list.sort()
@@ -271,30 +282,13 @@ class EventRegistrationsView(EventPermissionMixin, generic.DetailView):
messages.success(request, _(u'Der Anmeldeschluss wurde gelöscht'))
def _accept_registration(self, request, registration):
event = registration.event
data = registration.get_data_dict()
del data['created_at']
del data['answered_obsolete']
data['position'] = registration.event.participants.count() + 1
position = event.participants.count() + 1
data = {
'event': event,
'position': position,
'personal_names': registration.personal_names,
'family_names': registration.family_names,
'address': registration.address,
'postal_code': registration.postal_code,
'city': registration.city,
'email_address': registration.email_address,
'year_of_birth': registration.year_of_birth,
'apply_reduced_fee': registration.apply_reduced_fee,
'phone_number': registration.phone_number,
'dav_member': registration.dav_member,
'dav_number': registration.dav_number,
'emergency_contact': registration.emergency_contact,
'experience': registration.experience,
'note': registration.note,
'purge_at': registration.purge_at,
}
participant = models.Participant.objects.create(**data)
registration.status.set_accepted()
messages.success(request, _(u'Teilnehmer hinzugefügt: {}'.format(participant.get_full_name())))
@@ -360,6 +354,12 @@ class EventRegistrationsView(EventPermissionMixin, generic.DetailView):
self._reset_registration(registration)
else:
raise FieldDoesNotExist('Event has no registrations')
elif action == 'toggle_reduced_fee':
self.enforce_permission(event, permission='payment')
participant_id = request.POST.get('id')
participant = event.participants.get(id=participant_id)
participant.apply_reduced_fee = not participant.apply_reduced_fee
participant.save()
elif action == 'confirm_payment':
self.enforce_permission(event, permission='payment')
participant_id = request.POST.get('id')
@@ -455,6 +455,62 @@ class EventRegistrationsView(EventPermissionMixin, generic.DetailView):
return super(EventRegistrationsView, self).dispatch(request, *args, **kwargs)
class RespondRegistrationView(EventPermissionMixin, generic.DetailView, generic.FormView):
permission = 'update-participants'
context_object_name = 'registration'
template_name = 'dav_events/registration_response.html'
form_class = forms.registration.RegistrationResponseForm
def _accept_registration(self, request, registration):
data = registration.get_data_dict()
del data['created_at']
del data['answered_obsolete']
data['position'] = registration.event.participants.count() + 1
participant = models.Participant.objects.create(**data)
registration.status.set_accepted()
messages.success(request, _(u'Teilnehmer hinzugefügt: {}'.format(participant.get_full_name())))
def has_permission(self, permission, obj):
user = self.request.user
return obj.event.workflow.has_permission(user, permission)
def get_queryset(self):
model = apps.get_model(app_label='dav_registration', model_name='Registration')
return model.objects.all()
def get_success_url(self):
return reverse('dav_events:registrations', args=[self.object.event.pk])
def get_initial(self):
return {
'apply_reduced_fee': self.object.apply_reduced_fee,
}
def form_valid(self, form):
registration = self.object
registration.apply_reduced_fee = form.cleaned_data['apply_reduced_fee']
registration.save()
self._accept_registration(self.request, registration)
return HttpResponseRedirect(self.get_success_url())
def get(self, request, *args, **kwargs):
self.object = self.get_object()
self.enforce_permission(self.object)
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
self.enforce_permission(self.object)
return super(RespondRegistrationView, self).post(request, *args, **kwargs)
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(RespondRegistrationView, self).dispatch(request, *args, **kwargs)
class EventUpdateStatusView(EventPermissionMixin, generic.DetailView):
model = models.Event
@@ -487,6 +543,18 @@ class EventUpdateStatusView(EventPermissionMixin, generic.DetailView):
messages.error(request, message)
return HttpResponseRedirect(event.get_absolute_url())
if not event.workflow.has_reached_status('publishing*') and not event.workflow.has_reached_status('published*'):
cur_pub_date = event.planned_publication_date
real_pub_date, real_pub_issue = event.workflow.plan_publication(event.first_day, event.deadline)
if cur_pub_date != real_pub_date:
if real_pub_date is None:
real_pub_str = _(u'Unverzüglich')
else:
real_pub_str = u'%s (%s)' % (real_pub_date.strftime('%d.%m.%Y'), real_pub_issue)
event.planned_publication_date = real_pub_date
event.save()
messages.warning(request, _(u'Veröffentlichungsdatum wurde angepasst: %s') % real_pub_str)
event.workflow.update_status(status, request.user)
if status.startswith('submit'):
@@ -546,7 +614,21 @@ class EventUpdateView(EventPermissionMixin, generic.UpdateView):
def form_valid(self, form):
form.instance.editor = self.request.user
self.object = form.save()
event = form.save()
self.object = event
if not event.workflow.has_reached_status('publishing*') and not event.workflow.has_reached_status('published*'):
cur_pub_date = event.planned_publication_date
real_pub_date, real_pub_issue = event.workflow.plan_publication(event.first_day, event.deadline)
if cur_pub_date != real_pub_date:
if real_pub_date is None:
real_pub_str = _(u'Unverzüglich')
else:
real_pub_str = u'%s (%s)' % (real_pub_date.strftime('%d.%m.%Y'), real_pub_issue)
event.planned_publication_date = real_pub_date
event.save()
messages.warning(self.request, _(u'Veröffentlichungsdatum wurde angepasst: %s') % real_pub_str)
return HttpResponseRedirect(self.get_success_url())
@method_decorator(login_required)

View File

@@ -489,9 +489,8 @@ class BasicWorkflow(object):
#
# Misc logic
#
# TODO: is a class method a good idea?
@classmethod
def plan_publication(cls, first_day, deadline=None):
@staticmethod
def plan_publication(first_day, deadline=None):
app_config = apps.get_containing_app_config(__package__)
if deadline:

View File

@@ -11,10 +11,14 @@ logger = logging.getLogger(__name__)
class RegistrationForm(forms.ModelForm):
not_dav_member = forms.BooleanField(required=False,
label=_('Ich bin noch kein DAV Mitglied.'),
help_text=_('Wenn du noch kein DAV Mitglied bist,'
' oder deine Aufnahme noch in Arbeit ist,'
' kreuze dieses Feld hier an.'))
label=_(u'Ich bin noch kein DAV Mitglied.'),
help_text=u'%s<br />\n%s' % (
_(u'Wenn du noch kein DAV Mitglied bist,'
u' oder deine Aufnahme noch in Arbeit ist,'
u' kreuze dieses Feld hier an.'),
_(u'Spätestens zu Veranstaltungsbeginn muss'
u' jedoch eine Mitgliedschaft bestehen.')
))
class Meta:
model = Registration
@@ -26,7 +30,7 @@ class RegistrationForm(forms.ModelForm):
'note': forms.Textarea(attrs={'rows': 5}),
}
labels = {
'apply_reduced_fee': _('Ich bin noch keine 25 Jahre alt oder besitze einen "Karlsruher Pass".'),
'apply_reduced_fee': _(u'Ich bin noch keine 25 Jahre alt oder besitze einen "Karlsruher Pass".'),
}
def clean_year_of_birth(self):

View File

@@ -164,6 +164,13 @@ Anmerkung:
note=self.note,
)
def get_data_dict(self):
data = {}
for field in self._meta.fields:
if not field.primary_key:
data[field.name] = getattr(self, field.name)
return data
def clean(self):
if self.dav_member and not self.dav_number:
raise ValidationError({'dav_number': _('Wenn du DAV Mitglied bist, brauchen wir deine Mitgliedsnummer.')})