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 c8a641e474ba86401f71e1b409cfb6a536deba9c Author: mariiaKraievska <[email protected]> AuthorDate: Wed Apr 23 16:31:45 2025 +0300 FINERACT-2226: Fix repayment reversal issue after charge off and MIR --- .../test/data/loanproduct/DefaultLoanProduct.java | 2 + .../global/LoanProductGlobalInitializerStep.java | 25 ++ .../fineract/test/support/TestContextKey.java | 2 + .../src/test/resources/features/Loan.feature | 2 +- .../test/resources/features/LoanChargeOff.feature | 287 ++++++++++++++++++++- .../domain/ChangedTransactionDetail.java | 2 +- ...dvancedPaymentScheduleTransactionProcessor.java | 50 ++-- .../ProgressiveLoanSummaryDataProvider.java | 3 +- 8 files changed, 354 insertions(+), 19 deletions(-) diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java index a3fad36394..e13df43213 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java @@ -113,6 +113,8 @@ public enum DefaultLoanProduct implements LoanProduct { LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_MULTIDISBURSE_EXPECT_TRANCHE, // LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_MULTIDISBURSE, // LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_CASH_ACCOUNTING_DISBURSEMENT_CHARGES, // + LP2_ADV_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ZERO_INT_CHARGE_OFF, // + LP2_ADV_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ACCELERATE_MATURITY_CHARGE_OFF, // ; @Override diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java index ead1740d8c..a39192be30 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java @@ -25,6 +25,7 @@ import static org.apache.fineract.test.factory.LoanProductsRequestFactory.INTERE import static org.apache.fineract.test.factory.LoanProductsRequestFactory.INTEREST_RATE_FREQUENCY_TYPE_WHOLE_TERM; import static org.apache.fineract.test.factory.LoanProductsRequestFactory.LOAN_ACCOUNTING_RULE_NONE; import static org.apache.fineract.test.factory.LoanProductsRequestFactory.REPAYMENT_FREQUENCY_TYPE_MONTHS; +import static org.apache.fineract.test.factory.LoanProductsRequestFactory.SHORT_NAME_PREFIX_EMI; import java.math.BigDecimal; import java.util.ArrayList; @@ -50,6 +51,7 @@ import org.apache.fineract.test.data.RecalculationRestFrequencyType; import org.apache.fineract.test.data.TransactionProcessingStrategyCode; import org.apache.fineract.test.data.loanproduct.DefaultLoanProduct; import org.apache.fineract.test.factory.LoanProductsRequestFactory; +import org.apache.fineract.test.helper.Utils; import org.apache.fineract.test.support.TestContext; import org.apache.fineract.test.support.TestContextKey; import org.springframework.stereotype.Component; @@ -2261,6 +2263,29 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ TestContext.INSTANCE.set( TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON_INTEREST_RECALC, responseLoanProductsRequestAdvZeroInterestChargeOffProgressiveDelinquentReasonIntRecalc); + + final String name91 = DefaultLoanProduct.LP2_ADV_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ZERO_INT_CHARGE_OFF.getName(); + final PostLoanProductsRequest loanProductsRequestLP2AdvPaymentIntEmiActualActualIntRefundFullZeroIntChargeOff = loanProductsRequestLP2AdvancedpaymentInterestEmiActualActualInterestRefundFull + .name(name91)// + .shortName(Utils.randomNameGenerator(SHORT_NAME_PREFIX_EMI, 3))// + .chargeOffBehaviour("ZERO_INTEREST");// + final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentIntEmiActualActualIntRefundFullZeroIntChargeOff = loanProductsApi + .createLoanProduct(loanProductsRequestLP2AdvPaymentIntEmiActualActualIntRefundFullZeroIntChargeOff).execute(); + TestContext.INSTANCE.set( + TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ZERO_INT_CHARGE_OFF, + responseLoanProductsRequestLP2AdvPaymentIntEmiActualActualIntRefundFullZeroIntChargeOff); + + final String name92 = DefaultLoanProduct.LP2_ADV_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ACCELERATE_MATURITY_CHARGE_OFF + .getName(); + final PostLoanProductsRequest loanProductsRequestLP2AdvPaymentIntEmiActualActualIntRefundFullAccelerateMaturityChargeOff = loanProductsRequestLP2AdvancedpaymentInterestEmiActualActualInterestRefundFull + .name(name92)// + .shortName(Utils.randomNameGenerator(SHORT_NAME_PREFIX_EMI, 3))// + .chargeOffBehaviour("ACCELERATE_MATURITY");// + final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentIntEmiActualActualIntRefundFullAccelerateMaturityChargeOff = loanProductsApi + .createLoanProduct(loanProductsRequestLP2AdvPaymentIntEmiActualActualIntRefundFullAccelerateMaturityChargeOff).execute(); + TestContext.INSTANCE.set( + TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ACCELERATE_MATURITY_CHARGE_OFF, + responseLoanProductsRequestLP2AdvPaymentIntEmiActualActualIntRefundFullAccelerateMaturityChargeOff); } public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule, diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java index 71af376932..c54debbaa4 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java @@ -101,6 +101,8 @@ public abstract class TestContextKey { public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_REST_FREQUENCY_DATE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyTillRestFrequencyDate"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_SAME_AS_REP_TILL_REST_FREQUENCY_DATE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationSameAsRepTillRestFrequencyDate"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND_FULL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualInterestRefundFull"; + public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ZERO_INT_CHARGE_OFF = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualInterestRefundFullZeroInterestChargeOff"; + public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ACCELERATE_MATURITY_CHARGE_OFF = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualInterestRefundFullAccelerateMaturityChargeOff"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_MULTIDISBURSE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030MultiDisburse"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_PAYMENT_ALLOCATION_INTEREST_RECALCULATION_DAILY_NO_CALC_ON_PAST_DUE_EMI_360_30_MULTIDISBURSE = "loanProductCreateResponseLP2AdvancedPaymentAllocationInterestRecalculationDailyNoCalcOnPastDueEmi36030MultiDisburse"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE = "loanProductCreateResponseLP2AdvancedCustomPaymentInterestRecalculationDailyEmi36030MultiDisburse"; diff --git a/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature b/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature index 873883f585..33da16b7ce 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature @@ -6441,7 +6441,7 @@ Feature: Loan | 11 March 2025 | Disbursement | 200.0 | 0.0 | 0.0 | 0.0 | 0.0 | 200.0 | | 11 March 2025 | Merchant Issued Refund | 200.0 | 200.0 | 0.0 | 0.0 | 0.0 | 0.0 | | 11 March 2025 | Disbursement | 200.0 | 0.0 | 0.0 | 0.0 | 0.0 | 200.0 | - When Admin set "LP2_DOWNPAYMENT_AUTO_ADVANCED_PAYMENT_ALLOCATION" loan product "MERCHANT_ISSUED_REFUND" transaction type to "NEXT_INSTALLMENT" future installment allocation rule + When Admin set "LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND_FULL" loan product "MERCHANT_ISSUED_REFUND" transaction type to "NEXT_INSTALLMENT" future installment allocation rule @TestRailId:C3570 Scenario: Verify Loan is fully paid and closed after full Merchant issued refund 1 day after disbursement 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 cc859aaf13..10dabed848 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature @@ -8439,4 +8439,289 @@ Feature: Charge-off | EXPENSE | 744007 | Credit Loss/Bad Debt | DEBIT | 100.00 | | INCOME | 404001 | Interest Income Charge Off | DEBIT | 0.62 | | EXPENSE | 744007 | Credit Loss/Bad Debt | CREDIT | 100.00 | - | INCOME | 404001 | Interest Income Charge Off | CREDIT | 0.62 | \ No newline at end of file + | INCOME | 404001 | Interest Income Charge Off | CREDIT | 0.62 | + + @TestRailId:C3619 + Scenario: Verify repayment reversal after charge-off and merchant issued refund + When Admin sets the business date to "14 March 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_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND_FULL | 14 March 2025 | 900 | 9.9 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 4 | MONTHS | 1 | MONTHS | 4 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + And Admin successfully approves the loan on "14 March 2025" with "900" amount and expected disbursement date on "14 March 2025" + And Admin successfully disburse the loan on "14 March 2025" with "900" EUR transaction amount + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 677.88 | 222.12 | 7.57 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 2 | 30 | 14 May 2025 | | 453.71 | 224.17 | 5.52 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 3 | 31 | 14 June 2025 | | 227.83 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 4 | 30 | 14 July 2025 | | 0.0 | 227.83 | 1.85 | 0.0 | 0.0 | 229.68 | 0.0 | 0.0 | 0.0 | 229.68 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 18.75 | 0.0 | 0.0 | 918.75 | 0.0 | 0.0 | 0.0 | 918.75 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + When Admin sets the business date to "05 April 2025" + And Customer makes "REPAYMENT" transaction with "AUTOPAY" payment type on "05 April 2025" with 100 EUR transaction amount and system-generated Idempotency key + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 677.63 | 222.37 | 7.32 | 0.0 | 0.0 | 229.69 | 100.0 | 100.0 | 0.0 | 129.69 | + | 2 | 30 | 14 May 2025 | | 453.45 | 224.18 | 5.51 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 3 | 31 | 14 June 2025 | | 227.57 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 4 | 30 | 14 July 2025 | | 0.0 | 227.57 | 1.85 | 0.0 | 0.0 | 229.42 | 0.0 | 0.0 | 0.0 | 229.42 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 18.49 | 0.0 | 0.0 | 918.49 | 100.0 | 100.0 | 0.0 | 818.49 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + When Admin sets the business date to "14 April 2025" + And Admin does charge-off the loan on "14 April 2025" + When Admin runs inline COB job for Loan + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 677.63 | 222.37 | 7.32 | 0.0 | 0.0 | 229.69 | 100.0 | 100.0 | 0.0 | 129.69 | + | 2 | 30 | 14 May 2025 | | 453.45 | 224.18 | 5.51 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 3 | 31 | 14 June 2025 | | 227.57 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 4 | 30 | 14 July 2025 | | 0.0 | 227.57 | 1.85 | 0.0 | 0.0 | 229.42 | 0.0 | 0.0 | 0.0 | 229.42 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 18.49 | 0.0 | 0.0 | 918.49 | 100.0 | 100.0 | 0.0 | 818.49 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 14 April 2025 | Charge-off | 818.49 | 800.0 | 18.49 | 0.0 | 0.0 | 0.0 | + When Admin sets the business date to "15 April 2025" + And Customer makes "MERCHANT_ISSUED_REFUND" transaction with "AUTOPAY" payment type on "15 April 2025" with 900 EUR transaction amount and system-generated Idempotency key + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | 15 April 2025 | 677.63 | 222.37 | 7.32 | 0.0 | 0.0 | 229.69 | 229.69 | 100.0 | 129.69 | 0.0 | + | 2 | 30 | 14 May 2025 | 15 April 2025 | 453.45 | 224.18 | 5.51 | 0.0 | 0.0 | 229.69 | 229.69 | 229.69 | 0.0 | 0.0 | + | 3 | 31 | 14 June 2025 | 15 April 2025 | 227.57 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 229.69 | 229.69 | 0.0 | 0.0 | + | 4 | 30 | 14 July 2025 | 15 April 2025 | 0.0 | 227.57 | 1.85 | 0.0 | 0.0 | 229.42 | 229.42 | 229.42 | 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 | + | 900.0 | 18.49 | 0.0 | 0.0 | 918.49 | 918.49 | 788.8 | 129.69 | 0.0 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 14 April 2025 | Charge-off | 818.49 | 800.0 | 18.49 | 0.0 | 0.0 | 0.0 | + | 15 April 2025 | Merchant Issued Refund | 900.0 | 800.0 | 18.49 | 0.0 | 0.0 | 0.0 | + | 15 April 2025 | Interest Refund | 18.49 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | + When Customer undo "1"th repayment on "05 April 2025" + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | 15 April 2025 | 677.88 | 222.12 | 7.57 | 0.0 | 0.0 | 229.69 | 229.69 | 0.0 | 229.69 | 0.0 | + | 2 | 30 | 14 May 2025 | 15 April 2025 | 453.71 | 224.17 | 5.52 | 0.0 | 0.0 | 229.69 | 229.69 | 229.69 | 0.0 | 0.0 | + | 3 | 31 | 14 June 2025 | 15 April 2025 | 227.83 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 229.69 | 229.69 | 0.0 | 0.0 | + | 4 | 30 | 14 July 2025 | 15 April 2025 | 0.0 | 227.83 | 1.85 | 0.0 | 0.0 | 229.68 | 229.68 | 229.68 | 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 | + | 900.0 | 18.75 | 0.0 | 0.0 | 918.75 | 918.75 | 689.06 | 229.69 | 0.0 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | false | false | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | true | false | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | false | false | + | 14 April 2025 | Accrual | 0.25 | 0.0 | 0.25 | 0.0 | 0.0 | 0.0 | false | false | + | 14 April 2025 | Charge-off | 918.75 | 900.0 | 18.75 | 0.0 | 0.0 | 0.0 | false | true | + | 15 April 2025 | Merchant Issued Refund | 900.0 | 883.1 | 16.9 | 0.0 | 0.0 | 16.9 | false | true | + | 15 April 2025 | Interest Refund | 18.75 | 16.9 | 1.85 | 0.0 | 0.0 | 0.0 | false | true | + + @TestRailId:C3620 + Scenario: Verify repayment reversal after zero interest behaviour charge-off and merchant issued refund + When Admin sets the business date to "14 March 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_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ZERO_INT_CHARGE_OFF | 14 March 2025 | 900 | 9.9 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 4 | MONTHS | 1 | MONTHS | 4 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + And Admin successfully approves the loan on "14 March 2025" with "900" amount and expected disbursement date on "14 March 2025" + And Admin successfully disburse the loan on "14 March 2025" with "900" EUR transaction amount + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 677.88 | 222.12 | 7.57 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 2 | 30 | 14 May 2025 | | 453.71 | 224.17 | 5.52 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 3 | 31 | 14 June 2025 | | 227.83 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 4 | 30 | 14 July 2025 | | 0.0 | 227.83 | 1.85 | 0.0 | 0.0 | 229.68 | 0.0 | 0.0 | 0.0 | 229.68 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 18.75 | 0.0 | 0.0 | 918.75 | 0.0 | 0.0 | 0.0 | 918.75 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + When Admin sets the business date to "05 April 2025" + And Customer makes "REPAYMENT" transaction with "AUTOPAY" payment type on "05 April 2025" with 100 EUR transaction amount and system-generated Idempotency key + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 677.63 | 222.37 | 7.32 | 0.0 | 0.0 | 229.69 | 100.0 | 100.0 | 0.0 | 129.69 | + | 2 | 30 | 14 May 2025 | | 453.45 | 224.18 | 5.51 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 3 | 31 | 14 June 2025 | | 227.57 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 4 | 30 | 14 July 2025 | | 0.0 | 227.57 | 1.85 | 0.0 | 0.0 | 229.42 | 0.0 | 0.0 | 0.0 | 229.42 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 18.49 | 0.0 | 0.0 | 918.49 | 100.0 | 100.0 | 0.0 | 818.49 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + When Admin sets the business date to "14 April 2025" + And Admin does charge-off the loan on "14 April 2025" + When Admin runs inline COB job for Loan + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 677.63 | 222.37 | 7.32 | 0.0 | 0.0 | 229.69 | 100.0 | 100.0 | 0.0 | 129.69 | + | 2 | 30 | 14 May 2025 | | 447.94 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 3 | 31 | 14 June 2025 | | 218.25 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 4 | 30 | 14 July 2025 | | 0.0 | 218.25 | 0.0 | 0.0 | 0.0 | 218.25 | 0.0 | 0.0 | 0.0 | 218.25 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 7.32 | 0.0 | 0.0 | 907.32 | 100.0 | 100.0 | 0.0 | 807.32 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 14 April 2025 | Charge-off | 807.32 | 800.0 | 7.32 | 0.0 | 0.0 | 0.0 | + When Admin sets the business date to "15 April 2025" + And Customer makes "MERCHANT_ISSUED_REFUND" transaction with "AUTOPAY" payment type on "15 April 2025" with 900 EUR transaction amount and system-generated Idempotency key + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | 15 April 2025 | 677.63 | 222.37 | 7.32 | 0.0 | 0.0 | 229.69 | 229.69 | 100.0 | 129.69 | 0.0 | + | 2 | 30 | 14 May 2025 | 15 April 2025 | 447.94 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | 229.69 | 229.69 | 0.0 | 0.0 | + | 3 | 31 | 14 June 2025 | 15 April 2025 | 218.25 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | 229.69 | 229.69 | 0.0 | 0.0 | + | 4 | 30 | 14 July 2025 | 15 April 2025 | 0.0 | 218.25 | 0.0 | 0.0 | 0.0 | 218.25 | 218.25 | 218.25 | 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 | + | 900.0 | 7.32 | 0.0 | 0.0 | 907.32 | 907.32 | 777.63 | 129.69 | 0.0 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 14 April 2025 | Charge-off | 807.32 | 800.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 15 April 2025 | Merchant Issued Refund | 900.0 | 800.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 15 April 2025 | Interest Refund | 7.32 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | + When Customer undo "1"th repayment on "05 April 2025" + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | 15 April 2025 | 677.88 | 222.12 | 7.57 | 0.0 | 0.0 | 229.69 | 229.69 | 0.0 | 229.69 | 0.0 | + | 2 | 30 | 14 May 2025 | 15 April 2025 | 448.19 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | 229.69 | 229.69 | 0.0 | 0.0 | + | 3 | 31 | 14 June 2025 | 15 April 2025 | 218.5 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | 229.69 | 229.69 | 0.0 | 0.0 | + | 4 | 30 | 14 July 2025 | 15 April 2025 | 0.0 | 218.5 | 0.0 | 0.0 | 0.0 | 218.5 | 218.5 | 218.5 | 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 | + | 900.0 | 7.57 | 0.0 | 0.0 | 907.57 | 907.57 | 677.88 | 229.69 | 0.0 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | false | false | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | true | false | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | false | false | + | 14 April 2025 | Accrual | 0.25 | 0.0 | 0.25 | 0.0 | 0.0 | 0.0 | false | false | + | 14 April 2025 | Charge-off | 907.57 | 900.0 | 7.57 | 0.0 | 0.0 | 0.0 | false | true | + | 15 April 2025 | Merchant Issued Refund | 900.0 | 892.43 | 7.57 | 0.0 | 0.0 | 7.57 | false | true | + | 15 April 2025 | Interest Refund | 7.57 | 7.57 | 0.0 | 0.0 | 0.0 | 0.0 | false | true | + + @TestRailId:C3621 + Scenario: Verify repayment reversal after accelerate maturity behaviour charge-off and merchant issued refund + When Admin sets the business date to "14 March 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_PYMNT_INT_DAILY_EMI_ACTUAL_ACTUAL_INT_REFUND_FULL_ACCELERATE_MATURITY_CHARGE_OFF | 14 March 2025 | 900 | 9.9 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 4 | MONTHS | 1 | MONTHS | 4 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + And Admin successfully approves the loan on "14 March 2025" with "900" amount and expected disbursement date on "14 March 2025" + And Admin successfully disburse the loan on "14 March 2025" with "900" EUR transaction amount + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 677.88 | 222.12 | 7.57 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 2 | 30 | 14 May 2025 | | 453.71 | 224.17 | 5.52 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 3 | 31 | 14 June 2025 | | 227.83 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 4 | 30 | 14 July 2025 | | 0.0 | 227.83 | 1.85 | 0.0 | 0.0 | 229.68 | 0.0 | 0.0 | 0.0 | 229.68 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 18.75 | 0.0 | 0.0 | 918.75 | 0.0 | 0.0 | 0.0 | 918.75 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + When Admin sets the business date to "05 April 2025" + And Customer makes "REPAYMENT" transaction with "AUTOPAY" payment type on "05 April 2025" with 100 EUR transaction amount and system-generated Idempotency key + Then Loan Repayment schedule has 4 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 677.63 | 222.37 | 7.32 | 0.0 | 0.0 | 229.69 | 100.0 | 100.0 | 0.0 | 129.69 | + | 2 | 30 | 14 May 2025 | | 453.45 | 224.18 | 5.51 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 3 | 31 | 14 June 2025 | | 227.57 | 225.88 | 3.81 | 0.0 | 0.0 | 229.69 | 0.0 | 0.0 | 0.0 | 229.69 | + | 4 | 30 | 14 July 2025 | | 0.0 | 227.57 | 1.85 | 0.0 | 0.0 | 229.42 | 0.0 | 0.0 | 0.0 | 229.42 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 18.49 | 0.0 | 0.0 | 918.49 | 100.0 | 100.0 | 0.0 | 818.49 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + When Admin sets the business date to "14 April 2025" + And Admin does charge-off the loan on "14 April 2025" + When Admin runs inline COB job for Loan + Then Loan Repayment schedule has 1 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | | 0.0 | 900.0 | 7.32 | 0.0 | 0.0 | 907.32 | 100.0 | 100.0 | 0.0 | 807.32 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 7.32 | 0.0 | 0.0 | 907.32 | 100.0 | 100.0 | 0.0 | 807.32 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 14 April 2025 | Charge-off | 807.32 | 800.0 | 7.32 | 0.0 | 0.0 | 0.0 | + When Admin sets the business date to "15 April 2025" + And Customer makes "MERCHANT_ISSUED_REFUND" transaction with "AUTOPAY" payment type on "15 April 2025" with 900 EUR transaction amount and system-generated Idempotency key + Then Loan Repayment schedule has 1 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | 15 April 2025 | 0.0 | 900.0 | 7.32 | 0.0 | 0.0 | 907.32 | 907.32 | 100.0 | 807.32 | 0.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 7.32 | 0.0 | 0.0 | 907.32 | 907.32 | 100.0 | 807.32 | 0.0 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 14 April 2025 | Charge-off | 807.32 | 800.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 15 April 2025 | Merchant Issued Refund | 900.0 | 800.0 | 7.32 | 0.0 | 0.0 | 0.0 | + | 15 April 2025 | Interest Refund | 7.32 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | + When Customer undo "1"th repayment on "05 April 2025" + Then Loan Repayment schedule has 1 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 | + | | | 14 March 2025 | | 900.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 14 April 2025 | 15 April 2025 | 0.0 | 900.0 | 7.57 | 0.0 | 0.0 | 907.57 | 907.57 | 0.0 | 907.57 | 0.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 900.0 | 7.57 | 0.0 | 0.0 | 907.57 | 907.57 | 0.0 | 907.57 | 0.0 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | + | 14 March 2025 | Disbursement | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | 900.0 | false | false | + | 05 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 800.0 | true | false | + | 14 April 2025 | Accrual | 7.32 | 0.0 | 7.32 | 0.0 | 0.0 | 0.0 | false | false | + | 14 April 2025 | Accrual | 0.25 | 0.0 | 0.25 | 0.0 | 0.0 | 0.0 | false | false | + | 14 April 2025 | Charge-off | 907.57 | 900.0 | 7.57 | 0.0 | 0.0 | 0.0 | false | true | + | 15 April 2025 | Merchant Issued Refund | 900.0 | 900.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | true | + | 15 April 2025 | Interest Refund | 7.57 | 0.0 | 7.57 | 0.0 | 0.0 | 0.0 | false | true | diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/ChangedTransactionDetail.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/ChangedTransactionDetail.java index ad4245fc0e..55ebcb1b76 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/ChangedTransactionDetail.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/ChangedTransactionDetail.java @@ -41,7 +41,7 @@ public class ChangedTransactionDetail { change.setNewTransaction(transactionChangeData.getNewTransaction()); return; } else if (transactionChangeData.getOldTransaction() == null && change.getOldTransaction() == null - && change.getNewTransaction() != null + && change.getNewTransaction() != null && transactionChangeData.getNewTransaction() != null && Objects.equals(change.getNewTransaction().getId(), transactionChangeData.getNewTransaction().getId())) { change.setNewTransaction(transactionChangeData.getNewTransaction()); return; 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 b83ae1fc85..c0fab83936 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 @@ -343,21 +343,41 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep return ctx.getChangedTransactionDetail(); } - private void handleInterestRefund(LoanTransaction loanTransaction, TransactionCtx ctx) { - - if (ctx instanceof ProgressiveTransactionCtx progCtx) { - Money interestBeforeRefund = emiCalculator.getSumOfDueInterestsOnDate(progCtx.getModel(), loanTransaction.getDateOf()); - List<Long> unmodifiedTransactionIds = progCtx.getAlreadyProcessedTransactions().stream().filter(LoanTransaction::isNotReversed) - .map(AbstractPersistableCustom::getId).toList(); - List<LoanTransaction> modifiedTransactions = new ArrayList<>(progCtx.getAlreadyProcessedTransactions().stream() - .filter(LoanTransaction::isNotReversed).filter(tr -> tr.getId() == null).toList()); - if (!modifiedTransactions.isEmpty()) { - Money interestAfterRefund = interestRefundService.totalInterestByTransactions(this, loanTransaction.getLoan().getId(), - loanTransaction.getDateOf(), modifiedTransactions, unmodifiedTransactionIds); - Money newAmount = interestBeforeRefund.minus(progCtx.getSumOfInterestRefundAmount()).minus(interestAfterRefund); - loanTransaction.updateAmount(newAmount.getAmount()); + private void handleInterestRefund(final LoanTransaction loanTransaction, final TransactionCtx ctx) { + final Loan loan = loanTransaction.getLoan(); + final LoanTransaction chargeOffTransaction = loan.getLoanTransactions().stream().filter(t -> t.isChargeOff() && t.isNotReversed()) + .findFirst().orElse(null); + if (loan.isChargedOff() && chargeOffTransaction != null) { + final LoanChargeOffBehaviour chargeOffBehaviour = loanTransaction.getLoan().getLoanProductRelatedDetail() + .getChargeOffBehaviour(); + if (loan.isProgressiveSchedule() && !LoanChargeOffBehaviour.REGULAR.equals(chargeOffBehaviour)) { + loanTransaction.updateAmount(getInterestTillChargeOffForPeriod(loan, chargeOffTransaction.getTransactionDate(), ctx)); + } else { + Money interestPortion = Money.zero(ctx.getCurrency()); + for (final LoanRepaymentScheduleInstallment currentInstallment : ctx.getInstallments()) { + interestPortion = interestPortion.plus(currentInstallment.getInterestCharged(ctx.getCurrency())); + } + loanTransaction.updateAmount(interestPortion.getAmount()); + } + if (ctx instanceof ProgressiveTransactionCtx progCtx) { + progCtx.setSumOfInterestRefundAmount(progCtx.getSumOfInterestRefundAmount().add(loanTransaction.getAmount())); + } + } else { + if (ctx instanceof ProgressiveTransactionCtx progCtx) { + final Money interestBeforeRefund = emiCalculator.getSumOfDueInterestsOnDate(progCtx.getModel(), + loanTransaction.getDateOf()); + final List<Long> unmodifiedTransactionIds = progCtx.getAlreadyProcessedTransactions().stream() + .filter(LoanTransaction::isNotReversed).map(AbstractPersistableCustom::getId).toList(); + final List<LoanTransaction> modifiedTransactions = new ArrayList<>(progCtx.getAlreadyProcessedTransactions().stream() + .filter(LoanTransaction::isNotReversed).filter(tr -> tr.getId() == null).toList()); + if (!modifiedTransactions.isEmpty()) { + final Money interestAfterRefund = interestRefundService.totalInterestByTransactions(this, loan.getId(), + loanTransaction.getDateOf(), modifiedTransactions, unmodifiedTransactionIds); + final Money newAmount = interestBeforeRefund.minus(progCtx.getSumOfInterestRefundAmount()).minus(interestAfterRefund); + loanTransaction.updateAmount(newAmount.getAmount()); + } + progCtx.setSumOfInterestRefundAmount(progCtx.getSumOfInterestRefundAmount().add(loanTransaction.getAmount())); } - progCtx.setSumOfInterestRefundAmount(progCtx.getSumOfInterestRefundAmount().add(loanTransaction.getAmount())); } handleRepayment(loanTransaction, ctx); } @@ -980,7 +1000,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep .filter(oldRelation -> LoanTransactionRelationTypeEnum.RELATED.equals(oldRelation.getRelationType())) .findFirst().map(oldRelation -> oldRelation.getToTransaction().getId()) .flatMap(oldToTransactionId -> ctx.getChangedTransactionDetail().getTransactionChanges().stream() - .filter(change -> change.getOldTransaction().getId() != null + .filter(change -> change.getOldTransaction() != null && change.getOldTransaction().getId() != null && change.getOldTransaction().getId().equals(oldToTransactionId)) .map(TransactionChangeData::getNewTransaction).findFirst()) .ifPresent(newRelation::setToTransaction)); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanSummaryDataProvider.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanSummaryDataProvider.java index fe54a91462..eb6893b5db 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanSummaryDataProvider.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanSummaryDataProvider.java @@ -100,7 +100,8 @@ public class ProgressiveLoanSummaryDataProvider extends CommonLoanSummaryDataPro loan.getCurrency(), loan.getRepaymentScheduleInstallments(), loan.getActiveCharges()); ProgressiveLoanInterestScheduleModel model = changedTransactionDetailProgressiveLoanInterestScheduleModelPair.getRight(); final List<Long> replayedTransactions = changedTransactionDetailProgressiveLoanInterestScheduleModelPair.getLeft() - .getTransactionChanges().stream().filter(change -> change.getOldTransaction() != null) + .getTransactionChanges().stream() + .filter(change -> change.getOldTransaction() != null && change.getNewTransaction() != null) .map(change -> change.getNewTransaction().getId()).filter(Objects::nonNull).toList(); if (!replayedTransactions.isEmpty()) {
