feat(invoices): configurable VAT/free-text note + fix multi-page page-number overlap (#794)
Two invoice-PDF changes from #794. 1. VAT / free-text note (Benedikt's request, placement A). A new `crm_invoices_vat_note_text` setting (Settings → CRM → Invoices) prints a free-text line directly under the MwSt. row on every invoice. Data-driven: the admin types the exact wording (Austrian Kleinunternehmer § 6 Abs. 1 Z 27 UStG, German § 19, reverse-charge, …) — no jurisdiction hardcoded. The totals-block reserve grows by the measured note height so a long note can't push the grand total into the footer. Read in invoice/render.js, threaded through normaliseContext, drawn in drawTotals. Empty → row omitted; quotes unaffected. 2. Multi-page footer overlap. On a full continuation page the line-item table filled to the bottom margin, but the "Seite X von Y" stamp was drawn at marginBottom-12 — INSIDE that fill zone — so items overlapped the page number. Move the stamp into the bottom margin (below the content edge), zeroing that page's bottom margin during the write so it can't trigger PDFKit's auto-page-break. Verified: on a full page the lowest item text is at pdfkitY ~790 while the page number sits at ~816 — ~26pt clearance. Tests: render the note on a single page (byte-delta proves it renders) and paginate a long invoice with the note (2–3 pages, no stray blank page).
This commit is contained in:
@@ -5233,6 +5233,11 @@
|
||||
"crm_invoices_late_fee_label": {
|
||||
"label": "Bezeichnung Mahngebühr"
|
||||
},
|
||||
"crm_invoices_vat_note_text": {
|
||||
"label": "MwSt.- / Freitext-Hinweis auf Rechnungen",
|
||||
"placeholder": "z. B. Gemäß § 6 Abs. 1 Z 27 UStG 1994 wird keine Umsatzsteuer berechnet (Kleinunternehmer).",
|
||||
"help": "Wird direkt unter der MwSt.-Zeile auf jeder Rechnungs-PDF gedruckt. Leer lassen zum Ausblenden. Bitte den genauen Wortlaut mit deinem Steuerberater abstimmen."
|
||||
},
|
||||
"crm_invoices_skonto_percent_default": {
|
||||
"label": "Standard-Skonto %"
|
||||
},
|
||||
|
||||
@@ -5231,6 +5231,11 @@
|
||||
"crm_invoices_late_fee_label": {
|
||||
"label": "Late fee label"
|
||||
},
|
||||
"crm_invoices_vat_note_text": {
|
||||
"label": "VAT / free-text note on invoices",
|
||||
"placeholder": "e.g. Gemäß § 6 Abs. 1 Z 27 UStG 1994 wird keine Umsatzsteuer berechnet (Kleinunternehmer).",
|
||||
"help": "Printed directly under the MwSt. line on every invoice PDF. Leave empty to hide. Please confirm the exact wording with your tax advisor."
|
||||
},
|
||||
"crm_invoices_skonto_percent_default": {
|
||||
"label": "Skonto rate (default %)"
|
||||
},
|
||||
|
||||
@@ -29,6 +29,8 @@ const SETTING_KEYS = [
|
||||
'crm_quotes_tos_url',
|
||||
'crm_invoices_qr_enabled',
|
||||
'crm_invoice_round_total',
|
||||
// Free-text VAT/legal note printed under the MwSt. line on invoice PDFs (#794).
|
||||
'crm_invoices_vat_note_text',
|
||||
'crm_invoices_reminders_enabled',
|
||||
'crm_invoices_reminder_first_days',
|
||||
'crm_invoices_reminder_second_days',
|
||||
@@ -249,6 +251,25 @@ export const CrmSettingsPage: React.FC = () => {
|
||||
{checkbox('crm_invoices_qr_enabled', 'Render payment QR on invoice PDFs')}
|
||||
{checkbox('crm_invoice_round_total', 'Reconcile sub-cent rounding to a clean total (adds a "Rundung" row when per-line rounding drifts from qty × rate)')}
|
||||
|
||||
{/* Free-text VAT / legal note (#794) — printed directly under the MwSt.
|
||||
line on every invoice PDF. Data-driven: the admin types the exact
|
||||
wording (Austrian Kleinunternehmer, German §19, reverse-charge, …). */}
|
||||
<div className="mt-3">
|
||||
<label className="block text-sm font-medium text-neutral-700 dark:text-neutral-300 mb-1">
|
||||
{t('crmSettings.crm_invoices_vat_note_text.label', 'VAT / free-text note on invoices')}
|
||||
</label>
|
||||
<textarea
|
||||
value={values.crm_invoices_vat_note_text ?? ''}
|
||||
onChange={(e) => setVal('crm_invoices_vat_note_text', e.target.value)}
|
||||
rows={2}
|
||||
placeholder={t('crmSettings.crm_invoices_vat_note_text.placeholder', 'e.g. Gemäß § 6 Abs. 1 Z 27 UStG 1994 wird keine Umsatzsteuer berechnet (Kleinunternehmer).') as string}
|
||||
className="w-full px-3 py-2 rounded-lg border border-neutral-300 dark:border-neutral-600 bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100"
|
||||
/>
|
||||
<p className="mt-1 text-xs text-neutral-500 dark:text-neutral-400">
|
||||
{t('crmSettings.crm_invoices_vat_note_text.help', 'Printed directly under the MwSt. line on every invoice PDF. Leave empty to hide. Please confirm the exact wording with your tax advisor.')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Reminder TIMING: owned by the Invoice dunning workflow when the
|
||||
engine is live (callout); otherwise the legacy schedule controls. The
|
||||
late-fee math below is configured here in both cases — it's the fee
|
||||
|
||||
Reference in New Issue
Block a user