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


The following commit(s) were added to refs/heads/develop by this push:
     new 3687391148 FINERACT-2221: Add immediate charge accrual post maturity 
for progressive loans
3687391148 is described below

commit 36873911485e6f6dad0d7565d89d20527e886989
Author: Oleksii Novikov <[email protected]>
AuthorDate: Mon Apr 21 14:04:52 2025 +0300

    FINERACT-2221: Add immediate charge accrual post maturity for progressive 
loans
---
 .../src/test/resources/features/LoanCharge.feature | 50 ++++++++++++++++++++--
 .../portfolio/loanaccount/domain/Loan.java         |  5 +++
 .../LoanChargeWritePlatformServiceImpl.java        | 10 +++--
 .../LoanChargeWritePlatformServiceImplTest.java    |  1 +
 .../LoanChargeProgressiveTest.java                 |  2 +-
 5 files changed, 61 insertions(+), 7 deletions(-)

diff --git 
a/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature
index 9e33a7a89d..2886bb482d 100644
--- a/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature
+++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature
@@ -2292,8 +2292,9 @@ Feature: LoanCharge
     Then Loan Transactions tab has the following data:
       | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance |
       | 01 January 2024  | Disbursement     | 1000.0 | 0.0       | 0.0      | 
0.0  | 0.0       | 1000.0       |
+      | 05 February 2024 | Accrual          | 25.0   | 0.0       | 0.0      | 
0.0  | 25.0      | 0.0          |
     Given Global configuration "enable-immediate-charge-accrual-post-maturity" 
is disabled
-    Then LoanAccrualTransactionCreatedBusinessEvent is not raised on "05 
February 2024"
+    Then LoanAccrualTransactionCreatedBusinessEvent is raised on "05 February 
2024"
 
   @TestRailId:C3320
   Scenario: Verify enhance the existing implementation to create accruals as 
part of Charge Creation post maturity with immediate charge accrual and zero 
interest rate
@@ -2331,8 +2332,9 @@ Feature: LoanCharge
     Then Loan Transactions tab has the following data:
       | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance |
       | 01 January 2024  | Disbursement     | 1000.0 | 0.0       | 0.0      | 
0.0  | 0.0       | 1000.0       |
+      | 05 February 2024 | Accrual          | 25.0   | 0.0       | 0.0      | 
0.0  | 25.0      | 0.0          |
     Given Global configuration "enable-immediate-charge-accrual-post-maturity" 
is disabled
-    Then LoanAccrualTransactionCreatedBusinessEvent is not raised on "05 
February 2024"
+    Then LoanAccrualTransactionCreatedBusinessEvent is raised on "05 February 
2024"
 
   @TestRailId:ะก3335
   Scenario: Verify enhance the existing implementation to create accruals as 
part of Charge Creation post maturity with inline COB run and non-zero interest 
rate
@@ -2454,7 +2456,8 @@ Feature: LoanCharge
     Then Loan Transactions tab has the following data:
       | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance |
       | 01 January 2024  | Disbursement     | 1000.0 | 0.0       | 0.0      | 
0.0  | 0.0       | 1000.0       |
-      | 05 February 2024 | Accrual          | 30.83  | 0.0       | 5.83     | 
0.0  | 25.0      | 0.0          |
+      | 05 February 2024 | Accrual          | 25.0   | 0.0       | 0.0      | 
0.0  | 25.0      | 0.0          |
+      | 05 February 2024 | Accrual          | 5.83   | 0.0       | 5.83     | 
0.0  | 0.0       | 0.0          |
     Given Global configuration "enable-immediate-charge-accrual-post-maturity" 
is disabled
     Then LoanAccrualTransactionCreatedBusinessEvent is raised on "05 February 
2024"
 
@@ -4750,3 +4753,44 @@ Feature: LoanCharge
       | 01 January 2024  | Repayment (at time of disbursement) | 1.0    | 0.0  
     | 0.0      | 1.0  | 0.0       | 100.0        | false    | false    |
       | 01 February 2024 | Repayment                           | 17.01  | 
16.43     | 0.58     | 0.0  | 0.0       | 83.57        | true     | false    |
       | 01 March 2024    | Repayment                           | 17.01  | 
16.43     | 0.58     | 0.0  | 0.0       | 83.57        | false    | true     |
+
+  @TestRailId:C3613
+  Scenario: Verify immediate charge accrual post maturity for Progressive loans
+    Given Global configuration "enable-immediate-charge-accrual-post-maturity" 
is enabled
+    When Admin sets the business date to "25 February 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 | 25 February 2025  | 
1000           | 0                      | DECLINING_BALANCE | DAILY             
          | EQUAL_INSTALLMENTS | 1                 | MONTHS                | 1  
            | MONTHS                 | 1                  | 0                   
    | 0                      | 0                    | 
ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "25 February 2025" with "1000" 
amount and expected disbursement date on "25 February 2025"
+    When Admin successfully disburse the loan on "25 February 2025" with 
"1000" EUR transaction amount
+    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 |
+      |    |      | 25 February 2025 |           | 1000.0          |           
    |          | 0.0  |           | 0.0    | 0.0  |            |      |         
    |
+      | 1  | 28   | 25 March 2025    |           | 0.0             | 1000.0    
    | 0.0      | 0.0  | 0.0       | 1000.0 | 0.0  | 0.0        | 0.0  | 1000.0  
    |
+    Then Loan Repayment schedule has the following data in Total row:
+      | Principal due | Interest | Fees | Penalties | Due    | Paid | In 
advance | Late | Outstanding |
+      | 1000.0        | 0.0      | 0.0  | 0.0       | 1000.0 | 0.0  | 0.0      
  | 0.0  | 1000.0      |
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance |
+      | 25 February 2025 | Disbursement     | 1000.0 | 0.0       | 0.0      | 
0.0  | 0.0       | 1000.0       |
+    When Admin sets the business date to "28 March 2025"
+    And Admin runs inline COB job for Loan
+    When Admin adds "LOAN_SNOOZE_FEE" due date charge with "28 March 2025" due 
date and 25 EUR transaction amount
+    Then Loan Charges tab has the following data:
+      | Name       | isPenalty | Payment due at     | Due as of     | 
Calculation type | Due  | Paid | Waived | Outstanding |
+      | Snooze fee | false     | Specified due date | 28 March 2025 | Flat     
        | 25.0 | 0.0  | 0.0    | 25.0        |
+    Then Loan Repayment schedule has 2 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 |
+      |    |      | 25 February 2025 |           | 1000.0          |           
    |          | 0.0  |           | 0.0    | 0.0  |            |      |         
    |
+      | 1  | 28   | 25 March 2025    |           | 0.0             | 1000.0    
    | 0.0      | 0.0  | 0.0       | 1000.0 | 0.0  | 0.0        | 0.0  | 1000.0  
    |
+      | 2  | 3    | 28 March 2025    |           | 0.0             | 0.0       
    | 0.0      | 25.0 | 0.0       | 25.0   | 0.0  | 0.0        | 0.0  | 25.0    
    |
+    Then Loan Repayment schedule has the following data in Total row:
+      | Principal due | Interest | Fees | Penalties | Due    | Paid | In 
advance | Late | Outstanding |
+      | 1000.0        | 0.0      | 25.0 | 0.0       | 1025.0 | 0.0  | 0.0      
  | 0.0  | 1025.0      |
+    Then Loan Transactions tab has the following data:
+      | Transaction date | Transaction Type | Amount | Principal | Interest | 
Fees | Penalties | Loan Balance |
+      | 25 February 2025 | Disbursement     | 1000.0 | 0.0       | 0.0      | 
0.0  | 0.0       | 1000.0       |
+      | 28 March 2025    | Accrual          | 25.0   | 0.0       | 0.0      | 
25.0 | 0.0       | 0.0          |
+    Then LoanAccrualTransactionCreatedBusinessEvent is raised on "28 March 
2025"
+    Given Global configuration "enable-immediate-charge-accrual-post-maturity" 
is disabled
\ No newline at end of file
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index 5f970c3b8b..fe77571ca0 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -644,6 +644,11 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom<Long> {
         if (isProgressiveSchedule()) {
             return null;
         }
+
+        return createChargeAppliedTransaction(loanCharge, 
suppliedTransactionDate);
+    }
+
+    public LoanTransaction createChargeAppliedTransaction(final LoanCharge 
loanCharge, final LocalDate suppliedTransactionDate) {
         final Money chargeAmount = loanCharge.getAmount(getCurrency());
         Money feeCharges = chargeAmount;
         Money penaltyCharges = Money.zero(getCurrency());
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java
index 03c39763f0..c47752d877 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java
@@ -1114,16 +1114,20 @@ public class LoanChargeWritePlatformServiceImpl 
implements LoanChargeWritePlatfo
         // we want to apply charge transactions only for those loans charges 
that are applied when a loan is active and
         // the loan product uses Upfront Accruals, or only when the loan are 
closed too,
         if ((loan.getStatus().isActive() && 
loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct())
-                || loan.getStatus().isOverpaid() || 
loan.getStatus().isClosedObligationsMet()
-                || 
(configurationDomainService.isImmediateChargeAccrualPostMaturityEnabled()
-                        && 
DateUtils.getBusinessLocalDate().isAfter(loan.getMaturityDate()))) {
+                || loan.getStatus().isOverpaid() || 
loan.getStatus().isClosedObligationsMet()) {
             final LoanTransaction applyLoanChargeTransaction = 
loan.handleChargeAppliedTransaction(loanCharge, null);
             if (applyLoanChargeTransaction != null) {
                 
this.loanTransactionRepository.saveAndFlush(applyLoanChargeTransaction);
                 businessEventNotifierService
                         .notifyPostBusinessEvent(new 
LoanAccrualTransactionCreatedBusinessEvent(applyLoanChargeTransaction));
             }
+        } else if 
(configurationDomainService.isImmediateChargeAccrualPostMaturityEnabled()
+                && 
DateUtils.getBusinessLocalDate().isAfter(loan.getMaturityDate())) {
+            final LoanTransaction loanTransaction = 
loan.createChargeAppliedTransaction(loanCharge, null);
+            this.loanTransactionRepository.saveAndFlush(loanTransaction);
+            businessEventNotifierService.notifyPostBusinessEvent(new 
LoanAccrualTransactionCreatedBusinessEvent(loanTransaction));
         }
+
         return DateUtils.isBeforeBusinessDate(loanCharge.getDueLocalDate());
     }
 
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImplTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImplTest.java
index 8b3309da17..f53cabc10f 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImplTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImplTest.java
@@ -220,6 +220,7 @@ class LoanChargeWritePlatformServiceImplTest {
         
when(configurationDomainService.isImmediateChargeAccrualPostMaturityEnabled()).thenReturn(isAccrualEnabled);
         when(loan.getMaturityDate()).thenReturn(maturityDate);
         when(loan.handleChargeAppliedTransaction(loanCharge, 
null)).thenReturn(loanTransaction);
+        when(loan.createChargeAppliedTransaction(loanCharge, 
null)).thenReturn(loanTransaction);
 
         if (isAccrualExpected) {
             
when(loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()).thenReturn(true);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeProgressiveTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeProgressiveTest.java
index a217e704b9..f84fdbcf30 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeProgressiveTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeProgressiveTest.java
@@ -79,7 +79,7 @@ public class LoanChargeProgressiveTest extends 
BaseLoanIntegrationTest {
             addLoanCharge(loanId, chargeResponse.getResourceId(), "03 October 
2024", 20.0d);
             final GetLoansLoanIdResponse loanDetails = 
loanTransactionHelper.getLoanDetails(loanId);
             Assertions.assertTrue(
-                    loanDetails.getTransactions().stream().noneMatch(t -> 
t.getType().getAccrual() && t.getAmount().equals(20.0d)));
+                    loanDetails.getTransactions().stream().anyMatch(t -> 
t.getType().getAccrual() && t.getAmount().equals(20.0d)));
         });
         runAt("04 October 2024", () -> {
             
globalConfigurationHelper.manageConfigurations(GlobalConfigurationConstants.ENABLE_IMMEDIATE_CHARGE_ACCRUAL_POST_MATURITY,

Reply via email to