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 c3ed5caab23fa6dd14be2cd102791da63b133334
Author: Adam Saghy <[email protected]>
AuthorDate: Wed Dec 10 16:14:41 2025 +0100

    FINERACT-2389: EMI rounding handling
---
 .../test/factory/LoanProductsRequestFactory.java         |  8 ++++----
 .../loanproduct/calc/ProgressiveEMICalculator.java       | 16 ++++++++++++++--
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java
index e976039474..bc7e295b60 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java
@@ -823,7 +823,7 @@ public class LoanProductsRequestFactory {
                 .inMultiplesOf(0)//
                 .installmentAmountInMultiplesOf(1)//
                 .useBorrowerCycle(false)//
-                .minPrincipal(100.0)//
+                .minPrincipal(1.0)//
                 .principal(1000.0)//
                 .maxPrincipal(10000.0)//
                 .minNumberOfRepayments(1)//
@@ -1046,7 +1046,7 @@ public class LoanProductsRequestFactory {
                 .digitsAfterDecimal(2)//
                 .inMultiplesOf(0)//
                 .useBorrowerCycle(false)//
-                .minPrincipal(10.0)//
+                .minPrincipal(1.0)//
                 .principal(1000.0)//
                 .maxPrincipal(10000.0)//
                 .minNumberOfRepayments(1)//
@@ -1295,7 +1295,7 @@ public class LoanProductsRequestFactory {
                 .inMultiplesOf(0)//
                 .installmentAmountInMultiplesOf(1)//
                 .useBorrowerCycle(false)//
-                .minPrincipal(100.0)//
+                .minPrincipal(1.0)//
                 .principal(1000.0)//
                 .maxPrincipal(10000.0)//
                 .minNumberOfRepayments(1)//
@@ -1534,7 +1534,7 @@ public class LoanProductsRequestFactory {
                 .inMultiplesOf(0)//
                 .installmentAmountInMultiplesOf(1)//
                 .useBorrowerCycle(false)//
-                .minPrincipal(100.0)//
+                .minPrincipal(1.0)//
                 .principal(1000.0)//
                 .maxPrincipal(10000.0)//
                 .minNumberOfRepayments(1)//
diff --git 
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java
 
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java
index 581198918a..21b68310c2 100644
--- 
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java
+++ 
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java
@@ -1398,11 +1398,23 @@ public final class ProgressiveEMICalculator implements 
EMICalculator {
 
     private Money applyInstallmentAmountInMultiplesOf(final 
ProgressiveLoanInterestScheduleModel scheduleModel,
             final Money equalMonthlyInstallment) {
-        return scheduleModel.installmentAmountInMultiplesOf() != null
-                ? Money.roundToMultiplesOf(equalMonthlyInstallment, 
scheduleModel.installmentAmountInMultiplesOf())
+        return scheduleModel.installmentAmountInMultiplesOf() != null && 
scheduleModel.installmentAmountInMultiplesOf() > 0
+                ? safeRoundingForEMI(equalMonthlyInstallment, 
scheduleModel.installmentAmountInMultiplesOf())
                 : equalMonthlyInstallment;
     }
 
+    /**
+     * Rounds the EMI to the nearest multiple of the given number. If the 
rounded EMI is zero, it adds one multiple of
+     * the given number to it.
+     */
+    private Money safeRoundingForEMI(Money unRoundedEMI, Integer multiplesOf) {
+        Money roundedEMI = Money.roundToMultiplesOf(unRoundedEMI, multiplesOf);
+        if (roundedEMI.isZero()) {
+            roundedEMI = 
roundedEMI.add(BigDecimal.ONE.multiply(BigDecimal.valueOf(multiplesOf)));
+        }
+        return roundedEMI;
+    }
+
     public EmiAdjustment getEmiAdjustment(final List<RepaymentPeriod> 
repaymentPeriods) {
         for (int idx = repaymentPeriods.size() - 1; idx > 0; --idx) {
             RepaymentPeriod lastPeriod = repaymentPeriods.get(idx);

Reply via email to