diff --git a/src/pretix/presale/checkoutflow.py b/src/pretix/presale/checkoutflow.py index 016340800f..099d9ba162 100644 --- a/src/pretix/presale/checkoutflow.py +++ b/src/pretix/presale/checkoutflow.py @@ -19,7 +19,8 @@ from pretix.presale.forms.checkout import ( AddOnsForm, ContactForm, InvoiceAddressForm, ) from pretix.presale.signals import ( - checkout_confirm_messages, checkout_flow_steps, order_meta_from_request, + checkout_confirm_messages, checkout_flow_steps, contact_form_fields, + order_meta_from_request, ) from pretix.presale.views import CartMixin, get_cart, get_cart_total from pretix.presale.views.async import AsyncAction @@ -255,10 +256,13 @@ class QuestionsStep(QuestionsViewMixin, CartMixin, TemplateFlowStep): @cached_property def contact_form(self): + initial = { + 'email': self.request.session.get('email', '') + } + initial.update(self.request.session.get('contact_form_data', {})) return ContactForm(data=self.request.POST if self.request.method == "POST" else None, - initial={ - 'email': self.request.session.get('email', '') - }) + event=self.request.event, + initial=initial) @cached_property def invoice_address(self): @@ -290,6 +294,7 @@ class QuestionsStep(QuestionsViewMixin, CartMixin, TemplateFlowStep): if request.event.settings.invoice_address_asked: addr = self.invoice_form.save() request.session['invoice_address'] = addr.pk + request.session['contact_form_data'] = self.contact_form.cleaned_data return redirect(self.get_next_url(request)) @@ -435,6 +440,18 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep): ctx['payment_provider'] = self.payment_provider ctx['addr'] = self.invoice_address ctx['confirm_messages'] = self.confirm_messages + + ctx['contact_info'] = [] + responses = contact_form_fields.send(self.event) + for r, response in sorted(responses, key=lambda r: str(r[0])): + for key, value in response.items(): + v = self.request.session.get('contact_form_data', {}).get(key) + if v is True: + v = _('Yes') + elif v is False: + v = _('No') + ctx['contact_info'].append((value.label, v)) + return ctx @cached_property @@ -485,9 +502,12 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep): }) return redirect(self.get_error_url()) - meta_info = {} + meta_info = { + 'contact_form_data': self.request.session.get('contact_form_data', {}) + } for receiver, response in order_meta_from_request.send(sender=request.event, request=request): meta_info.update(response) + return self.do(self.request.event.id, self.payment_provider.identifier, [p.id for p in self.positions], request.session.get('email'), translation.get_language(), self.invoice_address.pk, meta_info) diff --git a/src/pretix/presale/forms/checkout.py b/src/pretix/presale/forms/checkout.py index 0d5a3f52a9..b7316ceeb3 100644 --- a/src/pretix/presale/forms/checkout.py +++ b/src/pretix/presale/forms/checkout.py @@ -14,6 +14,7 @@ from django.utils.translation import ugettext_lazy as _ from pretix.base.models import ItemVariation, Question from pretix.base.models.orders import InvoiceAddress from pretix.base.templatetags.rich_text import rich_text +from pretix.presale.signals import contact_form_fields class ContactForm(forms.Form): @@ -23,6 +24,16 @@ class ContactForm(forms.Form): 'modifications to your order or download your ticket later.'), widget=forms.EmailInput(attrs={'data-typocheck-target': '1'})) + def __init__(self, *args, **kwargs): + self.event = kwargs.pop('event') + super().__init__(*args, **kwargs) + + responses = contact_form_fields.send(self.event) + for r, response in sorted(responses, key=lambda r: str(r[0])): + for key, value in response.items(): + # We need to be this explicit, since OrderedDict.update does not retain ordering + self.fields[key] = value + class InvoiceAddressForm(forms.ModelForm): diff --git a/src/pretix/presale/signals.py b/src/pretix/presale/signals.py index a6a8eb335c..ac0ac695b3 100644 --- a/src/pretix/presale/signals.py +++ b/src/pretix/presale/signals.py @@ -69,6 +69,18 @@ You will recieve the request triggering the order creation as the ``request`` ke As with all event-plugin signals, the ``sender`` keyword argument will contain the event. """ +contact_form_fields = EventPluginSignal( + providing_args=[] +) +""" +This signals allows you to add form fields to the contact form that is presented during checkout +and by default only asks for the email address. You are supposed to return a dictionary of +form fields with globally unique keys. The validated form results will be saved into the +``contact_form_data`` entry of the order metadata dictionary. + +As with all plugin signals, the ``sender`` keyword argument will contain the event. +""" + order_info = EventPluginSignal( providing_args=["order"] ) diff --git a/src/pretix/presale/templates/pretixpresale/event/checkout_confirm.html b/src/pretix/presale/templates/pretixpresale/event/checkout_confirm.html index 8740245242..87e4870bc9 100644 --- a/src/pretix/presale/templates/pretixpresale/event/checkout_confirm.html +++ b/src/pretix/presale/templates/pretixpresale/event/checkout_confirm.html @@ -111,6 +111,12 @@