This is an automated email from the ASF dual-hosted git repository. adamsaghy pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract.git
commit 3b0d053d52c5ca14bdcec500653221dfa7522921 Author: Oleksii Novikov <[email protected]> AuthorDate: Fri Jan 23 16:44:19 2026 +0200 FINERACT-2456: Fix charge off after repayment reversal with merchant refunds and credit balance refund --- .../test/resources/features/LoanChargeOff.feature | 63 ++++++++++++++++++++++ ...dvancedPaymentScheduleTransactionProcessor.java | 13 ++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature index a20f8c5fa4..2192a81958 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature @@ -10076,3 +10076,66 @@ Feature: Charge-off And Admin does charge-off the loan on "01 October 2025" Then Loan has 11.51 total unpaid payable due interest Then Loan has 0.0 total unpaid payable not due interest + + Scenario: Verify charge-off after repayment reversal with merchant refunds and credit balance refund + When Admin sets the business date to "03 November 2025" + When Admin creates a client with random data + When Admin creates a fully customized loan with the following data: + | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | + | LP2_ADV_CUSTOM_PMT_ALLOC_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALC_ZERO_CHARGE_OFF_ACCRUAL | 03 November 2025 | 127.17 | 9.51 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 24 | MONTHS | 1 | MONTHS | 24 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + And Admin successfully approves the loan on "03 November 2025" with "127.17" amount and expected disbursement date on "03 November 2025" + When Admin successfully disburse the loan on "03 November 2025" with "127.17" EUR transaction amount + When Admin sets the business date to "03 December 2025" + When Customer makes "REPAYMENT" transaction with "AUTOPAY" payment type on "03 December 2025" with 6 EUR transaction amount and system-generated Idempotency key + When Admin sets the business date to "17 December 2025" + When Customer makes "MERCHANT_ISSUED_REFUND" transaction with "AUTOPAY" payment type on "17 December 2025" with 145 EUR transaction amount and system-generated Idempotency key + When Admin sets the business date to "23 January 2026" + When Admin makes Credit Balance Refund transaction on "23 January 2026" with 23.83 EUR transaction amount + When Customer undo "1"th "Repayment" transaction made on "03 December 2025" + And Admin does charge-off the loan on "23 January 2026" + Then Loan status will be "ACTIVE" + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | + | 03 November 2025 | Disbursement | 127.17 | 0.0 | 0.0 | 0.0 | 0.0 | 127.17 | false | + | 03 December 2025 | Repayment | 6.0 | 5.01 | 0.99 | 0.0 | 0.0 | 122.16 | true | + | 03 December 2025 | Accrual Activity | 0.99 | 0.0 | 0.99 | 0.0 | 0.0 | 0.0 | false | + | 17 December 2025 | Accrual | 1.44 | 0.0 | 1.44 | 0.0 | 0.0 | 0.0 | false | + | 17 December 2025 | Merchant Issued Refund | 145.0 | 127.17 | 1.45 | 0.0 | 0.0 | 0.0 | false | + | 17 December 2025 | Interest Refund | 1.45 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | + | 17 December 2025 | Accrual Activity | 0.46 | 0.0 | 0.46 | 0.0 | 0.0 | 0.0 | false | + | 03 January 2026 | Accrual Activity | 0.46 | 0.0 | 0.46 | 0.0 | 0.0 | 0.0 | false | + | 23 January 2026 | Credit Balance Refund | 23.83 | 6.0 | 0.0 | 0.0 | 0.0 | 6.0 | false | + | 23 January 2026 | Accrual | 0.01 | 0.0 | 0.01 | 0.0 | 0.0 | 0.0 | false | + | 23 January 2026 | Charge-off | 6.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | + Then Loan Repayment schedule has 24 periods, with the following data for periods: + | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | | | 03 November 2025 | | 127.17 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 30 | 03 December 2025 | 17 December 2025 | 122.32 | 4.85 | 0.99 | 0.0 | 0.0 | 5.84 | 5.84 | 0.0 | 5.84 | 0.0 | + | 2 | 31 | 03 January 2026 | 17 December 2025 | 116.94 | 5.38 | 0.46 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 3 | 31 | 03 February 2026 | | 111.1 | 29.67 | 0.0 | 0.0 | 0.0 | 29.67 | 23.67 | 23.67 | 0.0 | 6.0 | + | 4 | 28 | 03 March 2026 | 17 December 2025 | 105.26 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 5 | 31 | 03 April 2026 | 17 December 2025 | 99.42 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 6 | 30 | 03 May 2026 | 17 December 2025 | 93.58 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 7 | 31 | 03 June 2026 | 17 December 2025 | 87.74 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 8 | 30 | 03 July 2026 | 17 December 2025 | 81.9 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 9 | 31 | 03 August 2026 | 17 December 2025 | 76.06 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 10 | 31 | 03 September 2026 | 17 December 2025 | 70.22 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 11 | 30 | 03 October 2026 | 17 December 2025 | 64.38 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 12 | 31 | 03 November 2026 | 17 December 2025 | 58.54 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 13 | 30 | 03 December 2026 | 17 December 2025 | 52.7 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 14 | 31 | 03 January 2027 | 17 December 2025 | 46.86 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 15 | 31 | 03 February 2027 | 17 December 2025 | 41.02 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 16 | 28 | 03 March 2027 | 17 December 2025 | 35.18 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 17 | 31 | 03 April 2027 | 17 December 2025 | 29.34 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 18 | 30 | 03 May 2027 | 17 December 2025 | 23.5 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 19 | 31 | 03 June 2027 | 17 December 2025 | 17.66 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 20 | 30 | 03 July 2027 | 17 December 2025 | 11.82 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 21 | 31 | 03 August 2027 | 17 December 2025 | 5.98 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 22 | 31 | 03 September 2027 | 17 December 2025 | 0.14 | 5.84 | 0.0 | 0.0 | 0.0 | 5.84 | 5.84 | 5.84 | 0.0 | 0.0 | + | 23 | 30 | 03 October 2027 | 17 December 2025 | 0.0 | 0.14 | 0.0 | 0.0 | 0.0 | 0.14 | 0.14 | 0.14 | 0.0 | 0.0 | + | 24 | 31 | 03 November 2027 | 17 December 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 151.0 | 1.45 | 0.0 | 0.0 | 152.45 | 146.45 | 140.61 | 5.84 | 6.0 | + When Loan Pay-off is made on "23 January 2026" + Then Loan's all installments have obligations met diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java index 3ec685dede..a058441095 100644 --- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java +++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java @@ -2189,12 +2189,21 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep } }); - final Money amountToEditLastInstallment = loanTransaction.getLoan().getPrincipal().minus(installments.stream() // - .filter(i -> i.getPrincipal() != null) // + final BigDecimal totalCreditedPrincipal = installments.stream() // .filter(i -> !i.isAdditional()) // + .map(i -> MathUtil.nullToZero(i.getCreditedPrincipal())) // + .reduce(ZERO, BigDecimal::add); + + final Money scheduledPrincipal = Money.of(currency, installments.stream() // + .filter(i -> i.getPrincipal() != null && !i.isAdditional()) // .map(LoanRepaymentScheduleInstallment::getPrincipal) // .reduce(ZERO, BigDecimal::add)); + final Money totalPrincipal = loanTransaction.getLoan().getPrincipal() // + .plus(Money.of(currency, totalCreditedPrincipal)); + + final Money amountToEditLastInstallment = totalPrincipal.minus(scheduledPrincipal); + BigDecimal principalBalance = amountToEditLastInstallment.getAmount(); for (int i = installments.size() - 1; i > 0 && BigDecimal.ZERO.compareTo(principalBalance) != 0; i--) { final LoanRepaymentScheduleInstallment installment = installments.get(i);
