Arnold Galovics created FINERACT-2910:
-----------------------------------------

             Summary: 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


🐛 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)

Reply via email to