[
https://issues.apache.org/jira/browse/FINERACT-2929?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Josue Araujo updated FINERACT-2929:
-----------------------------------
Priority: Critical (was: Major)
> undo/adjust/waiveCharge/payCharge fail with results.in.balance.going.negative
> after a force withdrawal, regardless of which transaction is targeted
> ---------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: FINERACT-2929
> URL: https://issues.apache.org/jira/browse/FINERACT-2929
> Project: Apache Fineract
> Issue Type: Bug
> Components: Savings, System
> Affects Versions: 1.15.0, 1.16.0
> Reporter: Josue Araujo
> Priority: Critical
> Fix For: 1.15.0, 1.16.0
>
>
> ## Summary
> SavingsAccount has two overloads of validateAccountBalanceConstraints():
> A) validateAccountBalanceConstraints(BigDecimal boolean, List boolean,
> boolean isForceWithdrawal)
> - used by regular deposit/withdrawal (handleWithdrawal)
> - fixed in FINERACT-2797 to recognize per-transaction force-withdrawal
> flags
> B) validateAccountBalanceConstraints(String transactionAction, List boolean)
> - used by undoTransaction, adjustTransaction, waiveChargeTransaction,
> and payCharge
> - has NO force-withdrawal awareness whatsoever: no isForceWithdrawal
> parameter,
> no call to isForceWithdrawalAllowed(...) anywhere in the method.
> As a result, once an account has ANY force-withdrawal transaction in its
> history (and overdraft is disabled), EVERY subsequent undo/adjust/waiveCharge/
> payCharge on that account fails with results.in.balance.going.negative — even
> when the specific operation's own net effect on the balance is fully positive
> — because the historical recalculation loop always re-encounters the old
> forced-withdrawal dip and this overload has no exception for it.
> This is not specific to which transaction is targeted by the undo/adjust; ANY
> transaction targeted on an account with a force-withdrawal in its history will
> reproduce the failure.
> ## Steps to reproduce
> 1. Savings product: no interest, overdraft NOT allowed.
> 2. Global config: allow-force-withdrawal-on-savings-account=true,
> force-withdrawal-on-savings-account-limit=1000.
> 3. Deposit 100.00 (balance: 100.00)
> 4. Force withdrawal 110.00 (balance: -10.00)
> 5. Deposit 5.00 (balance: -5.00)
> 6. Deposit 5.00 (balance: 0.00)
> 7. Deposit 50.00 (balance: 50.00)
> 8. Undo transaction #3 (net effect: 100 - 110 + 5 + 50 = 45.00, positive)
> -> ACTUAL: throws PlatformApiDataValidationException,
> code "results.in.balance.going.negative".
> ## Expected behavior
> Step 8 should succeed, since the undo's own net effect leaves the balance
> positive (45.00). A previously-authorized forced-withdrawal dip should not
> retroactively block unrelated future undo/adjust/waiveCharge/payCharge
> operations, just as fixed for regular withdrawals in FINERACT-2797.
> ## Environment
> - Branch: develop
> - Feature introduced in: 8c187f9d17fb839f26fc888f34a64f7c1f57a802
> (FINERACT-2471)
> - Verified still present as of commit c6328ab3062d8e1cf8395c00c40918a1741134ad
> (2026-07-27)
> ## Suggested fix
> Reuse the is_force_transaction flag and isForceWithdrawalAllowed(transaction,
> ...)
> introduced in FINERACT-2797 inside the
> validateAccountBalanceConstraints(String, ...)
> overload's loop, exactly as done for the other overload. Draft PR to follow,
> built on top of the FINERACT-2797 branch.
> Blocked by: FINERACT-2797
--
This message was sent by Atlassian Jira
(v8.20.10#820010)