Disable shop and waiting list after end of event

This commit is contained in:
Raphael Michel
2018-02-04 14:14:49 +01:00
parent 2f00db8081
commit 67678e35bb
11 changed files with 126 additions and 26 deletions
+21 -18
View File
@@ -43,7 +43,7 @@ class EventMixin:
Returns a shorter formatted string containing the start date of the event with respect Returns a shorter formatted string containing the start date of the event with respect
to the current locale and to the ``show_times`` setting. 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( return _date(
self.date_from.astimezone(tz), self.date_from.astimezone(tz),
"SHORT_DATETIME_FORMAT" if self.settings.show_times and show_times else "DATE_FORMAT" "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 to the current locale and to the ``show_times`` setting. Returns an empty string
if ``show_date_to`` is ``False``. 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: if not self.settings.show_date_to or not self.date_to:
return "" return ""
return _date( return _date(
@@ -68,7 +68,7 @@ class EventMixin:
Returns a formatted string containing the start date of the event with respect Returns a formatted string containing the start date of the event with respect
to the current locale and to the ``show_times`` setting. 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( return _date(
self.date_from.astimezone(tz), self.date_from.astimezone(tz),
"DATETIME_FORMAT" if self.settings.show_times and show_times else "DATE_FORMAT" "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 Returns a formatted string containing the start time of the event, ignoring
the ``show_times`` setting. the ``show_times`` setting.
""" """
tz = tz or pytz.timezone(self.settings.timezone) tz = tz or self.timezone
return _date( return _date(
self.date_from.astimezone(tz), "TIME_FORMAT" 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 to the current locale and to the ``show_times`` setting. Returns an empty string
if ``show_date_to`` is ``False``. 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: if not self.settings.show_date_to or not self.date_to:
return "" return ""
return _date( return _date(
@@ -104,19 +104,26 @@ class EventMixin:
of the event with respect to the current locale and to the ``show_times`` and of the event with respect to the current locale and to the ``show_times`` and
``show_date_to`` settings. ``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: if not self.settings.show_date_to or not self.date_to:
return _date(self.date_from.astimezone(tz), "DATE_FORMAT") return _date(self.date_from.astimezone(tz), "DATE_FORMAT")
return daterange(self.date_from.astimezone(tz), self.date_to.astimezone(tz)) return daterange(self.date_from.astimezone(tz), self.date_to.astimezone(tz))
@property
def timezone(self):
return pytz.timezone(self.settings.timezone)
@property @property
def presale_has_ended(self): def presale_has_ended(self):
""" """
Is true, when ``presale_end`` is set and in the past. Is true, when ``presale_end`` is set and in the past.
""" """
if self.presale_end and now() > self.presale_end: if self.presale_end:
return True return now() > self.presale_end
return False elif self.date_to:
return now() > self.date_to
else:
return now().astimezone(self.timezone).date() > self.date_from.astimezone(self.timezone).date()
@property @property
def presale_is_running(self): def presale_is_running(self):
@@ -126,9 +133,7 @@ class EventMixin:
""" """
if self.presale_start and now() < self.presale_start: if self.presale_start and now() < self.presale_start:
return False return False
if self.presale_end and now() > self.presale_end: return not self.presale_has_ended
return False
return True
@property @property
def event_microdata(self): def event_microdata(self):
@@ -229,7 +234,8 @@ class Event(EventMixin, LoggedModel):
presale_end = models.DateTimeField( presale_end = models.DateTimeField(
null=True, blank=True, null=True, blank=True,
verbose_name=_("End of presale"), 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( presale_start = models.DateTimeField(
null=True, blank=True, null=True, blank=True,
@@ -323,10 +329,6 @@ class Event(EventMixin, LoggedModel):
else: else:
return get_connection(fail_silently=False) return get_connection(fail_silently=False)
@property
def timezone(self):
return pytz.timezone(self.settings.timezone)
@property @property
def payment_term_last(self): def payment_term_last(self):
""" """
@@ -590,7 +592,8 @@ class SubEvent(EventMixin, LoggedModel):
presale_end = models.DateTimeField( presale_end = models.DateTimeField(
null=True, blank=True, null=True, blank=True,
verbose_name=_("End of presale"), 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( presale_start = models.DateTimeField(
null=True, blank=True, null=True, blank=True,
+1 -1
View File
@@ -112,7 +112,7 @@ class CartManager:
def _check_presale_dates(self): def _check_presale_dates(self):
if self.event.presale_start and self.now_dt < self.event.presale_start: if self.event.presale_start and self.now_dt < self.event.presale_start:
raise CartError(error_messages['not_started']) 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']) raise CartError(error_messages['ended'])
def _extend_expiry_of_valid_existing_positions(self): def _extend_expiry_of_valid_existing_positions(self):
+1 -1
View File
@@ -321,7 +321,7 @@ class OrderError(LazyLocaleException):
def _check_date(event: Event, now_dt: datetime): def _check_date(event: Event, now_dt: datetime):
if event.presale_start and now_dt < event.presale_start: if event.presale_start and now_dt < event.presale_start:
raise OrderError(error_messages['not_started']) 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']) raise OrderError(error_messages['ended'])
+5 -1
View File
@@ -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: if (wle.item, wle.variation) in gone:
continue continue
ev = (wle.subevent or event)
if not ev.presale_is_running:
continue
quotas = (wle.variation.quotas.filter(subevent=wle.subevent) quotas = (wle.variation.quotas.filter(subevent=wle.subevent)
if wle.variation if wle.variation
else wle.item.quotas.filter(subevent=wle.subevent)) 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): def process_waitinglist(sender, **kwargs):
qs = Event.objects.prefetch_related('_settings_objects', 'organizer___settings_objects').select_related('organizer') qs = Event.objects.prefetch_related('_settings_objects', 'organizer___settings_objects').select_related('organizer')
for e in qs: 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,)) assign_automatically.apply_async(args=(e.pk,))
+32
View File
@@ -1020,6 +1020,38 @@ class EventTest(TestCase):
assert event2.checkin_lists.count() == 1 assert event2.checkin_lists.count() == 1
assert [i.pk for i in event2.checkin_lists.first().limit_products.all()] == [i1new.pk] 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): class SubEventTest(TestCase):
@classmethod @classmethod
+17
View File
@@ -1,3 +1,5 @@
from datetime import timedelta
from django.core import mail as djmail from django.core import mail as djmail
from django.test import TestCase from django.test import TestCase
from django.utils.timezone import now from django.utils.timezone import now
@@ -115,6 +117,21 @@ class WaitingListTestCase(TestCase):
assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 10 assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 10
assert Voucher.objects.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): def test_send_periodic(self):
self.event.settings.set('waiting_list_enabled', True) self.event.settings.set('waiting_list_enabled', True)
self.event.settings.set('waiting_list_auto', True) self.event.settings.set('waiting_list_auto', True)
+1 -1
View File
@@ -14,7 +14,7 @@ def env(client):
orga = Organizer.objects.create(name='CCC', slug='ccc') orga = Organizer.objects.create(name='CCC', slug='ccc')
event = Event.objects.create( event = Event.objects.create(
organizer=orga, name='30C3', slug='30c3', 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', plugins='pretix.plugins.paypal',
live=True live=True
) )
+1 -1
View File
@@ -24,7 +24,7 @@ def env(client):
orga = Organizer.objects.create(name='CCC', slug='ccc') orga = Organizer.objects.create(name='CCC', slug='ccc')
event = Event.objects.create( event = Event.objects.create(
organizer=orga, name='30C3', slug='30c3', 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', plugins='pretix.plugins.stripe',
live=True live=True
) )
+12 -1
View File
@@ -25,7 +25,7 @@ class CartTestMixin:
self.orga = Organizer.objects.create(name='CCC', slug='ccc') self.orga = Organizer.objects.create(name='CCC', slug='ccc')
self.event = Event.objects.create( self.event = Event.objects.create(
organizer=self.orga, name='30C3', slug='30c3', 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, live=True,
plugins="pretix.plugins.banktransfer" plugins="pretix.plugins.banktransfer"
) )
@@ -68,6 +68,17 @@ class CartTest(CartTestMixin, TestCase):
assert 'alert-danger' in response.rendered_content assert 'alert-danger' in response.rendered_content
assert not CartPosition.objects.filter(cart_id=self.session_key, event=self.event).exists() 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): def test_before_presale(self):
self.event.presale_start = now() + timedelta(days=1) self.event.presale_start = now() + timedelta(days=1)
self.event.save() self.event.save()
+14 -1
View File
@@ -26,7 +26,7 @@ class CheckoutTestCase(TestCase):
self.orga = Organizer.objects.create(name='CCC', slug='ccc') self.orga = Organizer.objects.create(name='CCC', slug='ccc')
self.event = Event.objects.create( self.event = Event.objects.create(
organizer=self.orga, name='30C3', slug='30c3', 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', plugins='pretix.plugins.stripe,pretix.plugins.banktransfer',
live=True live=True
) )
@@ -1110,6 +1110,19 @@ class CheckoutTestCase(TestCase):
self.assertEqual(len(doc.select(".alert-danger")), 1) self.assertEqual(len(doc.select(".alert-danger")), 1)
self.assertEqual(CartPosition.objects.filter(cart_id=self.session_key).count(), 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): def test_confirm_presale_over(self):
self.event.presale_end = now() - datetime.timedelta(days=1) self.event.presale_end = now() - datetime.timedelta(days=1)
self.event.save() self.event.save()
+21 -1
View File
@@ -24,7 +24,7 @@ class EventTestMixin:
self.orga = Organizer.objects.create(name='CCC', slug='ccc') self.orga = Organizer.objects.create(name='CCC', slug='ccc')
self.event = Event.objects.create( self.event = Event.objects.create(
organizer=self.orga, name='30C3', slug='30c3', 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 live=True
) )
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') 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('alert-danger', response.rendered_content)
self.assertIn('not yet started', 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): def test_over(self):
self.event.presale_end = now() - datetime.timedelta(days=1) self.event.presale_end = now() - datetime.timedelta(days=1)
self.event.save() self.event.save()