Fix #782 -- Select2 widget for item selection for vouchers

This commit is contained in:
Raphael Michel
2018-04-03 12:10:34 +02:00
parent 7ec5adb6b4
commit bb10d25561
6 changed files with 163 additions and 36 deletions

View File

@@ -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]

View File

@@ -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