mirror of
https://github.com/pretix/pretix.git
synced 2026-05-04 15:04:03 +00:00
Fix #782 -- Select2 widget for item selection for vouchers
This commit is contained in:
@@ -1,20 +1,25 @@
|
||||
import copy
|
||||
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||
from django.db.models.functions import Lower
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import pgettext_lazy, ugettext_lazy as _
|
||||
|
||||
from pretix.base.forms import I18nModelForm
|
||||
from pretix.base.models import Item, ItemVariation, Quota, Voucher
|
||||
from pretix.base.models import Item, Voucher
|
||||
from pretix.control.forms import SplitDateTimePickerWidget
|
||||
from pretix.control.forms.widgets import Select2
|
||||
from pretix.control.forms.widgets import Select2, Select2ItemVarQuota
|
||||
from pretix.control.signals import voucher_form_validation
|
||||
|
||||
|
||||
class FakeChoiceField(forms.ChoiceField):
|
||||
def valid_value(self, value):
|
||||
return True
|
||||
|
||||
|
||||
class VoucherForm(I18nModelForm):
|
||||
itemvar = forms.ChoiceField(
|
||||
itemvar = FakeChoiceField(
|
||||
label=_("Product"),
|
||||
help_text=_(
|
||||
"This product is added to the user's cart if the voucher is redeemed."
|
||||
@@ -72,43 +77,48 @@ class VoucherForm(I18nModelForm):
|
||||
del self.fields['subevent']
|
||||
|
||||
choices = []
|
||||
for i in self.instance.event.items.prefetch_related('variations').all():
|
||||
variations = list(i.variations.all())
|
||||
if variations:
|
||||
choices.append((str(i.pk), _('{product} – Any variation').format(product=i.name)))
|
||||
for v in variations:
|
||||
choices.append(('%d-%d' % (i.pk, v.pk), '%s – %s' % (i.name, v.value)))
|
||||
else:
|
||||
choices.append((str(i.pk), i.name))
|
||||
for q in self.instance.event.quotas.all():
|
||||
choices.append(('q-%d' % q.pk, _('Any product in quota "{quota}"').format(quota=q)))
|
||||
self.fields['itemvar'].choices = choices
|
||||
self.fields['itemvar'].widget = Select2ItemVarQuota(
|
||||
attrs={
|
||||
'data-model-select2': 'generic',
|
||||
'data-select2-url': reverse('control:event.vouchers.itemselect2', kwargs={
|
||||
'event': instance.event.slug,
|
||||
'organizer': instance.event.organizer.slug,
|
||||
}),
|
||||
'data-placeholder': ''
|
||||
}
|
||||
)
|
||||
self.fields['itemvar'].widget.choices = self.fields['itemvar'].choices
|
||||
self.fields['itemvar'].required = True
|
||||
|
||||
def clean(self):
|
||||
data = super().clean()
|
||||
|
||||
if not self._errors:
|
||||
itemid = quotaid = None
|
||||
iv = self.data.get('itemvar', '')
|
||||
if iv.startswith('q-'):
|
||||
quotaid = iv[2:]
|
||||
elif '-' in iv:
|
||||
itemid, varid = iv.split('-')
|
||||
else:
|
||||
itemid, varid = iv, None
|
||||
|
||||
if itemid:
|
||||
self.instance.item = Item.objects.get(pk=itemid, event=self.instance.event)
|
||||
if varid:
|
||||
self.instance.variation = ItemVariation.objects.get(pk=varid, item=self.instance.item)
|
||||
try:
|
||||
itemid = quotaid = None
|
||||
iv = self.data.get('itemvar', '')
|
||||
if iv.startswith('q-'):
|
||||
quotaid = iv[2:]
|
||||
elif '-' in iv:
|
||||
itemid, varid = iv.split('-')
|
||||
else:
|
||||
self.instance.variation = None
|
||||
self.instance.quota = None
|
||||
itemid, varid = iv, None
|
||||
|
||||
else:
|
||||
self.instance.quota = Quota.objects.get(pk=quotaid, event=self.instance.event)
|
||||
self.instance.item = None
|
||||
self.instance.variation = None
|
||||
if itemid:
|
||||
self.instance.item = self.instance.event.items.get(pk=itemid)
|
||||
if varid:
|
||||
self.instance.variation = self.instance.item.variations.get(pk=varid)
|
||||
else:
|
||||
self.instance.variation = None
|
||||
self.instance.quota = None
|
||||
|
||||
else:
|
||||
self.instance.quota = self.instance.event.quotas.get(pk=quotaid)
|
||||
self.instance.item = None
|
||||
self.instance.variation = None
|
||||
except ObjectDoesNotExist:
|
||||
raise ValidationError(_("Invalid product selected."))
|
||||
|
||||
if 'codes' in data:
|
||||
data['codes'] = [a.strip() for a in data.get('codes', '').strip().split("\n") if a]
|
||||
|
||||
@@ -36,3 +36,23 @@ class Select2(Select2Mixin, forms.Select):
|
||||
|
||||
class Select2Multiple(Select2Mixin, forms.SelectMultiple):
|
||||
pass
|
||||
|
||||
|
||||
class Select2ItemVarQuotaMixin(Select2Mixin):
|
||||
|
||||
def options(self, name, value, attrs=None):
|
||||
if value and value[0]:
|
||||
yield self.create_option(
|
||||
None,
|
||||
value[0],
|
||||
value[0],
|
||||
True,
|
||||
0,
|
||||
subindex=None,
|
||||
attrs=attrs
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class Select2ItemVarQuota(Select2ItemVarQuotaMixin, forms.Select):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user