diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index f2229a821..d193f0323 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -1930,8 +1930,6 @@ DEFAULTS = { 'serializer_class': serializers.BooleanField, 'form_kwargs': dict( label=_("Hide all unavailable dates from calendar or list views"), - help_text=_("This option currently only affects the calendar of this event series, not the organizer-wide " - "calendar.") ) }, 'event_calendar_future_only': { diff --git a/src/pretix/presale/views/event.py b/src/pretix/presale/views/event.py index a7cff433e..fe54f21eb 100644 --- a/src/pretix/presale/views/event.py +++ b/src/pretix/presale/views/event.py @@ -79,7 +79,7 @@ from pretix.presale.signals import seatingframe_html_head from pretix.presale.views.organizer import ( EventListMixin, add_subevents_for_days, days_for_template, filter_qs_by_attr, filter_subevents_with_plugins, has_before_after, - weeks_for_template, + should_hide_subevent, weeks_for_template, ) from . import ( @@ -443,12 +443,10 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView): ) ) subevents = filter_subevents_with_plugins(list(subevents), self.request.sales_channel) - context['subevent_list'] = subevents - if self.request.event.settings.event_list_available_only and not voucher: - context['subevent_list'] = [ - se for se in subevents - if not se.presale_has_ended and (se.best_availability_state is None or se.best_availability_state >= Quota.AVAILABILITY_RESERVED) - ] + context['subevent_list'] = [ + se for se in subevents + if not should_hide_subevent(self.request.event.settings, se, voucher) + ] context['visible_events'] = len(subevents) > 0 return context diff --git a/src/pretix/presale/views/organizer.py b/src/pretix/presale/views/organizer.py index a89fa3069..0b4b15381 100644 --- a/src/pretix/presale/views/organizer.py +++ b/src/pretix/presale/views/organizer.py @@ -601,6 +601,32 @@ def filter_subevents_with_plugins(subevents, sales_channel=None): return subevents +def should_hide_subevent(settings, subevent, voucher=None): + hide = False + if settings.event_list_available_only: + hide = ( + # Presale is over → the subevent is not available → hide + subevent.presale_has_ended or + # Not a single product is available on this sales channel → hide + # Note that means there could be products which are ignored for calendar availability (Quota.ignore_for_event_availability) + # or products only visible with a voucher. However, for customers with these scenarios, the event_list_available_only + # makes only very little sense as it would never do anything, so the flag can just be removed -- or the products should + # be made visible so people know why there are no products. In case a voucher is already entered on the calendar view, + # this is already respected and subevents are shown correctly. + subevent.best_availability_state is None or + ( + # Sold out → hide, unless we have a voucher active that can bypass all quotas + (not voucher or not voucher.allow_ignore_quota) and + subevent.best_availability_state < Quota.AVAILABILITY_RESERVED + ) + ) + + if settings.event_calendar_future_only: + if (subevent.date_to or subevent.date_from) < time_machine_now(): + hide = True + return hide + + def add_subevents_for_days(qs, before, after, ebd, timezones, sales_channel, event=None, cart_namespace=None, voucher=None): qs = qs.filter(active=True, is_public=True).filter( @@ -640,19 +666,8 @@ def add_subevents_for_days(qs, before, after, ebd, timezones, sales_channel, eve kwargs['cart_namespace'] = cart_namespace s = event.settings if event else se.event.settings - - if s.event_list_available_only: - hide = se.presale_has_ended or ( - (not voucher or not voucher.allow_ignore_quota) and - se.best_availability_state is not None and - se.best_availability_state < Quota.AVAILABILITY_RESERVED - ) - if hide: - continue - - if s.event_calendar_future_only: - if (se.date_to or se.date_from) < time_machine_now(): - continue + if should_hide_subevent(s, se, voucher): + continue timezones.add(s.timezone) tz = ZoneInfo(s.timezone) diff --git a/src/pretix/presale/views/widget.py b/src/pretix/presale/views/widget.py index 553e48458..bc1432f89 100644 --- a/src/pretix/presale/views/widget.py +++ b/src/pretix/presale/views/widget.py @@ -75,7 +75,7 @@ from pretix.presale.views.cart import get_or_create_cart_id from pretix.presale.views.organizer import ( EventListMixin, add_events_for_days, add_subevents_for_days, days_for_template, filter_qs_by_attr, filter_subevents_with_plugins, - weeks_for_template, + should_hide_subevent, weeks_for_template, ) logger = logging.getLogger(__name__) @@ -757,14 +757,10 @@ class WidgetAPIProductList(EventListMixin, View): evs = evs[:limit] tz = request.event.timezone - if self.request.event.settings.event_list_available_only: - evs = [ - se for se in evs - if not se.presale_has_ended and ( - se.best_availability_state is not None and - se.best_availability_state >= Quota.AVAILABILITY_RESERVED - ) - ] + evs = [ + se for se in evs + if not should_hide_subevent(self.request.event.settings, se) + ] data['events'] = [ {