diff --git a/src/pretix/control/forms/organizer.py b/src/pretix/control/forms/organizer.py
index 82afb94a44..1a44359f99 100644
--- a/src/pretix/control/forms/organizer.py
+++ b/src/pretix/control/forms/organizer.py
@@ -565,6 +565,13 @@ class CustomerUpdateForm(forms.ModelForm):
return self.cleaned_data
+class CustomerCreateForm(CustomerUpdateForm):
+
+ class Meta:
+ model = Customer
+ fields = ['identifier', 'is_active', 'name_parts', 'email', 'is_verified', 'locale']
+
+
class MembershipUpdateForm(forms.ModelForm):
class Meta:
diff --git a/src/pretix/control/templates/pretixcontrol/organizers/customer_edit.html b/src/pretix/control/templates/pretixcontrol/organizers/customer_edit.html
index 9267d34e09..e3d2ceaa2e 100644
--- a/src/pretix/control/templates/pretixcontrol/organizers/customer_edit.html
+++ b/src/pretix/control/templates/pretixcontrol/organizers/customer_edit.html
@@ -2,15 +2,23 @@
{% load i18n %}
{% load bootstrap3 %}
{% block title %}
- {% blocktrans trimmed with id=customer.identifier %}
- Customer #{{ id }}
- {% endblocktrans %}
-{% endblock %}
-{% block inner %}
-
+ {% if not customer.id %}
+ {% trans "New customer" %}
+ {% else %}
{% blocktrans trimmed with id=customer.identifier %}
Customer #{{ id }}
{% endblocktrans %}
+ {% endif %}
+{% endblock %}
+{% block inner %}
+
+ {% if not customer.id %}
+ {% trans "New customer" %}
+ {% else %}
+ {% blocktrans trimmed with id=customer.identifier %}
+ Customer #{{ id }}
+ {% endblocktrans %}
+ {% endif %}
+
+ {% trans "Create a new customer" %}
+
diff --git a/src/pretix/control/urls.py b/src/pretix/control/urls.py
index da14f08f28..d05eb5d785 100644
--- a/src/pretix/control/urls.py
+++ b/src/pretix/control/urls.py
@@ -133,6 +133,8 @@ urlpatterns = [
name='organizer.membershiptype.delete'),
re_path(r'^organizer/(?P[^/]+)/customers$', organizer.CustomerListView.as_view(), name='organizer.customers'),
re_path(r'^organizer/(?P[^/]+)/customers/select2$', typeahead.customer_select2, name='organizer.customers.select2'),
+ re_path(r'^organizer/(?P[^/]+)/customer/add$',
+ organizer.CustomerCreateView.as_view(), name='organizer.customer.create'),
re_path(r'^organizer/(?P[^/]+)/customer/(?P[^/]+)/$',
organizer.CustomerDetailView.as_view(), name='organizer.customer'),
re_path(r'^organizer/(?P[^/]+)/customer/(?P[^/]+)/edit$',
diff --git a/src/pretix/control/views/organizer.py b/src/pretix/control/views/organizer.py
index 828b25f311..dcc7850fea 100644
--- a/src/pretix/control/views/organizer.py
+++ b/src/pretix/control/views/organizer.py
@@ -89,8 +89,8 @@ from pretix.control.forms.filter import (
)
from pretix.control.forms.orders import ExporterForm
from pretix.control.forms.organizer import (
- CustomerUpdateForm, DeviceForm, EventMetaPropertyForm, GateForm,
- GiftCardCreateForm, GiftCardUpdateForm, MailSettingsForm,
+ CustomerCreateForm, CustomerUpdateForm, DeviceForm, EventMetaPropertyForm,
+ GateForm, GiftCardCreateForm, GiftCardUpdateForm, MailSettingsForm,
MembershipTypeForm, MembershipUpdateForm, OrganizerDeleteForm,
OrganizerForm, OrganizerSettingsForm, OrganizerUpdateForm, TeamForm,
WebHookForm,
@@ -1863,6 +1863,35 @@ class CustomerDetailView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
return ctx
+class CustomerCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, CreateView):
+ template_name = 'pretixcontrol/organizers/customer_edit.html'
+ permission = 'can_manage_customers'
+ context_object_name = 'customer'
+ form_class = CustomerCreateForm
+
+ def get_form_kwargs(self):
+ ctx = super().get_form_kwargs()
+ c = Customer(organizer=self.request.organizer)
+ c.assign_identifier()
+ ctx['instance'] = c
+ return ctx
+
+ def form_valid(self, form):
+ r = super().form_valid(form)
+ form.instance.log_action('pretix.customer.created', user=self.request.user, data={
+ k: getattr(form.instance, k)
+ for k in form.changed_data
+ })
+ messages.success(self.request, _('Your changes have been saved.'))
+ return r
+
+ def get_success_url(self):
+ return reverse('control:organizer.customer', kwargs={
+ 'organizer': self.request.organizer.slug,
+ 'customer': self.object.identifier,
+ })
+
+
class CustomerUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, UpdateView):
template_name = 'pretixcontrol/organizers/customer_edit.html'
permission = 'can_manage_customers'
diff --git a/src/tests/control/test_permissions.py b/src/tests/control/test_permissions.py
index 7bde4dfed1..c00fd6106e 100644
--- a/src/tests/control/test_permissions.py
+++ b/src/tests/control/test_permissions.py
@@ -194,6 +194,7 @@ organizer_urls = [
'organizer/abc/webhook/1/edit',
'organizer/abc/webhook/1/logs',
'organizer/abc/customers',
+ 'organizer/abc/customer/add',
'organizer/abc/customer/1/',
'organizer/abc/giftcards',
'organizer/abc/giftcard/add',