diff --git a/doc/api/resources/orders.rst b/doc/api/resources/orders.rst index 8f0ff758a0..f14fd1b1b8 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 da253e531b..a4b1b40bb5 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.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 dc73363301..c26226e97d 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 a4dd0c83a7..00d29491c4 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 1ac565b876..e5f5b9b838 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 @@ -81,7 +81,7 @@ from pretix.base.i18n import language from pretix.base.models import ( CachedFile, CachedTicket, Checkin, Invoice, InvoiceAddress, Item, ItemVariation, LogEntry, Order, QuestionAnswer, Quota, - ScheduledEventExport, generate_secret, + ScheduledEventExport, generate_secret, GiftCard, ) from pretix.base.models.orders import ( CancellationRequest, OrderFee, OrderPayment, OrderPosition, OrderRefund, @@ -2248,6 +2248,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 @@ -2307,7 +2313,7 @@ class OrderContactChange(OrderView): if self.form.cleaned_data['regenerate_secrets']: changed = True self.order.secret = generate_secret() - for op in self.order.all_positions.all(): + for op in self.order.all_positions.filter(~Exists(GiftCard.objects.filter(issued_in=OuterRef('pk')))): op.web_secret = generate_secret() op.save(update_fields=["web_secret"]) assign_ticket_secret(