diff --git a/src/pretix/base/services/invoices.py b/src/pretix/base/services/invoices.py
index c6c138efd4..919c5bdce7 100644
--- a/src/pretix/base/services/invoices.py
+++ b/src/pretix/base/services/invoices.py
@@ -9,6 +9,7 @@ from django.contrib.staticfiles import finders
from django.core.files.base import ContentFile
from django.db import transaction
from django.utils.formats import date_format
+from django.utils.timezone import now
from django.utils.translation import pgettext, ugettext as _
from reportlab.lib import pagesizes
from reportlab.lib.styles import ParagraphStyle, StyleSheet1
@@ -399,3 +400,53 @@ def invoice_pdf(*args, **kwargs):
# was committed and therefore fails to find the invoice object. The invoice_pdf_task
# will prevent this kind of race condition.
invoice_pdf_task.apply_async(args=args, kwargs=kwargs)
+
+
+class DummyRollbackException(Exception):
+ pass
+
+
+def build_preview_invoice_pdf(event):
+ locale = event.settings.invoice_language
+ pdf = None
+ if not locale or locale == '__user__':
+ locale = event.settings.locale
+
+ try:
+ with transaction.atomic(), language(locale):
+ order = event.orders.create(status=Order.STATUS_PENDING, datetime=now(),
+ expires=now(), code="PREVIEW", total=119)
+ invoice = Invoice(
+ order=order, event=event, invoice_no="PREVIEW",
+ date=date.today(), locale=locale
+ )
+ invoice.invoice_from = event.settings.get('invoice_address_from')
+
+ introductory = event.settings.get('invoice_introductory_text', as_type=LazyI18nString)
+ additional = event.settings.get('invoice_additional_text', as_type=LazyI18nString)
+ footer = event.settings.get('invoice_footer_text', as_type=LazyI18nString)
+ payment = _("A payment provider specific text might appear here.")
+
+ invoice.introductory_text = str(introductory).replace('\n', '
')
+ invoice.additional_text = str(additional).replace('\n', '
')
+ invoice.footer_text = str(footer)
+ invoice.payment_provider_text = str(payment).replace('\n', '
')
+ invoice.invoice_to = _("John Doe\n214th Example Street\n012345 Somecity")
+ invoice.file = None
+ invoice.save()
+ invoice.lines.all().delete()
+
+ InvoiceLine.objects.create(
+ invoice=invoice, description=_("Sample product A"),
+ gross_value=119, tax_value=19,
+ tax_rate=19
+ )
+ with tempfile.NamedTemporaryFile(suffix=".pdf") as f:
+ _invoice_generate_german(invoice, f)
+ f.seek(0)
+ pdf = f.read()
+ raise DummyRollbackException()
+ except DummyRollbackException:
+ return pdf
+ else:
+ raise Exception('Invalid state, should have rolled back.')
diff --git a/src/pretix/control/templates/pretixcontrol/event/invoicing.html b/src/pretix/control/templates/pretixcontrol/event/invoicing.html
index 1aa3b9942e..044b640112 100644
--- a/src/pretix/control/templates/pretixcontrol/event/invoicing.html
+++ b/src/pretix/control/templates/pretixcontrol/event/invoicing.html
@@ -19,6 +19,9 @@
{% bootstrap_field form.invoice_footer_text layout="horizontal" %}