Compare commits

...
Author SHA1 Message Date
Raphael MichelandRichard Schreiber e4af51f207 Update src/pretix/presale/views/organizer.py
Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
2026-09-02 18:02:19 +02:00
Raphael Michel 07a0d78a36 Event calendar: consider events without products "not available" for filtering
Also, drop the help text of the flag that is no longer accurate.
2026-09-02 10:30:24 +02:00
Richard Schreiber 58a58eff83 Widget: fix show taxline for 0 or 0.00 tax-rate (#6502) 2026-09-01 13:19:32 +02:00
Martin Gross a84a02c298 Vite: Add dev CORS (#6511) 2026-09-01 11:22:19 +02:00
7 changed files with 48 additions and 33 deletions
-2
View File
@@ -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': {
+5 -7
View File
@@ -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
+28 -13
View File
@@ -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)
+5 -9
View File
@@ -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'] = [
{
@@ -345,7 +345,7 @@ Vue.component('pricebox', {
+ ' :min="display_price_nonlocalized" :value="suggested_price_nonlocalized" :name="field_name"'
+ ' step="any" v-bind:aria-labelledby="aria_labelledby" v-bind:aria-describedby="price_desc_id">'
+ '</div>'
+ '<small class="pretix-widget-pricebox-tax" :id="price_desc_id" v-if="price.rate != \'0\' && price.gross != \'0.00\'">'
+ '<small class="pretix-widget-pricebox-tax" :id="price_desc_id" v-if="show_taxline">'
+ '{{ taxline }}'
+ '</small>'
+ '</div>'),
@@ -422,6 +422,10 @@ Vue.component('pricebox', {
return '<span class="pretix-widget-pricebox-currency">' + this.$root.currency + "</span> " + this.display_price;
}
},
show_taxline: function () {
// rate can either be "0.00" or "0" => parseFloat to check
return Number.parseFloat(this.price.rate) && Number.parseFloat(this.price.gross);
},
taxline: function () {
if (this.$root.display_net_prices) {
if (this.price.includes_mixed_tax_rate) {
@@ -86,7 +86,8 @@ const taxline = computed(() => {
}
})
const showTaxline = computed(() => props.price.rate !== '0' && props.price.gross !== '0.00')
// rate can either be "0.00" or "0" => parseFloat to check
const showTaxline = computed(() => Number.parseFloat(props.price.rate) && Number.parseFloat(props.price.gross))
</script>
<template lang="pug">
.pretix-widget-pricebox
+3
View File
@@ -31,6 +31,9 @@ export default defineConfig({
// Allow serving source files from sibling plugin directories
allow: ['src', ...pluginDirs],
},
cors: {
origin: /^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\]|[^:]+\.pretix\.(dev|work))(?::\d+)?$/
},
},
build: {
manifest: true,