diff --git a/src/pretix/base/ticketoutput.py b/src/pretix/base/ticketoutput.py index daa0a4e156..2934e64f1e 100644 --- a/src/pretix/base/ticketoutput.py +++ b/src/pretix/base/ticketoutput.py @@ -45,6 +45,13 @@ class BaseTicketOutput: This method should generate the download file and return a tuple consisting of a filename, a file type and file content. The extension will be taken from the filename which is otherwise ignored. + + .. note:: If the event uses the event series feature (internally called subevents) + and your generated ticket contains information like the event name or date, + you probably want to display the properties of the subevent. A common pattern + to do this would be a declaration ``ev = position.subevent or position.order.event`` + and then access properties that are present on both classes like ``ev.name`` or + ``ev.date_from``. """ raise NotImplementedError() diff --git a/src/pretix/plugins/ticketoutputpdf/ticketoutput.py b/src/pretix/plugins/ticketoutputpdf/ticketoutput.py index f11e384f64..49fc0818c6 100644 --- a/src/pretix/plugins/ticketoutputpdf/ticketoutput.py +++ b/src/pretix/plugins/ticketoutputpdf/ticketoutput.py @@ -63,6 +63,7 @@ class PdfTicketOutput(BaseTicketOutput): renderPDF.draw(d, canvas, qr_x, qr_y) def _get_text_content(self, op: OrderPosition, order: Order, o: dict): + ev = op.subevent or order.event if o['content'] == 'other': return o['text'].replace("\n", "
\n") elif o['content'] == 'order': @@ -80,25 +81,25 @@ class PdfTicketOutput(BaseTicketOutput): elif o['content'] == 'attendee_name': return op.attendee_name or (op.addon_to.attendee_name if op.addon_to else '') elif o['content'] == 'event_name': - return str(order.event) + return str(ev.name) elif o['content'] == 'event_location': - return str(order.event.location).replace("\n", "
\n") + return str(ev.location).replace("\n", "
\n") elif o['content'] == 'event_date': - return order.event.get_date_from_display(show_times=False) + return ev.get_date_from_display(show_times=False) elif o['content'] == 'event_date_range': - return order.event.get_date_range_display() + return ev.get_date_range_display() elif o['content'] == 'event_begin': - return order.event.get_date_from_display(show_times=True) + return ev.get_date_from_display(show_times=True) elif o['content'] == 'event_begin_time': - return order.event.get_time_from_display() + return ev.get_time_from_display() elif o['content'] == 'event_admission': - if order.event.date_admission: + if ev.date_admission: tz = timezone(order.event.settings.timezone) - return date_format(order.event.date_admission.astimezone(tz), "SHORT_DATETIME_FORMAT") + return date_format(ev.date_admission.astimezone(tz), "SHORT_DATETIME_FORMAT") elif o['content'] == 'event_admission_time': - if order.event.date_admission: + if ev.date_admission: tz = timezone(order.event.settings.timezone) - return date_format(order.event.date_admission.astimezone(tz), "TIME_FORMAT") + return date_format(ev.date_admission.astimezone(tz), "TIME_FORMAT") elif o['content'] == 'addons': return "
".join([ '{} - {}'.format(p.item, p.variation) if p.variation else str(p.item)