diff --git a/doc/api/resources/orders.rst b/doc/api/resources/orders.rst index 8f0ff758a..f14fd1b1b 100644 --- a/doc/api/resources/orders.rst +++ b/doc/api/resources/orders.rst @@ -864,6 +864,9 @@ Generating new secrets Triggers generation of new ``secret`` and ``web_secret`` attributes for both the order and all order positions. + Ticket secrets of order positions that have been used to issue a gift card can not + be changed. Only the link (``web_secret``) will be changed in this case. + **Example request**: .. sourcecode:: http @@ -895,6 +898,9 @@ Generating new secrets Triggers generation of a new ``secret`` and ``web_secret`` attribute for a single order position. + Ticket secrets of order positions that have been used to issue a gift card can not + be changed. Only the link (``web_secret``) will be changed in this case. + **Example request**: .. sourcecode:: http diff --git a/src/pretix/base/secrets.py b/src/pretix/base/secrets.py index da253e531..42f1b9799 100644 --- a/src/pretix/base/secrets.py +++ b/src/pretix/base/secrets.py @@ -245,6 +245,9 @@ def recv_classic(sender, **kwargs): def assign_ticket_secret(event, position, force_invalidate_if_revokation_list_used=False, force_invalidate=False, save=True): + if position.pk and position.issued_gift_cards.exists(): + return + gen = event.ticket_secret_generator if gen.use_revocation_list and force_invalidate_if_revokation_list_used: force_invalidate = True diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index dc7336330..c26226e97 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -1599,6 +1599,7 @@ class OrderChangeManager: 'seat_forbidden': gettext_lazy('The selected product does not allow to select a seat.'), 'tax_rule_country_blocked': gettext_lazy('The selected country is blocked by your tax rule.'), 'gift_card_change': gettext_lazy('You cannot change the price of a position that has been used to issue a gift card.'), + 'gift_card_secret': gettext_lazy('You cannot change the ticket secret of a position that has been used to issue a gift card.'), 'max_items_per_product': ngettext_lazy( "You cannot select more than %(max)s item of the product %(product)s.", "You cannot select more than %(max)s items of the product %(product)s.", @@ -1756,6 +1757,9 @@ class OrderChangeManager: self._operations.append(self.RegenerateSecretOperation(position)) def change_ticket_secret(self, position: OrderPosition, new_secret: str): + if position.issued_gift_cards.exists(): + raise OrderError(self.error_messages['gift_card_secret']) + self._operations.append(self.ChangeSecretOperation(position, new_secret)) def change_valid_from(self, position: OrderPosition, new_value: datetime): diff --git a/src/pretix/control/templates/pretixcontrol/order/change.html b/src/pretix/control/templates/pretixcontrol/order/change.html index a4dd0c83a..00d29491c 100644 --- a/src/pretix/control/templates/pretixcontrol/order/change.html +++ b/src/pretix/control/templates/pretixcontrol/order/change.html @@ -284,6 +284,14 @@
{% bootstrap_field position.form.operation_secret layout='inline' %} + {% if position.issued_gift_cards.exists %} +
+ {% blocktrans trimmed %} + Ticket secrets of order positions that have been used to issue a gift card can not + be changed. Only the link will be changed in this case. + {% endblocktrans %} +
+ {% endif %}
diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index 53b628ed5..3b8cd26e6 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -64,7 +64,7 @@ from django.urls import reverse from django.utils import formats from django.utils.formats import date_format, get_format from django.utils.functional import cached_property -from django.utils.html import conditional_escape, escape +from django.utils.html import conditional_escape, escape, format_html from django.utils.http import url_has_allowed_host_and_scheme from django.utils.safestring import mark_safe from django.utils.timezone import make_aware, now @@ -79,7 +79,7 @@ from pretix.base.email import get_email_context from pretix.base.exporter import MultiSheetListExporter from pretix.base.i18n import language from pretix.base.models import ( - CachedFile, CachedTicket, Checkin, Invoice, InvoiceAddress, Item, + CachedFile, CachedTicket, Checkin, GiftCard, Invoice, InvoiceAddress, Item, ItemVariation, LogEntry, Order, QuestionAnswer, Quota, ScheduledEventExport, generate_secret, ) @@ -1994,7 +1994,7 @@ class OrderChange(OrderView): positions = list(self.order.positions.select_related( 'item', 'item__tax_rule', 'used_membership', 'used_membership__membership_type', 'tax_rule', 'seat', 'subevent', - ).prefetch_related('granted_memberships')) + ).prefetch_related('granted_memberships', 'issued_gift_cards')) for p in positions: p.form = OrderPositionChangeForm(prefix='op-{}'.format(p.pk), instance=p, items=self.items, initial={'seat': p.seat.seat_guid if p.seat else None}, @@ -2261,6 +2261,12 @@ class OrderContactChange(OrderView): def get_context_data(self, **kwargs): ctx = super().get_context_data() ctx['form'] = self.form + if self.order.all_positions.filter(Exists(GiftCard.objects.filter(issued_in=OuterRef('pk')))).exists(): + self.form.fields['regenerate_secrets'].help_text = format_html( + '{}

{}', + self.form.fields['regenerate_secrets'].help_text, + _("Ticket secrets of order positions that have been used to issue a gift card can not be changed. Only the link will be changed in this case."), + ) return ctx @cached_property