diff --git a/src/pretix/control/forms/waitinglist.py b/src/pretix/control/forms/waitinglist.py
index 394f75c238..8df7de7a95 100644
--- a/src/pretix/control/forms/waitinglist.py
+++ b/src/pretix/control/forms/waitinglist.py
@@ -39,11 +39,18 @@ class WaitingListEntryEditForm(I18nModelForm):
def __init__(self, *args, **kwargs):
self.instance = kwargs.get('instance', None)
initial = kwargs.get('initial', {})
+
+ choices = []
if self.instance and self.instance.pk and 'itemvar' not in initial:
if self.instance.variation is not None:
initial['itemvar'] = f'{self.instance.item.pk}-{self.instance.variation.pk}'
+ if self.instance.variation.active is False:
+ choices.append((initial['itemvar'], str(self.instance.variation)))
else:
initial['itemvar'] = self.instance.item.pk
+ if self.instance.item.active is False:
+ choices.append((initial['itemvar'], str(self.instance)))
+
kwargs['initial'] = initial
super().__init__(*args, **kwargs)
@@ -78,29 +85,21 @@ class WaitingListEntryEditForm(I18nModelForm):
if not self.event.settings.waiting_list_phones_asked:
del self.fields['phone']
- choices = []
- items = self.event.items.prefetch_related('variations').prefetch_related('quotas')
+ items = self.event.items.filter(active=True).prefetch_related('variations')
+
for item in items:
- # don't offer items in the selection if they don't allow waitinglists or aren't on sale at all
- if not item.allow_waitinglist | item.quotas.exists():
- # except if they are currently set in the waitinglist, this will be then caught on submit in the clean step
- if not self.instance.item.pk == item.pk:
- continue
-
- if len(item.variations.all()) > 0:
- for v in item.variations.all():
- choices.append((
- '{}-{}'.format(item.pk, v.pk),
- '{} – {}'.format(item, v.value) if item.active else mark_safe(
- f'{escape(item)} – {escape(v.value)}')
- ))
+ active_variations = item.variations.filter(active=True)
+ if len(active_variations) > 0:
+ for variation in active_variations:
+ choices.append(
+ ('{}-{}'.format(item.pk, variation.pk), str(variation))
+ )
else:
- choices.append(('{}'.format(item.pk), str(item) if item.active else mark_safe(
- f'{escape(item)}')))
+ choices.append(('{}'.format(item.pk), str(item)))
self.fields['itemvar'].label = _("Product")
- self.fields['itemvar'].help_text = _("Only includes products which have the waiting list enabled.")
+ self.fields['itemvar'].help_text = _("Only includes active products.")
self.fields['itemvar'].required = True
self.fields['itemvar'].widget = Select2ItemVarQuota(
attrs={
@@ -115,16 +114,17 @@ class WaitingListEntryEditForm(I18nModelForm):
self.fields['itemvar'].choices = choices
def clean(self):
- if self.instance.voucher is not None:
- self.add_error(None, _('A voucher for this waiting list entry was sent out already.'))
+ cleaned_data = super().clean()
- itemvar = self.data.get('itemvar')
- if itemvar is None:
- self.add_error('itemvar', _('Item and Variation are required'))
- else:
- self.instance.item = Item.objects.get(pk=itemvar.split('-')[0])
+ if self.instance.voucher is not None:
+ raise ValidationError(_('A voucher for this waiting list entry was sent out already.'))
+
+ itemvar = cleaned_data.get('itemvar')
+
+ if itemvar:
+ self.instance.item = self.event.items.get(pk=itemvar.split('-')[0])
if '-' in itemvar:
- self.instance.variation = ItemVariation.objects.get(pk=itemvar.split('-')[1])
+ self.instance.variation = self.instance.item.variations.get(pk=itemvar.split('-')[1])
if not self.instance.item.allow_waitinglist:
self.add_error('itemvar', _('The selected product does not allow waiting list entries.'))
@@ -132,9 +132,11 @@ class WaitingListEntryEditForm(I18nModelForm):
self.add_error('itemvar', _('The selected product is not on sale because there is no quota configured for it.'))
if self.instance.variation and not self.instance.variation.quotas.filter(subevent=self.data.get('subevent')).exists():
self.add_error('itemvar', _('The selected product is not on sale because there is no quota configured for it.'))
+ if ((self.instance.item and not self.instance.item.active) or
+ (self.instance.variation and not self.instance.variation.active)):
+ self.add_error('itemvar', _('The selected product is not active.'))
- data = super().clean()
- return data
+ return cleaned_data
class Meta:
model = WaitingListEntry
diff --git a/src/tests/control/test_waitinglist.py b/src/tests/control/test_waitinglist.py
index 50286b20f5..0f886547db 100644
--- a/src/tests/control/test_waitinglist.py
+++ b/src/tests/control/test_waitinglist.py
@@ -277,61 +277,6 @@ def test_edit_voucher_send_out(client, env):
assert response.status_code == 404
-@pytest.mark.django_db
-def test_edit_item_without_waitinglist(client, env):
- event = env[0]
- item = Item.objects.create(event=event, name="Ticket", default_price=23, admission=True, allow_waitinglist=True)
- item_without_waitinglist = Item.objects.create(event=event, name="Ticket", default_price=23, admission=True, allow_waitinglist=False)
- quota = Quota.objects.create(event=event)
- quota.items.add(item)
- quota.items.add(item_without_waitinglist)
-
- client.login(email='dummy@dummy.dummy', password='dummy')
- with scopes_disabled():
- wle = WaitingListEntry.objects.create(
- event=event, item=item, email='foo@bar.com'
- )
-
- client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id)
-
- response = client.post(
- '/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id,
- data={
- "email": f"1_{wle.email}",
- "itemvar": item_without_waitinglist.pk
- },
- follow=True
- )
- assert response.context['form'].errors == {'itemvar': ["The selected product does not allow waiting list entries."]}
-
-
-@pytest.mark.django_db
-def test_edit_item_without_quota(client, env):
- event = env[0]
- item = Item.objects.create(event=event, name="Ticket", default_price=23, admission=True, allow_waitinglist=True)
- item_without_waitinglist = Item.objects.create(event=event, name="Ticket", default_price=23, admission=True, allow_waitinglist=True)
- quota = Quota.objects.create(event=event)
- quota.items.add(item)
-
- client.login(email='dummy@dummy.dummy', password='dummy')
- with scopes_disabled():
- wle = WaitingListEntry.objects.create(
- event=event, item=item, email='foo@bar.com'
- )
-
- client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id)
-
- response = client.post(
- '/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id,
- data={
- "email": f"1_{wle.email}",
- "itemvar": item_without_waitinglist.pk
- },
- follow=True
- )
- assert response.context['form'].errors == {'itemvar': ["The selected product is not on sale because there is no quota configured for it."]}
-
-
@pytest.mark.django_db
def test_dashboard(client, env):
with scopes_disabled():