Voucher creation: Auto-select products based on seat

This commit is contained in:
Raphael Michel
2019-11-22 13:15:33 +01:00
parent ee4f75c2fb
commit 84fb25e4d9
3 changed files with 29 additions and 14 deletions

View File

@@ -78,7 +78,7 @@ class VoucherSerializer(I18nAwareModelSerializer):
if full_data.get('seat'):
data['seat'] = Voucher.clean_seat_id(
full_data, full_data.get('item'), self.context.get('event'),
full_data, full_data.get('item'), full_data.get('quota'), self.context.get('event'),
self.instance.pk if self.instance else None
)

View File

@@ -217,11 +217,12 @@ class Voucher(LoggedModel):
self.event,
self.quota,
self.item,
self.variation
self.variation,
seats_given=bool(self.seat)
)
@staticmethod
def clean_item_properties(data, event, quota, item, variation):
def clean_item_properties(data, event, quota, item, variation, seats_given=False):
if quota:
if quota.event != event:
raise ValidationError(_('You cannot select a quota that belongs to a different event.'))
@@ -240,7 +241,7 @@ class Voucher(LoggedModel):
'Otherwise it might be unclear which quotas to block.'))
if item.category and item.category.is_addon:
raise ValidationError(_('It is currently not possible to create vouchers for add-on products.'))
else:
elif not seats_given:
raise ValidationError(_('You need to specify either a quota or a product.'))
@staticmethod
@@ -342,14 +343,18 @@ class Voucher(LoggedModel):
raise ValidationError(_('A voucher with this code already exists.'))
@staticmethod
def clean_seat_id(data, item, event, pk):
def clean_seat_id(data, item, quota, event, pk):
try:
if event.has_subevents:
if not data.get('subevent'):
raise ValidationError(_('You need to choose a date if you select a seat.'))
seat = event.seats.get(seat_guid=data.get('seat'), subevent=data.get('subevent'))
seat = event.seats.select_related('product').get(
seat_guid=data.get('seat'), subevent=data.get('subevent')
)
else:
seat = event.seats.get(seat_guid=data.get('seat'))
seat = event.seats.select_related('product').get(
seat_guid=data.get('seat')
)
except Seat.DoesNotExist:
raise ValidationError(_('The specified seat ID "{id}" does not exist for this event.').format(
id=data.get('seat')))
@@ -359,13 +364,13 @@ class Voucher(LoggedModel):
'different voucher).').format(
id=seat.seat_guid))
if not item:
if quota:
raise ValidationError(_('You need to choose a specific product if you select a seat.'))
if data.get('max_usages', 1) > 1:
raise ValidationError(_('Seat-specific vouchers can only be used once.'))
if seat.product != item:
if item and seat.product != item:
raise ValidationError(_('You need to choose the product "{prod}" for this seat.').format(prod=seat.product))
if not seat.is_available(ignore_voucher_id=pk):

View File

@@ -113,7 +113,6 @@ class VoucherForm(I18nModelForm):
}
)
self.fields['itemvar'].widget.choices = self.fields['itemvar'].choices
self.fields['itemvar'].required = True
if self.instance.event.seating_plan or self.instance.event.subevents.filter(seating_plan__isnull=False).exists():
self.fields['seat'] = forms.CharField(
@@ -124,11 +123,14 @@ class VoucherForm(I18nModelForm):
initial=self.instance.seat.seat_guid if self.instance.seat else '',
help_text=str(self.instance.seat) if self.instance.seat else '',
)
self.fields['itemvar'].required = False
else:
self.fields['itemvar'].required = True
def clean(self):
data = super().clean()
if not self._errors:
if not self._errors and self.data.get('itemvar'):
try:
itemid = quotaid = None
iv = self.data.get('itemvar', '')
@@ -162,7 +164,8 @@ class VoucherForm(I18nModelForm):
Voucher.clean_item_properties(
data, self.instance.event,
self.instance.quota, self.instance.item, self.instance.variation
self.instance.quota, self.instance.item, self.instance.variation,
seats_given=data.get('seat') or data.get('seats')
)
if not self.instance.show_hidden_items and (
(self.instance.quota and all(i.hide_without_voucher for i in self.instance.quota.items.all()))
@@ -190,7 +193,10 @@ class VoucherForm(I18nModelForm):
)
Voucher.clean_voucher_code(data, self.instance.event, self.instance.pk)
if 'seat' in self.fields and data.get('seat'):
self.instance.seat = Voucher.clean_seat_id(data, self.instance.item, self.instance.event, self.instance.pk)
self.instance.seat = Voucher.clean_seat_id(
data, self.instance.item, self.instance.quota, self.instance.event, self.instance.pk
)
self.instance.item = self.instance.seat.product
voucher_form_validation.send(sender=self.instance.event, form=self, data=data)
@@ -357,7 +363,10 @@ class VoucherBulkForm(VoucherForm):
data['seats'] = []
for s in seatids:
data['seat'] = s
data['seats'].append(Voucher.clean_seat_id(data, self.instance.item, self.instance.event, None))
data['seats'].append(Voucher.clean_seat_id(
data, self.instance.item, self.instance.quota, self.instance.event, None
))
self.instance.seat = data['seats'][0] # Trick model-level validation
else:
data['seats'] = []
@@ -371,6 +380,7 @@ class VoucherBulkForm(VoucherForm):
obj.code = code
try:
obj.seat = self.cleaned_data['seats'].pop()
obj.item = obj.seat.product
except IndexError:
pass
data = dict(self.cleaned_data)