diff --git a/src/pretix/base/invoicing/national.py b/src/pretix/base/invoicing/national.py index d8fe76e55..b8c71fa55 100644 --- a/src/pretix/base/invoicing/national.py +++ b/src/pretix/base/invoicing/national.py @@ -22,7 +22,7 @@ from django import forms from django.core.validators import RegexValidator -from django.utils.translation import pgettext_lazy +from django.utils.translation import pgettext, pgettext_lazy from django_countries.fields import Country from localflavor.it.forms import ITSocialSecurityNumberField @@ -73,3 +73,12 @@ class ItalianSdITransmissionType(TransmissionType): if is_business: return base | {"company", "vat_id", "transmission_it_sdi_pec", "transmission_it_sdi_recipient_code"} return base | {"transmission_it_sdi_codice_fiscale"} + + def pdf_info_text(self) -> str: + # Watermark is not necessary as this is a usual precaution in Italy + return pgettext( + "italian_invoice", + "This PDF document is a visual copy of the invoice and does not constitute an invoice for VAT " + "purposes. The invoice is issued in XML format, transmitted in accordance with the procedures and terms " + "set forth in No. 89757/2018 of April 30, 2018, issued by the Director of the Revenue Agency." + ) diff --git a/src/pretix/base/invoicing/pdf.py b/src/pretix/base/invoicing/pdf.py index 843e21bcd..a6cbea7ea 100644 --- a/src/pretix/base/invoicing/pdf.py +++ b/src/pretix/base/invoicing/pdf.py @@ -20,6 +20,7 @@ # . # import logging +import math import re import unicodedata from collections import defaultdict @@ -223,6 +224,9 @@ class BaseReportlabInvoiceRenderer(BaseInvoiceRenderer): stylesheet.add(ParagraphStyle(name='FineprintHeading', fontName=self.font_bold, fontSize=8, leading=12)) stylesheet.add(ParagraphStyle(name='Fineprint', fontName=self.font_regular, fontSize=8, leading=10)) stylesheet.add(ParagraphStyle(name='FineprintRight', fontName=self.font_regular, fontSize=8, leading=10, alignment=TA_RIGHT)) + stylesheet.add(ParagraphStyle(name='WarningBlock', fontName=self.font_bold, fontSize=10, leading=12, + alignment=TA_LEFT, borderWidth=1 * mm, borderColor=colors.black, + borderPadding=2 * mm, spaceBefore=5 * mm, spaceAfter=5 * mm)) return stylesheet def _register_fonts(self): @@ -576,11 +580,28 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer): canvas.drawRightString(self.pagesize[0] - 20 * mm, (297 - 100) * mm, self._normalize(gettext('TEST MODE'))) canvas.restoreState() + def _draw_watermark(self, canvas): + watermark = self.invoice.transmission_type_instance.pdf_watermark() + if watermark: + canvas.saveState() + for font_size in range(200, 20, -10): + width = stringWidth(watermark, self.font_bold, font_size) + if width < self.pagesize[0]: + break + + canvas.translate(self.pagesize[0] / 2, self.pagesize[1] / 2) + canvas.rotate(math.atan(self.pagesize[1] / self.pagesize[0]) / math.pi * 180) + canvas.setFont(self.font_bold, font_size) + canvas.setFillColorRGB(.92, .92, .92) + canvas.drawCentredString(0, - font_size / 2, self._normalize(watermark)) + canvas.restoreState() + def _on_first_page(self, canvas: Canvas, doc): canvas.setCreator('pretix.eu') canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number)) canvas.saveState() + self._draw_watermark(canvas) self._draw_footer(canvas) self._draw_testmode(canvas) self._draw_invoice_from_label(canvas) @@ -610,6 +631,14 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer): def _get_intro(self): story = [] + + type_info_text = self.invoice.transmission_type_instance.pdf_info_text() + if type_info_text: + story.append(FontFallbackParagraph( + type_info_text, + self.stylesheet['WarningBlock'] + )) + if self.invoice.custom_field: story.append(FontFallbackParagraph( '{}: {}'.format( diff --git a/src/pretix/base/invoicing/peppol.py b/src/pretix/base/invoicing/peppol.py index ebd5d9d48..b31b3e645 100644 --- a/src/pretix/base/invoicing/peppol.py +++ b/src/pretix/base/invoicing/peppol.py @@ -23,7 +23,7 @@ import re from django import forms from django.core.exceptions import ValidationError -from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext_lazy as _, pgettext from django_countries.fields import Country from pretix.base.invoicing.transmission import ( @@ -165,3 +165,13 @@ class PeppolTransmissionType(TransmissionType): "company", "street", "zipcode", "city", "country", } return base | {"transmission_peppol_participant_id"} + + def pdf_watermark(self) -> str: + return pgettext("peppol_invoice", "Visual copy") + + def pdf_info_text(self) -> str: + return pgettext( + "peppol_invoice", + "This PDF document is a visual copy of the invoice and does not constitute an invoice for VAT " + "purposes. The original invoice is issued in XML format and transmitted through the Peppol network." + ) diff --git a/src/pretix/base/invoicing/transmission.py b/src/pretix/base/invoicing/transmission.py index fd3133569..584a056e5 100644 --- a/src/pretix/base/invoicing/transmission.py +++ b/src/pretix/base/invoicing/transmission.py @@ -104,6 +104,18 @@ class TransmissionType: def transmission_info_to_form_data(self, transmission_info: dict) -> dict: return transmission_info + def pdf_watermark(self) -> Optional[str]: + """ + Return a watermark that should be rendered across the PDF file. + """ + return None + + def pdf_info_text(self) -> Optional[str]: + """ + Return an info text that should be rendered on the PDF file. + """ + return None + class TransmissionProvider: """