Allow RelativeDate in relation to a moment of order (#6160)

* initial implementation

* factor out _resolve_base_date

* add js to prevent illegal inputs

* fix tests

* Update src/pretix/base/reldate.py

Co-authored-by: Raphael Michel <michel@pretix.eu>

* Apply suggestions from code review

Co-authored-by: Raphael Michel <mail@raphaelmichel.de>

* move js includes of to fragment_js.html

* add type annotations

* moves logic from RelativeDateWrapper into RelativeDate and adds BaseChoice for configuring which models attributes support which relationship

* fix tests

* test upgrade behaviour

* Apply suggestions from code review

Co-authored-by: Raphael Michel <mail@raphaelmichel.de>

* move reldate.js include in correct file

* add OptionAttrsSelect to allow select options with their own attributes per value

* add a little bit of information to the tests for future reference

* rewrite reldate.js use data-attributes

* general cleanup

* add test for order.subevents cases

* use correct choice format

* remove order.subevent variants

* various cleanup

* Apply suggestions from code review

Co-authored-by: Raphael Michel <mail@raphaelmichel.de>

* remove empty docstrings

* add depreciation warning

* change event listener to pretix:bind-forms

---------

Co-authored-by: Raphael Michel <michel@pretix.eu>
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
This commit is contained in:
Lukas Bockstaller
2026-08-12 15:37:29 +02:00
committed by GitHub
co-authored by Raphael Michel Raphael Michel
parent f25c233e91
commit 7fe31634e6
16 changed files with 588 additions and 254 deletions
+14 -14
View File
@@ -473,7 +473,7 @@ class QuotaTestCase(BaseQuotaTestCase):
@classscope(attr='o')
def test_waitinglist_auto_disable(self):
self.event.settings.waiting_list_auto_disable = RelativeDateWrapper(
RelativeDate(days=0, time=None, base_date_name='date_from', minutes=20, is_after=True)
RelativeDate(days=0, time=None, base_date_name='event__date_from', minutes=20, is_after=True)
)
self.quota.items.add(self.item1)
self.quota.size = 1
@@ -484,7 +484,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
self.assertEqual(self.item1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1))
self.event.settings.waiting_list_auto_disable = RelativeDateWrapper(
RelativeDate(days=0, time=None, base_date_name='date_from', minutes=20, is_after=False)
RelativeDate(days=0, time=None, base_date_name='event__date_from', minutes=20, is_after=False)
)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
self.assertEqual(self.item1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1))
@@ -1192,7 +1192,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.op2.subevent = se2
self.op2.save()
self.event.settings.set('payment_term_last', RelativeDateWrapper(
RelativeDate(days=2, time=None, base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=None, base_date_name='event__date_from', minutes=None)
))
self.order.status = Order.STATUS_EXPIRED
@@ -1347,7 +1347,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.op2.subevent = se2
self.op2.save()
self.event.settings.set('last_order_modification_date', RelativeDateWrapper(
RelativeDate(days=2, time=None, base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=None, base_date_name='event__date_from', minutes=None)
))
assert self.order.can_modify_answers
self.op2.subevent = se3
@@ -1363,7 +1363,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.date_from = datetime.datetime(2017, 5, 3, 12, 0, 0, tzinfo=datetime.timezone.utc)
self.event.save()
self.event.settings.set('payment_term_last', RelativeDateWrapper(
RelativeDate(days=2, time=None, base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=None, base_date_name='event__date_from', minutes=None)
))
assert self.order.payment_term_last == datetime.datetime(2017, 5, 1, 23, 59, 59, tzinfo=datetime.timezone.utc)
@@ -1379,7 +1379,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.op2.subevent = se2
self.op2.save()
self.event.settings.set('payment_term_last', RelativeDateWrapper(
RelativeDate(days=2, time=None, base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=None, base_date_name='event__date_from', minutes=None)
))
assert self.order.payment_term_last > now()
self.op2.subevent = se3
@@ -1395,7 +1395,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.date_from = datetime.datetime(2017, 5, 3, 12, 0, 0, tzinfo=datetime.timezone.utc)
self.event.save()
self.event.settings.set('ticket_download_date', RelativeDateWrapper(
RelativeDate(days=2, time=None, base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=None, base_date_name='event__date_from', minutes=None)
))
assert self.order.ticket_download_date == datetime.datetime(2017, 5, 1, 12, 0, 0, tzinfo=datetime.timezone.utc)
@@ -1411,7 +1411,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.op2.subevent = se2
self.op2.save()
self.event.settings.set('ticket_download_date', RelativeDateWrapper(
RelativeDate(days=2, time=None, base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=None, base_date_name='event__date_from', minutes=None)
))
assert self.order.ticket_download_date > now()
self.op2.subevent = se3
@@ -1582,13 +1582,13 @@ class OrderTestCase(BaseQuotaTestCase):
assert self.order.user_cancel_deadline is None
self.event.settings.set('cancel_allow_user_until', RelativeDateWrapper(
RelativeDate(days=2, time=datetime.time(14, 0, 0), base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=datetime.time(14, 0, 0), base_date_name='event__date_from', minutes=None)
))
self.order = Order.objects.get(pk=self.order.pk)
assert self.order.user_cancel_deadline > now()
assert self.order.user_cancel_allowed
self.event.settings.set('cancel_allow_user_until', RelativeDateWrapper(
RelativeDate(days=4, time=datetime.time(14, 0, 0), base_date_name='date_from', minutes=None)
RelativeDate(days=4, time=datetime.time(14, 0, 0), base_date_name='event__date_from', minutes=None)
))
self.order = Order.objects.get(pk=self.order.pk)
assert self.order.user_cancel_deadline < now()
@@ -1607,7 +1607,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.op2.save()
self.event.settings.set('cancel_allow_user_until', RelativeDateWrapper(
RelativeDate(days=2, time=datetime.time(14, 0, 0), base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=datetime.time(14, 0, 0), base_date_name='event__date_from', minutes=None)
))
self.order = Order.objects.get(pk=self.order.pk)
assert self.order.user_cancel_deadline < now()
@@ -2018,13 +2018,13 @@ class OrderTestCase(BaseQuotaTestCase):
assert self.order.user_change_deadline is None
self.event.settings.set('change_allow_user_until', RelativeDateWrapper(
RelativeDate(days=2, time=datetime.time(14, 0, 0), base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=datetime.time(14, 0, 0), base_date_name='event__date_from', minutes=None)
))
self.order = Order.objects.get(pk=self.order.pk)
assert self.order.user_change_deadline > now()
assert self.order.user_change_allowed
self.event.settings.set('change_allow_user_until', RelativeDateWrapper(
RelativeDate(days=4, time=datetime.time(14, 0, 0), base_date_name='date_from', minutes=None)
RelativeDate(days=4, time=datetime.time(14, 0, 0), base_date_name='event__date_from', minutes=None)
))
self.order = Order.objects.get(pk=self.order.pk)
assert self.order.user_change_deadline < now()
@@ -2046,7 +2046,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.op2.save()
self.event.settings.set('change_allow_user_until', RelativeDateWrapper(
RelativeDate(days=2, time=datetime.time(14, 0, 0), base_date_name='date_from', minutes=None)
RelativeDate(days=2, time=datetime.time(14, 0, 0), base_date_name='event__date_from', minutes=None)
))
self.order = Order.objects.get(pk=self.order.pk)
assert self.order.user_change_deadline < now()