diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index 4dbe55c04d..a419f5cad0 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -268,6 +268,13 @@ class Event(EventMixin, LoggedModel): def __str__(self): return str(self.name) + @property + def presale_has_ended(self): + if self.has_subevents: + return self.presale_end and now() > self.presale_end + else: + return super().presale_has_ended + def save(self, *args, **kwargs): obj = super().save(*args, **kwargs) self.cache.clear() diff --git a/src/pretix/base/services/cart.py b/src/pretix/base/services/cart.py index 24f3f22769..71155f80fb 100644 --- a/src/pretix/base/services/cart.py +++ b/src/pretix/base/services/cart.py @@ -188,7 +188,7 @@ class CartManager: if op.subevent and op.subevent.presale_start and self.now_dt < op.subevent.presale_start: raise CartError(error_messages['not_started']) - if op.subevent and op.subevent.presale_end and self.now_dt > op.subevent.presale_end: + if op.subevent and op.subevent.presale_has_ended: raise CartError(error_messages['ended']) if isinstance(op, self.AddOperation): diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index b2f64a3282..3362f412d4 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -361,7 +361,7 @@ def _check_positions(event: Event, now_dt: datetime, positions: List[CartPositio cp.delete() break - if cp.subevent and cp.subevent.presale_end and now_dt > cp.subevent.presale_end: + if cp.subevent and cp.subevent.presale_has_ended: err = err or error_messages['some_subevent_ended'] cp.delete() break diff --git a/src/tests/presale/test_cart.py b/src/tests/presale/test_cart.py index d79560e4b5..e47d3aee47 100644 --- a/src/tests/presale/test_cart.py +++ b/src/tests/presale/test_cart.py @@ -218,6 +218,21 @@ class CartTest(CartTestMixin, TestCase): objs = list(CartPosition.objects.filter(cart_id=self.session_key, event=self.event)) self.assertEqual(len(objs), 0) + def test_subevent_ignore_series_date(self): + self.event.has_subevents = True + self.event.date_to = now() - timedelta(days=1) + self.event.save() + se = self.event.subevents.create(name='Foo', date_from=now(), active=True, + presale_end=now() + timedelta(days=1)) + q = se.quotas.create(name="foo", size=None, event=self.event) + q.items.add(self.ticket) + self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), { + 'item_%d' % self.ticket.id: '1', + 'subevent': se.pk + }, follow=False) + objs = list(CartPosition.objects.filter(cart_id=self.session_key, event=self.event)) + self.assertEqual(len(objs), 1) + def test_subevent_sale_over(self): self.event.has_subevents = True self.event.save() diff --git a/src/tests/presale/test_checkout.py b/src/tests/presale/test_checkout.py index d4b1cfc9cd..99a4d80cf8 100644 --- a/src/tests/presale/test_checkout.py +++ b/src/tests/presale/test_checkout.py @@ -1401,3 +1401,18 @@ class CheckoutTestCase(TestCase): self.assertGreaterEqual(len(doc.select(".alert-danger")), 1) assert 'presale period for one of the events in your cart has ended.' in response.rendered_content assert not CartPosition.objects.filter(cart_id=self.session_key).exists() + + def test_confirm_subevent_ignore_series_dates(self): + self.event.has_subevents = True + self.event.date_to = now() - datetime.timedelta(days=1) + self.event.save() + se = self.event.subevents.create(name='Foo', date_from=now(), presale_end=now() + datetime.timedelta(days=1)) + CartPosition.objects.create( + event=self.event, cart_id=self.session_key, item=self.ticket, + price=23, expires=now() + timedelta(minutes=10), subevent=se + ) + self._set_session('payment', 'banktransfer') + + response = self.client.post('/%s/%s/checkout/confirm/' % (self.orga.slug, self.event.slug), follow=True) + doc = BeautifulSoup(response.rendered_content, "lxml") + self.assertEqual(len(doc.select(".thank-you")), 1)