mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
Invoicing: Allow types to add text and watermarks (#5453)
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core.validators import RegexValidator
|
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 django_countries.fields import Country
|
||||||
from localflavor.it.forms import ITSocialSecurityNumberField
|
from localflavor.it.forms import ITSocialSecurityNumberField
|
||||||
|
|
||||||
@@ -73,3 +73,12 @@ class ItalianSdITransmissionType(TransmissionType):
|
|||||||
if is_business:
|
if is_business:
|
||||||
return base | {"company", "vat_id", "transmission_it_sdi_pec", "transmission_it_sdi_recipient_code"}
|
return base | {"company", "vat_id", "transmission_it_sdi_pec", "transmission_it_sdi_recipient_code"}
|
||||||
return base | {"transmission_it_sdi_codice_fiscale"}
|
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."
|
||||||
|
)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
# <https://www.gnu.org/licenses/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import logging
|
import logging
|
||||||
|
import math
|
||||||
import re
|
import re
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from collections import defaultdict
|
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='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='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='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
|
return stylesheet
|
||||||
|
|
||||||
def _register_fonts(self):
|
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.drawRightString(self.pagesize[0] - 20 * mm, (297 - 100) * mm, self._normalize(gettext('TEST MODE')))
|
||||||
canvas.restoreState()
|
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):
|
def _on_first_page(self, canvas: Canvas, doc):
|
||||||
canvas.setCreator('pretix.eu')
|
canvas.setCreator('pretix.eu')
|
||||||
canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number))
|
canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number))
|
||||||
|
|
||||||
canvas.saveState()
|
canvas.saveState()
|
||||||
|
self._draw_watermark(canvas)
|
||||||
self._draw_footer(canvas)
|
self._draw_footer(canvas)
|
||||||
self._draw_testmode(canvas)
|
self._draw_testmode(canvas)
|
||||||
self._draw_invoice_from_label(canvas)
|
self._draw_invoice_from_label(canvas)
|
||||||
@@ -610,6 +631,14 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
|
|
||||||
def _get_intro(self):
|
def _get_intro(self):
|
||||||
story = []
|
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:
|
if self.invoice.custom_field:
|
||||||
story.append(FontFallbackParagraph(
|
story.append(FontFallbackParagraph(
|
||||||
'{}: {}'.format(
|
'{}: {}'.format(
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import re
|
|||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core.exceptions import ValidationError
|
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 django_countries.fields import Country
|
||||||
|
|
||||||
from pretix.base.invoicing.transmission import (
|
from pretix.base.invoicing.transmission import (
|
||||||
@@ -165,3 +165,13 @@ class PeppolTransmissionType(TransmissionType):
|
|||||||
"company", "street", "zipcode", "city", "country",
|
"company", "street", "zipcode", "city", "country",
|
||||||
}
|
}
|
||||||
return base | {"transmission_peppol_participant_id"}
|
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."
|
||||||
|
)
|
||||||
|
|||||||
@@ -104,6 +104,18 @@ class TransmissionType:
|
|||||||
def transmission_info_to_form_data(self, transmission_info: dict) -> dict:
|
def transmission_info_to_form_data(self, transmission_info: dict) -> dict:
|
||||||
return transmission_info
|
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:
|
class TransmissionProvider:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user