forked from CGM_Public/pretix_original
Small refactoring in cart.py and related locations
This commit is contained in:
@@ -782,7 +782,7 @@ class Item(Versionable):
|
|||||||
self._get_all_available_variations_cache = variations
|
self._get_all_available_variations_cache = variations
|
||||||
return variations
|
return variations
|
||||||
|
|
||||||
def availability(self):
|
def check_quotas(self):
|
||||||
"""
|
"""
|
||||||
This method is used to determine whether this Item is currently available
|
This method is used to determine whether this Item is currently available
|
||||||
for sale. It may return any of the return codes of Quota.availability()
|
for sale. It may return any of the return codes of Quota.availability()
|
||||||
@@ -792,7 +792,7 @@ class Item(Versionable):
|
|||||||
'but call this on their ItemVariation objects')
|
'but call this on their ItemVariation objects')
|
||||||
return min([q.availability() for q in self.quotas.all()])
|
return min([q.availability() for q in self.quotas.all()])
|
||||||
|
|
||||||
def execute_restrictions(self):
|
def check_restrictions(self):
|
||||||
"""
|
"""
|
||||||
This method is used to determine whether this ItemVariation is restricted
|
This method is used to determine whether this ItemVariation is restricted
|
||||||
in sale by any restriction plugins.
|
in sale by any restriction plugins.
|
||||||
@@ -869,7 +869,7 @@ class ItemVariation(Versionable):
|
|||||||
if self.item:
|
if self.item:
|
||||||
self.item.event.get_cache().clear()
|
self.item.event.get_cache().clear()
|
||||||
|
|
||||||
def availability(self):
|
def check_quotas(self):
|
||||||
"""
|
"""
|
||||||
This method is used to determine whether this ItemVariation is currently
|
This method is used to determine whether this ItemVariation is currently
|
||||||
available for sale in terms of quotas. It may return any of the return codes
|
available for sale in terms of quotas. It may return any of the return codes
|
||||||
@@ -884,7 +884,7 @@ class ItemVariation(Versionable):
|
|||||||
vd['variation'] = self
|
vd['variation'] = self
|
||||||
return vd
|
return vd
|
||||||
|
|
||||||
def execute_restrictions(self):
|
def check_restrictions(self):
|
||||||
"""
|
"""
|
||||||
This method is used to determine whether this ItemVariation is restricted
|
This method is used to determine whether this ItemVariation is restricted
|
||||||
in sale by any restriction plugins.
|
in sale by any restriction plugins.
|
||||||
|
|||||||
@@ -202,15 +202,15 @@ class QuotaTestCase(TestCase):
|
|||||||
|
|
||||||
def test_available(self):
|
def test_available(self):
|
||||||
self.quota.items.add(self.item1)
|
self.quota.items.add(self.item1)
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_OK, 2))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
|
||||||
self.quota.items.add(self.item2)
|
self.quota.items.add(self.item2)
|
||||||
self.quota.variations.add(self.var1)
|
self.quota.variations.add(self.var1)
|
||||||
try:
|
try:
|
||||||
self.item2.availability()
|
self.item2.check_quotas()
|
||||||
self.assertTrue(False)
|
self.assertTrue(False)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.assertEqual(self.var1.availability(), (Quota.AVAILABILITY_OK, 2))
|
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
|
||||||
|
|
||||||
def test_sold_out(self):
|
def test_sold_out(self):
|
||||||
self.quota.items.add(self.item1)
|
self.quota.items.add(self.item1)
|
||||||
@@ -219,19 +219,19 @@ class QuotaTestCase(TestCase):
|
|||||||
total=4)
|
total=4)
|
||||||
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
||||||
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_GONE, 0))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
|
||||||
|
|
||||||
self.quota.items.add(self.item2)
|
self.quota.items.add(self.item2)
|
||||||
self.quota.variations.add(self.var1)
|
self.quota.variations.add(self.var1)
|
||||||
self.quota.size = 3
|
self.quota.size = 3
|
||||||
self.quota.save()
|
self.quota.save()
|
||||||
self.assertEqual(self.var1.availability(), (Quota.AVAILABILITY_OK, 1))
|
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
|
||||||
|
|
||||||
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
|
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
|
||||||
expires=now() + timedelta(days=3),
|
expires=now() + timedelta(days=3),
|
||||||
total=4)
|
total=4)
|
||||||
OrderPosition.objects.create(order=order, item=self.item2, variation=self.var1, price=2)
|
OrderPosition.objects.create(order=order, item=self.item2, variation=self.var1, price=2)
|
||||||
self.assertEqual(self.var1.availability(), (Quota.AVAILABILITY_GONE, 0))
|
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
|
||||||
|
|
||||||
def test_ordered(self):
|
def test_ordered(self):
|
||||||
self.quota.items.add(self.item1)
|
self.quota.items.add(self.item1)
|
||||||
@@ -239,17 +239,17 @@ class QuotaTestCase(TestCase):
|
|||||||
expires=now() + timedelta(days=3),
|
expires=now() + timedelta(days=3),
|
||||||
total=4)
|
total=4)
|
||||||
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_OK, 1))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
|
||||||
|
|
||||||
order = Order.objects.create(event=self.event, status=Order.STATUS_PENDING,
|
order = Order.objects.create(event=self.event, status=Order.STATUS_PENDING,
|
||||||
expires=now() + timedelta(days=3),
|
expires=now() + timedelta(days=3),
|
||||||
total=4)
|
total=4)
|
||||||
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_ORDERED, 0))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
|
||||||
|
|
||||||
order.expires = now() - timedelta(days=3)
|
order.expires = now() - timedelta(days=3)
|
||||||
order.save()
|
order.save()
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_OK, 1))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
|
||||||
|
|
||||||
def test_reserved(self):
|
def test_reserved(self):
|
||||||
self.quota.items.add(self.item1)
|
self.quota.items.add(self.item1)
|
||||||
@@ -259,36 +259,36 @@ class QuotaTestCase(TestCase):
|
|||||||
expires=now() + timedelta(days=3),
|
expires=now() + timedelta(days=3),
|
||||||
total=4)
|
total=4)
|
||||||
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_OK, 2))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
|
||||||
|
|
||||||
order = Order.objects.create(event=self.event, status=Order.STATUS_PENDING,
|
order = Order.objects.create(event=self.event, status=Order.STATUS_PENDING,
|
||||||
expires=now() + timedelta(days=3),
|
expires=now() + timedelta(days=3),
|
||||||
total=4)
|
total=4)
|
||||||
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_OK, 1))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
|
||||||
|
|
||||||
cp = CartPosition.objects.create(event=self.event, item=self.item1, price=2,
|
cp = CartPosition.objects.create(event=self.event, item=self.item1, price=2,
|
||||||
expires=now() + timedelta(days=3))
|
expires=now() + timedelta(days=3))
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_RESERVED, 0))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_RESERVED, 0))
|
||||||
|
|
||||||
cp.expires = now() - timedelta(days=3)
|
cp.expires = now() - timedelta(days=3)
|
||||||
cp.save()
|
cp.save()
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_OK, 1))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
|
||||||
|
|
||||||
self.quota.items.add(self.item2)
|
self.quota.items.add(self.item2)
|
||||||
self.quota.variations.add(self.var1)
|
self.quota.variations.add(self.var1)
|
||||||
cp = CartPosition.objects.create(event=self.event, item=self.item2, variation=self.var1,
|
cp = CartPosition.objects.create(event=self.event, item=self.item2, variation=self.var1,
|
||||||
price=2, expires=now() + timedelta(days=3))
|
price=2, expires=now() + timedelta(days=3))
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_RESERVED, 0))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_RESERVED, 0))
|
||||||
|
|
||||||
def test_multiple(self):
|
def test_multiple(self):
|
||||||
self.quota.items.add(self.item1)
|
self.quota.items.add(self.item1)
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_OK, 2))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
|
||||||
|
|
||||||
quota2 = Quota.objects.create(event=self.event, name="Test 2", size=1)
|
quota2 = Quota.objects.create(event=self.event, name="Test 2", size=1)
|
||||||
quota2.items.add(self.item1)
|
quota2.items.add(self.item1)
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_OK, 1))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
|
||||||
|
|
||||||
quota2.size = 0
|
quota2.size = 0
|
||||||
quota2.save()
|
quota2.save()
|
||||||
self.assertEqual(self.item1.availability(), (Quota.AVAILABILITY_GONE, 0))
|
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
|
||||||
|
|||||||
@@ -39,8 +39,11 @@ class CartActionMixin:
|
|||||||
|
|
||||||
class CartAdd(EventViewMixin, CartActionMixin, View):
|
class CartAdd(EventViewMixin, CartActionMixin, View):
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def _items_from_post_data(self):
|
||||||
# Parse input
|
"""
|
||||||
|
Parses the POST data and returns a list of tuples in the
|
||||||
|
form (item id, variation id or None, number)
|
||||||
|
"""
|
||||||
items = []
|
items = []
|
||||||
for key, value in self.request.POST.items():
|
for key, value in self.request.POST.items():
|
||||||
if value.strip() == '':
|
if value.strip() == '':
|
||||||
@@ -49,14 +52,23 @@ class CartAdd(EventViewMixin, CartActionMixin, View):
|
|||||||
try:
|
try:
|
||||||
items.append((key.split("_")[1], None, int(value)))
|
items.append((key.split("_")[1], None, int(value)))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
messages.error(self.request, _('Please only enter numbers.'))
|
messages.error(self.request, _('Please enter numbers only.'))
|
||||||
return redirect(self.get_failure_url())
|
return False
|
||||||
elif key.startswith('variation_'):
|
elif key.startswith('variation_'):
|
||||||
try:
|
try:
|
||||||
items.append((key.split("_")[1], key.split("_")[2], int(value)))
|
items.append((key.split("_")[1], key.split("_")[2], int(value)))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
messages.error(self.request, _('Please only enter numbers.'))
|
messages.error(self.request, _('Please enter numbers only.'))
|
||||||
return redirect(self.get_failure_url())
|
return False
|
||||||
|
if len(items) == 0:
|
||||||
|
messages.error(self.request, _('You did not select any items.'))
|
||||||
|
return False
|
||||||
|
return items
|
||||||
|
|
||||||
|
def post(self, *args, **kwargs):
|
||||||
|
items = self._items_from_post_data()
|
||||||
|
if not items:
|
||||||
|
return redirect(self.get_failure_url())
|
||||||
|
|
||||||
if sum(i[2] for i in items) > self.request.event.max_items_per_order:
|
if sum(i[2] for i in items) > self.request.event.max_items_per_order:
|
||||||
# TODO: Plurals
|
# TODO: Plurals
|
||||||
@@ -64,9 +76,6 @@ class CartAdd(EventViewMixin, CartActionMixin, View):
|
|||||||
_("You cannot select more than %d items per order") % self.event.max_items_per_order)
|
_("You cannot select more than %d items per order") % self.event.max_items_per_order)
|
||||||
return redirect(self.get_failure_url())
|
return redirect(self.get_failure_url())
|
||||||
|
|
||||||
# items is now a list of tuples of the form
|
|
||||||
# (item id, variation id or None, number)
|
|
||||||
|
|
||||||
# Fetch items from the database
|
# Fetch items from the database
|
||||||
items_cache = {
|
items_cache = {
|
||||||
i.identity: i for i
|
i.identity: i for i
|
||||||
@@ -91,7 +100,7 @@ class CartAdd(EventViewMixin, CartActionMixin, View):
|
|||||||
return redirect(self.get_failure_url())
|
return redirect(self.get_failure_url())
|
||||||
item = items_cache[i[0]]
|
item = items_cache[i[0]]
|
||||||
variation = variations_cache[i[1]] if i[1] is not None else None
|
variation = variations_cache[i[1]] if i[1] is not None else None
|
||||||
price = item.execute_restrictions() if variation is None else variation.execute_restrictions()
|
price = item.check_restrictions() if variation is None else variation.check_restrictions()
|
||||||
|
|
||||||
if price is False:
|
if price is False:
|
||||||
if not msg_some_unavailable:
|
if not msg_some_unavailable:
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ class EventIndex(EventViewMixin, TemplateView):
|
|||||||
item.has_variations = (len(item.available_variations) != 1
|
item.has_variations = (len(item.available_variations) != 1
|
||||||
or not item.available_variations[0].empty())
|
or not item.available_variations[0].empty())
|
||||||
if not item.has_variations:
|
if not item.has_variations:
|
||||||
item.cached_availability = list(item.availability())
|
item.cached_availability = list(item.check_quotas())
|
||||||
item.cached_availability[1] = min(item.cached_availability[1],
|
item.cached_availability[1] = min(item.cached_availability[1],
|
||||||
self.request.event.max_items_per_order)
|
self.request.event.max_items_per_order)
|
||||||
item.price = item.available_variations[0]['price']
|
item.price = item.available_variations[0]['price']
|
||||||
else:
|
else:
|
||||||
for var in item.available_variations:
|
for var in item.available_variations:
|
||||||
var.cached_availability = list(var['variation'].availability())
|
var.cached_availability = list(var['variation'].check_quotas())
|
||||||
var.cached_availability[1] = min(var.cached_availability[1],
|
var.cached_availability[1] = min(var.cached_availability[1],
|
||||||
self.request.event.max_items_per_order)
|
self.request.event.max_items_per_order)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user