mirror of
https://github.com/pretix/pretix.git
synced 2026-08-04 09:47:50 +00:00
Disable shop and waiting list after end of event
This commit is contained in:
@@ -43,7 +43,7 @@ class EventMixin:
|
||||
Returns a shorter formatted string containing the start date of the event with respect
|
||||
to the current locale and to the ``show_times`` setting.
|
||||
"""
|
||||
tz = tz or pytz.timezone(self.settings.timezone)
|
||||
tz = tz or self.timezone
|
||||
return _date(
|
||||
self.date_from.astimezone(tz),
|
||||
"SHORT_DATETIME_FORMAT" if self.settings.show_times and show_times else "DATE_FORMAT"
|
||||
@@ -55,7 +55,7 @@ class EventMixin:
|
||||
to the current locale and to the ``show_times`` setting. Returns an empty string
|
||||
if ``show_date_to`` is ``False``.
|
||||
"""
|
||||
tz = tz or pytz.timezone(self.settings.timezone)
|
||||
tz = tz or self.timezone
|
||||
if not self.settings.show_date_to or not self.date_to:
|
||||
return ""
|
||||
return _date(
|
||||
@@ -68,7 +68,7 @@ class EventMixin:
|
||||
Returns a formatted string containing the start date of the event with respect
|
||||
to the current locale and to the ``show_times`` setting.
|
||||
"""
|
||||
tz = tz or pytz.timezone(self.settings.timezone)
|
||||
tz = tz or self.timezone
|
||||
return _date(
|
||||
self.date_from.astimezone(tz),
|
||||
"DATETIME_FORMAT" if self.settings.show_times and show_times else "DATE_FORMAT"
|
||||
@@ -79,7 +79,7 @@ class EventMixin:
|
||||
Returns a formatted string containing the start time of the event, ignoring
|
||||
the ``show_times`` setting.
|
||||
"""
|
||||
tz = tz or pytz.timezone(self.settings.timezone)
|
||||
tz = tz or self.timezone
|
||||
return _date(
|
||||
self.date_from.astimezone(tz), "TIME_FORMAT"
|
||||
)
|
||||
@@ -90,7 +90,7 @@ class EventMixin:
|
||||
to the current locale and to the ``show_times`` setting. Returns an empty string
|
||||
if ``show_date_to`` is ``False``.
|
||||
"""
|
||||
tz = tz or pytz.timezone(self.settings.timezone)
|
||||
tz = tz or self.timezone
|
||||
if not self.settings.show_date_to or not self.date_to:
|
||||
return ""
|
||||
return _date(
|
||||
@@ -104,19 +104,26 @@ class EventMixin:
|
||||
of the event with respect to the current locale and to the ``show_times`` and
|
||||
``show_date_to`` settings.
|
||||
"""
|
||||
tz = tz or pytz.timezone(self.settings.timezone)
|
||||
tz = tz or self.timezone
|
||||
if not self.settings.show_date_to or not self.date_to:
|
||||
return _date(self.date_from.astimezone(tz), "DATE_FORMAT")
|
||||
return daterange(self.date_from.astimezone(tz), self.date_to.astimezone(tz))
|
||||
|
||||
@property
|
||||
def timezone(self):
|
||||
return pytz.timezone(self.settings.timezone)
|
||||
|
||||
@property
|
||||
def presale_has_ended(self):
|
||||
"""
|
||||
Is true, when ``presale_end`` is set and in the past.
|
||||
"""
|
||||
if self.presale_end and now() > self.presale_end:
|
||||
return True
|
||||
return False
|
||||
if self.presale_end:
|
||||
return now() > self.presale_end
|
||||
elif self.date_to:
|
||||
return now() > self.date_to
|
||||
else:
|
||||
return now().astimezone(self.timezone).date() > self.date_from.astimezone(self.timezone).date()
|
||||
|
||||
@property
|
||||
def presale_is_running(self):
|
||||
@@ -126,9 +133,7 @@ class EventMixin:
|
||||
"""
|
||||
if self.presale_start and now() < self.presale_start:
|
||||
return False
|
||||
if self.presale_end and now() > self.presale_end:
|
||||
return False
|
||||
return True
|
||||
return not self.presale_has_ended
|
||||
|
||||
@property
|
||||
def event_microdata(self):
|
||||
@@ -229,7 +234,8 @@ class Event(EventMixin, LoggedModel):
|
||||
presale_end = models.DateTimeField(
|
||||
null=True, blank=True,
|
||||
verbose_name=_("End of presale"),
|
||||
help_text=_("Optional. No products will be sold after this date."),
|
||||
help_text=_("Optional. No products will be sold after this date. If you do not set this value, the presale "
|
||||
"will end after the end date of your event."),
|
||||
)
|
||||
presale_start = models.DateTimeField(
|
||||
null=True, blank=True,
|
||||
@@ -323,10 +329,6 @@ class Event(EventMixin, LoggedModel):
|
||||
else:
|
||||
return get_connection(fail_silently=False)
|
||||
|
||||
@property
|
||||
def timezone(self):
|
||||
return pytz.timezone(self.settings.timezone)
|
||||
|
||||
@property
|
||||
def payment_term_last(self):
|
||||
"""
|
||||
@@ -590,7 +592,8 @@ class SubEvent(EventMixin, LoggedModel):
|
||||
presale_end = models.DateTimeField(
|
||||
null=True, blank=True,
|
||||
verbose_name=_("End of presale"),
|
||||
help_text=_("Optional. No products will be sold after this date."),
|
||||
help_text=_("Optional. No products will be sold after this date. If you do not set this value, the presale "
|
||||
"will end after the end date of your event."),
|
||||
)
|
||||
presale_start = models.DateTimeField(
|
||||
null=True, blank=True,
|
||||
|
||||
@@ -112,7 +112,7 @@ class CartManager:
|
||||
def _check_presale_dates(self):
|
||||
if self.event.presale_start and self.now_dt < self.event.presale_start:
|
||||
raise CartError(error_messages['not_started'])
|
||||
if self.event.presale_end and self.now_dt > self.event.presale_end:
|
||||
if self.event.presale_has_ended:
|
||||
raise CartError(error_messages['ended'])
|
||||
|
||||
def _extend_expiry_of_valid_existing_positions(self):
|
||||
|
||||
@@ -321,7 +321,7 @@ class OrderError(LazyLocaleException):
|
||||
def _check_date(event: Event, now_dt: datetime):
|
||||
if event.presale_start and now_dt < event.presale_start:
|
||||
raise OrderError(error_messages['not_started'])
|
||||
if event.presale_end and now_dt > event.presale_end:
|
||||
if event.presale_has_ended:
|
||||
raise OrderError(error_messages['ended'])
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@ def assign_automatically(event_id: int, user_id: int=None, subevent_id: int=None
|
||||
if (wle.item, wle.variation) in gone:
|
||||
continue
|
||||
|
||||
ev = (wle.subevent or event)
|
||||
if not ev.presale_is_running:
|
||||
continue
|
||||
|
||||
quotas = (wle.variation.quotas.filter(subevent=wle.subevent)
|
||||
if wle.variation
|
||||
else wle.item.quotas.filter(subevent=wle.subevent))
|
||||
@@ -66,5 +70,5 @@ def assign_automatically(event_id: int, user_id: int=None, subevent_id: int=None
|
||||
def process_waitinglist(sender, **kwargs):
|
||||
qs = Event.objects.prefetch_related('_settings_objects', 'organizer___settings_objects').select_related('organizer')
|
||||
for e in qs:
|
||||
if e.settings.waiting_list_enabled and e.settings.waiting_list_auto:
|
||||
if e.settings.waiting_list_enabled and e.settings.waiting_list_auto and e.presale_is_running:
|
||||
assign_automatically.apply_async(args=(e.pk,))
|
||||
|
||||
@@ -1020,6 +1020,38 @@ class EventTest(TestCase):
|
||||
assert event2.checkin_lists.count() == 1
|
||||
assert [i.pk for i in event2.checkin_lists.first().limit_products.all()] == [i1new.pk]
|
||||
|
||||
def test_presale_has_ended(self):
|
||||
event = Event(
|
||||
organizer=self.organizer, name='Download', slug='download',
|
||||
date_from=now()
|
||||
)
|
||||
assert not event.presale_has_ended
|
||||
assert event.presale_is_running
|
||||
|
||||
event.date_from = now().replace(hour=23, minute=59, second=59)
|
||||
assert not event.presale_has_ended
|
||||
assert event.presale_is_running
|
||||
|
||||
event.date_from = now() - timedelta(days=1)
|
||||
assert event.presale_has_ended
|
||||
assert not event.presale_is_running
|
||||
|
||||
event.date_to = now() + timedelta(days=1)
|
||||
assert not event.presale_has_ended
|
||||
assert event.presale_is_running
|
||||
|
||||
event.date_to = now() - timedelta(days=1)
|
||||
assert event.presale_has_ended
|
||||
assert not event.presale_is_running
|
||||
|
||||
event.presale_end = now() + timedelta(days=1)
|
||||
assert not event.presale_has_ended
|
||||
assert event.presale_is_running
|
||||
|
||||
event.presale_end = now() - timedelta(days=1)
|
||||
assert event.presale_has_ended
|
||||
assert not event.presale_is_running
|
||||
|
||||
|
||||
class SubEventTest(TestCase):
|
||||
@classmethod
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from django.core import mail as djmail
|
||||
from django.test import TestCase
|
||||
from django.utils.timezone import now
|
||||
@@ -115,6 +117,21 @@ class WaitingListTestCase(TestCase):
|
||||
assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 10
|
||||
assert Voucher.objects.count() == 10
|
||||
|
||||
def test_send_periodic_event_over(self):
|
||||
self.event.settings.set('waiting_list_enabled', True)
|
||||
self.event.settings.set('waiting_list_auto', True)
|
||||
self.event.presale_end = now() - timedelta(days=1)
|
||||
self.event.save()
|
||||
for i in range(5):
|
||||
WaitingListEntry.objects.create(
|
||||
event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i)
|
||||
)
|
||||
process_waitinglist(None)
|
||||
assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 5
|
||||
assert Voucher.objects.count() == 0
|
||||
self.event.presale_end = now() + timedelta(days=1)
|
||||
self.event.save()
|
||||
|
||||
def test_send_periodic(self):
|
||||
self.event.settings.set('waiting_list_enabled', True)
|
||||
self.event.settings.set('waiting_list_auto', True)
|
||||
|
||||
@@ -14,7 +14,7 @@ def env(client):
|
||||
orga = Organizer.objects.create(name='CCC', slug='ccc')
|
||||
event = Event.objects.create(
|
||||
organizer=orga, name='30C3', slug='30c3',
|
||||
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
date_from=datetime.datetime(now().year + 1, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
plugins='pretix.plugins.paypal',
|
||||
live=True
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ def env(client):
|
||||
orga = Organizer.objects.create(name='CCC', slug='ccc')
|
||||
event = Event.objects.create(
|
||||
organizer=orga, name='30C3', slug='30c3',
|
||||
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
date_from=datetime.datetime(now().year + 1, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
plugins='pretix.plugins.stripe',
|
||||
live=True
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ class CartTestMixin:
|
||||
self.orga = Organizer.objects.create(name='CCC', slug='ccc')
|
||||
self.event = Event.objects.create(
|
||||
organizer=self.orga, name='30C3', slug='30c3',
|
||||
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
date_from=datetime.datetime(now().year + 1, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
live=True,
|
||||
plugins="pretix.plugins.banktransfer"
|
||||
)
|
||||
@@ -68,6 +68,17 @@ class CartTest(CartTestMixin, TestCase):
|
||||
assert 'alert-danger' in response.rendered_content
|
||||
assert not CartPosition.objects.filter(cart_id=self.session_key, event=self.event).exists()
|
||||
|
||||
def test_after_event(self):
|
||||
self.event.date_to = now() - timedelta(days=1)
|
||||
self.event.save()
|
||||
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
|
||||
'item_%d' % self.ticket.id: '1'
|
||||
}, follow=True)
|
||||
self.assertRedirects(response, '/%s/%s/?require_cookie=true' % (self.orga.slug, self.event.slug),
|
||||
target_status_code=200)
|
||||
assert 'alert-danger' in response.rendered_content
|
||||
assert not CartPosition.objects.filter(cart_id=self.session_key, event=self.event).exists()
|
||||
|
||||
def test_before_presale(self):
|
||||
self.event.presale_start = now() + timedelta(days=1)
|
||||
self.event.save()
|
||||
|
||||
@@ -26,7 +26,7 @@ class CheckoutTestCase(TestCase):
|
||||
self.orga = Organizer.objects.create(name='CCC', slug='ccc')
|
||||
self.event = Event.objects.create(
|
||||
organizer=self.orga, name='30C3', slug='30c3',
|
||||
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
date_from=datetime.datetime(now().year + 1, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
plugins='pretix.plugins.stripe,pretix.plugins.banktransfer',
|
||||
live=True
|
||||
)
|
||||
@@ -1110,6 +1110,19 @@ class CheckoutTestCase(TestCase):
|
||||
self.assertEqual(len(doc.select(".alert-danger")), 1)
|
||||
self.assertEqual(CartPosition.objects.filter(cart_id=self.session_key).count(), 1)
|
||||
|
||||
def test_confirm_event_over(self):
|
||||
self.event.date_to = now() - datetime.timedelta(days=1)
|
||||
self.event.save()
|
||||
CartPosition.objects.create(
|
||||
event=self.event, cart_id=self.session_key, item=self.ticket,
|
||||
price=23, expires=now() + timedelta(minutes=10)
|
||||
)
|
||||
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.assertGreaterEqual(len(doc.select(".alert-danger")), 1)
|
||||
|
||||
def test_confirm_presale_over(self):
|
||||
self.event.presale_end = now() - datetime.timedelta(days=1)
|
||||
self.event.save()
|
||||
|
||||
@@ -24,7 +24,7 @@ class EventTestMixin:
|
||||
self.orga = Organizer.objects.create(name='CCC', slug='ccc')
|
||||
self.event = Event.objects.create(
|
||||
organizer=self.orga, name='30C3', slug='30c3',
|
||||
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
date_from=datetime.datetime(now().year + 1, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
live=True
|
||||
)
|
||||
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
|
||||
@@ -706,6 +706,26 @@ class DeadlineTest(EventTestMixin, TestCase):
|
||||
self.assertIn('alert-danger', response.rendered_content)
|
||||
self.assertIn('not yet started', response.rendered_content)
|
||||
|
||||
def test_event_over(self):
|
||||
self.event.date_to = now() - datetime.timedelta(days=1)
|
||||
self.event.presale_end = None
|
||||
self.event.save()
|
||||
response = self.client.get(
|
||||
'/%s/%s/' % (self.orga.slug, self.event.slug)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn('alert-info', response.rendered_content)
|
||||
self.assertNotIn('btn-add-to-cart', response.rendered_content)
|
||||
response = self.client.post(
|
||||
'/%s/%s/cart/add' % (self.orga.slug, self.event.slug),
|
||||
{
|
||||
'item_%d' % self.item.id: '1'
|
||||
},
|
||||
follow=True
|
||||
)
|
||||
self.assertIn('alert-danger', response.rendered_content)
|
||||
self.assertIn('is over', response.rendered_content)
|
||||
|
||||
def test_over(self):
|
||||
self.event.presale_end = now() - datetime.timedelta(days=1)
|
||||
self.event.save()
|
||||
|
||||
Reference in New Issue
Block a user