Commit 44ca1d67 authored by Thom Wiggers's avatar Thom Wiggers 📐
Browse files

Merge branch 'fix/340-events-post' into 'master'

Make sure events registration uses POST and is done when 'register' is pressed

Closes #340 and #346

See merge request !411
parents 2532f723 a17708a0
......@@ -95,33 +95,39 @@
{% if request.user.is_authenticated and request.user.member is not None and request.user.member.current_membership is not None and request.user.member.can_attend_events %}
{% if event.status == event.REGISTRATION_OPEN or event.status == event.REGISTRATION_OPEN_NO_CANCEL %}
{% if registration is not None and registration.date_cancelled is None and event.has_fields %}
<a class="btn btn-style1" href="{% url 'events:registration' event.id 'update' %}">{% trans "Update registration" %}</a>
<br /><br />
<form action="{% url 'events:registration' event.id 'update' %}" method="post">{% csrf_token %}
<input type="submit" class="btn btn-style1" value="{% trans "Update registration" %}" />
</form>
{% endif %}
{% endif %}
{% if event.status == event.REGISTRATION_OPEN or event.status == event.REGISTRATION_CLOSED_CANCEL_ONLY or event.status == event.REGISTRATION_OPEN_NO_CANCEL %}
{% if registration is None or registration.date_cancelled is not None %}
{% if event.status == event.REGISTRATION_OPEN or event.status == event.REGISTRATION_OPEN_NO_CANCEL %}
<a class="btn btn-style1" href="{% url 'events:registration' event.id 'register' %}">
<form action="{% url 'events:registration' event.id 'register' %}" method="post">{% csrf_token %}
{% if event.reached_participants_limit %}
{% trans "Put me on the waiting list" %}
<input type="submit" class="btn btn-style1" value="{% trans "Put me on the waiting list" %}" />
{% else %}
{% trans "Register" %}
<input type="submit" class="btn btn-style1" value="{% trans "Register" %}" />
{% endif %}
</a>
</form>
{% endif %}
{% elif registration is not None and registration.date_cancelled is None %}
{# Special message to accept costs when cancelling after the deadline, unless member is on the waiting list #}
{% if registration.queue_position == 0 and event.after_cancel_deadline %}
<a class="btn btn-style1" href="{% url 'events:registration' event.id 'cancel' %}" onclick="return confirm('{% blocktrans with costs=event.fine %}The deadline has passed, are you sure you want to cancel your registration and pay the full costs of €{{ costs }}? You will not be able to undo this!{% endblocktrans %}');">{% trans "Cancel registration" %}</a>
{% else %}
<a class="btn btn-style1" href="{% url 'events:registration' event.id 'cancel' %}" onclick="return confirm('{% trans "Are you sure you want to cancel your registration?" %}');">{% trans "Cancel registration" %}</a>
{% endif %}
<form action="{% url 'events:registration' event.id 'cancel' %}" method="post">{% csrf_token %}
{% if event.reached_participants_limit %}
<input type="submit" class="btn btn-style1" value="{% trans "Cancel registration" %}" onclick="return confirm('{% blocktrans with costs=event.fine %}The deadline has passed, are you sure you want to cancel your registration and pay the full costs of €{{ costs }}? You will not be able to undo this!{% endblocktrans %}');" />
{% else %}
<input type="submit" class="btn btn-style1" value="{% trans "Cancel registration" %}" />
{% endif %}
</form>
{% endif %}
{% endif %}
{% elif request.user.is_authenticated is False %}
<a class="btn btn-style1" href="{% url 'login' %}?next={{ request.path }}">{% trans "Login" %}</a>
{% endif %}
</form>
</td>
</tr>
<tr>
......
......@@ -66,7 +66,7 @@ class RegistrationTest(TestCase):
response = self.client.post('/events/1/registration/register/',
follow=True)
self.assertEqual(response.status_code, 200)
response = self.client.post('/events/1/registration/register',
response = self.client.post('/events/1/registration/register/',
follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.num_participants(), 1)
......@@ -162,6 +162,7 @@ class RegistrationTest(TestCase):
response = self.client.post('/events/1/registration/register/',
follow=True)
self.assertEqual(response.status_code, 200)
template_names = [template.name for template in response.templates]
self.assertIn('events/event_fields.html', template_names)
......
......@@ -173,6 +173,121 @@ def event(request, event_id):
return render(request, 'events/event.html', context)
def _send_queue_mail(event):
if (event.max_participants is not None and
Registration.objects
.filter(event=event, date_cancelled=None)
.count() > event.max_participants):
# Prepare email to send to the first person on the waiting
# list
first_waiting = (Registration.objects
.filter(event=event, date_cancelled=None)
.order_by('date')[event.max_participants])
first_waiting_member = first_waiting.member
text_template = get_template('events/email.txt')
with translation.override(first_waiting_member.language):
subject = _("[THALIA] Notification about your "
"reg for '{}'").format(
event.title)
text_message = text_template.render({
'event': event,
'reg': first_waiting,
'member': first_waiting_member
})
EmailMessage(
subject,
text_message,
to=[first_waiting_member.user.email]
).send()
def _show_registration_fields(request, event, reg, action):
form = FieldsForm(registration=reg)
if request.POST:
form = FieldsForm(request.POST, registration=reg)
if form.is_valid():
reg.save()
form_field_values = form.field_values()
for field in form_field_values:
if (field['field'].type ==
RegistrationInformationField.INTEGER_FIELD and
field['value'] is None):
field['value'] = 0
field['field'].set_value_for(reg,
field['value'])
return render(request, 'events/event_fields.html',
{'event': event, 'form': form, 'action': action})
def _registration_register(request, event, reg):
if reg is None:
reg = Registration()
reg.event = event
reg.member = request.user.member
messages.success(request, _("Registration successful."))
if event.has_fields():
return _show_registration_fields(request, event, reg, 'register')
else:
reg.save()
elif reg.date_cancelled is not None:
if reg.is_late_cancellation():
messages.error(request, _("You cannot re-register anymore since "
"you've cancelled after the deadline."))
else:
reg.date = timezone.now()
reg.date_cancelled = None
messages.success(request, _("Registration successful."))
if event.has_fields():
return _show_registration_fields(request, event, reg,
'register')
else:
reg.save()
elif not reg.member.can_attend_events:
messages.error(request, _("You may not register"))
else:
storage = messages.get_messages(request)
was_success = False
for message in storage:
was_success = message.message == _("Registration successful.")
storage.used = False
if not was_success:
messages.error(request, _("You were already registered."))
return redirect(event)
def _registration_update(request, event, reg):
if not event.has_fields():
return redirect(event)
if reg is None:
messages.error(request, _("You are not registered for this event."))
return redirect(event)
return _show_registration_fields(request, event, reg, 'update')
def _registration_cancel(request, event, reg):
if reg is None or reg.date_cancelled is not None:
messages.error(request, _("You are not registered for this event."))
else:
# Note that this doesn't remove the values for the
# information fields that the user entered upon registering.
# But this is regarded as a feature, not a bug. Especially
# since the values will still appear in the backend.
reg.date_cancelled = timezone.now()
reg.save()
_send_queue_mail(event)
messages.success(request, _("Registration successfully cancelled."))
return redirect(event)
@login_required
def registration(request, event_id, action=None):
event = get_object_or_404(
......@@ -184,117 +299,25 @@ def registration(request, event_id, action=None):
request.user.member.current_membership is not None and
request.user.member.can_attend_events):
try:
obj = Registration.objects.get(
reg = Registration.objects.get(
event=event,
member=request.user.member
)
except Registration.DoesNotExist:
obj = None
success_message = None
error_message = None
show_fields = False
waiting_list_notification = None
if action == 'register' and (
event.status == Event.REGISTRATION_OPEN or
event.status == Event.REGISTRATION_OPEN_NO_CANCEL
):
if obj is None:
obj = Registration()
obj.event = event
obj.member = request.user.member
elif obj.date_cancelled is not None:
if obj.is_late_cancellation():
error_message = _("You cannot re-register anymore since "
"you've cancelled after the deadline.")
else:
obj.date = timezone.now()
obj.date_cancelled = None
elif not obj.member.can_attend_events:
error_message = _("You may not register")
else:
error_message = _("You were already registered.")
if error_message is None:
success_message = _("Registration successful.")
if event.has_fields():
show_fields = True
else:
obj.save()
elif (action == 'update' and
event.has_fields() and
obj is not None and
(event.status == Event.REGISTRATION_OPEN or
event.status == Event.REGISTRATION_OPEN_NO_CANCEL)):
show_fields = True
success_message = _("Registration successfully updated.")
elif action == 'cancel':
if (obj is not None and
obj.date_cancelled is None):
if (event.max_participants is not None and
Registration.objects
.filter(event=event, date_cancelled=None)
.count() > event.max_participants):
# Prepare email to send to the first person on the waiting
# list
first_waiting = (Registration.objects
.filter(event=event, date_cancelled=None)
.order_by('date')[event.max_participants])
first_waiting_member = first_waiting.member
text_template = get_template('events/email.txt')
with translation.override(first_waiting_member.language):
subject = _("[THALIA] Notification about your "
"registration for '{}'").format(
event.title)
text_message = text_template.render({
'event': event,
'registration': first_waiting,
'member': first_waiting_member
})
waiting_list_notification = EmailMessage(
subject,
text_message,
to=[first_waiting_member.user.email]
)
# Note that this doesn't remove the values for the
# information fields that the user entered upon registering.
# But this is regarded as a feature, not a bug. Especially
# since the values will still appear in the backend.
obj.date_cancelled = timezone.now()
obj.save()
success_message = _("Registration successfully cancelled.")
else:
error_message = _("You were not registered for this event.")
if show_fields:
if request.POST:
form = FieldsForm(request.POST, registration=obj)
if form.is_valid():
obj.save()
form_field_values = form.field_values()
for field in form_field_values:
if (field['field'].type ==
RegistrationInformationField.INTEGER_FIELD and
field['value'] is None):
field['value'] = 0
field['field'].set_value_for(obj,
field['value'])
else:
form = FieldsForm(registration=obj)
context = {'event': event, 'form': form, 'action': action}
return render(request, 'events/event_fields.html', context)
if success_message is not None:
messages.success(request, success_message)
elif error_message is not None:
messages.error(request, error_message)
if waiting_list_notification is not None:
waiting_list_notification.send()
reg = None
if request.method.lower() == 'post':
if action == 'register' and (
event.status == Event.REGISTRATION_OPEN or
event.status == Event.REGISTRATION_OPEN_NO_CANCEL
):
return _registration_register(request, event, reg)
elif (action == 'update' and
(event.status == Event.REGISTRATION_OPEN or
event.status == Event.REGISTRATION_OPEN_NO_CANCEL)):
return _registration_update(request, event, reg)
elif action == 'cancel':
return _registration_cancel(request, event, reg)
return redirect(event)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment