You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@fineract.apache.org by "Adam Saghy (Jira)" <ji...@apache.org> on 2026/10/18 17:59:00 UTC

[jira] [Resolved] (FINERACT-2910) Fix stale installment interest after add-charge / undo-waive when external events are disabled

     [ https://issues.apache.org/jira/browse/FINERACT-2910?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Adam Saghy resolved FINERACT-2910.
----------------------------------
    Resolution: Fixed

> Fix stale installment interest after add-charge / undo-waive when external events are disabled
> ----------------------------------------------------------------------------------------------
>
>                 Key: FINERACT-2910
>                 URL: https://issues.apache.org/jira/browse/FINERACT-2910
>             Project: Apache Fineract
>          Issue Type: Bug
>            Reporter: Arnold Galovics
>            Assignee: Arnold Galovics
>            Priority: Major
>             Fix For: 1.16.0
>
>
> 🐛 Steps to Reproduce
> 1. Check out apache/fineract tag 1.15.0 (commit d5636847), or develop at ad2abe93f306cf5308afa17719ab3e933e2d836e (1.16.0-SNAPSHOT, needs JDK 25).
> 2. Build the image: ./gradlew :fineract-provider:jibDockerBuild -x test -x cucumber
> 3. Start the stack from docker-compose-postgresql*.yml with config/docker/env/\{fineract,fineract-common,fineract-postgresql}.env (profiles test,diagnostics) on a fresh database, with FINERACT_EXTERNAL_EVENTS_ENABLED=false and no ActiveMQ.
> 4. Run the e2e client with INITIALIZATION_ENABLED=true and EVENT_VERIFICATION_ENABLED=false, one scenario at a time:
> -Pcucumber.features=src/test/resources/features/LoanReAmortization-Part1.feature:1933
> ("Verify Re-amortization with overdue penalties - Interest calculation: Default Behavior - Re-amortization with overdue penalties", C4311)
> -Pcucumber.features=src/test/resources/features/LoanDelayedScheduleCaptures-Part1.feature:2006
> ("UC15 - Verify full term tranche - charge waive and undo waive after 2nd disbursement")
> 5. Repeat on a fresh database with events enabled as in docker-compose-postgresql-test-activemq.yml + activemq.env, everything else unchanged.
>  
> ❌ Actual Result (events disabled)
> • C4311, installment 3 (01 April 2024): [3, 31, 01 April 2024, null, 50.43, 16.62, 0.39, 5.0, 10.0, 32.01, ...]
> • UC15, installment 2 (01 March 2024): [2, 29, 01 March 2024, null, 150.91, 32.75, 1.51, ...]
> • The stored interest is lower than the same operation produces with events enabled.
>  
> ✅ Expected Result
> • C4311, installment 3: [3, 31, 01 April 2024, null, 50.46, 16.59, 0.42, 5.0, 10.0, 32.01, ...]
> • UC15, installment 2: [2, 29, 01 March 2024, null, 150.94, 32.72, 1.54, ...]
> • The persisted schedule is identical whether external events are enabled or disabled.
>  
> ℹ️ Notes
> • Affects 1.15.0 and develop (ad2abe93, committed 2026-10-08). Other versions not tested.
> • Deterministic: fresh database for each run, identical test-client settings in both configurations. Each configuration was run once per version.
> • With events enabled both scenarios pass (26/26 and 40/40 steps) on both versions. The project's CI at 1.15.0, which runs with events enabled (activemq.env), passes them too.
> • The difference of 0.03 equals the daily interest on the overdue principal from the due date to the business date (C4311: 16.52 x 7% / 360 x 9 days = 0.029). The due amount of each installment is unchanged; only the interest/principal split differs.
> • Impact: external events are disabled by default (FINERACT_EXTERNAL_EVENTS_ENABLED:false). In that configuration the stored interest of the installment containing the business date stays stale until the next reprocess or COB run (LOAN_INTEREST_RECALCULATION), and the project's own e2e scenarios cannot pass.
> • Attach: run logs for 1.15.0 and develop, events disabled and enabled.
>  
> 🔧 Technical Notes (suspected cause, from code reading, not traced at runtime)
> • LoanChargeWritePlatformServiceImpl.addLoanCharge skips the reprocess when the charge due date is after the last transaction date. undoSpecifiedDueDateCharge only edits the installment's waived amounts and never reprocesses.
> • Both raise LoanBalanceChangedBusinessEvent. With events enabled, BusinessEventNotifierServiceImpl.beforeCommit calls externalEventService.postEvent, which serializes the event inside the command transaction. LoanBusinessEventSerializer then reaches ProgressiveLoanSummaryDataProvider.computeTotalUnpaidPayableNotDueInterestAmountOnActualPeriod -> getSavedModel(loan, businessDate) -> recalculateInterestForDate(..., updateInstallments=true), which mutates the managed installments; they are flushed on commit.
> • So serializing an event changes persisted loan data, and the stored schedule depends on whether event posting is enabled.
> • Unchanged between 1.15.0 and develop: LoanChargeWritePlatformServiceImpl, LoanBusinessEventSerializer. Touched only by unrelated commits: BusinessEventNotifierServiceImpl (FINERACT-2684, 2798, 2621, 2455), ProgressiveLoanSummaryDataProvider (FINERACT-2807).
> • Suggested fix: recalculate and update the installment interest explicitly in the add-charge and undo-waive paths, so persisted state does not depend on event serialization.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)