From f7b4e37c95933d5cffd94b43ee135f8676611280 Mon Sep 17 00:00:00 2001 From: Mira Weller Date: Thu, 25 Jan 2024 17:38:18 +0100 Subject: [PATCH] respect individual allowed positions from plugins --- src/pretix/base/models/orders.py | 25 +++++++++---------- src/pretix/base/services/orders.py | 7 ++---- src/pretix/base/services/tickets.py | 7 +++--- src/pretix/base/ticketoutput.py | 5 +++- .../plugins/ticketoutputpdf/ticketoutput.py | 3 ++- .../pretixpresale/event/fragment_cart.html | 2 +- .../event/fragment_downloads.html | 2 +- src/pretix/presale/views/order.py | 19 ++++++++------ 8 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index cba3e76a87..1a991f8ea1 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -1137,12 +1137,20 @@ class Order(LockModel, LoggedModel): attach_tickets=True, ) + @property + def positions_with_tickets_ignoring_plugins(self): + return (op for op in self.positions.select_related('item') if op.generate_ticket) + @property def positions_with_tickets(self): - for op in self.positions.select_related('item'): - if not op.generate_ticket: - continue - yield op + signal_response = allow_ticket_download.send(self.event, order=self) + print("signal_response", signal_response) + if all([r is True for rr, r in signal_response]): + return self.positions_with_tickets_ignoring_plugins + elif any([r is False for rr, r in signal_response]): + return [] + else: + return set.intersection(set(self.positions_with_tickets_ignoring_plugins), *[set(r) for rr, r in signal_response if isinstance(r, Iterable)]) def create_transactions(self, is_new=False, positions=None, fees=None, dt_now=None, migrated=False, _backfill_before_cancellation=False, save=True): @@ -1200,15 +1208,6 @@ class Order(LockModel, LoggedModel): _transactions_mark_order_clean(self.pk) return create - @property - def plugins_allow_ticket_download(self): - signal_response = allow_ticket_download.send(self.event, order=self) - if all([r == True for rr, r in signal_response]): - return True - elif any([r == False for rr, r in signal_response]): - return False - else: - return set.intersection(*[set(r) for rr, r in signal_response if isinstance(r, Iterable)]) def answerfile_name(instance, filename: str) -> str: diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index 4b78a6b93e..f168de4a2f 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -1408,20 +1408,17 @@ def send_download_reminders(sender, **kwargs): if o.download_reminder_sent: # Race condition continue - if not o.plugins_allow_ticket_download: + positions = o.positions_with_tickets + if not positions: continue if not o.ticket_download_available: continue - positions = o.positions.select_related('item') if o.status != Order.STATUS_PAID: if o.status != Order.STATUS_PENDING or o.require_approval or (not o.valid_if_pending and not o.event.settings.ticket_download_pending): continue - if not any(p.generate_ticket for p in positions): - continue - with language(o.locale, o.event.settings.region): o.download_reminder_sent = True o.save(update_fields=['download_reminder_sent']) diff --git a/src/pretix/base/services/tickets.py b/src/pretix/base/services/tickets.py index a1aafd5750..dd78261452 100644 --- a/src/pretix/base/services/tickets.py +++ b/src/pretix/base/services/tickets.py @@ -21,6 +21,7 @@ # import logging import os +from typing import Iterable from django.core.files.base import ContentFile from django.utils.timezone import now @@ -124,8 +125,8 @@ def preview(event: int, provider: str): def get_tickets_for_order(order, base_position=None): - can_download = order.plugins_allow_ticket_download - if not can_download: + positions_with_ticket = order.positions_with_tickets + if not positions_with_ticket: return [] if not order.ticket_download_available: return [] @@ -138,7 +139,7 @@ def get_tickets_for_order(order, base_position=None): tickets = [] - positions = list(order.positions_with_tickets) + positions = list(positions_with_ticket) if base_position: # Only the given position and its children positions = [ diff --git a/src/pretix/base/ticketoutput.py b/src/pretix/base/ticketoutput.py index 5a8d4c618f..cd86ab9487 100644 --- a/src/pretix/base/ticketoutput.py +++ b/src/pretix/base/ticketoutput.py @@ -96,6 +96,9 @@ class BaseTicketOutput: """ raise NotImplementedError() + def get_tickets_to_print(self, order): + return order.positions_with_tickets + def generate_order(self, order: Order) -> Tuple[str, str, str]: """ This method is the same as order() but should not generate one file per order position @@ -116,7 +119,7 @@ class BaseTicketOutput: """ with tempfile.TemporaryDirectory() as d: with ZipFile(os.path.join(d, 'tmp.zip'), 'w') as zipf: - for pos in order.positions_with_tickets: + for pos in self.get_tickets_to_print(order): fname, __, content = self.generate(pos) zipf.writestr('{}-{}{}'.format( order.code, pos.positionid, os.path.splitext(fname)[1] diff --git a/src/pretix/plugins/ticketoutputpdf/ticketoutput.py b/src/pretix/plugins/ticketoutputpdf/ticketoutput.py index 157a57c0f9..c62137c1c9 100644 --- a/src/pretix/plugins/ticketoutputpdf/ticketoutput.py +++ b/src/pretix/plugins/ticketoutputpdf/ticketoutput.py @@ -115,7 +115,8 @@ class PdfTicketOutput(BaseTicketOutput): def generate_order(self, order: Order): merger = PdfWriter() with language(order.locale, self.event.settings.region): - for op in order.positions_with_tickets: + for op in self.get_tickets_to_print(order): + print("generating ticket ",op) layout = override_layout.send_chained( order.event, 'layout', orderposition=op, layout=self.layout_map.get( (op.item_id, self.override_channel or order.sales_channel), diff --git a/src/pretix/presale/templates/pretixpresale/event/fragment_cart.html b/src/pretix/presale/templates/pretixpresale/event/fragment_cart.html index 24210626a2..7bf4977fc8 100644 --- a/src/pretix/presale/templates/pretixpresale/event/fragment_cart.html +++ b/src/pretix/presale/templates/pretixpresale/event/fragment_cart.html @@ -243,7 +243,7 @@ {% if download %}
- {% if line.generate_ticket %} + {% if line.ticket_download_allowed %} {% for b in download_buttons %}
diff --git a/src/pretix/presale/templates/pretixpresale/event/fragment_downloads.html b/src/pretix/presale/templates/pretixpresale/event/fragment_downloads.html index 8c138016e8..236716761e 100644 --- a/src/pretix/presale/templates/pretixpresale/event/fragment_downloads.html +++ b/src/pretix/presale/templates/pretixpresale/event/fragment_downloads.html @@ -35,7 +35,7 @@

-{% elif can_download and download_buttons and order.count_positions %} +{% elif can_download and download_buttons and order.count_positions and tickets_with_download %}

{% trans "Ticket download" %}

{% if cart.positions|length > 1 and can_download_multi %} {# never True on ticket page #} diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py index 2d2db40367..d178d0ed58 100644 --- a/src/pretix/presale/views/order.py +++ b/src/pretix/presale/views/order.py @@ -177,14 +177,11 @@ class TicketPageMixin: ctx['order'] = self.order - can_download = self.order.plugins_allow_ticket_download + can_download = self.order.positions_with_tickets ctx['plugins_allow_ticket_download'] = can_download if self.request.event.settings.ticket_download_date: ctx['ticket_download_date'] = self.order.ticket_download_date - can_download = ( - can_download and self.order.ticket_download_available and - list(self.order.positions_with_tickets) - ) + can_download = can_download and self.order.ticket_download_available ctx['download_email_required'] = can_download and ( self.request.event.settings.ticket_download_require_validated_email and self.order.sales_channel == 'web' and @@ -261,7 +258,10 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TicketPageMixin, queryset=qs, order=self.order ) - ctx['tickets_with_download'] = [p for p in ctx['cart']['positions'] if p.generate_ticket] + download_allowed = self.order.positions_with_tickets + ctx['tickets_with_download'] = [p for p in ctx['cart']['positions'] if p in download_allowed] + for allowed_op in ctx['tickets_with_download']: + allowed_op.ticket_download_allowed = True ctx['can_download_multi'] = any([b['multi'] for b in self.download_buttons]) and ( [p.generate_ticket for p in ctx['cart']['positions']].count(True) > 1 ) @@ -365,7 +365,10 @@ class OrderPositionDetails(EventViewMixin, OrderPositionDetailMixin, CartMixin, queryset=qs, order=self.order ) - ctx['tickets_with_download'] = [p for p in ctx['cart']['positions'] if p.generate_ticket] + download_allowed = self.order.positions_with_tickets + ctx['tickets_with_download'] = [p for p in ctx['cart']['positions'] if p in download_allowed] + for allowed_op in ctx['tickets_with_download']: + allowed_op.ticket_download_allowed = True ctx['attendee_change_allowed'] = self.position.attendee_change_allowed return ctx @@ -1028,7 +1031,7 @@ class OrderDownloadMixin: @cached_property def output(self): - if not self.order.plugins_allow_ticket_download: + if not self.order.positions_with_tickets: return None responses = register_ticket_outputs.send(self.request.event) for receiver, response in responses: