Phase 2: structured iban/bic instead of free-text bankDetails

InvoiceSeller.bankDetails becomes iban/bic (EN16931 wants discrete
PaymentMeans data, not a paragraph a human formatted by hand). The
footer's bank-details line also drops the misleading "(für Überweisung)"
qualifier — it was never actually conditional on the order's payment
method (only on whether the field was set at all), just worded as if it
were. Now shown whenever iban or bic is set, regardless of payment
method.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-07-23 10:06:12 +00:00
parent 9336cfd0ba
commit 62821ddc8a
4 changed files with 24 additions and 3 deletions
+2
View File
@@ -15,6 +15,8 @@ Before this package, `taxBreakdown.ts` and `correctionInvoicePdf.tsx` were hand-
One canonical implementation, consumed by both repos, makes this class of drift structurally impossible instead of relying on manual vigilance.
**2026-07-23, Phase 2:** `InvoiceSeller.bankDetails` (a free-text textarea on `company-settings`) became structured `iban`/`bic` fields — EN16931 e-invoicing wants discrete PaymentMeans data, not a paragraph a human formatted by hand. The footer's bank-details line also changed from "Bankverbindung (für Überweisung): …" to plain "Bankverbindung: IBAN … · BIC …", shown whenever either is set — it was never actually conditional on the order's payment method (that label was misleading), and there's no reason to hide it from a card/PayPal customer who might still want it (e.g. for a refund).
## How this is consumed
Not published to npm — installed as a git dependency:
+7 -1
View File
@@ -300,7 +300,13 @@ function CorrectionInvoiceDocument({ kind, order, seller }: { kind: CorrectionIn
{seller.registerCourt && seller.registerNumber ? ` · ${seller.registerCourt} · ${seller.registerNumber}` : ""}
{seller.managingDirector ? ` · Geschäftsführung: ${seller.managingDirector}` : ""}
</Text>
{seller.bankDetails ? <Text style={{ marginTop: 4 }}>Bankverbindung (für Überweisung): {seller.bankDetails}</Text> : null}
{/* Always shown when set, regardless of payment method — see
invoicePdf.tsx's own comment on this same line. */}
{(seller.iban || seller.bic) && (
<Text style={{ marginTop: 4 }}>
Bankverbindung: {[seller.iban && `IBAN ${seller.iban}`, seller.bic && `BIC ${seller.bic}`].filter(Boolean).join(" · ")}
</Text>
)}
</View>
</Page>
</Document>
+9 -1
View File
@@ -334,7 +334,15 @@ export function InvoiceDocument({ order, seller }: { order: InvoiceOrder; seller
{seller.registerCourt && seller.registerNumber ? ` · ${seller.registerCourt} · ${seller.registerNumber}` : ""}
{seller.managingDirector ? ` · Geschäftsführung: ${seller.managingDirector}` : ""}
</Text>
{seller.bankDetails ? <Text style={{ marginTop: 4 }}>Bankverbindung (für Überweisung): {seller.bankDetails}</Text> : null}
{/* Always shown when set, regardless of payment method — not
gated on "Überweisung" specifically (a customer who paid by
card can still want the seller's bank details for other
reasons, e.g. a refund) — see this package's README. */}
{(seller.iban || seller.bic) && (
<Text style={{ marginTop: 4 }}>
Bankverbindung: {[seller.iban && `IBAN ${seller.iban}`, seller.bic && `BIC ${seller.bic}`].filter(Boolean).join(" · ")}
</Text>
)}
</View>
</Page>
</Document>
+6 -1
View File
@@ -11,7 +11,12 @@ export type InvoiceSeller = {
sellerEmail: string;
vatId: string;
taxRatePercent: number;
bankDetails?: string | null;
// Structured (Phase 2 of the e-invoicing migration — EN16931 wants
// discrete PaymentMeans data, not a free-text paragraph a human
// formatted by hand) — replaces what used to be a single `bankDetails`
// textarea field.
iban?: string | null;
bic?: string | null;
// Pflichtangaben in Geschäftsbriefen for registered legal forms (§37a
// HGB / §35a GmbHG) — optional because a sole proprietorship (the
// default legalForm in company-settings) has neither.