Add signal for required pre-checkout confirmations

This commit is contained in:
Raphael Michel
2017-02-20 15:40:55 +01:00
parent 2d00563088
commit f16aabc136
5 changed files with 58 additions and 3 deletions

View File

@@ -25,7 +25,7 @@ Frontend
--------
.. automodule:: pretix.presale.signals
:members: html_head, footer_links, front_page_top, front_page_bottom
:members: html_head, footer_links, front_page_top, front_page_bottom, checkout_confirm_messages
.. automodule:: pretix.presale.signals

View File

@@ -2,7 +2,7 @@ from django.conf import settings
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.core.validators import EmailValidator
from django.http import HttpResponseNotAllowed
from django.http import HttpResponseNotAllowed, JsonResponse
from django.shortcuts import redirect
from django.utils import translation
from django.utils.functional import cached_property
@@ -15,7 +15,9 @@ from pretix.base.services.orders import perform_order
from pretix.base.signals import register_payment_providers
from pretix.multidomain.urlreverse import eventreverse
from pretix.presale.forms.checkout import ContactForm, InvoiceAddressForm
from pretix.presale.signals import checkout_flow_steps, order_meta_from_request
from pretix.presale.signals import (
checkout_confirm_messages, checkout_flow_steps, order_meta_from_request,
)
from pretix.presale.views import CartMixin, get_cart_total
from pretix.presale.views.async import AsyncAction
from pretix.presale.views.questions import QuestionsViewMixin
@@ -307,8 +309,17 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep):
ctx['payment'] = self.payment_provider.checkout_confirm_render(self.request)
ctx['payment_provider'] = self.payment_provider
ctx['addr'] = self.invoice_address
ctx['confirm_messages'] = self.confirm_messages
return ctx
@cached_property
def confirm_messages(self):
msgs = {}
responses = checkout_confirm_messages.send(self.request.event)
for receiver, response in responses:
msgs.update(response)
return msgs
@cached_property
def payment_provider(self):
responses = register_payment_providers.send(self.request.event)
@@ -335,6 +346,20 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep):
def post(self, request):
self.request = request
if self.confirm_messages:
for key, msg in self.confirm_messages.items():
if request.POST.get('confirm_{}'.format(key)) != 'yes':
msg = str(_('You need to check all checkboxes on the bottom of the page.'))
messages.error(self.request, msg)
if "ajax" in self.request.POST or "ajax" in self.request.GET:
return JsonResponse({
'ready': True,
'redirect': self.get_error_url(),
'message': msg
})
return redirect(self.get_error_url())
meta_info = {}
for receiver, response in order_meta_from_request.send(sender=request.event, request=request):
meta_info.update(response)

View File

@@ -21,6 +21,16 @@ are expected to return a dictionary containing the keys ``label`` and ``url``.
As with all plugin signals, the ``sender`` keyword argument will contain the event.
"""
checkout_confirm_messages = EventPluginSignal()
"""
This signal is sent out to retrieve short messages that need to be acknowledged by the user before the
order can be completed. This is typically used for something like "accept the terms and conditions".
Receivers are expected to return a dictionary where the keys are globally unique identifiers for the
message and the values can be arbitrary HTML.
As with all plugin signals, the ``sender`` keyword argument will contain the event.
"""
checkout_flow_steps = EventPluginSignal()
"""
This signal is sent out to retrieve pages for the checkout flow

View File

@@ -115,6 +115,25 @@
</div>
</div>
</div>
{% if confirm_messages %}
<div class="panel panel-primary panel-contact">
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Confirmations" %}
</h3>
</div>
<div class="panel-body">
{% for key, desc in confirm_messages.items %}
<div class="checkbox">
<label>
<input type="checkbox" class="checkbox" value="yes" name="confirm_{{ key }}" required>
{{ desc|safe }}
</label>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<div class="row checkout-button-row clearfix">
<div class="col-md-4">
<a class="btn btn-block btn-default btn-lg"

View File

@@ -14,6 +14,7 @@ from django.views.generic import TemplateView
from pretix.base.models import ItemVariation
from pretix.multidomain.urlreverse import eventreverse
from . import CartMixin, EventViewMixin
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore