Quota form: Change item selection field per context (#3839)

* Change item checkbox select to multiselect widget

* Make item selection widget dependent on count

* Make item selection widget dependent on variable

* Adjust widget choices

* Fix widget choices

* Fix item variation key errors

* Simplify code

* Fix classname

* Improve argument name

* Fix widget name
This commit is contained in:
Phin Wolkwitz
2024-02-08 09:33:39 +01:00
committed by GitHub
parent 2b72cfdaff
commit 39f9329207
7 changed files with 86 additions and 9 deletions

View File

@@ -67,7 +67,7 @@ from pretix.control.forms import (
ButtonGroupRadioSelect, ItemMultipleChoiceField, SizeValidationMixin,
SplitDateTimeField, SplitDateTimePickerWidget,
)
from pretix.control.forms.widgets import Select2
from pretix.control.forms.widgets import Select2, Select2ItemVarMulti
from pretix.helpers.models import modelcopy
from pretix.helpers.money import change_decimal_field
@@ -207,14 +207,20 @@ class QuestionOptionForm(I18nModelForm):
class QuotaForm(I18nModelForm):
itemvars = forms.MultipleChoiceField(
label=_("Products"),
required=True,
)
def __init__(self, **kwargs):
self.instance = kwargs.get('instance', None)
self.event = kwargs.get('event')
items = kwargs.pop('items', None) or self.event.items.prefetch_related('variations')
searchable_selection = kwargs.pop('searchable_selection', None)
self.original_instance = modelcopy(self.instance) if self.instance else None
initial = kwargs.get('initial', {})
if self.instance and self.instance.pk and 'itemvars' not in initial:
initial['itemvars'] = [str(i.pk) for i in self.instance.items.all()] + [
initial['itemvars'] = [str(i.pk) for i in self.instance.items.all() if (len(i.variations.all()) == 0)] + [
'{}-{}'.format(v.item_id, v.pk) for v in self.instance.variations.all()
]
kwargs['initial'] = initial
@@ -231,12 +237,22 @@ class QuotaForm(I18nModelForm):
else:
choices.append(('{}'.format(item.pk), str(item) if item.active else mark_safe(f'<strike class="text-muted">{escape(item)}</strike>')))
self.fields['itemvars'] = forms.MultipleChoiceField(
label=_('Products'),
required=True,
choices=choices,
widget=forms.CheckboxSelectMultiple
)
if searchable_selection:
self.fields['itemvars'].widget = Select2ItemVarMulti(
attrs={
'data-model-select2': 'generic',
'data-select2-url': reverse('control:event.items.itemvars.select2', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
}),
'data-placeholder': _('All products')
},
choices=choices,
)
else:
self.fields['itemvars'].widget = forms.CheckboxSelectMultiple()
self.fields['itemvars'].choices = choices
if self.event.has_subevents:
self.fields['subevent'].queryset = self.event.subevents.all()

View File

@@ -360,6 +360,7 @@ class BulkSubEventItemVariationForm(SubEventItemVariationForm):
class QuotaFormSet(I18nInlineFormSet):
def __init__(self, *args, **kwargs):
self.searchable_selection = kwargs.pop('searchable_selection', None)
self.event = kwargs.pop('event', None)
self.locales = self.event.settings.get('locales')
super().__init__(*args, **kwargs)
@@ -372,7 +373,7 @@ class QuotaFormSet(I18nInlineFormSet):
kwargs['locales'] = self.locales
kwargs['event'] = self.event
kwargs['items'] = self.items
kwargs['items'] = self.items
kwargs['searchable_selection'] = self.searchable_selection
return super()._construct_form(i, **kwargs)
@property

View File

@@ -77,3 +77,19 @@ class Select2ItemVarQuotaMixin(Select2Mixin):
class Select2ItemVarQuota(Select2ItemVarQuotaMixin, forms.Select):
pass
class Select2ItemVarMulti(Select2Mixin, forms.SelectMultiple):
def options(self, name, value, attrs=None):
# we need this for multi-selection without a queryset for the selection of items and variations
for i, v in enumerate(value):
yield self.create_option(
None,
v,
dict(self.choices)[v],
True,
i,
subindex=None,
attrs=attrs
)
return