diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index babbf5af1..00d4ec6da 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -686,6 +686,15 @@ class Order(LockModel, LoggedModel): } ) + @property + def positions_with_tickets(self): + for op in self.positions.all(): + if op.addon_to_id and not self.event.settings.ticket_download_addons: + continue + if not op.item.admission and not self.event.settings.ticket_download_nonadm: + continue + yield op + def answerfile_name(instance, filename: str) -> str: secret = get_random_string(length=32, allowed_chars=string.ascii_letters + string.digits) diff --git a/src/pretix/base/services/tickets.py b/src/pretix/base/services/tickets.py index 06eb65fd6..4d4454149 100644 --- a/src/pretix/base/services/tickets.py +++ b/src/pretix/base/services/tickets.py @@ -117,6 +117,8 @@ def get_tickets_for_order(order): if p.multi_download_enabled: try: + if len(order.positions_with_tickets) == 0: + continue ct = CachedCombinedTicket.objects.filter( order=order, provider=p.identifier, file__isnull=False ).last() @@ -132,11 +134,7 @@ def get_tickets_for_order(order): except: logger.exception('Failed to generate ticket.') else: - for pos in order.positions.all(): - if pos.addon_to and not order.event.settings.ticket_download_addons: - continue - if not pos.item.admission and not order.event.settings.ticket_download_nonadm: - continue + for pos in order.positions_with_tickets: try: ct = CachedTicket.objects.filter( order_position=pos, provider=p.identifier, file__isnull=False diff --git a/src/pretix/base/ticketoutput.py b/src/pretix/base/ticketoutput.py index f34ad2415..d569862fd 100644 --- a/src/pretix/base/ticketoutput.py +++ b/src/pretix/base/ticketoutput.py @@ -70,14 +70,12 @@ class BaseTicketOutput: If you override this method, make sure that positions that are addons (i.e. ``addon_to`` is set) are only outputted if the event setting ``ticket_download_addons`` is active. Do the same for positions that are non-admission without ``ticket_download_nonadm`` active. + If you want, you can just iterate over ``order.positions_with_tickets`` which applies the + appropriate filters for you. """ with tempfile.TemporaryDirectory() as d: with ZipFile(os.path.join(d, 'tmp.zip'), 'w') as zipf: - for pos in order.positions.all(): - if pos.addon_to_id and not self.event.settings.ticket_download_addons: - continue - if not pos.item.admission and not self.event.settings.ticket_download_nonadm: - continue + for pos in order.positions_with_tickets: 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 06bbf1a0d..b64321e6f 100644 --- a/src/pretix/plugins/ticketoutputpdf/ticketoutput.py +++ b/src/pretix/plugins/ticketoutputpdf/ticketoutput.py @@ -73,12 +73,7 @@ class PdfTicketOutput(BaseTicketOutput): def generate_order(self, order: Order): merger = PdfFileMerger() with language(order.locale): - for op in order.positions.all(): - if op.addon_to_id and not self.event.settings.ticket_download_addons: - continue - if not op.item.admission and not self.event.settings.ticket_download_nonadm: - continue - + for op in order.positions_with_tickets: layout = self.layout_map.get( (op.item_id, order.sales_channel), self.layout_map.get( diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py index c0c040e8b..8e0bf508a 100644 --- a/src/pretix/presale/views/order.py +++ b/src/pretix/presale/views/order.py @@ -94,7 +94,7 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TemplateView): can_download = all([r for rr, r in allow_ticket_download.send(self.request.event, order=self.order)]) if self.request.event.settings.ticket_download_date: ctx['ticket_download_date'] = self.order.ticket_download_date - ctx['can_download'] = can_download and self.order.ticket_download_available + ctx['can_download'] = can_download and self.order.ticket_download_available and self.order.positions_with_tickets ctx['download_buttons'] = self.download_buttons ctx['cart'] = self.get_cart( answers=True, downloads=ctx['can_download'],