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 d82ffddeccf17c8042b3bf81156f140c7e697259
Author: adam.magyari <[email protected]>
AuthorDate: Wed Jul 30 16:38:44 2025 +0200

    FINERACT-2338: Allow backdated interest rate change on progressive loans
---
 .../test/resources/features/EMICalculation.feature |  58 --------
 .../features/LoanInterestRateChange.feature        | 155 +++++++++++++++++++++
 ...gressiveLoanRescheduleRequestDataValidator.java |  22 +--
 ...nRescheduleRequestWritePlatformServiceImpl.java |  10 ++
 .../LoanRescheduleRequestTest.java                 |  17 +--
 5 files changed, 168 insertions(+), 94 deletions(-)

diff --git 
a/fineract-e2e-tests-runner/src/test/resources/features/EMICalculation.feature 
b/fineract-e2e-tests-runner/src/test/resources/features/EMICalculation.feature
index 61828b35ad..e50ec3ada9 100644
--- 
a/fineract-e2e-tests-runner/src/test/resources/features/EMICalculation.feature
+++ 
b/fineract-e2e-tests-runner/src/test/resources/features/EMICalculation.feature
@@ -1589,64 +1589,6 @@ Feature: EMI calculation and repayment schedule checks 
for interest bearing loan
       | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
       | 01 February 2024 | Repayment        | 17.01  | 16.43     | 0.58     | 
0.0  | 0.0       | 83.57        | false    | false    |
 
-  @TestRailId:C3217
-  Scenario: Verify the Loan reschedule - Interest modification - UC3: Interest 
modification results an error when rescheduleFromDate equals business date
-    When Admin sets the business date to "01 January 2024"
-    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_360_30 | 01 January 2024   | 100      
      | 7                      | 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 2024" with "100" 
amount and expected disbursement date on "01 January 2024"
-    When Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
-    Then Loan Repayment schedule has 6 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 |
-      |    |      | 01 January 2024  |           | 100.0           |           
    |          | 0.0  |           | 0.0   | 0.0  |            |      |          
   |
-      | 1  | 31   | 01 February 2024 |           | 83.57           | 16.43     
    | 0.58     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 2  | 29   | 01 March 2024    |           | 67.05           | 16.52     
    | 0.49     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 3  | 31   | 01 April 2024    |           | 50.43           | 16.62     
    | 0.39     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 4  | 30   | 01 May 2024      |           | 33.71           | 16.72     
    | 0.29     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 5  | 31   | 01 June 2024     |           | 16.9            | 16.81     
    | 0.2      | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 6  | 30   | 01 July 2024     |           | 0.0             | 16.9      
    | 0.1      | 0.0  | 0.0       | 17.0  | 0.0  | 0.0        | 0.0  | 17.0     
   |
-    Then Loan Repayment schedule has the following data in Total row:
-      | Principal due | Interest | Fees | Penalties | Due    | Paid | In 
advance | Late | Outstanding |
-      | 100.0         | 2.05     | 0.0  | 0.0       | 102.05 | 0.0  | 0.0      
  | 0.0  | 102.05      |
-    Then Loan Transactions tab has the following data:
-      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
-      | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
-    When Admin sets the business date to "14 February 2024"
-    Then Loan reschedule with the following data results a 403 error and 
"LOAN_RESCHEDULE_DATE_NOT_IN_FUTURE" error message
-      | rescheduleFromDate | submittedOnDate  | adjustedDueDate | 
graceOnPrincipal | graceOnInterest | extraTerms | newInterestRate |
-      | 14 February 2024   | 14 February 2024 |                 | 0            
    | 0               | 0          | 4               |
-
-  @TestRailId:C3218
-  Scenario: Verify the Loan reschedule - Interest modification - UC4: Interest 
modification results an error when rescheduleFromDate is earlier than business 
date
-    When Admin sets the business date to "01 January 2024"
-    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_360_30 | 01 January 2024   | 100      
      | 7                      | 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 2024" with "100" 
amount and expected disbursement date on "01 January 2024"
-    When Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
-    Then Loan Repayment schedule has 6 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 |
-      |    |      | 01 January 2024  |           | 100.0           |           
    |          | 0.0  |           | 0.0   | 0.0  |            |      |          
   |
-      | 1  | 31   | 01 February 2024 |           | 83.57           | 16.43     
    | 0.58     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 2  | 29   | 01 March 2024    |           | 67.05           | 16.52     
    | 0.49     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 3  | 31   | 01 April 2024    |           | 50.43           | 16.62     
    | 0.39     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 4  | 30   | 01 May 2024      |           | 33.71           | 16.72     
    | 0.29     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 5  | 31   | 01 June 2024     |           | 16.9            | 16.81     
    | 0.2      | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
-      | 6  | 30   | 01 July 2024     |           | 0.0             | 16.9      
    | 0.1      | 0.0  | 0.0       | 17.0  | 0.0  | 0.0        | 0.0  | 17.0     
   |
-    Then Loan Repayment schedule has the following data in Total row:
-      | Principal due | Interest | Fees | Penalties | Due    | Paid | In 
advance | Late | Outstanding |
-      | 100.0         | 2.05     | 0.0  | 0.0       | 102.05 | 0.0  | 0.0      
  | 0.0  | 102.05      |
-    Then Loan Transactions tab has the following data:
-      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
-      | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
-    When Admin sets the business date to "14 February 2024"
-    Then Loan reschedule with the following data results a 403 error and 
"LOAN_RESCHEDULE_DATE_NOT_IN_FUTURE" error message
-      | rescheduleFromDate | submittedOnDate  | adjustedDueDate | 
graceOnPrincipal | graceOnInterest | extraTerms | newInterestRate |
-      | 13 February 2024   | 14 February 2024 |                 | 0            
    | 0               | 0          | 4               |
-
   @TestRailId:C3219
   Scenario: Verify Repayment schedule in case of 2nd disbursement (created on 
business date before 1st installment) is backdated to before 1st disbursement
     When Admin sets the business date to "01 January 2024"
diff --git 
a/fineract-e2e-tests-runner/src/test/resources/features/LoanInterestRateChange.feature
 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanInterestRateChange.feature
new file mode 100644
index 0000000000..d19807579d
--- /dev/null
+++ 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanInterestRateChange.feature
@@ -0,0 +1,155 @@
+@InterestRateChangeFeature
+Feature: Loan interest rate change on repayment schedule
+
+  Scenario: Verify Interest rate change - backdated, modification on 
installment due date - UC1
+    When Admin sets the business date to "01 January 2024"
+    When Admin creates a client with random data
+    When Admin set 
"LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE"
 loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future 
installment allocation rule
+    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_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE
 | 01 January 2024   | 100            | 7                      | 
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 2024" with "100" 
amount and expected disbursement date on "01 January 2024"
+    When Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    When Admin runs inline COB job for Loan
+    Then Loan Repayment schedule has 6 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 |
+      |    |      | 01 January 2024  |           | 100.0           |           
    |          | 0.0  |           | 0.0   | 0.0  |            |      |          
   |
+      | 1  | 31   | 01 February 2024 |           | 83.57           | 16.43     
    | 0.58     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 2  | 29   | 01 March 2024    |           | 67.05           | 16.52     
    | 0.49     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 3  | 31   | 01 April 2024    |           | 50.43           | 16.62     
    | 0.39     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 4  | 30   | 01 May 2024      |           | 33.71           | 16.72     
    | 0.29     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 5  | 31   | 01 June 2024     |           | 16.9            | 16.81     
    | 0.2      | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 6  | 30   | 01 July 2024     |           | 0.0             | 16.9      
    | 0.1      | 0.0  | 0.0       | 17.0  | 0.0  | 0.0        | 0.0  | 17.0     
   |
+    Then Loan Repayment schedule has the following data in Total row:
+      | Principal due | Interest | Fees | Penalties | Due    | Paid | In 
advance | Late | Outstanding |
+      | 100.0         | 2.05     | 0.0  | 0.0       | 102.05 | 0.0  | 0.0      
  | 0.0  | 102.05      |
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
+    When Admin sets the business date to "01 April 2024"
+    And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 
EUR transaction amount
+    And Customer makes "AUTOPAY" repayment on "01 March 2024" with 17.01 EUR 
transaction amount
+    When Admin creates and approves Loan reschedule with the following data:
+      | rescheduleFromDate | submittedOnDate  | adjustedDueDate | 
graceOnPrincipal | graceOnInterest | extraTerms | newInterestRate |
+      | 02 February 2024   | 02 February 2024 |                 |              
    |                 |            | 4               |
+    Then Loan Repayment schedule has 6 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 |
+      |    |      | 01 January 2024  |                  | 100.0           |    
           |          | 0.0  |           | 0.0   | 0.0   |            |      |  
           |
+      | 1  | 31   | 01 February 2024 | 01 February 2024 | 83.57           | 
16.43         | 0.58     | 0.0  | 0.0       | 17.01 | 17.01 | 0.0        | 0.0  
| 0.0         |
+      | 2  | 29   | 01 March 2024    | 01 March 2024    | 66.97           | 
16.6          | 0.28     | 0.0  | 0.0       | 16.88 | 16.88 | 0.0        | 0.0  
| 0.0         |
+      | 3  | 31   | 01 April 2024    |                  | 50.31           | 
16.66         | 0.22     | 0.0  | 0.0       | 16.88 | 0.13  | 0.13       | 0.0  
| 16.75       |
+      | 4  | 30   | 01 May 2024      |                  | 33.6            | 
16.71         | 0.17     | 0.0  | 0.0       | 16.88 | 0.0   | 0.0        | 0.0  
| 16.88       |
+      | 5  | 31   | 01 June 2024     |                  | 16.83           | 
16.77         | 0.11     | 0.0  | 0.0       | 16.88 | 0.0   | 0.0        | 0.0  
| 16.88       |
+      | 6  | 30   | 01 July 2024     |                  | 0.0             | 
16.83         | 0.06     | 0.0  | 0.0       | 16.89 | 0.0   | 0.0        | 0.0  
| 16.89       |
+    Then Loan Repayment schedule has the following data in Total row:
+      | Principal due | Interest | Fees | Penalties | Due    | Paid  | In 
advance | Late | Outstanding |
+      | 100.0         | 1.42     | 0.0  | 0.0       | 101.42 | 34.02 | 0.13    
   | 0.0  | 67.4        |
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
+      | 01 February 2024 | Repayment        | 17.01  | 16.43     | 0.58     | 
0.0  | 0.0       | 83.57        | false    | false    |
+      | 01 March 2024    | Repayment        | 17.01  | 16.73     | 0.28     | 
0.0  | 0.0       | 66.84        | false    | true     |
+    When Loan Pay-off is made on "01 April 2024"
+    Then Loan's all installments have obligations met
+
+  Scenario: Verify Interest rate change - backdated, modification in middle of 
installment - UC2
+    When Admin sets the business date to "01 January 2024"
+    When Admin creates a client with random data
+    When Admin set 
"LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE"
 loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future 
installment allocation rule
+    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_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE
 | 01 January 2024   | 100            | 7                      | 
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 2024" with "100" 
amount and expected disbursement date on "01 January 2024"
+    When Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    When Admin runs inline COB job for Loan
+    Then Loan Repayment schedule has 6 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 |
+      |    |      | 01 January 2024  |           | 100.0           |           
    |          | 0.0  |           | 0.0   | 0.0  |            |      |          
   |
+      | 1  | 31   | 01 February 2024 |           | 83.57           | 16.43     
    | 0.58     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 2  | 29   | 01 March 2024    |           | 67.05           | 16.52     
    | 0.49     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 3  | 31   | 01 April 2024    |           | 50.43           | 16.62     
    | 0.39     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 4  | 30   | 01 May 2024      |           | 33.71           | 16.72     
    | 0.29     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 5  | 31   | 01 June 2024     |           | 16.9            | 16.81     
    | 0.2      | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 6  | 30   | 01 July 2024     |           | 0.0             | 16.9      
    | 0.1      | 0.0  | 0.0       | 17.0  | 0.0  | 0.0        | 0.0  | 17.0     
   |
+    Then Loan Repayment schedule has the following data in Total row:
+      | Principal due | Interest | Fees | Penalties | Due    | Paid | In 
advance | Late | Outstanding |
+      | 100.0         | 2.05     | 0.0  | 0.0       | 102.05 | 0.0  | 0.0      
  | 0.0  | 102.05      |
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
+    When Admin sets the business date to "01 April 2024"
+    And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 
EUR transaction amount
+    And Customer makes "AUTOPAY" repayment on "01 March 2024" with 17.01 EUR 
transaction amount
+    When Admin creates and approves Loan reschedule with the following data:
+      | rescheduleFromDate | submittedOnDate  | adjustedDueDate | 
graceOnPrincipal | graceOnInterest | extraTerms | newInterestRate |
+      | 16 February 2024   | 16 February 2024 |                 |              
    |                 |            | 4               |
+    Then Loan Repayment schedule has 6 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 |
+      |    |      | 01 January 2024  |                  | 100.0           |    
           |          | 0.0  |           | 0.0   | 0.0   |            |      |  
           |
+      | 1  | 31   | 01 February 2024 | 01 February 2024 | 83.57           | 
16.43         | 0.58     | 0.0  | 0.0       | 17.01 | 17.01 | 0.0        | 0.0  
| 0.0         |
+      | 2  | 29   | 01 March 2024    | 01 March 2024    | 67.05           | 
16.52         | 0.38     | 0.0  | 0.0       | 16.9  | 16.9  | 0.0        | 0.0  
| 0.0         |
+      | 3  | 31   | 01 April 2024    |                  | 50.37           | 
16.68         | 0.22     | 0.0  | 0.0       | 16.9  | 0.11  | 0.11       | 0.0  
| 16.79       |
+      | 4  | 30   | 01 May 2024      |                  | 33.64           | 
16.73         | 0.17     | 0.0  | 0.0       | 16.9  | 0.0   | 0.0        | 0.0  
| 16.9        |
+      | 5  | 31   | 01 June 2024     |                  | 16.85           | 
16.79         | 0.11     | 0.0  | 0.0       | 16.9  | 0.0   | 0.0        | 0.0  
| 16.9        |
+      | 6  | 30   | 01 July 2024     |                  | 0.0             | 
16.85         | 0.06     | 0.0  | 0.0       | 16.91 | 0.0   | 0.0        | 0.0  
| 16.91       |
+    Then Loan Repayment schedule has the following data in Total row:
+      | Principal due | Interest | Fees | Penalties | Due    | Paid  | In 
advance | Late | Outstanding |
+      | 100.0         | 1.52     | 0.0  | 0.0       | 101.52 | 34.02 | 0.11    
   | 0.0  | 67.5        |
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
+      | 01 February 2024 | Repayment        | 17.01  | 16.43     | 0.58     | 
0.0  | 0.0       | 83.57        | false    | false    |
+      | 01 March 2024    | Repayment        | 17.01  | 16.63     | 0.38     | 
0.0  | 0.0       | 66.94        | false    | true     |
+    When Loan Pay-off is made on "01 April 2024"
+    Then Loan's all installments have obligations met
+
+  Scenario: Verify Interest rate change - backdated, modification in middle of 
installment, no reverse-replay - UC3
+    When Admin sets the business date to "01 January 2024"
+    When Admin creates a client with random data
+    When Admin set 
"LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE"
 loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future 
installment allocation rule
+    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_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE
 | 01 January 2024   | 100            | 7                      | 
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 2024" with "100" 
amount and expected disbursement date on "01 January 2024"
+    When Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    When Admin runs inline COB job for Loan
+    Then Loan Repayment schedule has 6 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 |
+      |    |      | 01 January 2024  |           | 100.0           |           
    |          | 0.0  |           | 0.0   | 0.0  |            |      |          
   |
+      | 1  | 31   | 01 February 2024 |           | 83.57           | 16.43     
    | 0.58     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 2  | 29   | 01 March 2024    |           | 67.05           | 16.52     
    | 0.49     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 3  | 31   | 01 April 2024    |           | 50.43           | 16.62     
    | 0.39     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 4  | 30   | 01 May 2024      |           | 33.71           | 16.72     
    | 0.29     | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 5  | 31   | 01 June 2024     |           | 16.9            | 16.81     
    | 0.2      | 0.0  | 0.0       | 17.01 | 0.0  | 0.0        | 0.0  | 17.01    
   |
+      | 6  | 30   | 01 July 2024     |           | 0.0             | 16.9      
    | 0.1      | 0.0  | 0.0       | 17.0  | 0.0  | 0.0        | 0.0  | 17.0     
   |
+    Then Loan Repayment schedule has the following data in Total row:
+      | Principal due | Interest | Fees | Penalties | Due    | Paid | In 
advance | Late | Outstanding |
+      | 100.0         | 2.05     | 0.0  | 0.0       | 102.05 | 0.0  | 0.0      
  | 0.0  | 102.05      |
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
+    When Admin sets the business date to "01 April 2024"
+    And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 
EUR transaction amount
+    And Customer makes "AUTOPAY" repayment on "01 March 2024" with 17.01 EUR 
transaction amount
+    When Admin creates and approves Loan reschedule with the following data:
+      | rescheduleFromDate | submittedOnDate  | adjustedDueDate | 
graceOnPrincipal | graceOnInterest | extraTerms | newInterestRate |
+      | 11 March 2024      | 11 March 2024    |                 |              
    |                 |            | 4               |
+    Then Loan Repayment schedule has 6 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 |
+      |    |      | 01 January 2024  |                  | 100.0           |    
           |          | 0.0  |           | 0.0   | 0.0   |            |      |  
           |
+      | 1  | 31   | 01 February 2024 | 01 February 2024 | 83.57           | 
16.43         | 0.58     | 0.0  | 0.0       | 17.01 | 17.01 | 0.0        | 0.0  
| 0.0         |
+      | 2  | 29   | 01 March 2024    | 01 March 2024    | 67.05           | 
16.52         | 0.49     | 0.0  | 0.0       | 17.01 | 17.01 | 0.0        | 0.0  
| 0.0         |
+      | 3  | 31   | 01 April 2024    |                  | 50.41           | 
16.64         | 0.27     | 0.0  | 0.0       | 16.91 | 0.0   | 0.0        | 0.0  
| 16.91       |
+      | 4  | 30   | 01 May 2024      |                  | 33.67           | 
16.74         | 0.17     | 0.0  | 0.0       | 16.91 | 0.0   | 0.0        | 0.0  
| 16.91       |
+      | 5  | 31   | 01 June 2024     |                  | 16.87           | 
16.8          | 0.11     | 0.0  | 0.0       | 16.91 | 0.0   | 0.0        | 0.0  
| 16.91       |
+      | 6  | 30   | 01 July 2024     |                  | 0.0             | 
16.87         | 0.06     | 0.0  | 0.0       | 16.93 | 0.0   | 0.0        | 0.0  
| 16.93       |
+    Then Loan Repayment schedule has the following data in Total row:
+      | Principal due | Interest | Fees | Penalties | Due    | Paid  | In 
advance | Late | Outstanding |
+      | 100.0         | 1.68     | 0.0  | 0.0       | 101.68 | 34.02 | 0.0     
   | 0.0  | 67.66       |
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance | Reverted | Replayed |
+      | 01 January 2024  | Disbursement     | 100.0  | 0.0       | 0.0      | 
0.0  | 0.0       | 100.0        | false    | false    |
+      | 01 February 2024 | Repayment        | 17.01  | 16.43     | 0.58     | 
0.0  | 0.0       | 83.57        | false    | false    |
+      | 01 March 2024    | Repayment        | 17.01  | 16.52     | 0.49     | 
0.0  | 0.0       | 67.05        | false    | false    |
+    When Loan Pay-off is made on "01 April 2024"
+    Then Loan's all installments have obligations met
diff --git 
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/ProgressiveLoanRescheduleRequestDataValidator.java
 
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/ProgressiveLoanRescheduleRequestDataValidator.java
index a110056f96..ad5037b645 100644
--- 
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/ProgressiveLoanRescheduleRequestDataValidator.java
+++ 
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/ProgressiveLoanRescheduleRequestDataValidator.java
@@ -45,7 +45,6 @@ import 
org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
 import 
org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
 import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
-import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
@@ -89,18 +88,8 @@ public class ProgressiveLoanRescheduleRequestDataValidator 
implements LoanResche
                     "Only one operation is supported at a time during Loan 
Rescheduling");
         }
 
-        final LocalDate businessDate = DateUtils.getBusinessLocalDate();
-        if (rescheduleFromDate != null) {
-            if (hasInterestRateChange && 
!rescheduleFromDate.isAfter(businessDate)) {
-                throw new GeneralPlatformDomainRuleException(
-                        
"loan.reschedule.interest.rate.change.reschedule.from.date.should.be.in.future",
-                        String.format("Loan Reschedule From date (%s) for 
Loan: %s should be in the future.", rescheduleFromDate,
-                                loan.getId()),
-                        loan.getId(), rescheduleFromDate);
-            }
-            if (hasInterestRateChange) {
-                validateInterestRateChangeRescheduleFromDate(loan, 
rescheduleFromDate);
-            }
+        if (rescheduleFromDate != null && hasInterestRateChange) {
+            validateInterestRateChangeRescheduleFromDate(loan, 
rescheduleFromDate);
         }
 
         LoanRepaymentScheduleInstallment installment;
@@ -159,13 +148,6 @@ public class ProgressiveLoanRescheduleRequestDataValidator 
implements LoanResche
 
         if 
(loanRescheduleRequest.getInterestRateFromInstallmentTermVariationIfExists() != 
null) {
             installment = 
loan.getRelatedRepaymentScheduleInstallment(rescheduleFromDate);
-            if (!rescheduleFromDate.isAfter(DateUtils.getBusinessLocalDate())) 
{
-                throw new GeneralPlatformDomainRuleException(
-                        
"loan.reschedule.interest.rate.change.reschedule.from.date.should.be.in.future",
-                        String.format("Loan Reschedule From date (%s) for 
Loan: %s should be in the future.", rescheduleFromDate,
-                                loan.getId()),
-                        loan.getId(), rescheduleFromDate);
-            }
         } else {
             installment = 
loan.fetchLoanRepaymentScheduleInstallmentByDueDate(rescheduleFromDate);
         }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
index ebc1cf86c6..e8cf532238 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
@@ -43,6 +43,7 @@ import 
org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import 
org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
 import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
+import 
org.apache.fineract.infrastructure.event.business.domain.loan.LoanBalanceChangedBusinessEvent;
 import 
org.apache.fineract.infrastructure.event.business.domain.loan.LoanRescheduledDueAdjustScheduleBusinessEvent;
 import 
org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
 import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
@@ -402,9 +403,15 @@ public class LoanRescheduleRequestWritePlatformServiceImpl 
implements LoanResche
             if (rescheduleFromDate == null) {
                 rescheduleFromDate = 
loanRescheduleRequest.getRescheduleFromDate();
             }
+
+            boolean hasInterestRateChange = false;
             for (LoanRescheduleRequestToTermVariationMapping mapping : 
loanRescheduleRequest
                     .getLoanRescheduleRequestToTermVariationMappings()) {
                 mapping.getLoanTermVariations().updateIsActive(true);
+                LoanTermVariationType termType = 
mapping.getLoanTermVariations().getTermType();
+                if (termType.isInterestRateVariation() || 
termType.isInterestRateFromInstallment()) {
+                    hasInterestRateChange = true;
+                }
             }
             BigDecimal annualNominalInterestRate = null;
             List<LoanTermVariationsData> loanTermVariations = new 
ArrayList<>();
@@ -457,6 +464,9 @@ public class LoanRescheduleRequestWritePlatformServiceImpl 
implements LoanResche
 
             postJournalEntries(loan, existingTransactionIds, 
existingReversedTransactionIds);
             
loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan,
 existingTransactionIds);
+            if (hasInterestRateChange) {
+                businessEventNotifierService.notifyPostBusinessEvent(new 
LoanBalanceChangedBusinessEvent(loan));
+            }
 
             return new 
CommandProcessingResultBuilder().withCommandId(jsonCommand.commandId()).withEntityId(loanRescheduleRequestId)
                     
.withLoanId(loanRescheduleRequest.getLoan().getId()).with(changes).withClientId(loan.getClientId())
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
index ac3b3c306c..93da039e9c 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
@@ -286,14 +286,6 @@ public class LoanRescheduleRequestTest extends 
BaseLoanIntegrationTest {
                     new PostLoansLoanIdRequest().actualDisbursementDate("15 
February 2023").dateFormat(DATETIME_PATTERN)
                             
.transactionAmount(BigDecimal.valueOf(500.00)).locale("en"));
 
-            exception = assertThrows(CallFailedRuntimeException.class,
-                    () -> loanRescheduleRequestHelper
-                            .createLoanRescheduleRequest(new 
PostCreateRescheduleLoansRequest().loanId(loanResponse.get().getLoanId())
-                                    
.dateFormat(DATETIME_PATTERN).locale("en").submittedOnDate("15 February 2023")
-                                    
.newInterestRate(BigDecimal.ONE).rescheduleReasonId(1L).rescheduleFromDate("15 
February 2023")));
-            assertEquals(403, exception.getResponse().code());
-            
assertTrue(exception.getMessage().contains("loan.reschedule.interest.rate.change.reschedule.from.date.should.be.in.future"));
-
             
rescheduleResponse.set(loanRescheduleRequestHelper.createLoanRescheduleRequest(new
 PostCreateRescheduleLoansRequest()
                     
.loanId(loanResponse.get().getLoanId()).dateFormat(DATETIME_PATTERN).locale("en").submittedOnDate("15
 February 2023")
                     
.newInterestRate(BigDecimal.ONE).rescheduleReasonId(1L).rescheduleFromDate("16 
February 2023")));
@@ -310,13 +302,6 @@ public class LoanRescheduleRequestTest extends 
BaseLoanIntegrationTest {
         // Do not allow create interest rate change if a previous interest 
rate change got already approved for that
         // date
         runAt("16 February 2023", () -> {
-            CallFailedRuntimeException exception = 
assertThrows(CallFailedRuntimeException.class,
-                    () -> 
loanRescheduleRequestHelper.approveLoanRescheduleRequest(rescheduleResponse.get().getResourceId(),
-                            new 
PostUpdateRescheduleLoansRequest().approvedOnDate("16 February 
2024").locale("en")
-                                    .dateFormat(DATETIME_PATTERN)));
-            assertEquals(403, exception.getResponse().code());
-            
assertTrue(exception.getMessage().contains("loan.reschedule.interest.rate.change.reschedule.from.date.should.be.in.future"));
-
             PostCreateRescheduleLoansResponse rescheduleLoansResponse = 
loanRescheduleRequestHelper
                     .createLoanRescheduleRequest(new 
PostCreateRescheduleLoansRequest().loanId(loanResponse.get().getLoanId())
                             
.dateFormat(DATETIME_PATTERN).locale("en").submittedOnDate("17 February 
2023").newInterestRate(BigDecimal.ONE)
@@ -325,7 +310,7 @@ public class LoanRescheduleRequestTest extends 
BaseLoanIntegrationTest {
             
loanRescheduleRequestHelper.approveLoanRescheduleRequest(rescheduleLoansResponse.getResourceId(),
                     new PostUpdateRescheduleLoansRequest().approvedOnDate("17 
February 2024").locale("en").dateFormat(DATETIME_PATTERN));
 
-            exception = assertThrows(CallFailedRuntimeException.class,
+            CallFailedRuntimeException exception = 
assertThrows(CallFailedRuntimeException.class,
                     () -> loanRescheduleRequestHelper
                             .createLoanRescheduleRequest(new 
PostCreateRescheduleLoansRequest().loanId(rescheduleLoansResponse.getLoanId())
                                     
.dateFormat(DATETIME_PATTERN).locale("en").submittedOnDate("17 February 2023")


Reply via email to