Skip to content

[29.0] [FR E-Reporting] Add payment and invoice lifecycle messages - #10822

Merged
Milica Đukić (djukicmilica) merged 48 commits into
microsoft:releases/29.0from
djukicmilica:backport/637593-29.0-collected-refused-messages
Sep 1, 2026
Merged

[29.0] [FR E-Reporting] Add payment and invoice lifecycle messages#10822
Milica Đukić (djukicmilica) merged 48 commits into
microsoft:releases/29.0from
djukicmilica:backport/637593-29.0-collected-refused-messages

Conversation

@djukicmilica

@djukicmilica Milica Đukić (djukicmilica) commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Why

French electronic invoicing requires lifecycle communication beyond the parent E-Document processing status. Eligible outgoing invoice payment applications and reversals must produce collected or negative-collected messages, buyers must be able to accept or refuse incoming invoices, and platform lifecycle messages must be correlated without overwriting the invoice's own state.

This change models these exchanges as child E-Document messages and adds reusable transport, queuing, response polling, payment-occurrence, payload, and external-reference infrastructure to E-Document Core.

Summary

  • Added a public E-Document message API with IMessageSender and IMessageResponseHandler integration contracts, payload persistence, processing statuses, queued background delivery, response polling, and retry support.
  • Added generic applied and reversed E-Document payment occurrences with replay protection and original-occurrence linkage.
  • Added French Collected and Negative Collected messages for payment applications and unapplications on approved or cleared Peppol BIS 3.0 FR and Factur-X FR documents with reportable unrealized VAT.
  • Added proportional VAT allocation by rate and category, deterministic rounding, reversal of the original VAT breakdown, and frozen sender-platform and invoice context for PPF/CDV lifecycle payloads.
  • Added buyer Accepted and Refused messages for incoming purchase invoices, with optional refusal reasons and validation that only one buyer response can be sent.
  • Added incoming lifecycle-message correlation by external document and message IDs, normalization of Submitted, Accepted, Refused, and Technical Rejected statuses, payload retention, transition validation, and deduplication.
  • Added PPF/CDV profile validation, French service setup fields, lifecycle actions and history pages, and focused Core and French integration tests covering transport, payments, buyer responses, profiles, VAT allocation, and incoming messages.
  • Fixed E-Document test object ID collisions and Factur-X test variable shadowing that blocked BCApps validation against NAV.

Fixes
AB#648388

@djukicmilica Milica Đukić (djukicmilica) removed the Team: Other GitHub request for other area than SCM, Finance or Integration label Aug 31, 2026
@github-actions github-actions Bot removed the Ownership: Needs Review Ownership is Other, low confidence, or needs manual correction label Aug 31, 2026
@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 1

Recommendation: Request Changes

What this PR does

This adds generic child-message support for E-Documents, including payload storage, queueing, retry, response polling, and external correlation. It also adds French invoice lifecycle messages for buyer accepted/refused statuses and payment collected/negative-collected events.

The main design matches the new lifecycle flow: payment applications are captured after detailed customer ledger entries are inserted, French code builds CDAR lifecycle payloads, and incoming messages are correlated back to the parent E-Document. However, one cleanup path is incomplete: child message rows are removed without removing their stored payload rows.

Problem-solution fit

Fit: Strong

The change is a coherent feature increment for French invoice lifecycle reporting. It covers outgoing payment events, buyer response messages, incoming status normalization, background processing, and tests for the key message flows, but the cleanup behavior does not yet match the data the feature now stores.

Suggestions

S1 (🔴 High): Delete message payload storage during cleanup
The cleanup test now expects the message payload to be removed, but deleting E-Document Message records does not delete the related E-Doc. Data Storage row. CleanupDocument() can leave orphaned lifecycle payloads after the parent document is cleaned up. Add cleanup for Data Storage Entry No. when an E-Document Message is deleted, using the same pattern as E-Document Log.

Risk assessment and necessity

Risk: The regression surface is the E-Document message infrastructure, French lifecycle messages, payment application/unapplication events, background jobs, and cleanup of stored payloads. The payment/VAT path is financially sensitive, and the new public message API can be used by connector apps, so persisted orphaned payloads are a data-integrity and storage-retention risk.

Necessity: The feature is needed to support the French invoice and payment lifecycle. The scope is appropriate for that goal, but the message payload lifecycle must be completed before merge so document cleanup removes all data introduced by the new message flow.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=10822 round=1 by=alexei-dobriansky at=2026-08-31T13:39:01Z lastSha=dd6a46b0f0fba0d8c099c9aea900923e3b3d2c13 reviewKey=70140d342776c90e8c6296697e02ed775d85d5948a4e6660246e4ae214aef747 suggestions=S1@361f901f

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 2

Recommendation: Request Changes

What this PR does

The new commits add retryable background handling for child message sending, response polling, and payment occurrences, and they update tests around those flows. The retry and dispatcher shape looks coherent, but the cleanup gap from round 1 is still present: deleting child message records still does not delete the stored payload rows they point to.

Status of previous suggestions
ID Title Status Author response
S1 Delete message payload storage during cleanup Not addressed None.
New observations (commits since round 1)

None - no new issue was found in the commits since round 1.

Risk assessment and necessity

Risk: The regression surface remains the E-Document message infrastructure, French lifecycle messages, payment application and reversal handling, background jobs, and document cleanup. The payment and VAT paths are financially sensitive, and orphaned payload rows remain a data-integrity and storage-retention risk.

Necessity: The feature is needed for the French invoice and payment lifecycle, and the scope is still appropriate for that goal. The cleanup lifecycle must still be completed before merge so all payload data introduced by child messages is removed with the parent document.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=10822 round=2 by=alexei-dobriansky at=2026-09-01T01:20:03Z lastSha=74607e045d9351e7e5e5114241468a4956541831 reviewKey=16726ab1445493ae38206e1a8118d2cb5a6985bb0102bb7bec6f1a42d9d08390 suggestions=S1@361f901f:notaddressed parentRound=1

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 3

Recommendation: Request Changes

What this PR does

The latest commits mainly add compile/test fixes and data-classification handling while the feature still adds child E-Document messages for French invoice and payment lifecycle events. The previous cleanup gap is still present, and the newest changes leave payment occurrences dependent on a dispatcher that is not scheduled anywhere in the current PR content.

Status of previous suggestions
ID Title Status Author response
S1 Delete message payload storage during cleanup Not addressed None.
New observations (commits since round 2)

S2 (🔴 High): Schedule payment occurrence processing
CreateOccurrence only inserts a Pending payment occurrence, and the current PR has no caller that creates the recurrent dispatcher. Restore dispatcher setup, or schedule each occurrence when it is inserted, so collected and negative-collected messages are sent in normal use.

Risk assessment and necessity

Risk: The regression surface remains E-Document child-message storage, French lifecycle messages, payment application and reversal handling, and background processing. The payment and VAT paths are financially sensitive; orphaned payload rows remain a storage and data-retention risk, and unscheduled payment occurrences can stop required lifecycle messages from being sent.

Necessity: The feature is needed for the French invoice and payment lifecycle, and the scope is coherent for that goal. The cleanup lifecycle and payment-occurrence scheduling need to be complete before merge so the new lifecycle records are both processed and removed correctly.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=10822 round=3 by=alexei-dobriansky at=2026-09-01T13:21:44Z lastSha=771f4137f0927853725c1d235dbecb5895b7ccfd reviewKey=dd13fc96bb657e6bd0aa3eb712516bb02e3400f0add4cde750dde46319e0f37a suggestions=S1@361f901f:notaddressed,S2@693a73a8:new parentRound=2

@djukicmilica
Milica Đukić (djukicmilica) merged commit 3128d7d into microsoft:releases/29.0 Sep 1, 2026
168 checks passed
Milica Đukić (djukicmilica) added a commit that referenced this pull request Sep 2, 2026
…10892)

Backport of #10822 to `releases/28.5`.

## Why

French electronic invoicing requires lifecycle communication beyond the
parent E-Document processing status. Eligible outgoing invoice payment
applications and reversals must produce collected or negative-collected
messages, buyers must be able to accept or refuse incoming invoices, and
platform lifecycle messages must be correlated without overwriting the
invoice's own state.

This change models these exchanges as child E-Document messages and adds
reusable transport, queuing, response polling, payment-occurrence,
payload, and external-reference infrastructure to E-Document Core.

## Summary

- **Added** a public E-Document message API with `IMessageSender` and
`IMessageResponseHandler` integration contracts, payload persistence,
processing statuses, queued background delivery, response polling, and
retry support.
- **Added** generic applied and reversed E-Document payment occurrences
with replay protection and original-occurrence linkage.
- **Added** French `Collected` and `Negative Collected` messages for
payment applications and unapplications on approved or cleared Peppol
BIS 3.0 FR and Factur-X FR documents with reportable unrealized VAT.
- **Added** proportional VAT allocation by rate and category,
deterministic rounding, reversal of the original VAT breakdown, and
frozen sender-platform and invoice context for PPF/CDV lifecycle
payloads.
- **Added** buyer `Accepted` and `Refused` messages for incoming
purchase invoices, with optional refusal reasons and validation that
only one buyer response can be sent.
- **Added** incoming lifecycle-message correlation by external document
and message IDs, normalization of `Submitted`, `Accepted`, `Refused`,
and `Technical Rejected` statuses, payload retention, transition
validation, and deduplication.
- **Added** PPF/CDV profile validation, French service setup fields,
lifecycle actions and history pages, and focused Core and French
integration tests covering transport, payments, buyer responses,
profiles, VAT allocation, and incoming messages.
- **Fixed** E-Document test object ID collisions and Factur-X test
variable shadowing that blocked BCApps validation against NAV.

Fixes 

[AB#648388](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/648388)

---------

Co-authored-by: djukicmilica <milicadjukic@microsoft.com>
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 AL: Apps (W1) Add-on apps for W1 From Fork Pull request is coming from a fork Ownership: Manual Preserve the manually selected team ownership Team: Finance GitHub request for Finance area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants