Skip to content

Add SaaS-safe unposted FatturaPA XML preview API (#12334) - #13014

Open
Marco Antonio Mauro (marcus905) wants to merge 7 commits into
microsoft:mainfrom
marcus905:feature/12334-fatturapa-xml-preview-pr-ready
Open

Marco Antonio Mauro (marcus905) wants to merge 7 commits into
microsoft:mainfrom
marcus905:feature/12334-fatturapa-xml-preview-pr-ready

Conversation

@marcus905

@marcus905 Marco Antonio Mauro (marcus905) commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What & why

The Italian FatturaPA implementation provides the standard outbound XML serializer, but extensions cannot currently prepare and generate the same payload for an unposted sales document through a SaaS-safe API without reproducing substantial parts of the standard logic or invoking posting/export functionality with persistent side effects.

This change introduces a preview-safe preparation path for unposted Sales Orders, Sales Invoices and Sales Credit Memos, allowing extensions to generate the standard FatturaPA XML before posting or transmitting the document.

The implementation:

  • Adds FatturaPA Preview Mgt. to prepare temporary Fattura Header and Fattura Line records from an unposted sales document, accepting a caller-supplied preview ProgressivoInvio.
  • Reuses the existing Export FatturaPA Document.GenerateXMLFile(...) serializer by making the required temporary-buffer APIs SaaS-callable.
  • Uses standard posting preview to obtain temporary VAT entries, customer ledger entries and detailed customer ledger entries without completing posting.
  • Reuses standard FatturaPA commercial-line processing, including pricing, discounts, VAT nature, extended text and VAT exemption information.
  • Reuses the standard VAT aggregation and fiscal classification logic, including split-payment and unrealized-VAT handling.
  • Extracts shared, read-only document-type resolution, preserving configured defaults and self-billing behavior. The posted-export path retains its existing setup-initialization behavior for compatibility.
  • Reuses the standard gross document-total calculation for invoices and credit memos, while using posting-preview accounting amounts for partial sales-order invoicing.
  • Leaves transmission-number allocation to the normal posted-export workflow.

The preview does not consume the actual FatturaPA progressive-number series, post the sales document, transmit XML, or initialize the Fattura Document Type setup catalog through the new read-only lookup path.

No new database tables or fields are introduced. The preview API operates on existing temporary FatturaPA buffers and uses Microsoft's existing outbound serializer rather than duplicating XML generation.

Linked work

Fixes #12334

Related: #11633 ÔÇö FatturaPA fiscal-regime setup initialization. A subsequent change can move Fattura Document Type catalog initialization into the company initialization/upgrade lifecycle once the relevant setup-management work is available. This PR keeps the existing posted-export initialization behavior unchanged.

How I validated this

  • I read the full diff and it contains only changes I intended.
  • I built the affected app(s) locally with no new analyzer warnings.
  • I ran the change in Business Central and confirmed it behaves as expected.
  • I added or updated tests for the new behavior, or explained below why none are needed.

What I tested and the outcome

  • Built and executed the changes in a local Business Central test environment.
  • Ran test codeunit 144200 "FatturaPA Test" on October 19, 2026.
  • 60 tests executed: 52 passed, 8 failed, 0 skipped.
  • All 15 new FatturaPA preview tests passed, covering:
    • Preparation and XML serialization for unposted invoices, credit memos and sales orders.
    • Preview-versus-posted XML parity for invoices and credit memos.
    • Extended text and multiple VAT rates.
    • Split payment, including ImportoTotaleDocumento.
    • Unrealized VAT and VAT fiscal classification.
    • Partially invoiced sales orders.
    • Explicit and configured Fattura Document Types, self-billing and incomplete setup catalogs.
    • Absence of document-type catalog initialization during read-only preview resolution.
    • No consumption of FatturaPA progressive numbers, including repeated preview and XML-generation calls.
  • Existing posted-export scenarios, including Sales and Service documents, split payment, unrealized VAT, discounts and extended text, passed.

The eight remaining failures are confined to existing *WithMissingFields tests. All fail in Library - Error Message.LoadErrorMessages() because field ID 2074815070 is missing from the test page. This same failure was present before the preview changes and remained unchanged throughout the test runs.

The final PR branch also retains the current upstream correction to the XSD test-file path. This adjustment does not alter production behavior.

Risk & compatibility

  • No schema changes: No database tables, fields or data migrations are introduced.
  • Posted-export compatibility: The existing posted-document export path and its FatturaPA progressive-number allocation behavior are retained.
  • SaaS API surface: The necessary OnPrem restrictions are removed from the existing temporary-buffer/serialization boundary, and the new preview preparation procedures are callable by extensions.
  • Posting preview dependency: Preview requires the standard posting-preview engine to successfully process the source document. It is therefore intended for documents that can be posted under the current configuration; it is not a replacement for posting validation.
  • Source scope: Preparation currently supports Sales Orders, Sales Invoices and Sales Credit Memos. Service documents continue to use their existing posted-export path.
  • Preview identity: The caller supplies a preview-only ProgressivoInvio; the real transmission identifier remains the responsibility of the standard export workflow.
  • Configuration compatibility: The new preview document-type resolver performs read-only lookup. Existing posted-export catalog initialization remains in place pending the separate setup-lifecycle work.
  • Follow-up: Once Fix #11371: Prevent invalid FatturaPA RegimeFiscale values #11633 or this PR is merged, coordinate the separation of Fattura Document Type initialization into company setup/upgrade without introducing overlapping changes to the pending contribution.

The change preserves the existing FatturaPA XML serializer as the authoritative implementation, allowing preview consumers to inherit standard XML generation behavior and future serializer improvements.

Fixes AB#655979

Reuse standard FatturaPA line and VAT rules, capture posting-preview accounting
entries, and expose side-effect-free preparation and XML serialization.
Cover invoice, credit memo and sales order preview, including accounting parity,
setup-safe document type resolution, and transmission number isolation.

Preserve upstream XSD test-path correction in the existing test helper.
@github-actions github-actions Bot added From Fork Pull request is coming from a fork Team: Finance GitHub request for Finance area ADO: Sync Creates an Azure DevOps work item if needed and indicates that one is linked labels Oct 19, 2026
@github-actions github-actions Bot added this to the Version 30.0 milestone Oct 19, 2026
@github-actions github-actions Bot added the needs-approval Workflow runs require maintainer approval to start label Oct 19, 2026
@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 1

Recommendation: Request Changes

What this PR does

This change adds a SaaS-callable path that prepares temporary FatturaPA buffers from unposted sales documents and reuses the standard XML serializer. Posting preview supplies the accounting entries, and the new tests cover the main invoice, credit memo, sales order, VAT, and numbering scenarios. However, the manual buffer preparation does not yet reproduce all fiscally significant header and order metadata, so the generated preview can differ from the standard posted export.

Problem-solution fit

Fit: Strong

The new API shape directly supports side-effect-free preparation and serialization with a caller-supplied preview progressive number. The remaining gaps are in parity with the standard payload rather than in the overall design.

Suggestions

S1 (🔴 High): Populate all standard fiscal header fields
The preview header does not copy the tax representative or applied-document data that the posted export adds. Configured tax representatives and applied credit memos will therefore produce different, incomplete XML.

S2 (🔴 High): Build order and shipment metadata rows
The preview only creates Document, VAT, and Payment rows. PopulateOrderData and PopulateShipmentData need Order/Shipment rows, so sales-order previews omit customer PO, CUP/CIG, and DDT data from the final XML.

S3 (🔴 High): Calculate the invoice discount FlowField
Invoice Discount Amount is a FlowField, but this code reads it without CalcFields. Documents with invoice discounts will omit the document-level ScontoMaggiorazione from preview XML.

Risk assessment and necessity

Risk: This code produces fiscal XML in a financially sensitive area. Missing discounts, tax representative data, or linked order/document references can make the preview materially different from the payload generated after posting; the new SaaS surface itself is additive and does not break existing callers.

Necessity: A side-effect-free preview API is useful and avoids duplicating the serializer. The scope is justified, but the preparation path must include the same fiscal metadata as the standard export before it is safe to expose as an authoritative preview.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=13014 round=1 by=alexei-dobriansky at=2026-10-20T01:06:46.3736790Z lastSha=8950ba91850f62e70bdf76778d30221702ef5a12 reviewKey=7007d8649f539411ab041d5be71d59865fd550d4c9769e955e4655dcf8e02b8b suggestions=S1@f05c2101,S2@22f24036,S3@1c1c4930

…rosoft#13014)

Calculate invoice discount FlowField; share tax representative resolution and order/shipment buffer writers; build available source document references without fabricating posting-only DDT IDs; expand regression coverage for header metadata, customer order references and shipped orders.

Verified with test codeunit 144200 (65 tests: 46 passed, 19 pre-existing environment failures).
@marcus905

Marco Antonio Mauro (marcus905) commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review. I've pushed follow-up commit 2bcef4d addressing S1-S3 and extending the preview/posted XML comparisons.

S1: Fiscal header: Preview now resolves the tax representative from temporary posting-preview VAT entries, with the same company-information fallback as posted export. Applied-document links dependent on the posted customer-ledger entry cannot reliably be inferred before posting, so preview deliberately does not fabricate them.

S2: Order and shipment data: Preview prepares available order/shipment references and reuses the standard buffer writers. XML regressions now compare DatiOrdineAcquisto and DatiDDT, including an order with an already-posted shipment. Shipment identifiers created by the current posting are intentionally excluded from pre-/post-comparison because they do not exist at preview time. Direct-invoice customer-PO behavior has also been aligned with posted export.

S3: Invoice discount: The source Invoice Discount Amount FlowField is now calculated before mapping, with a dedicated regression test.

Validation: Codeunit 144200 FatturaPA Test: 65 tests executed, 57 passed, including all 20 preview tests. The remaining 8 failures are known test-environment issues (missing error-message page field ID 2074815070).

Please re-review, particularly whether the explicit preview boundary for posting-only applied-document and shipment identifiers meets the intended scope of #12334.

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 2

Recommendation: Request Changes

What this PR does

The follow-up now calculates the invoice-discount FlowField, copies tax-representative data from posting preview, and builds order and shipment metadata. The discount fix is correct, but two parity gaps remain: known document applications are still omitted, and the shipment scan can include fully invoiced shipment lines from earlier invoices.

Status of previous suggestions
ID Title Status Author response
S1 Populate all standard fiscal header fields Disputed Tax-representative data was added. Applied-document data was left out because it was considered unavailable before posting, but Applies-to Doc. No. already identifies the target document in the direct-application scenario.
S2 Build order and shipment metadata rows Not addressed Order and DDT rows were added, but the preview reads every item shipment line for the order. It must exclude fully invoiced historical shipments and map only the lines included in the pending invoice.
S3 Calculate the invoice discount FlowField Addressed The FlowField is calculated before mapping, with a focused regression test.
New observations (commits since round 1)

None - the remaining shipment concern is part of S2.

Risk assessment and necessity

Risk: The preview can still omit DatiFattureCollegate for a credit memo with a known application. A later partial invoice can also include stale DatiDDT and order references from shipment quantities that were already invoiced, so the preview may differ materially from the posted fiscal XML.

Necessity: The side-effect-free preview API remains useful and the chosen reuse of standard serialization is appropriate. The remaining work should narrow source references to the pending invoice and map application data that is already known before posting.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=13014 round=2 by=alexei-dobriansky at=2026-10-20T19:19:19.0754414Z lastSha=2bcef4d83f9d80746dfe29e7cc8b9f09dda13499 reviewKey=ea462d30114b91b26f197f685af344af191542a431583a2e52eef827edb0cb98 suggestions=S1@f05c2101:disputed,S2@22f24036:notaddressed,S3@1c1c4930:addressed parentRound=1

…ain DDT references to pending invoice quantities
…DTs (microsoft#13014)

Preserve known credit-memo Applies-to Doc. No. fiscal references, exclude fully invoiced historical shipment lines from preview, fix unsupported Min call, and cover fiscal XML application and shipment metadata with regression tests.

Codeunit 144200 verified: 68 tests, 49 passed including all 23 preview tests, 19 known environment failures (11 missing XSD, 8 missing error-message page field).
@marcus905

Copy link
Copy Markdown
Contributor Author

Thanks for the Round 2 review. I've pushed follow-up commits addressing the remaining S1 and S2 concerns.

S1: Known applications: The preview now resolves direct credit-memo applications using Applies-to Doc. Type and Applies-to Doc. No., including the applied invoice date and available CUP/CIG information. A regression test verifies that the generated XML contains the expected DatiFattureCollegate/IdDocumento.

S2: Shipment references: Preview now considers only sales-order lines being invoiced, excludes fully invoiced historical shipments, and limits shipment references to the quantities relevant to the pending invoice. A regression test verifies that an already-invoiced DDT is excluded while the pending shipment is retained.

Validation: Codeunit 144200 "FatturaPA Test": 68 tests executed, 60 passed, including all 23 preview tests. The remaining 8 failures are known test-environment issues related to missing page field ID 2074815070.

The existing standard FatturaPA XML serializer remains unchanged. Please re-review the updated implementation.

This branch was successfully deployed

1 active (outdated) deployment
triage — 8950ba91 Deployed Oct 19, 2026 by marcus905 via Classify team ownership #8349
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ADO: Sync Creates an Azure DevOps work item if needed and indicates that one is linked From Fork Pull request is coming from a fork needs-approval Workflow runs require maintainer approval to start Team: Finance GitHub request for Finance area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[IT][Extensibility Request] Expose a cloud-safe API to generate the standard FatturaPA payload

2 participants