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 2ee19f9825894a66ce5b98bb8fa134a790c5b62f
Author: Soma Sörös <[email protected]>
AuthorDate: Wed Jan 28 15:48:43 2026 +0100

    FINERACT-2413: Allow multiple Re-amortization on a loan account
---
 .../reamortization/LoanReAmortizationService.java  |  2 +-
 .../LoanReAmortizationValidator.java               | 33 ++++++++++++++++++----
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationService.java
index 1311e0deb1..73ad6bfd11 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationService.java
@@ -150,7 +150,7 @@ public class LoanReAmortizationService {
     }
 
     private LoanScheduleData previewReAmortization(final Loan loan, final 
ReAmortizationPreviewRequest reAmortizationPreviewRequest) {
-        reAmortizationValidator.validateReAmortize(loan);
+        reAmortizationValidator.validateReAmortize(loan, 
reAmortizationPreviewRequest);
 
         final LoanTransaction reAmortizeTransaction = 
createReAmortizeTransactionFromPreviewRequest(loan, 
reAmortizationPreviewRequest);
         processReAmortizationTransaction(loan, reAmortizeTransaction, false);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationValidator.java
index 5faeed9141..b535721e6d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationValidator.java
@@ -34,9 +34,11 @@ import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
 import 
org.apache.fineract.portfolio.loanaccount.api.LoanReAmortizationApiConstants;
+import 
org.apache.fineract.portfolio.loanaccount.api.request.ReAmortizationPreviewRequest;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
 import 
org.apache.fineract.portfolio.loanaccount.domain.reamortization.LoanReAmortizationInterestHandlingType;
+import 
org.apache.fineract.portfolio.loanaccount.domain.reamortization.LoanReAmortizationParameter;
 import 
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
 import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.springframework.stereotype.Component;
@@ -49,11 +51,9 @@ public class LoanReAmortizationValidator {
 
     public void validateReAmortize(Loan loan, JsonCommand command) {
         validateReAmortizeRequest(command);
-        validateReAmortizeBusinessRules(loan);
-    }
-
-    public void validateReAmortize(final Loan loan) {
-        validateReAmortizeBusinessRules(loan);
+        LoanReAmortizationInterestHandlingType interestHandlingType = 
command.enumValueOfParameterNamed(
+                
LoanReAmortizationApiConstants.reAmortizationInterestHandlingParamName, 
LoanReAmortizationInterestHandlingType.class);
+        validateReAmortizeBusinessRules(loan, interestHandlingType);
     }
 
     private void validateReAmortizeRequest(JsonCommand command) {
@@ -84,7 +84,7 @@ public class LoanReAmortizationValidator {
         throwExceptionIfValidationErrorsExist(dataValidationErrors);
     }
 
-    private void validateReAmortizeBusinessRules(Loan loan) {
+    private void validateReAmortizeBusinessRules(Loan loan, 
LoanReAmortizationInterestHandlingType interestHandlingType) {
         // validate reamortization shouldn't happen after maturity
         if (DateUtils.isAfter(getBusinessLocalDate(), loan.getMaturityDate())) 
{
             throw new 
GeneralPlatformDomainRuleException("error.msg.loan.reamortize.cannot.be.submitted.after.maturity",
@@ -120,6 +120,22 @@ public class LoanReAmortizationValidator {
                     loan.getId());
         }
 
+        // validate if there is active re-amortization transaction, it should 
have the same interest handling strategy
+        Optional<LoanTransaction> previousReAmortizationTransaction = 
loan.getLoanTransactions().stream()
+                
.filter(LoanTransaction::isNotReversed).filter(LoanTransaction::isReAmortize).findAny();
+        if (previousReAmortizationTransaction.isPresent()) {
+            LoanReAmortizationInterestHandlingType 
previousInterestHandlingType = Optional
+                    
.ofNullable(previousReAmortizationTransaction.get().getLoanReAmortizationParameter())
+                    
.map(LoanReAmortizationParameter::getInterestHandlingType).orElse(LoanReAmortizationInterestHandlingType.DEFAULT);
+            LoanReAmortizationInterestHandlingType currentInterestHandlingType 
= Optional.ofNullable(interestHandlingType)
+                    .orElse(LoanReAmortizationInterestHandlingType.DEFAULT);
+            if 
(!previousInterestHandlingType.equals(currentInterestHandlingType)) {
+                throw new GeneralPlatformDomainRuleException(
+                        
"error.msg.loan.reamortize.reamortize.transaction.interest.handling.strategy.missmatch",
+                        "Previous active reamortization transactiuon has 
different interest handling strategy.", loan.getId());
+            }
+        }
+
         // validate loan is not charged-off
         if (loan.isChargedOff()) {
             throw new 
GeneralPlatformDomainRuleException("error.msg.loan.reamortize.not.allowed.on.charged.off",
@@ -163,4 +179,9 @@ public class LoanReAmortizationValidator {
         }
     }
 
+    public void validateReAmortize(Loan loan, ReAmortizationPreviewRequest 
reAmortizationPreviewRequest) {
+        LoanReAmortizationInterestHandlingType interestHandlingType = 
LoanReAmortizationInterestHandlingType
+                
.valueOf(reAmortizationPreviewRequest.getReAmortizationInterestHandling());
+        validateReAmortizeBusinessRules(loan, interestHandlingType);
+    }
 }

Reply via email to