diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py
index 2a24074afd..6350c9109b 100644
--- a/src/pretix/base/models/event.py
+++ b/src/pretix/base/models/event.py
@@ -118,25 +118,49 @@ class EventMixin:
def timezone(self):
return pytz.timezone(self.settings.timezone)
+ @property
+ def effective_presale_end(self):
+ """
+ Returns the effective presale end date, taking for subevents into consideration if the presale end
+ date might have been further limited by the event-level presale end date
+ """
+ if isinstance(self, SubEvent):
+ presale_ends = [self.presale_end, self.event.presale_end]
+ return min(filter(lambda x: x is not None, presale_ends)) if any(presale_ends) else None
+ else:
+ return self.presale_end
+
@property
def presale_has_ended(self):
"""
Is true, when ``presale_end`` is set and in the past.
"""
- if self.presale_end:
- return now() > self.presale_end
+ if self.effective_presale_end:
+ return now() > self.effective_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 effective_presale_start(self):
+ """
+ Returns the effective presale start date, taking for subevents into consideration if the presale start
+ date might have been further limited by the event-level presale start date
+ """
+ if isinstance(self, SubEvent):
+ presale_starts = [self.presale_start, self.event.presale_start]
+ return max(filter(lambda x: x is not None, presale_starts)) if any(presale_starts) else None
+ else:
+ return self.presale_start
+
@property
def presale_is_running(self):
"""
Is true, when ``presale_end`` is not set or in the future and ``presale_start`` is not
set or in the past.
"""
- if self.presale_start and now() < self.presale_start:
+ if self.effective_presale_start and now() < self.effective_presale_start:
return False
return not self.presale_has_ended
diff --git a/src/pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html b/src/pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html
index 81c2d4dd10..dbe32b4c81 100644
--- a/src/pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html
+++ b/src/pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html
@@ -36,7 +36,7 @@
{% trans "Sale over" %}
{% elif event.settings.presale_start_show_date %}
- {% blocktrans trimmed with date=subev.presale_start|date:"SHORT_DATE_FORMAT" %}
+ {% blocktrans trimmed with date=subev.effective_presale_start|date:"SHORT_DATE_FORMAT" %}
Sale starts {{ date }}
{% endblocktrans %}
diff --git a/src/pretix/presale/templates/pretixpresale/event/index.html b/src/pretix/presale/templates/pretixpresale/event/index.html
index ad2d263a6b..e421dd9ba5 100644
--- a/src/pretix/presale/templates/pretixpresale/event/index.html
+++ b/src/pretix/presale/templates/pretixpresale/event/index.html
@@ -155,7 +155,7 @@
{% endblocktrans %}
{% endif %}
{% elif event.settings.presale_start_show_date %}
- {% blocktrans trimmed with date=ev.presale_start|date:"SHORT_DATE_FORMAT" time=ev.presale_start|time:"TIME_FORMAT" %}
+ {% blocktrans trimmed with date=ev.effective_presale_start|date:"SHORT_DATE_FORMAT" time=ev.effective_presale_start|time:"TIME_FORMAT" %}
The presale for this event will start on {{ date }} at {{ time }}.
{% endblocktrans %}
{% else %}
diff --git a/src/pretix/presale/templates/pretixpresale/organizers/index.html b/src/pretix/presale/templates/pretixpresale/organizers/index.html
index 855e968b9e..68c9c3d382 100644
--- a/src/pretix/presale/templates/pretixpresale/organizers/index.html
+++ b/src/pretix/presale/templates/pretixpresale/organizers/index.html
@@ -120,7 +120,7 @@
{% trans "Sale over" %}
{% elif e.settings.presale_start_show_date %}
- {% blocktrans trimmed with date=e.presale_start|date:"SHORT_DATE_FORMAT" %}
+ {% blocktrans trimmed with date=e.effective_presale_start|date:"SHORT_DATE_FORMAT" %}
Sale starts {{ date }}
{% endblocktrans %}
diff --git a/src/pretix/presale/views/widget.py b/src/pretix/presale/views/widget.py
index a576605f58..f1ad8d57c0 100644
--- a/src/pretix/presale/views/widget.py
+++ b/src/pretix/presale/views/widget.py
@@ -569,8 +569,8 @@ class WidgetAPIProductList(EventListMixin, View):
data['error'] = gettext('The presale period for this event is over.')
elif request.event.settings.presale_start_show_date:
data['error'] = gettext('The presale for this event will start on %(date)s at %(time)s.') % {
- 'date': date_format(ev.presale_start.astimezone(request.event.timezone), "SHORT_DATE_FORMAT"),
- 'time': date_format(ev.presale_start.astimezone(request.event.timezone), "TIME_FORMAT"),
+ 'date': date_format(ev.effective_presale_start.astimezone(request.event.timezone), "SHORT_DATE_FORMAT"),
+ 'time': date_format(ev.effective_presale_start.astimezone(request.event.timezone), "TIME_FORMAT"),
}
else:
data['error'] = gettext('The presale for this event has not yet started.')