Skip to content

feat(e-billing,invoice,zugferd): credit notes, corrected invoices, preceding invoice and supplier number - #1085

Merged
jbagsik merged 12 commits into
mainfrom
feature/credit-note-moscow-parser
Sep 29, 2026
Merged

jbagsik merged 12 commits into
mainfrom
feature/credit-note-moscow-parser

Conversation

@jbagsik

@jbagsik jbagsik commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Proper support for credit notes (381) and corrected invoices (384) in the e-billing pipeline, plus the seller identifier:

  • Preceding invoice reference (BG-3). New invoices.preceding_invoices (BT-25 number, BT-26 date) through InvoiceDraft / InvoiceBuilder, the parser DTO and both Zugferd adapters. ZugferdConverter emits one InvoiceReferencedDocument per entry.
  • Supplier number (BT-29). New indexed invoices.supplier_number, persisted verbatim from the DTO. Emitted via addDocumentSellerId when non-empty, could in all profiles, shown in the seller group (ADR 0012).
  • Profiles per document type (ADR 0009 + addenda).
    • field_validation.document_type_profiles maps BT-3 to a key prefix (381 → credit_note, 384 → corrected_invoice), with fallback to invoice_*.
    • The review queue, validator, score, approval checks and ViewInvoice all use the document's
      profile.
    • Preceding-invoice lookup: a match links to the original invoice; no match or a different date
      is a non-blocking warning.
  • Negative credit notes blocked (ADR 0010). A 381 with negative BT-112 cannot be approved, auto-approved or dispatched.
  • BR-CO-25 on credit notes. e-billing.credit_note_payment_terms (default null) is emitted as BT-20 for a 381 without due date and payment terms.
  • Document classification (ADR 0011).
    • ClassifyDocumentTypeAction switches between the configured classification types before approval, flipping all amounts when the signs differ.
    • Audited via moox/audit (document_classified), never counted as a value correction.
  • Declared type at manual upload (ADR 0011 addendum).
    • resources.{key}.manual_upload.document_types adds a required type choice without preselection, with a collapsible, translatable instruction (en/de).
    • The choice is stored on UploadedPdfSource.document_type and applied after parsing, including the sign flip.
    • A parsed type outside the selectable set is kept and flagged for review.
  • Classification family. Credit notes and corrected invoices count as one type for both duplicate checks.
  • Credit-note list. Shows 381 and 384 with per-type tabs and a type badge. allowed_document_type_codes now includes 384.
  • Fix: PO-box addresses. Without a street, the next address line (e.g. a PO box) becomes BT-50 instead of repeating the company name (shared Data\Address::toEn16931Address()).

Breaking changes

  • Moox\Zugferd\Contracts\ZugferdInvoice gains precedingInvoices and supplierNumber. Custom implementations must add both.
  • InvoiceDraft gains supplier_number (and optional preceding_invoices).
  • FieldValidationProfile::priorityMapsDifferByType() is replaced by documentTypesWithOwnPriorities().
  • ClassifyDocumentTypeAction::classificationSigns() is replaced by DocumentClassification::signs().

Migrations (publish + run)

  • invoice: add_preceding_invoices_to_invoices_table, add_supplier_number_to_invoices_table
  • e-billing: add_document_type_to_ebilling_uploaded_pdf_sources_table

Hosts

  • Hosts with their own field_validation / invoice_ui config add the credit_note_* / corrected_invoice_* keys and document_type_profiles, or rely on the invoice_* fallback.
  • Hosts add supplier_number to their maps if they override them.
  • 384 => negative assumes corrections issued as a credit (delta). Hosts issuing full restatements set positive.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
25.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@jbagsik
jbagsik merged commit 1a01e1c into main Sep 29, 2026
10 of 18 checks passed
@jbagsik
jbagsik deleted the feature/credit-note-moscow-parser branch September 29, 2026 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant