Skip to content

intent: a settlement sizes an allocation from the invoice's rows, not its lagging paid roll-up (#7559) - #7662

Merged
delchev merged 3 commits into
eclipse-dirigible:masterfrom
NicoleNG18:issue-7559-settlement-open-from-rows
Oct 3, 2026
Merged

delchev merged 3 commits into
eclipse-dirigible:masterfrom
NicoleNG18:issue-7559-settlement-open-from-rows

Conversation

@NicoleNG18

Copy link
Copy Markdown
Contributor

Cause

The generated settlement handlers computed an invoice's open amount as total - Paid. Paid is a roll-up maintained asynchronously (outbox + listener), so it lags the allocation rows. A payment event arriving inside that lag, such as the payment's own -updated after its allocated roll-up write, sized an allocation from the stale figure. The junction's capacity guard (#7448) re-sums the rows synchronously and correctly refused it. The listener then failed with an ERROR and stopped at the exception, so whatever of the payment the same pass would have spent on later invoices stayed unallocated.

Change

This follows the issue's preferred fix: derive the open amount from the rows instead of catching the guard's exception.

  • open() re-sums the rows. In SettlementOnPayment (all its variants: create, correction, re-key) and in SettlementOnInvoice, open() now re-sums the invoice's junction rows. That is the guard's own computation, and it mirrors allocated(paymentId) on the payment side of the same class. Paid is no longer read.
  • Same rows as the roll-up and the guard. The settlement descriptor carries the where: clauses (intent: a cumulative ceiling over the documents that reference one parent (credit notes <= invoice total) has no declarative form #7542) of the roll-up that keeps the settlement's paid column (over the junction, via the invoice relation, summing amount). GlueGenerator renders them with the same JavaLiterals.criteriaChain that the roll-up recompute and the guard use. So a cancelled allocation the roll-up has retired does not still hold the invoice's capacity here, which would have under-allocated compared to today. A .glue generated before the key existed sums every row.
  • invoicePaid leaves the descriptor. paid: still names the roll-up whose definition decides which rows count.
  • The assistant guide, the README and the SettlementIntent docs are updated.

Verification

  • New unit tests:
    • GlueSettlementOpenAmountTest: the paid roll-up's filter travels on the descriptor; no filter means none is carried; a filtered roll-up of a different column is ignored.
    • A new GlueGeneratorTest case: the clauses render as a .ne("Status", 2) chain; an old descriptor renders "".
  • engine-intent (1466) and ide-template (215) unit suites pass.
  • New IntentSettlementOpenAmountIT (HTTP-only, runtime). The race depends on timing, so the fixture makes the lag permanent: the capacity-bearing roll-up keeps another column, so paid is never written. A payment of 100 settles the older 120 invoice; correcting it to 300 must put only 20 more on that invoice and 180 on the newer one. Sized from Paid, the handler would request 120, the guard would refuse, and the newer invoice would get nothing.
  • IntentEngineIT (81, the settlement test now asserts every handler's open() sums .eq("Invoice", invoice.Id) and reads no invoice.Paid) and IntentSettlementAllocationDeleteIT pass. "capacity exceeded" appears nowhere in the run's log.
  • mvn formatter:validate passes after wiping the formatter cache.

Not verified:

  • The PostgreSQL leg.
  • A run of the new IT against the unfixed templates. Its failure mode before the fix is argued above, not observed.
  • The release-javadoc build: no public SDK Javadoc changed.

Not in scope: the payment-side allocated(paymentId) sums every junction row of the payment and does not apply the payment-side roll-up's filter. That is unchanged by this PR.

Fixes #7559

🤖 Generated with Claude Code

NicoleNG18 and others added 3 commits October 3, 2026 11:05
… its lagging paid roll-up (eclipse-dirigible#7559)

Cause: the generated settlement handlers computed an invoice's open amount
as total - Paid, where Paid is a roll-up maintained asynchronously through
the outbox. A payment event arriving while the allocation rows had moved
but Paid had not caught up sized an allocation the junction's capacity
guard (which re-sums the rows synchronously) refused: the listener failed
with an ERROR, and the rest of the payment the same pass would have spent
on later invoices stayed unallocated.

Change:
- open() in SettlementOnPayment (create / correction / re-key) and
  SettlementOnInvoice re-sums the invoice's junction rows - the guard's own
  computation, the mirror of allocated(paymentId) - and no longer reads Paid.
- The rows summed are the rows the paid roll-up counts: the settlement
  descriptor carries that roll-up's where: clauses (invoiceRowsFilter),
  rendered by GlueGenerator with the same criteriaChain the recompute and
  the guard use, so a cancelled allocation does not hold the invoice. A
  .glue without the key sums every row.
- invoicePaid leaves the descriptor; `paid:` still names the roll-up.
- Assistant guide, README and SettlementIntent docs updated.

Verified: GlueSettlementOpenAmountTest + GlueGeneratorTest case (new);
engine-intent (1466) and ide-template (215) unit suites;
IntentSettlementOpenAmountIT (new, runtime: the paid column made
permanently stale, a correction must take only what is left on the older
invoice and carry the rest), IntentSettlementAllocationDeleteIT and
IntentEngineIT (81) green on H2; formatter:validate with the cache wiped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nt-open-from-rows

# Conflicts:
#	components/engine/engine-intent/README.md
#	components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/GlueIntentGenerator.java
#	components/engine/engine-intent/src/main/resources/intent-assistant-guide.md
#	components/ide/ide-template/src/main/java/org/eclipse/dirigible/components/ide/template/service/model/GlueGenerator.java
#	tests/tests-integrations/src/main/java/org/eclipse/dirigible/integration/tests/api/IntentEngineIT.java
@delchev
delchev merged commit c294b7e into eclipse-dirigible:master Oct 3, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants