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 3e197e367b0a9cc2b786bf0578b9d92f4b4774c6
Author: Rustam Zeinalov <[email protected]>
AuthorDate: Thu Dec 11 17:32:06 2025 +0100

    FINERACT-2421: added e2e test for verifying reprocess Interest Refund txn 
amount if no txn was changed
---
 .../test/data/loanproduct/DefaultLoanProduct.java  |  1 +
 .../global/LoanProductGlobalInitializerStep.java   | 21 ++++++++
 .../fineract/test/support/TestContextKey.java      |  1 +
 .../features/LoanMerchantIssuedRefund.feature      | 58 ++++++++++++++++++++++
 ...dvancedPaymentScheduleTransactionProcessor.java | 14 ++++--
 .../integrationtests/LoanInterestRefundTest.java   | 33 ++++++------
 ...nManualInterestRefundResponseStructureTest.java |  9 ++--
 7 files changed, 114 insertions(+), 23 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 b5b40998f4..4776e322bb 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
@@ -87,6 +87,7 @@ public enum DefaultLoanProduct implements LoanProduct {
     LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND, //
     LP1_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, //
     LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, //
+    LP2_ADV_PMT_ALLOC_ACTUAL_ACTUAL_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, //
     
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE_WHOLE_TERM,
 //
     
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_IR_DAILY_TILL_PRECLOSE_LAST_INSTALLMENT_STRATEGY,
 //
     
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND_INTEREST_RECALCULATION,
 //
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 1eba7e12f9..0fd7cceefd 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
@@ -4231,6 +4231,27 @@ public class LoanProductGlobalInitializerStep implements 
FineractGlobalInitializ
                 
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_MULTIDISBURSE_CHARGEBACK,
                 
responseLoanProductsRequestLP2AdvancedpaymentInterestEmi36030InterestRecalcDailyMultiDisburseChargeback);
 
+        // LP2 + interest recalculation + advanced custom payment allocation + 
progressive loan schedule + horizontal
+        // (LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL)
+        String name152 = 
DefaultLoanProduct.LP2_ADV_PMT_ALLOC_ACTUAL_ACTUAL_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL.getName();
+
+        PostLoanProductsRequest 
loanProductsRequestAdvPaymentAllocationActualActualProgressiveLoanSchedule = 
loanProductsRequestFactory
+                .defaultLoanProductsRequestLP2InterestDailyRecalculation()//
+                .name(name152)//
+                
.supportedInterestRefundTypes(Arrays.asList("MERCHANT_ISSUED_REFUND", 
"PAYOUT_REFUND"))//
+                .enableAccrualActivityPosting(true) //
+                .daysInYearType(DaysInYearType.ACTUAL.value)//
+                .daysInMonthType(DaysInMonthType.ACTUAL.value)//
+                .paymentAllocation(List.of(//
+                        createPaymentAllocation("DEFAULT", 
"NEXT_INSTALLMENT"), //
+                        createPaymentAllocation("PAYOUT_REFUND", 
"LAST_INSTALLMENT"), //
+                        createPaymentAllocation("MERCHANT_ISSUED_REFUND", 
"LAST_INSTALLMENT")));//
+        PostLoanProductsResponse 
responseLoanProductsRequestAdvPaymentAllocationActualActualProgressiveLoanSchedule
 = createLoanProductIdempotent(
+                
loanProductsRequestAdvPaymentAllocationActualActualProgressiveLoanSchedule);
+        TestContext.INSTANCE.set(
+                
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_PAYMENT_ALLOCATION_ACTUAL_ACTUAL_PROGRESSIVE_LOAN_SCHEDULE,
+                
responseLoanProductsRequestAdvPaymentAllocationActualActualProgressiveLoanSchedule);
+
         // 
LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL_PRINCIPAL_FIRST
         // Same as 
LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL but with 
PRINCIPAL before INTEREST
         // in payment allocation order
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 634ac3dd0b..56e52d42c7 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
@@ -88,6 +88,7 @@ public abstract class TestContextKey {
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_DOWNPAYMENT_AUTO = 
"loanProductCreateResponseLP2DownPaymentAuto";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_DOWNPAYMENT_ADVANCED_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE
 = "loanProductCreateResponseLP2DownPaymentProgressiveLoanSchedule";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE
 = "loanProductCreateResponseLP2ProgressiveLoanScheduleCustomPaymentAllocation";
+    public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_PAYMENT_ALLOCATION_ACTUAL_ACTUAL_PROGRESSIVE_LOAN_SCHEDULE
 = 
"loanProductCreateResponseLP2ProgressiveLoanScheduleActualActualAdvancedPaymentAllocation";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_DOWNPAYMENT_ADVANCED_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL
 = "loanProductCreateResponseLP2DownPaymentProgressiveLoanScheduleVertical";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_DOWNPAYMENT_ADVANCED_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE_INSTALLMENT_LEVEL_DELINQUENCY
 = 
"loanProductCreateResponseLP2DownPaymentProgressiveLoanScheduleInstallmentLevelDelinquency";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROG_SCHEDULE_HOR_INST_LVL_DELINQUENCY_CREDIT_ALLOCATION
 = 
"loanProductCreateResponseLP2DownPaymentProgressiveLoanScheduleHorizontalInstallmentLevelDelinquencyCreditAllocation";
diff --git 
a/fineract-e2e-tests-runner/src/test/resources/features/LoanMerchantIssuedRefund.feature
 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanMerchantIssuedRefund.feature
index 9c3952ae64..81dfa1f8a9 100644
--- 
a/fineract-e2e-tests-runner/src/test/resources/features/LoanMerchantIssuedRefund.feature
+++ 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanMerchantIssuedRefund.feature
@@ -637,3 +637,61 @@ Feature: MerchantIssuedRefund
       | 02 October 2025  | Interest Refund        | 17.07  |   0.0     | 0.0   
   | 0.0  | 0.0       |   0.0        | false    | false    |
       | 02 October 2025  | Accrual                | 18.33  |   0.0     | 18.33 
   | 0.0  | 0.0       |   0.0        | false    | false    |
       | 02 October 2025  | Accrual Activity       |  8.97  |   0.0     | 8.97  
   | 0.0  | 0.0       |   0.0        | false    | false    |
+
+  @TestRailId:C4355
+  Scenario: Verify manual Interest Refund is recalculated during reprocessing 
even if no prior transaction was reverse-replayed
+    When Admin sets the business date to "01 January 2025"
+    And Admin creates a client with random data
+    And 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_PMT_ALLOC_ACTUAL_ACTUAL_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 
01 January 2025   | 100            | 26                     | DECLINING_BALANCE 
| DAILY                       | EQUAL_INSTALLMENTS | 6                 | MONTHS 
               | 1              | MONTHS                 | 6                  | 
0                       | 0                      | 0                    | 
ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "01 January 2025" with "100" 
amount and expected disbursement date on "01 January 2025"
+    And Admin successfully disburse the loan on "01 January 2025" with "100" 
EUR transaction amount
+    And Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2025  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
+    # MIR with interestRefundCalculation=false (no auto Interest Refund)
+    When Admin sets the business date to "01 February 2025"
+    And Customer makes "MERCHANT_ISSUED_REFUND" transaction with "AUTOPAY" 
payment type on "01 February 2025" with 66.41 EUR transaction amount and 
system-generated Idempotency key and interestRefundCalculation false
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type       | Amount | Principal | 
Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2025  | Disbursement           | 100.0  | 0.0       | 0.0   
   | 0.0  | 0.0       | 100.0        | false    | false    |
+      | 01 February 2025 | Merchant Issued Refund | 66.41  | 64.2      | 2.21  
   | 0.0  | 0.0       | 35.8         | false    | false    |
+    # Manually create Interest Refund with arbitrary amount (0.47 EUR)
+    When Admin manually adds Interest Refund for "MERCHANT_ISSUED_REFUND" 
transaction made on "01 February 2025" with 0.47 EUR interest refund amount
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type       | Amount | Principal | 
Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2025  | Disbursement           | 100.0  | 0.0       | 0.0   
   | 0.0  | 0.0       | 100.0        | false    | false    |
+      | 01 February 2025 | Merchant Issued Refund | 66.41  | 64.2      | 2.21  
   | 0.0  | 0.0       | 35.8         | false    | false    |
+      | 01 February 2025 | Interest Refund        | 0.47   | 0.47      | 0.0   
   | 0.0  | 0.0       | 35.33         | false    | false    |
+    # Backdated repayment on 20 January (before MIR) - triggers replay of MIR
+    And Customer makes "REPAYMENT" transaction with "AUTOPAY" payment type on 
"20 January 2025" with 17.94 EUR transaction amount and system-generated 
Idempotency key
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type       | Amount | Principal | 
Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2025  | Disbursement           | 100.0  | 0.0       | 0.0   
   | 0.0  | 0.0       | 100.0        | false    | false    |
+      | 20 January 2025  | Repayment              | 17.94  | 16.59     | 1.35  
   | 0.0  | 0.0       | 83.41        | false    | false    |
+      | 01 February 2025 | Merchant Issued Refund | 66.41  | 66.41     | 0.0   
   | 0.0  | 0.0       | 17.0         | false    | true     |
+      | 01 February 2025 | Interest Refund        | 1.48   | 1.48      | 0.0   
   | 0.0  | 0.0       | 15.52        | false    | true     |
+#   Step 4: Make another repayment on 25 January (also before MIR)
+    And Customer makes "REPAYMENT" transaction with "AUTOPAY" payment type on 
"25 January 2025" with 10.94 EUR transaction amount and system-generated 
Idempotency key
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type       | Amount | Principal | 
Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2025  | Disbursement           | 100.0  | 0.0       | 0.0   
   | 0.0  | 0.0       | 100.0        | false    | false    |
+      | 20 January 2025  | Repayment              | 17.94  | 16.59     | 1.35  
   | 0.0  | 0.0       | 83.41        | false    | false    |
+      | 25 January 2025  | Repayment              | 10.94  | 10.94     | 0.0   
   | 0.0  | 0.0       | 72.47        | false    | false    |
+      | 01 February 2025 | Merchant Issued Refund | 66.41  | 66.41     | 0.0   
   | 0.0  | 0.0       | 6.06         | false    | true     |
+      | 01 February 2025 | Interest Refund        | 1.47   | 1.47      | 0.0   
   | 0.0  | 0.0       | 4.59         | false    | true     |
+#   Step 5: Reverse the 1st repayment (20 Jan) - this triggers full 
transaction reprocessing
+#   Key expectation: Interest Refund should be RECALCULATED even though MIR 
wasn't modified
+#   Before fix: Interest Refund kept 1.47 because no txn before it was changed
+#   After fix: Interest Refund recalculated to correct value
+    When Customer undo "1"th "Repayment" transaction made on "20 January 2025"
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type       | Amount | Principal | 
Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2025  | Disbursement           | 100.0  | 0.0       | 0.0   
   | 0.0  | 0.0       | 100.0        | false    | false    |
+      | 20 January 2025  | Repayment              | 17.94  | 16.59     | 1.35  
   | 0.0  | 0.0       | 83.41        | true     | false    |
+      | 25 January 2025  | Repayment              | 10.94  | 10.94     | 0.0   
   | 0.0  | 0.0       | 89.06        | false    | false     |
+      | 01 February 2025 | Merchant Issued Refund | 66.41  | 64.26     | 2.15  
   | 0.0  | 0.0       | 24.8         | false    | true     |
+      | 01 February 2025 | Interest Refund        | 1.46   | 1.46      | 0.0   
   | 0.0  | 0.0       | 23.34        | false    | true     |
+    #following steps will fail if Interest Refund is not recalculated properly
+    Then Loan has 23.97 outstanding amount
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 121172ee17..a0b789a7fe 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
@@ -568,16 +568,22 @@ public class AdvancedPaymentScheduleTransactionProcessor 
extends AbstractLoanRep
                         
.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());
-                final Money interestAfterRefund = 
interestRefundService.totalInterestByTransactions(this, loan.getId(), 
targetDate,
-                        modifiedTransactions, unmodifiedTransactionIds);
-                final Money newAmount = 
interestBeforeRefund.minus(progCtx.getSumOfInterestRefundAmount()).minus(interestAfterRefund);
-                loanTransaction.updateAmount(newAmount.getAmount());
+                if 
(validateInterestRefundTransactionRelation(loanTransaction)) {
+                    final Money interestAfterRefund = 
interestRefundService.totalInterestByTransactions(this, loan.getId(), 
targetDate,
+                            modifiedTransactions, unmodifiedTransactionIds);
+                    final Money newAmount = 
interestBeforeRefund.minus(progCtx.getSumOfInterestRefundAmount()).minus(interestAfterRefund);
+                    loanTransaction.updateAmount(newAmount.getAmount());
+                }
                 
progCtx.setSumOfInterestRefundAmount(progCtx.getSumOfInterestRefundAmount().add(loanTransaction.getAmount()));
             }
         }
         handleRepayment(loanTransaction, ctx);
     }
 
+    private boolean validateInterestRefundTransactionRelation(final 
LoanTransaction interestRefundTransaction) {
+        return interestRefundTransaction.getLoanTransactionRelations(tr -> 
tr.getToTransaction().getId() != null).isEmpty();
+    }
+
     private boolean chargeOffIsInEffect(TransactionCtx ctx, LoanTransaction 
chargeOffTransaction, LoanTransaction loanTransaction) {
         if (ctx instanceof ProgressiveTransactionCtx progressiveCtx && 
progressiveCtx.isChargedOff()) {
             return true;
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestRefundTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestRefundTest.java
index 02c8acfe8b..e5e064192b 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestRefundTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestRefundTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.fineract.integrationtests;
 
-import static 
org.apache.fineract.portfolio.loanaccount.domain.Loan.DATE_FORMAT;
 import static 
org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRelationTypeEnum.REPLAYED;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -47,7 +46,6 @@ import 
org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
 import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
 import 
org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
 import org.apache.fineract.client.util.CallFailedRuntimeException;
-import org.apache.fineract.integrationtests.common.BusinessStepHelper;
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
@@ -64,7 +62,6 @@ public class LoanInterestRefundTest extends 
BaseLoanIntegrationTest {
     private static RequestSpecification requestSpec;
     private static LoanTransactionHelper loanTransactionHelper;
     private static PostClientsResponse client;
-    private static BusinessStepHelper businessStepHelper;
 
     @BeforeAll
     public static void setup() {
@@ -1646,9 +1643,9 @@ public class LoanInterestRefundTest extends 
BaseLoanIntegrationTest {
             disburseLoan(loanId, BigDecimal.valueOf(100.0), "1 January 2025");
 
             final String transactionExternalId = UUID.randomUUID().toString();
-            final PostLoansLoanIdTransactionsResponse refundResponse = 
loanTransactionHelper
-                    .makeMerchantIssuedRefund(loanId, new 
PostLoansLoanIdTransactionsRequest().dateFormat(DATETIME_PATTERN)
-                        .transactionDate("1 February 
2025").locale("en").transactionAmount(66.41).externalId(transactionExternalId).interestRefundCalculation(false));
+            final PostLoansLoanIdTransactionsResponse refundResponse = 
loanTransactionHelper.makeMerchantIssuedRefund(loanId,
+                    new 
PostLoansLoanIdTransactionsRequest().dateFormat(DATETIME_PATTERN).transactionDate("1
 February 2025").locale("en")
+                            
.transactionAmount(66.41).externalId(transactionExternalId).interestRefundCalculation(false));
             Assertions.assertNotNull(refundResponse.getResourceId());
 
             verifyTransactions(loanId, //
@@ -1657,16 +1654,16 @@ public class LoanInterestRefundTest extends 
BaseLoanIntegrationTest {
             );
 
             // Create manual interest refund via API
-            PostLoansLoanIdTransactionsResponse interestRefundResponse = 
loanTransactionHelper.createManualInterestRefund(loanId, 
refundResponse.getResourceId(),
-                    "1 February 2025", 1.47, null);
+            loanTransactionHelper.createManualInterestRefund(loanId, 
refundResponse.getResourceId(), "1 February 2025", 0.47, null);
 
             verifyTransactions(loanId, //
                     transaction(100.0, "Disbursement", "01 January 2025"), //
                     transaction(66.41, "Merchant Issued Refund", "01 February 
2025"), //
-                    transaction(1.47, "Interest Refund", "01 February 2025") //
+                    transaction(0.47, "Interest Refund", "01 February 2025") //
             );
 
-            PostLoansLoanIdTransactionsResponse repaymentResponse = 
loanTransactionHelper.makeLoanRepayment(loanId, "Repayment", "20 January 2025", 
17.94);
+            PostLoansLoanIdTransactionsResponse repaymentResponse = 
loanTransactionHelper.makeLoanRepayment(loanId, "Repayment",
+                    "20 January 2025", 17.94);
             loanTransactionHelper.makeLoanRepayment(loanId, "Repayment", "25 
January 2025", 10.94);
 
             verifyTransactions(loanId, //
@@ -1678,12 +1675,20 @@ public class LoanInterestRefundTest extends 
BaseLoanIntegrationTest {
             );
 
             loanTransactionHelper.reverseLoanTransaction(loanId, 
repaymentResponse.getResourceId(),
-                    new 
PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat(DATETIME_PATTERN)
-                    .transactionDate("25 January 
2021").transactionAmount(0.0).locale("en"));
+                    new 
PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat(DATETIME_PATTERN).transactionDate("25
 January 2025")
+                            .transactionAmount(0.0).locale("en"));
+
+            verifyTransactions(loanId, //
+                    transaction(100.0, "Disbursement", "01 January 2025"), //
+                    reversedTransaction(17.94, "Repayment", "20 January 
2025"), //
+                    transaction(10.94, "Repayment", "25 January 2025"), //
+                    transaction(66.41, "Merchant Issued Refund", "01 February 
2025"), //
+                    transaction(1.47, "Interest Refund", "01 February 2025") //
+            );
 
             GetLoansLoanIdResponse loanDetails = 
loanTransactionHelper.getLoanDetails(loanId);
-            verifyLoanStatus(loanDetails, LoanStatus.OVERPAID);
-            Assertions.assertEquals(0.36, 
Utils.getDoubleValue(loanDetails.getTotalOverpaid()));
+            verifyLoanStatus(loanDetails, LoanStatus.ACTIVE);
+            Assertions.assertEquals(23.97, 
Utils.getDoubleValue(loanDetails.getSummary().getTotalOutstanding()));
         });
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanManualInterestRefundResponseStructureTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanManualInterestRefundResponseStructureTest.java
index abd5d4144e..3b29fae772 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanManualInterestRefundResponseStructureTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanManualInterestRefundResponseStructureTest.java
@@ -36,7 +36,6 @@ import 
org.apache.fineract.client.models.GetLoansLoanIdTransactions;
 import org.apache.fineract.client.models.PostClientsResponse;
 import org.apache.fineract.client.models.PostLoanProductsResponse;
 import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
-import 
org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
@@ -96,8 +95,8 @@ public class LoanManualInterestRefundResponseStructureTest 
extends BaseLoanInteg
             targetTransactionIdRef.set(refundResponse.getResourceId());
 
             // Create manual interest refund via API
-            PostLoansLoanIdTransactionsResponse interestRefundResponse = 
loanTransactionHelper.createManualInterestRefund(loanId, 
refundResponse.getResourceId(),
-                    "15 January 2024", 5.0, null);
+            PostLoansLoanIdTransactionsResponse interestRefundResponse = 
loanTransactionHelper.createManualInterestRefund(loanId,
+                    refundResponse.getResourceId(), "15 January 2024", 5.0, 
null);
 
             assertNotNull(interestRefundResponse, "Interest refund response 
should not be null");
             assertNotNull(interestRefundResponse.getResourceId(), "Interest 
refund resource ID should not be null");
@@ -157,8 +156,8 @@ public class LoanManualInterestRefundResponseStructureTest 
extends BaseLoanInteg
 
             // Create manual interest refund with external ID
             String interestRefundExternalId = UUID.randomUUID().toString();
-            PostLoansLoanIdTransactionsResponse interestRefundResponse = 
loanTransactionHelper.createManualInterestRefund(loanId, 
refundResponse.getResourceId(),
-                    "15 February 2024", 5.0, interestRefundExternalId);
+            PostLoansLoanIdTransactionsResponse interestRefundResponse = 
loanTransactionHelper.createManualInterestRefund(loanId,
+                    refundResponse.getResourceId(), "15 February 2024", 5.0, 
interestRefundExternalId);
 
             assertNotNull(interestRefundResponse, "Interest refund response 
should not be null");
             assertNotNull(interestRefundResponse.getResourceId(), "Interest 
refund resource ID should not be null");

Reply via email to