Fix invalid handling of variations with quota-level vouchers

This commit is contained in:
Raphael Michel
2019-04-25 11:54:03 +02:00
parent 13bf975dd5
commit ef600ceddb
4 changed files with 81 additions and 1 deletions

View File

@@ -344,6 +344,8 @@ class Voucher(LoggedModel):
a variation).
"""
if self.quota_id:
if variation:
return variation.quotas.filter(pk=self.quota_id).exists()
return item.quotas.filter(pk=self.quota_id).exists()
if self.item_id and not self.variation_id:
return self.item_id == item.pk

View File

@@ -94,6 +94,11 @@ def get_grouped_items(event, subevent=None, voucher=None, channel='web'):
item_price_override = {}
var_price_override = {}
restrict_vars = set()
if voucher and voucher.quota_id:
# If a voucher is set to a specific quota, we need to filter out on that level
restrict_vars = set(voucher.quota.variations.all())
for item in items:
if voucher and voucher.item_id and voucher.variation_id:
# Restrict variations if the voucher only allows one
@@ -163,8 +168,11 @@ def get_grouped_items(event, subevent=None, voucher=None, channel='web'):
display_add_to_cart = display_add_to_cart or var.order_max > 0
item.available_variations = [
v for v in item.available_variations if v._subevent_quotas
v for v in item.available_variations if v._subevent_quotas and (
not voucher or not voucher.quota_id or v in restrict_vars
)
]
if voucher and voucher.variation_id:
item.available_variations = [v for v in item.available_variations
if v.pk == voucher.variation_id]

View File

@@ -650,6 +650,15 @@ class VoucherTestCase(BaseQuotaTestCase):
self.assertTrue(v.applies_to(self.var1.item, self.var1))
self.assertFalse(v.applies_to(self.var1.item, self.var2))
def test_voucher_applicability_variation_through_quota(self):
self.quota.variations.add(self.var1)
self.quota.items.add(self.var1.item)
v = Voucher.objects.create(quota=self.quota, event=self.event)
self.assertFalse(v.applies_to(self.item1))
self.assertTrue(v.applies_to(self.var1.item)) # semantics unclear
self.assertTrue(v.applies_to(self.var1.item, self.var1))
self.assertFalse(v.applies_to(self.var1.item, self.var2))
def test_voucher_no_item_with_quota(self):
with self.assertRaises(ValidationError):
v = Voucher(quota=self.quota, item=self.item1, event=self.event)

View File

@@ -242,6 +242,67 @@ class WidgetCartTest(CartTestMixin, TestCase):
"cart_exists": False
}
def test_product_list_view_with_voucher_variation_through_quota(self):
self.event.vouchers.create(quota=self.quota_shirts, code="ABCDE")
self.quota_shirts.variations.remove(self.shirt_blue)
response = self.client.get('/%s/%s/widget/product_list?voucher=ABCDE' % (self.orga.slug, self.event.slug))
assert response['Access-Control-Allow-Origin'] == '*'
data = json.loads(response.content.decode())
assert data == {
"name": "30C3",
"currency": "EUR",
"show_variations_expanded": False,
"display_net_prices": False,
"vouchers_exist": True,
"waiting_list_enabled": False,
"error": None,
"items_by_category": [
{
"items": [
{
'id': self.shirt.pk,
'name': 'T-Shirt',
'picture': None,
'description': None,
'has_variations': 2,
'require_voucher': False,
'order_min': None,
'order_max': None,
'price': None,
'min_price': '14.00',
'max_price': '14.00',
'free_price': False,
'avail': None,
'original_price': None,
'variations': [
{
'id': self.shirt_red.pk,
'value': 'Red',
'order_max': 2,
'description': None,
'price': {
'gross': '14.00',
'net': '11.76',
'tax': '2.24',
'rate': '19.00',
'name': '',
'includes_mixed_tax_rate': False
},
'avail': [100, None]
},
]
}
],
"description": None,
"id": self.category.pk,
"name": "Everything"
}
],
"itemnum": 1,
"display_add_to_cart": True,
"cart_exists": False
}
def test_product_list_view_with_voucher_expired(self):
self.event.vouchers.create(item=self.ticket, code="ABCDE", valid_until=now() - datetime.timedelta(days=1))
response = self.client.get('/%s/%s/widget/product_list?voucher=ABCDE' % (self.orga.slug, self.event.slug))