diff --git a/src/pretix/base/services/cart.py b/src/pretix/base/services/cart.py index 3aea9dce8d..d282c4d9f2 100644 --- a/src/pretix/base/services/cart.py +++ b/src/pretix/base/services/cart.py @@ -276,6 +276,10 @@ class CartManager: err = None changed_prices = {} for cp in expired: + removed_positions = {op.position.pk for op in self._operations if isinstance(op, self.RemoveOperation)} + if cp.pk in removed_positions or (cp.addon_to_id and cp.addon_to_id in removed_positions): + continue + if cp.is_bundled: try: bundle = cp.addon_to.item.bundles.get(bundled_item=cp.item, bundled_variation=cp.variation) diff --git a/src/tests/presale/test_cart.py b/src/tests/presale/test_cart.py index 6ad8e71289..0eeda0f246 100644 --- a/src/tests/presale/test_cart.py +++ b/src/tests/presale/test_cart.py @@ -1023,6 +1023,18 @@ class CartTest(CartTestMixin, TestCase): self.assertIn('empty', doc.select('.alert-success')[0].text) self.assertFalse(CartPosition.objects.filter(cart_id=self.session_key, event=self.event).exists()) + def test_remove_expired_voucher(self): + v = Voucher.objects.create(item=self.ticket, event=self.event, valid_until=now() - timedelta(days=1)) + cp = CartPosition.objects.create( + event=self.event, cart_id=self.session_key, item=self.ticket, + price=23, expires=now() - timedelta(minutes=10), voucher=v + ) + self.client.post('/%s/%s/cart/remove' % (self.orga.slug, self.event.slug), { + 'id': cp.pk + }, follow=True) + objs = list(CartPosition.objects.filter(cart_id=self.session_key, event=self.event)) + self.assertEqual(len(objs), 0) + def test_voucher(self): v = Voucher.objects.create(item=self.ticket, event=self.event) self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {