SubEvent: Automatically bump all orders when date is changed

This commit is contained in:
Raphael Michel
2020-08-26 11:00:43 +02:00
parent 0bfc436970
commit 7a3418e32f
2 changed files with 52 additions and 0 deletions

View File

@@ -1113,12 +1113,28 @@ class SubEvent(EventMixin, LoggedModel):
if self.event and clear_cache: if self.event and clear_cache:
self.event.cache.clear() self.event.cache.clear()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__original_dates = (self.date_from, self.date_to)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
from .orders import Order
clear_cache = kwargs.pop('clear_cache', False) clear_cache = kwargs.pop('clear_cache', False)
super().save(*args, **kwargs) super().save(*args, **kwargs)
if self.event and clear_cache: if self.event and clear_cache:
self.event.cache.clear() self.event.cache.clear()
if (self.date_from, self.date_to) != self.__original_dates:
"""
This is required to guarantee a synchronization invariant of our scanning apps.
Our syncing apps throw away order records of subevents more than X days ago, since
they are not interesting for ticket scanning and pose a performance hazard. However,
the app needs to know when a subevent is moved to a date in the future, since that
might require it to re-download and re-store the orders.
"""
Order.objects.filter(all_positions__subevent=self).update(last_modified=now())
@staticmethod @staticmethod
def clean_items(event, items): def clean_items(event, items):
for item in items: for item in items:

View File

@@ -1,5 +1,6 @@
import datetime import datetime
import sys import sys
import time
from datetime import date, timedelta from datetime import date, timedelta
from decimal import Decimal from decimal import Decimal
@@ -2566,3 +2567,38 @@ def test_question_answer_validation_multiple_choice():
assert q.clean_answer([o1.pk, o3.pk + 1000]) == [o1] assert q.clean_answer([o1.pk, o3.pk + 1000]) == [o1]
with pytest.raises(ValidationError): with pytest.raises(ValidationError):
assert q.clean_answer([o1.pk, 'FOO']) == [o1] assert q.clean_answer([o1.pk, 'FOO']) == [o1]
@pytest.mark.django_db
def test_subevent_date_updates_order_date():
# When the date of a subevent changes, all orders need to get a bumped modification date to hold
# a required invariant of the libpretixsync synchronization approach.
organizer = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=organizer):
event = Event.objects.create(
organizer=organizer, name='Dummy', slug='dummy',
date_from=now(), date_to=now() - timedelta(hours=1), has_subevents=True
)
item1 = Item.objects.create(event=event, name="Ticket", default_price=23, admission=True)
se1 = event.subevents.create(date_from=now(), name="SE 1")
se2 = event.subevents.create(date_from=now(), name="SE 2")
order1 = Order.objects.create(event=event, status=Order.STATUS_PAID, expires=now() + timedelta(days=3), total=6)
OrderPosition.objects.create(order=order1, item=item1, subevent=se1, price=2)
order2 = Order.objects.create(event=event, status=Order.STATUS_PAID, expires=now() + timedelta(days=3), total=6)
OrderPosition.objects.create(order=order2, item=item1, subevent=se2, price=2)
o1lm = order1.last_modified
o2lm = order2.last_modified
time.sleep(1)
se1.date_from += timedelta(days=2)
se1.save()
se2.name = "foo"
se2.save()
order1.refresh_from_db()
order2.refresh_from_db()
assert order1.last_modified > o1lm
assert order2.last_modified == o2lm