forked from CGM_Public/pretix_original
Fix quota handling to allow for "add-on swapping"
This commit is contained in:
@@ -318,7 +318,7 @@ class CartManager:
|
|||||||
self._check_item_constraints(op)
|
self._check_item_constraints(op)
|
||||||
operations.append(op)
|
operations.append(op)
|
||||||
|
|
||||||
self._quota_diff += quota_diff
|
self._quota_diff.update(quota_diff)
|
||||||
self._voucher_use_diff += voucher_use_diff
|
self._voucher_use_diff += voucher_use_diff
|
||||||
self._operations += operations
|
self._operations += operations
|
||||||
|
|
||||||
@@ -456,7 +456,7 @@ class CartManager:
|
|||||||
for k, v in al.items():
|
for k, v in al.items():
|
||||||
if k not in input_addons[cp.id]:
|
if k not in input_addons[cp.id]:
|
||||||
if v.expires > self.now_dt:
|
if v.expires > self.now_dt:
|
||||||
quotas = list(cp.quotas)
|
quotas = list(v.quotas)
|
||||||
|
|
||||||
for quota in quotas:
|
for quota in quotas:
|
||||||
quota_diff[quota] -= 1
|
quota_diff[quota] -= 1
|
||||||
@@ -464,12 +464,14 @@ class CartManager:
|
|||||||
op = self.RemoveOperation(position=v)
|
op = self.RemoveOperation(position=v)
|
||||||
operations.append(op)
|
operations.append(op)
|
||||||
|
|
||||||
self._quota_diff += quota_diff
|
self._quota_diff.update(quota_diff)
|
||||||
self._operations += operations
|
self._operations += operations
|
||||||
|
|
||||||
def _get_quota_availability(self):
|
def _get_quota_availability(self):
|
||||||
quotas_ok = {}
|
quotas_ok = defaultdict(int)
|
||||||
for quota, count in self._quota_diff.items():
|
for quota, count in self._quota_diff.items():
|
||||||
|
if count <= 0:
|
||||||
|
quotas_ok[quota] = 0
|
||||||
avail = quota.availability(self.now_dt)
|
avail = quota.availability(self.now_dt)
|
||||||
if avail[1] is not None and avail[1] < count:
|
if avail[1] is not None and avail[1] < count:
|
||||||
quotas_ok[quota] = min(count, avail[1])
|
quotas_ok[quota] = min(count, avail[1])
|
||||||
@@ -541,6 +543,9 @@ class CartManager:
|
|||||||
|
|
||||||
for op in self._operations:
|
for op in self._operations:
|
||||||
if isinstance(op, self.RemoveOperation):
|
if isinstance(op, self.RemoveOperation):
|
||||||
|
if op.position.expires > self.now_dt:
|
||||||
|
for q in op.position.quotas:
|
||||||
|
quotas_ok[q] += 1
|
||||||
op.position.delete()
|
op.position.delete()
|
||||||
|
|
||||||
elif isinstance(op, self.AddOperation) or isinstance(op, self.ExtendOperation):
|
elif isinstance(op, self.AddOperation) or isinstance(op, self.ExtendOperation):
|
||||||
|
|||||||
@@ -1737,6 +1737,43 @@ class CartAddonTest(CartTestMixin, TestCase):
|
|||||||
])
|
])
|
||||||
self.cm.commit()
|
self.cm.commit()
|
||||||
|
|
||||||
|
def test_sold_out_swap_addons(self):
|
||||||
|
cp1 = CartPosition.objects.create(
|
||||||
|
expires=now() + timedelta(minutes=10), item=self.ticket, price=Decimal('23.00'),
|
||||||
|
event=self.event, cart_id=self.session_key
|
||||||
|
)
|
||||||
|
CartPosition.objects.create(
|
||||||
|
expires=now() + timedelta(minutes=10), item=self.workshop1, price=Decimal('12.00'),
|
||||||
|
event=self.event, cart_id=self.session_key, addon_to=cp1
|
||||||
|
)
|
||||||
|
cp2 = CartPosition.objects.create(
|
||||||
|
expires=now() + timedelta(minutes=10), item=self.ticket, price=Decimal('23.00'),
|
||||||
|
event=self.event, cart_id=self.session_key
|
||||||
|
)
|
||||||
|
CartPosition.objects.create(
|
||||||
|
expires=now() + timedelta(minutes=10), item=self.workshop2, price=Decimal('12.00'),
|
||||||
|
event=self.event, cart_id=self.session_key, addon_to=cp2
|
||||||
|
)
|
||||||
|
self.workshopquota.size = 0
|
||||||
|
self.workshopquota.save()
|
||||||
|
self.cm.set_addons([
|
||||||
|
{
|
||||||
|
'addon_to': cp1.pk,
|
||||||
|
'item': self.workshop2.pk,
|
||||||
|
'variation': None
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'addon_to': cp2.pk,
|
||||||
|
'item': self.workshop1.pk,
|
||||||
|
'variation': None
|
||||||
|
},
|
||||||
|
])
|
||||||
|
self.cm.commit()
|
||||||
|
assert cp1.addons.count() == 1
|
||||||
|
assert cp2.addons.count() == 1
|
||||||
|
assert cp1.addons.first().item == self.workshop2
|
||||||
|
assert cp2.addons.first().item == self.workshop1
|
||||||
|
|
||||||
def test_expand_expired(self):
|
def test_expand_expired(self):
|
||||||
cp1 = CartPosition.objects.create(
|
cp1 = CartPosition.objects.create(
|
||||||
expires=now() - timedelta(minutes=10), item=self.ticket, price=Decimal('23.00'),
|
expires=now() - timedelta(minutes=10), item=self.ticket, price=Decimal('23.00'),
|
||||||
|
|||||||
Reference in New Issue
Block a user