From d7b6856322087156cb97819968ca748f6682f758 Mon Sep 17 00:00:00 2001 From: Richard Schreiber Date: Mon, 17 Nov 2025 15:36:53 +0100 Subject: [PATCH] Fix not allowing program times on event series (API/copy) (#5595) * Fix not allowing program times on event series (API/copy) * Return 400 when reading endpoint in event series * add docs program times not available on event series * fix isort --- doc/api/resources/item_program_times.rst | 1 + doc/api/resources/items.rst | 3 +++ src/pretix/api/serializers/item.py | 6 ++++++ src/pretix/api/views/item.py | 4 +++- src/pretix/base/models/event.py | 9 +++++---- src/pretix/base/models/items.py | 2 ++ 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/doc/api/resources/item_program_times.rst b/doc/api/resources/item_program_times.rst index 0bfaf617a..eedf3be0a 100644 --- a/doc/api/resources/item_program_times.rst +++ b/doc/api/resources/item_program_times.rst @@ -5,6 +5,7 @@ Resource description -------------------- Program times for products (items) that can be set in addition to event times, e.g. to display seperate schedules within an event. +Note that ``program_times`` are not available for items inside event series. The program times resource contains the following public fields: .. rst-class:: rest-resource-table diff --git a/doc/api/resources/items.rst b/doc/api/resources/items.rst index 4c8041284..a8a5a1482 100644 --- a/doc/api/resources/items.rst +++ b/doc/api/resources/items.rst @@ -142,6 +142,7 @@ variations list of objects A list with o program_times list of objects A list with one object for each program time of this item. Can be empty. Only writable during creation, use separate endpoint to modify this later. + Not available for items in event series. ├ id integer Internal ID of the variation ├ value multi-lingual string The "name" of the variation ├ default_price money (string) The price set directly for this variation or ``null`` @@ -243,6 +244,8 @@ Also note that ``variations``, ``bundles``, ``addons`` and ``program_times`` ar bundles, add-ons and program times please use the dedicated nested endpoints. By design this endpoint does not support ``PATCH`` and ``PUT`` with nested ``variations``, ``bundles``, ``addons`` and/or ``program_times``. +``program_times`` is not available to items in event series. + Endpoints --------- diff --git a/src/pretix/api/serializers/item.py b/src/pretix/api/serializers/item.py index dea711d79..a2c6258f5 100644 --- a/src/pretix/api/serializers/item.py +++ b/src/pretix/api/serializers/item.py @@ -241,6 +241,12 @@ class ItemProgramTimeSerializer(serializers.ModelSerializer): if start > end: raise ValidationError(_("The program end must not be before the program start.")) + event = self.context['event'] + if event.has_subevents: + raise ValidationError({ + _("You cannot use program times on an event series.") + }) + return data diff --git a/src/pretix/api/views/item.py b/src/pretix/api/views/item.py index 6e0336c0c..443a5157f 100644 --- a/src/pretix/api/views/item.py +++ b/src/pretix/api/views/item.py @@ -40,7 +40,7 @@ from django_filters.rest_framework import DjangoFilterBackend, FilterSet from django_scopes import scopes_disabled from rest_framework import viewsets from rest_framework.decorators import action -from rest_framework.exceptions import PermissionDenied +from rest_framework.exceptions import PermissionDenied, ValidationError from rest_framework.response import Response from pretix.api.pagination import TotalOrderingFilter @@ -293,6 +293,8 @@ class ItemProgramTimeViewSet(viewsets.ModelViewSet): return get_object_or_404(Item, pk=self.kwargs['item'], event=self.request.event) def get_queryset(self): + if self.request.event.has_subevents: + raise ValidationError('You cannot use program times on an event series.') return self.item.program_times.all() def get_serializer_context(self): diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index a6d78ed49..dfe1616cb 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -990,10 +990,11 @@ class Event(EventMixin, LoggedModel): ia.bundled_variation = variation_map[ia.bundled_variation.pk] ia.save(force_insert=True) - for ipt in ItemProgramTime.objects.filter(item__event=other).prefetch_related('item'): - ipt.pk = None - ipt.item = item_map[ipt.item.pk] - ipt.save(force_insert=True) + if not self.has_subevents and not other.has_subevents: + for ipt in ItemProgramTime.objects.filter(item__event=other).prefetch_related('item'): + ipt.pk = None + ipt.item = item_map[ipt.item.pk] + ipt.save(force_insert=True) quota_map = {} for q in Quota.objects.filter(event=other, subevent__isnull=True).prefetch_related('items', 'variations'): diff --git a/src/pretix/base/models/items.py b/src/pretix/base/models/items.py index 84147ca7c..40ffcec34 100644 --- a/src/pretix/base/models/items.py +++ b/src/pretix/base/models/items.py @@ -2311,6 +2311,8 @@ class ItemProgramTime(models.Model): end = models.DateTimeField(verbose_name=_("End")) def clean(self): + if self.item.event.has_subevents: + raise ValidationError(_("You cannot use program times on an event series.")) self.clean_start_end(start=self.start, end=self.end) super().clean()