Emit invoices as validated ZUGFeRD (DATEV) and XRechnung (B2G)
Playwright Tests / test (pull_request) Has been cancelled

Completes the eRechnung output path: finalized invoices are emitted as a
ZUGFeRD/Factur-X EN 16931 hybrid (DATEV) or, when a Leitweg-ID is present, as
XRechnung 3.0 for B2G. Both are externally validated as ACCEPTED (0 errors) and
PDF/A-3B COMPLIANT against the ProcessWeb eInvoice service.

- ERechnungMapper: FdsInvoiceData -> EN 16931 model. Seller master data now from
  Fuchs:ERechnung:Seller config (VAT id BT-31, Steuernummer BT-32, optional
  Handelsregister BT-30, IBAN/BIC, contact). Adds payment terms BT-20/BT-9
  (BR-CO-25), buyer VAT id, §13b reverse charge, and the service date/period
  (BT-72 / BG-14) parsed from ProvisionPeriod (BR-DE-TMP-32). B2G -> XRechnung
  profile with the required electronic addresses/contact.
- ERechnungValidator: client for POST /validatepdf (EN 16931 XML + PDF/A-3 in
  one call). A pure "scenario not matched" with zero errors is not treated as a
  hard failure; real errors optionally withhold the hybrid (FailOnError).
- ERechnungSettings: seller + validation config; wired in Program.cs; ServiceUrl
  in appsettings.
- Online editor: structured German-only dialogs for the recipient address
  (incl. Leitweg-ID) and the service date/period (single date or range).
- Bumps the eRechnungLib submodule to the CII rsm-namespace / PDF-A subtype fix.

Fuchs.Tests 514/514, eRechnungLib 97/97.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 00:05:24 +02:00
co-authored by Claude Opus 4.8
parent d94974ce06
commit 00e72c96d4
19 changed files with 847 additions and 80 deletions
+18 -6
View File
@@ -46,15 +46,27 @@ Editor (structured recipient dialog)
(no VAT id) is fully valid — B2C stays effortless. The free-text `SendToAddress` is composed
from it so the PDF layout is unchanged.
- **Mapping.** `ERechnungMapper` maps the Fuchs invoice to the EN 16931 model: seller = Fuchs
(constants mirroring the FuchsPdf letterhead — name, Steuernummer BT-32, IBAN/BIC), buyer =
the structured recipient, lines from the invoice items, §13b → reverse charge (category AE +
exemption reason). VAT breakdown and totals are recomputed by the library.
(from `Fuchs:ERechnung:Seller` config — name, address, Steuernummer BT-32, **USt-IdNr BT-31**,
IBAN/BIC, contact; defaults mirror the FuchsPdf letterhead), buyer = the structured recipient,
lines from the invoice items, §13b → reverse charge (category AE + exemption reason), payment
terms BT-20/BT-9, and the service date/period (BT-72 or BG-14) parsed from the structured
`ProvisionPeriod`. VAT breakdown and totals are recomputed by the library.
- **Profile selection (B2B/B2C vs B2G).** Default is ZUGFeRD **EN 16931** (DATEV). When the
recipient carries a **Leitweg-ID** (`InvoiceRecipientAddress.LeitwegId``BuyerReference` BT-10),
the invoice is B2G and emitted as **XRechnung** (`ZugferdProfile.XRechnung`, embedded
`xrechnung.xml`); the mapper then also fills the seller electronic address/contact (BT-34/BG-6)
and buyer electronic address (BT-49) that XRechnung requires.
- **Feature flag & fallback.** Emission is gated by `Fuchs:ERechnung:Enabled` (off until fully
validated). `IERechnungService` returns `null` on disable **or any failure**, so
`RenderInvoicePdfBytesAsync` falls back to the plain Spire PDF/A — invoicing never breaks.
- **Formal verification.** `Fuchs:ERechnung:Validation:ServiceUrl` is the seam for an external
online veraPDF (PDF/A-3) + ZUGFeRD validator; until the URL is provisioned, verification is
reported as not-configured.
- **Formal verification.** `Fuchs:ERechnung:Validation` calls the ProcessWeb eInvoice service
(`POST {ServiceUrl}/validatepdf`, raw `application/pdf`) which checks the EN 16931 XML **and**
PDF/A-3 (veraPDF) in one call. Both the EN 16931-ZUGFeRD and the XRechnung 3.0 output are
externally **ACCEPTED** (0 errors) and **PDF/A-3B COMPLIANT**. Getting there required fixing two
eRechnungLib defects (CII root children must be `rsm:` not `ram:`; embedded-file `/Subtype` MIME
encoding) and completing the mapper (seller VAT id BT-31, payment terms BT-20/BT-9). The
validator's target feature scope is documented in
[`../eRechnung-Validator-Requirements.md`](../eRechnung-Validator-Requirements.md).
## Key files
- `Fuchs/Services/InvoiceRecipientAddress.cs` — structured buyer address, composition, conformity.