diff --git a/src/pretix/api/serializers/event.py b/src/pretix/api/serializers/event.py index 5e9dbac3d..58a8d370d 100644 --- a/src/pretix/api/serializers/event.py +++ b/src/pretix/api/serializers/event.py @@ -683,6 +683,7 @@ class EventSettingsSerializer(SettingsSerializer): 'waiting_list_phones_asked', 'waiting_list_phones_required', 'waiting_list_phones_explanation_text', + 'waiting_list_limit_per_user', 'max_items_per_order', 'reservation_time', 'contact_mail', diff --git a/src/pretix/api/serializers/waitinglist.py b/src/pretix/api/serializers/waitinglist.py index e0b8d857f..ca6a661a1 100644 --- a/src/pretix/api/serializers/waitinglist.py +++ b/src/pretix/api/serializers/waitinglist.py @@ -39,7 +39,7 @@ class WaitingListSerializer(I18nAwareModelSerializer): full_data = self.to_internal_value(self.to_representation(self.instance)) if self.instance else {} full_data.update(data) - WaitingListEntry.clean_duplicate(full_data.get('email'), full_data.get('item'), full_data.get('variation'), + WaitingListEntry.clean_duplicate(event, full_data.get('email'), full_data.get('item'), full_data.get('variation'), full_data.get('subevent'), self.instance.pk if self.instance else None) WaitingListEntry.clean_itemvar(event, full_data.get('item'), full_data.get('variation')) WaitingListEntry.clean_subevent(event, full_data.get('subevent')) diff --git a/src/pretix/base/models/waitinglist.py b/src/pretix/base/models/waitinglist.py index e3924f201..8d577938a 100644 --- a/src/pretix/base/models/waitinglist.py +++ b/src/pretix/base/models/waitinglist.py @@ -119,7 +119,7 @@ class WaitingListEntry(LoggedModel): def clean(self): try: - WaitingListEntry.clean_duplicate(self.email, self.item, self.variation, self.subevent, self.pk) + WaitingListEntry.clean_duplicate(self.event, self.email, self.item, self.variation, self.subevent, self.pk) WaitingListEntry.clean_itemvar(self.event, self.item, self.variation) WaitingListEntry.clean_subevent(self.event, self.subevent) except ObjectDoesNotExist: @@ -308,9 +308,9 @@ class WaitingListEntry(LoggedModel): raise ValidationError(_('The subevent does not belong to this event.')) @staticmethod - def clean_duplicate(email, item, variation, subevent, pk): + def clean_duplicate(event, email, item, variation, subevent, pk): if WaitingListEntry.objects.filter( item=item, variation=variation, email__iexact=email, voucher__isnull=True, subevent=subevent - ).exclude(pk=pk).exists(): + ).exclude(pk=pk).count() >= event.settings.waiting_list_limit_per_user: raise ValidationError(_('You are already on this waiting list! We will notify ' 'you as soon as we have a ticket available for you.')) diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 2dd293552..e83cbe076 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -1330,6 +1330,21 @@ DEFAULTS = { help_text=_("If you ask for a phone number, explain why you do so and what you will use the phone number for.") ) }, + 'waiting_list_limit_per_user': { + 'default': '1', + 'type': int, + 'serializer_class': serializers.IntegerField, + 'form_class': forms.IntegerField, + 'serializer_kwargs': dict( + min_value=1, + ), + 'form_kwargs': dict( + label=_("Maximum number of entries per email address for the same product"), + min_value=1, + required=True, + widget=forms.NumberInput(), + ) + }, 'show_checkin_number_user': { 'default': 'False', 'type': bool, diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 19ec1e645..2c73e7e8b 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -542,6 +542,7 @@ class EventSettingsForm(EventSettingsValidationMixin, SettingsForm): 'waiting_list_phones_asked', 'waiting_list_phones_required', 'waiting_list_phones_explanation_text', + 'waiting_list_limit_per_user', 'max_items_per_order', 'reservation_time', 'contact_mail', diff --git a/src/pretix/control/templates/pretixcontrol/event/settings.html b/src/pretix/control/templates/pretixcontrol/event/settings.html index 3d8b5cc95..a3c165f24 100644 --- a/src/pretix/control/templates/pretixcontrol/event/settings.html +++ b/src/pretix/control/templates/pretixcontrol/event/settings.html @@ -361,6 +361,7 @@ {% bootstrap_field sform.waiting_list_names_asked_required layout="control" %} {% bootstrap_field sform.waiting_list_phones_asked_required layout="control" %} {% bootstrap_field sform.waiting_list_phones_explanation_text layout="control" %} + {% bootstrap_field sform.waiting_list_limit_per_user layout="control" %}
{% trans "Item metadata" %}