You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2022/09/22 08:58:31 UTC

[fineract] branch develop updated: Fix loan repayment schedule with multidisburse

This is an automated email from the ASF dual-hosted git repository.

arnold 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 1521b9dcf Fix loan repayment schedule with multidisburse
1521b9dcf is described below

commit 1521b9dcf64c67be48389be6556b7f080e54f5c8
Author: Jose Alberto Hernandez <al...@MacBook-Pro.local>
AuthorDate: Thu Aug 18 19:38:47 2022 -0500

    Fix loan repayment schedule with multidisburse
---
 .../portfolio/calendar/service/CalendarUtils.java  |   1 -
 .../portfolio/loanaccount/domain/Loan.java         |  30 ++-
 .../domain/AbstractLoanScheduleGenerator.java      |  10 +-
 .../domain/DefaultScheduledDateGenerator.java      |  23 +-
 .../loanschedule/domain/LoanApplicationTerms.java  | 126 +---------
 .../LoanWritePlatformServiceJpaRepositoryImpl.java |  12 +-
 .../ClientLoanIntegrationTest.java                 |   8 +-
 .../DelinquencyBucketsIntegrationTest.java         |   6 +-
 .../LoanAuditingIntegrationTest.java               |   2 +-
 .../LoanDisbursementDetailsIntegrationTest.java    | 276 +++++++++++----------
 .../LoanRepaymentRescheduleAtDisbursementTest.java |   2 +-
 .../LoanRescheduleWithAdvancePaymentTest.java      |   4 +-
 .../LoanReschedulingWithinCenterTest.java          |   2 +-
 .../LoanTransactionAuditingIntegrationTest.java    |   2 +-
 .../common/loans/LoanApplicationTestBuilder.java   |   2 +-
 .../common/loans/LoanProductTestBuilder.java       |   7 +
 .../common/loans/LoanTransactionHelper.java        |  14 ++
 17 files changed, 237 insertions(+), 290 deletions(-)

diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarUtils.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarUtils.java
index 16cd36a8d..d5332238a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarUtils.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarUtils.java
@@ -373,7 +373,6 @@ public final class CalendarUtils {
     }
 
     public static boolean isValidRedurringDate(final String recurringRule, final LocalDate seedDate, final LocalDate date) {
-
         final Recur recur = CalendarUtils.getICalRecur(recurringRule);
         if (recur == null) {
             return false;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index 3acf93cc1..105fdbfe9 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -59,6 +59,7 @@ import javax.persistence.Table;
 import javax.persistence.Transient;
 import javax.persistence.UniqueConstraint;
 import javax.persistence.Version;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.infrastructure.codes.domain.CodeValue;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
@@ -142,6 +143,7 @@ import org.apache.fineract.portfolio.repaymentwithpostdatedchecks.domain.PostDat
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.springframework.stereotype.Component;
 
+@Slf4j
 @Entity
 @Component
 @Table(name = "m_loan", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "loan_account_no_UNIQUE"),
@@ -5112,15 +5114,8 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
         actualChanges.put(LoanApiConstants.disbursementPrincipalParameterName,
                 command.bigDecimalValueOfParameterNamed(LoanApiConstants.disbursementPrincipalParameterName, locale));
 
-        Collection<LoanDisbursementDetails> loanDisburseDetails = this.getDisbursementDetails();
-        BigDecimal setPrincipalAmount = BigDecimal.ZERO;
-        for (LoanDisbursementDetails details : loanDisburseDetails) {
-            if (details.actualDisbursementDate() != null) {
-                setPrincipalAmount = setPrincipalAmount.add(details.principal());
-            }
-        }
+        this.loanRepaymentScheduleDetail.setPrincipal(getPrincipalAmountForRepaymentSchedule());
 
-        this.loanRepaymentScheduleDetail.setPrincipal(setPrincipalAmount);
         if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
             regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
         } else {
@@ -5141,6 +5136,25 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
         return changedTransactionDetail;
     }
 
+    public BigDecimal getPrincipalAmountForRepaymentSchedule() {
+        BigDecimal principalAmount = BigDecimal.ZERO;
+
+        if (isMultiDisburmentLoan() && isDisbursed()) {
+            Collection<LoanDisbursementDetails> loanDisburseDetails = this.getDisbursementDetails();
+            for (LoanDisbursementDetails details : loanDisburseDetails) {
+                if (details.actualDisbursementDate() != null) {
+                    principalAmount = principalAmount.add(details.principal());
+                }
+            }
+        } else if (isApproved()) {
+            principalAmount = getApprovedPrincipal();
+        } else {
+            principalAmount = getPrincipal().getAmount();
+        }
+
+        return principalAmount;
+    }
+
     public BigDecimal retriveLastEmiAmount() {
         BigDecimal emiAmount = this.fixedEmiAmount;
         LocalDate startDate = this.getDisbursementDate();
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
index 3a695c326..1bb5793e7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
@@ -1259,8 +1259,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
      */
     private Money getPrincipalToBeScheduled(final LoanApplicationTerms loanApplicationTerms) {
         Money principalToBeScheduled;
-        if (loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) {
-            principalToBeScheduled = loanApplicationTerms.getApprovedPrincipal();
+        if (loanApplicationTerms.isMultiDisburseLoan()) {
+            if (loanApplicationTerms.getTotalDisbursedAmount().isGreaterThanZero()) {
+                principalToBeScheduled = loanApplicationTerms.getTotalMultiDisbursedAmount();
+            } else if (loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) {
+                principalToBeScheduled = loanApplicationTerms.getApprovedPrincipal();
+            } else {
+                principalToBeScheduled = loanApplicationTerms.getPrincipal();
+            }
         } else {
             principalToBeScheduled = loanApplicationTerms.getPrincipal();
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java
index 154856a4c..b4abfea6d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java
@@ -20,9 +20,11 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
 
 import java.time.LocalDate;
 import java.time.temporal.ChronoUnit;
+import net.fortuna.ical4j.model.Recur;
 import org.apache.fineract.organisation.holiday.domain.Holiday;
 import org.apache.fineract.organisation.holiday.service.HolidayUtil;
 import org.apache.fineract.organisation.workingdays.data.AdjustedDateDetailsDTO;
+import org.apache.fineract.organisation.workingdays.domain.RepaymentRescheduleType;
 import org.apache.fineract.organisation.workingdays.service.WorkingDaysUtil;
 import org.apache.fineract.portfolio.calendar.data.CalendarHistoryDataWrapper;
 import org.apache.fineract.portfolio.calendar.domain.Calendar;
@@ -131,10 +133,14 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
     private AdjustedDateDetailsDTO recursivelyCheckNonWorkingDaysAndHolidaysAndWorkingDaysExemptionToGenerateNextRepaymentPeriodDate(
             final AdjustedDateDetailsDTO adjustedDateDetailsDTO, final LoanApplicationTerms loanApplicationTerms,
             final HolidayDetailDTO holidayDetailDTO, final boolean isFirstRepayment) {
-
-        checkAndUpdateWorkingDayIfRepaymentDateIsNonWorkingDay(adjustedDateDetailsDTO, holidayDetailDTO, loanApplicationTerms,
-                isFirstRepayment);
-
+        final Recur recur = CalendarUtils.getICalRecur(holidayDetailDTO.getWorkingDays().getRecurrence());
+        final boolean isSevenDaysWeek = (recur.getDayList().size() == 7); // 7 Seven days in the week
+        // If Workings days are not seven day week
+        if (!isSevenDaysWeek) {
+            checkAndUpdateWorkingDayIfRepaymentDateIsNonWorkingDay(adjustedDateDetailsDTO, holidayDetailDTO, loanApplicationTerms,
+                    isFirstRepayment);
+        }
+        // Check Holidays If applied
         checkAndUpdateWorkingDayIfRepaymentDateIsHolidayDay(adjustedDateDetailsDTO, holidayDetailDTO, loanApplicationTerms,
                 isFirstRepayment);
 
@@ -148,6 +154,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
             recursivelyCheckNonWorkingDaysAndHolidaysAndWorkingDaysExemptionToGenerateNextRepaymentPeriodDate(adjustedDateDetailsDTO,
                     loanApplicationTerms, holidayDetailDTO, isFirstRepayment);
         }
+
         return adjustedDateDetailsDTO;
     }
 
@@ -192,10 +199,12 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
      */
     private void checkAndUpdateWorkingDayIfRepaymentDateIsNonWorkingDay(final AdjustedDateDetailsDTO adjustedDateDetailsDTO,
             final HolidayDetailDTO holidayDetailDTO, final LoanApplicationTerms loanApplicationTerms, final boolean isFirstRepayment) {
+
         while (WorkingDaysUtil.isNonWorkingDay(holidayDetailDTO.getWorkingDays(), adjustedDateDetailsDTO.getChangedScheduleDate())) {
-            if (WorkingDaysUtil
-                    .getRepaymentRescheduleType(holidayDetailDTO.getWorkingDays(), adjustedDateDetailsDTO.getChangedScheduleDate())
-                    .isMoveToNextRepaymentDay()) {
+            final RepaymentRescheduleType repaymentRescheduleType = WorkingDaysUtil
+                    .getRepaymentRescheduleType(holidayDetailDTO.getWorkingDays(), adjustedDateDetailsDTO.getChangedScheduleDate());
+
+            if (repaymentRescheduleType.isMoveToNextRepaymentDay()) {
                 while (WorkingDaysUtil.isNonWorkingDay(holidayDetailDTO.getWorkingDays(),
                         adjustedDateDetailsDTO.getNextRepaymentPeriodDueDate())
                         || adjustedDateDetailsDTO.getChangedScheduleDate()
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java
index f0bb45fc2..bfa24b54d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java
@@ -43,7 +43,6 @@ import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
 import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsDataWrapper;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalculationDetails;
 import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
 import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
 import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
@@ -252,32 +251,6 @@ public final class LoanApplicationTerms {
 
     }
 
-    public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
-            final PeriodFrequencyType loanTermPeriodFrequencyType, NthDayType nthDay, DayOfWeekType dayOfWeek,
-            final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
-            final LocalDate calculatedRepaymentsStartingFromDate, final Money inArrearsTolerance,
-            final LoanProductRelatedDetail loanProductRelatedDetail, final boolean multiDisburseLoan, final BigDecimal emiAmount,
-            final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance, final LocalDate interestChargedFromDate,
-            final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
-            final RecalculationFrequencyType recalculationFrequencyType, final CalendarInstance restCalendarInstance,
-            final InterestRecalculationCompoundingMethod compoundingMethod, final CalendarInstance compoundingCalendarInstance,
-            final RecalculationFrequencyType compoundingFrequencyType,
-            final LoanPreClosureInterestCalculationStrategy loanPreClosureInterestCalculationStrategy,
-            final LoanRescheduleStrategyMethod rescheduleStrategyMethod, BigDecimal approvedAmount, BigDecimal annualNominalInterestRate,
-            List<LoanTermVariationsData> loanTermVariations, final Integer numberOfDays, final boolean isSkipRepaymentOnFirstDayOfMonth,
-            final Calendar loanCalendar, final HolidayDetailDTO holidayDetailDTO, final boolean allowCompoundingOnEod) {
-        final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
-
-        return assembleFrom(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, nthDay, dayOfWeek,
-                expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, inArrearsTolerance,
-                loanProductRelatedDetail, multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance, interestChargedFromDate,
-                principalThresholdForLastInstalment, installmentAmountInMultiplesOf, recalculationFrequencyType, restCalendarInstance,
-                compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType, loanPreClosureInterestCalculationStrategy,
-                rescheduleStrategyMethod, loanCalendar, approvedAmount, annualNominalInterestRate, loanTermVariations,
-                calendarHistoryDataWrapper, numberOfDays, isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, false,
-                false, null, false);
-    }
-
     public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
             final PeriodFrequencyType loanTermPeriodFrequencyType, NthDayType nthDay, DayOfWeekType dayOfWeek,
             final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
@@ -337,93 +310,6 @@ public final class LoanApplicationTerms {
                 isPrincipalCompoundingDisabledForOverdueLoans);
     }
 
-    public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
-            final PeriodFrequencyType loanTermPeriodFrequencyType, final LocalDate expectedDisbursementDate,
-            final LocalDate repaymentsStartingFromDate, final LocalDate calculatedRepaymentsStartingFromDate,
-            final Money inArrearsTolerance, final LoanProductRelatedDetail loanProductRelatedDetail, final boolean multiDisburseLoan,
-            final BigDecimal emiAmount, final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance,
-            final LocalDate interestChargedFromDate, final LoanInterestRecalculationDetails interestRecalculationDetails,
-            final CalendarInstance restCalendarInstance, final RecalculationFrequencyType recalculationFrequencyType,
-            final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
-            final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
-            final LoanPreClosureInterestCalculationStrategy loanPreClosureInterestCalculationStrategy, final Calendar loanCalendar,
-            BigDecimal approvedAmount, final BigDecimal annualNominalInterestRate, final List<LoanTermVariationsData> loanTermVariations,
-            Integer numberOfDays, boolean isSkipRepaymentOnFirstDayOfMonth, final HolidayDetailDTO holidayDetailDTO,
-            final boolean allowCompoundingOnEod) {
-
-        final Integer numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments();
-        final Integer repaymentEvery = loanProductRelatedDetail.getRepayEvery();
-        final PeriodFrequencyType repaymentPeriodFrequencyType = loanProductRelatedDetail.getRepaymentPeriodFrequencyType();
-        final AmortizationMethod amortizationMethod = loanProductRelatedDetail.getAmortizationMethod();
-        final InterestMethod interestMethod = loanProductRelatedDetail.getInterestMethod();
-        final BigDecimal interestRatePerPeriod = loanProductRelatedDetail.getNominalInterestRatePerPeriod();
-        final PeriodFrequencyType interestRatePeriodFrequencyType = loanProductRelatedDetail.getInterestPeriodFrequencyType();
-        final InterestCalculationPeriodMethod interestCalculationPeriodMethod = loanProductRelatedDetail
-                .getInterestCalculationPeriodMethod();
-        final boolean allowPartialPeriodInterestCalcualtion = loanProductRelatedDetail.isAllowPartialPeriodInterestCalcualtion();
-        final Money principalMoney = loanProductRelatedDetail.getPrincipal();
-
-        //
-        final Integer graceOnPrincipalPayment = loanProductRelatedDetail.graceOnPrincipalPayment();
-        final Integer recurringMoratoriumOnPrincipalPeriods = loanProductRelatedDetail.recurringMoratoriumOnPrincipalPeriods();
-        final Integer graceOnInterestPayment = loanProductRelatedDetail.graceOnInterestPayment();
-        final Integer graceOnInterestCharged = loanProductRelatedDetail.graceOnInterestCharged();
-
-        // Interest recalculation settings
-        final DaysInMonthType daysInMonthType = loanProductRelatedDetail.fetchDaysInMonthType();
-        final DaysInYearType daysInYearType = loanProductRelatedDetail.fetchDaysInYearType();
-        final boolean isInterestRecalculationEnabled = loanProductRelatedDetail.isInterestRecalculationEnabled();
-        LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
-        InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null;
-        if (isInterestRecalculationEnabled) {
-            rescheduleStrategyMethod = interestRecalculationDetails.getRescheduleStrategyMethod();
-            interestRecalculationCompoundingMethod = interestRecalculationDetails.getInterestRecalculationCompoundingMethod();
-        }
-        final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
-        final boolean isInterestChargedFromDateSameAsDisbursalDateEnabled = false;
-        final boolean isEqualAmortization = loanProductRelatedDetail.isEqualAmortization();
-        return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
-                repaymentEvery, repaymentPeriodFrequencyType, null, null, amortizationMethod, interestMethod, interestRatePerPeriod,
-                interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
-                allowPartialPeriodInterestCalcualtion, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
-                calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods,
-                graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount,
-                disbursementDatas, maxOutstandingBalance, loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType,
-                isInterestRecalculationEnabled, rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance,
-                recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
-                installmentAmountInMultiplesOf, loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
-                calendarHistoryDataWrapper, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays,
-                isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization, false, false, null, false);
-
-    }
-
-    public static LoanApplicationTerms assembleFrom(final LoanApplicationTerms applicationTerms,
-            final List<LoanTermVariationsData> loanTermVariations) {
-        return new LoanApplicationTerms(applicationTerms.currency, applicationTerms.loanTermFrequency,
-                applicationTerms.loanTermPeriodFrequencyType, applicationTerms.numberOfRepayments, applicationTerms.repaymentEvery,
-                applicationTerms.repaymentPeriodFrequencyType, applicationTerms.nthDay, applicationTerms.weekDayType,
-                applicationTerms.amortizationMethod, applicationTerms.interestMethod, applicationTerms.interestRatePerPeriod,
-                applicationTerms.interestRatePeriodFrequencyType, applicationTerms.annualNominalInterestRate,
-                applicationTerms.interestCalculationPeriodMethod, applicationTerms.allowPartialPeriodInterestCalcualtion,
-                applicationTerms.principal, applicationTerms.expectedDisbursementDate, applicationTerms.repaymentsStartingFromDate,
-                applicationTerms.calculatedRepaymentsStartingFromDate, applicationTerms.principalGrace,
-                applicationTerms.recurringMoratoriumOnPrincipalPeriods, applicationTerms.interestPaymentGrace,
-                applicationTerms.interestChargingGrace, applicationTerms.interestChargedFromDate, applicationTerms.inArrearsTolerance,
-                applicationTerms.multiDisburseLoan, applicationTerms.actualFixedEmiAmount, applicationTerms.disbursementDatas,
-                applicationTerms.maxOutstandingBalance, applicationTerms.graceOnArrearsAgeing, applicationTerms.daysInMonthType,
-                applicationTerms.daysInYearType, applicationTerms.interestRecalculationEnabled, applicationTerms.rescheduleStrategyMethod,
-                applicationTerms.interestRecalculationCompoundingMethod, applicationTerms.restCalendarInstance,
-                applicationTerms.recalculationFrequencyType, applicationTerms.compoundingCalendarInstance,
-                applicationTerms.compoundingFrequencyType, applicationTerms.principalThresholdForLastInstalment,
-                applicationTerms.installmentAmountInMultiplesOf, applicationTerms.preClosureInterestCalculationStrategy,
-                applicationTerms.loanCalendar, applicationTerms.approvedPrincipal.getAmount(), loanTermVariations,
-                applicationTerms.calendarHistoryDataWrapper, applicationTerms.isInterestChargedFromDateSameAsDisbursalDateEnabled,
-                applicationTerms.numberOfDays, applicationTerms.isSkipRepaymentOnFirstDayOfMonth, applicationTerms.holidayDetailDTO,
-                applicationTerms.allowCompoundingOnEod, applicationTerms.isEqualAmortization,
-                applicationTerms.isFirstRepaymentDateAllowedOnHoliday, applicationTerms.isInterestToBeRecoveredFirstWhenGreaterThanEMI,
-                applicationTerms.fixedPrincipalPercentagePerInstallment, applicationTerms.isPrincipalCompoundingDisabledForOverdueLoans);
-    }
-
     private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
             final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
             final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer nthDay, final DayOfWeekType weekDayType,
@@ -1702,6 +1588,18 @@ public final class LoanApplicationTerms {
         return disbursedAmount;
     }
 
+    public Money getTotalMultiDisbursedAmount() {
+        Money disbursedAmount = Money.zero(getCurrency());
+        if (isMultiDisburseLoan()) {
+            for (DisbursementData disbursement : getDisbursementDatas()) {
+                disbursedAmount = disbursedAmount.plus(disbursement.getPrincipal());
+            }
+        } else {
+            disbursedAmount = getPrincipal();
+        }
+        return disbursedAmount;
+    }
+
     public void updatePeriodNumberApplicableForPrincipalOrInterestGrace(final Integer periodsApplicationForGrace) {
         int applicablePeriodNumber = periodsApplicationForGrace;
         int graceOnPrincipal = defaultToZeroIfNull(this.principalGrace);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
index 58ff84cbb..19c9462b5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
@@ -2996,20 +2996,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
         ChangedTransactionDetail changedTransactionDetail = null;
 
         if (command.entityId() != null) {
-
             changedTransactionDetail = loan.updateDisbursementDateAndAmountForTranche(loanDisbursementDetails, command, changes,
                     scheduleGeneratorDTO);
         } else {
-            // BigDecimal setAmount = loan.getApprovedPrincipal();
-            Collection<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails();
-            BigDecimal setAmount = BigDecimal.ZERO;
-            for (LoanDisbursementDetails details : loanDisburseDetails) {
-                if (details.actualDisbursementDate() != null) {
-                    setAmount = setAmount.add(details.principal());
-                }
-            }
-
-            loan.repaymentScheduleDetail().setPrincipal(setAmount);
+            loan.repaymentScheduleDetail().setPrincipal(loan.getPrincipalAmountForRepaymentSchedule());
 
             if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
                 loan.regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
index f2a61b0db..0303cf825 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
@@ -1288,7 +1288,7 @@ public class ClientLoanIntegrationTest {
                 .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
                 .withExpectedDisbursementDate("20 September 2011") //
                 .withSubmittedOnDate("20 September 2011") //
-                .withwithRepaymentStrategy(repaymentStrategy) //
+                .withRepaymentStrategy(repaymentStrategy) //
                 .withCollaterals(collaterals).withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId);
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
     }
@@ -1316,7 +1316,7 @@ public class ClientLoanIntegrationTest {
                 .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
                 .withExpectedDisbursementDate(fourMonthsfromNow) //
                 .withSubmittedOnDate(fourMonthsfromNow) //
-                .withwithRepaymentStrategy(repaymentStrategy) //
+                .withRepaymentStrategy(repaymentStrategy) //
                 .withCollaterals(collaterals).withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId);
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
     }
@@ -4757,7 +4757,7 @@ public class ClientLoanIntegrationTest {
                 .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
                 .withExpectedDisbursementDate(disbursementDate) //
                 .withSubmittedOnDate(disbursementDate) //
-                .withwithRepaymentStrategy(repaymentStrategy) //
+                .withRepaymentStrategy(repaymentStrategy) //
                 .withPrincipalGrace(graceOnPrincipalPayment) //
                 .withInterestGrace(graceOnInterestPayment)//
                 .withCharges(charges)//
@@ -5816,7 +5816,7 @@ public class ClientLoanIntegrationTest {
                 .withRepaymentEveryAfter("2")
                 //
                 .withAmortizationTypeAsEqualPrincipalPayments().withRepaymentFrequencyTypeAsWeeks()
-                .withwithRepaymentStrategy(LoanProductTestBuilder.RBI_INDIA_STRATEGY).withInterestTypeAsFlatBalance()
+                .withRepaymentStrategy(LoanProductTestBuilder.RBI_INDIA_STRATEGY).withInterestTypeAsFlatBalance()
                 .withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withPrincipalGrace("1").withInterestGrace("1")
                 .withLoanTermFrequency("4") //
                 .withLoanTermFrequencyAsMonths() //
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyBucketsIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyBucketsIntegrationTest.java
index ab5c8e10d..17814e645 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyBucketsIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyBucketsIntegrationTest.java
@@ -478,7 +478,7 @@ public class DelinquencyBucketsIntegrationTest {
         // First Loan Delinquency Classification after Disbursement command
         assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
 
-        printRepaymentSchedule(getLoansLoanIdResponse);
+        loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
 
         // Apply a partial repayment
         operationDate = Utils.dateFormatter.format(todaysDate);
@@ -660,7 +660,7 @@ public class DelinquencyBucketsIntegrationTest {
         // First Loan Delinquency Classification after Disbursement command
         assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected01);
 
-        printRepaymentSchedule(getLoansLoanIdResponse);
+        loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
 
         // Apply a repayment to get a first full paid installment
         operationDate = Utils.dateFormatter.format(todaysDate);
@@ -752,7 +752,7 @@ public class DelinquencyBucketsIntegrationTest {
         // First Loan Delinquency Classification after Disbursement command
         assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
 
-        printRepaymentSchedule(getLoansLoanIdResponse);
+        loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
 
         // Apply a repayment to get a full paid installment
         operationDate = Utils.dateFormatter.format(todaysDate);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAuditingIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAuditingIntegrationTest.java
index fc2de616f..05396c2ed 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAuditingIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAuditingIntegrationTest.java
@@ -176,7 +176,7 @@ public class LoanAuditingIntegrationTest {
                 .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
                 .withExpectedDisbursementDate(submittedOnDate) //
                 .withSubmittedOnDate(submittedOnDate) //
-                .withwithRepaymentStrategy(repaymentStrategy) //
+                .withRepaymentStrategy(repaymentStrategy) //
                 .withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId);
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
     }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
index a2c3d5de0..6b6df5410 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
@@ -19,6 +19,8 @@
 package org.apache.fineract.integrationtests;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import io.restassured.builder.RequestSpecBuilder;
 import io.restassured.builder.ResponseSpecBuilder;
@@ -32,6 +34,10 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
+import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
+import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
 import org.apache.fineract.integrationtests.common.Utils;
@@ -43,17 +49,15 @@ import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
+@Slf4j
 @SuppressWarnings({ "rawtypes", "unchecked" })
 public class LoanDisbursementDetailsIntegrationTest {
 
-    private static final Logger LOG = LoggerFactory.getLogger(LoanDisbursementDetailsIntegrationTest.class);
     private ResponseSpecification responseSpec;
     private RequestSpecification requestSpec;
     private LoanTransactionHelper loanTransactionHelper;
-    private Integer loanID;
+    private Integer loanId;
     private Integer disbursementId;
     final String approveDate = "01 March 2014";
     final String expectedDisbursementDate = "01 March 2014";
@@ -80,18 +84,18 @@ public class LoanDisbursementDetailsIntegrationTest {
         createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 September 2015", "5000"));
 
         final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
-        LOG.info("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------{}", clientID);
+        log.info("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------{}", clientID);
 
         final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
                 .withInterestTypeAsDecliningBalance().withMoratorium("", "").withAmortizationTypeAsEqualInstallments().withTranches(true)
                 .withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null));
-        LOG.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
+        log.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
                 loanProductID);
 
         final Integer loanIDWithEmi = applyForLoanApplicationWithEmiAmount(clientID, loanProductID, proposedAmount, createTranches,
                 installmentAmount);
 
-        LOG.info("-----------------------------------LOAN CREATED WITH EMI LOANID------------------------------------------------- {}",
+        log.info("-----------------------------------LOAN CREATED WITH EMI LOANID------------------------------------------------- {}",
                 loanIDWithEmi);
 
         HashMap repaymentScheduleWithEmi = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
@@ -105,24 +109,23 @@ public class LoanDisbursementDetailsIntegrationTest {
         HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanIDWithEmi);
         LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
 
-        LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+        log.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
         loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount("01 June 2015", "01 June 2015", "10000", loanIDWithEmi,
                 createTranches);
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
-        LOG.info(
+        log.info(
                 "-----------------------------------MULTI DISBURSAL LOAN WITH EMI APPROVED SUCCESSFULLY---------------------------------------");
 
         final Integer loanIDWithoutEmi = applyForLoanApplicationWithEmiAmount(clientID, loanProductID, proposedAmount, createTranches,
                 withoutInstallmentAmount);
 
-        HashMap repaymentScheduleWithoutEmi = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
-                loanIDWithoutEmi, "repaymentSchedule");
+        this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanIDWithoutEmi, "repaymentSchedule");
 
         ArrayList<HashMap> periods1 = (ArrayList<HashMap>) repaymentScheduleWithEmi.get("periods");
         assertEquals(15, periods1.size());
 
-        LOG.info("-----------------------------------LOAN CREATED WITHOUT EMI LOANID------------------------------------------------- {}",
+        log.info("-----------------------------------LOAN CREATED WITHOUT EMI LOANID------------------------------------------------- {}",
                 loanIDWithoutEmi);
 
         /* To be uncommented once issue MIFOSX-2006 is closed. */
@@ -131,12 +134,12 @@ public class LoanDisbursementDetailsIntegrationTest {
         HashMap loanStatusMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanIDWithoutEmi);
         LoanStatusChecker.verifyLoanIsPending(loanStatusMap);
 
-        LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+        log.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
         loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount("01 June 2015", "01 June 2015", "10000",
                 loanIDWithoutEmi, createTranches);
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
-        LOG.info(
+        log.info(
                 "-----------------------------------MULTI DISBURSAL LOAN WITHOUT EMI APPROVED SUCCESSFULLY---------------------------------------");
 
     }
@@ -205,6 +208,7 @@ public class LoanDisbursementDetailsIntegrationTest {
         list.add(expectedRepaymentSchedule14);
 
         for (int i = 0; i < list.size(); i++) {
+            log.info("values {} {} {}", i, periods.get(i), list.get(i));
             this.assertRepaymentScheduleValuesWithEMI(periods.get(i), list.get(i), i);
         }
     }
@@ -213,7 +217,7 @@ public class LoanDisbursementDetailsIntegrationTest {
 
         assertEquals(period.get("dueDate").toString(), expectedRepaymentSchedule.getDueDate());
         assertEquals(period.get("principalLoanBalanceOutstanding"), expectedRepaymentSchedule.getPrincipalLoanBalanceOutstanding());
-        LOG.info("{}", period.get("totalOriginalDueForPeriod").toString());
+        log.info("{}", period.get("totalOriginalDueForPeriod").toString());
         assertEquals(Float.parseFloat(period.get("totalOriginalDueForPeriod").toString()),
                 expectedRepaymentSchedule.getTotalOriginalDueForPeriod().floatValue(), 0.0f);
 
@@ -233,103 +237,25 @@ public class LoanDisbursementDetailsIntegrationTest {
         }
     }
 
-    /* Uncomment and modify test builder values once MIFOSX-2006 is closed. */
-    /*
-     * private void validateRepaymentScheduleWithoutEMI(ArrayList<HashMap> periods){ LoanDisbursementTestBuilder
-     * expectedRepaymentSchedule0 = new LoanDisbursementTestBuilder( "[2015, 6, 1]", 0.0f, 0.0f, null, null, 5000.0f,
-     * null, null, null);
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule1 = new LoanDisbursementTestBuilder( "[2015, 7, 1]", 800.0f,
-     * 800.0f, 50.0f, 750.0f, 4250.0f, 750.0f, 750.0f, "[2015, 6, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule2 = new LoanDisbursementTestBuilder( "[2015, 8, 1]", 800.0f,
-     * 800.0f, 42.5f, 757.5f, 3492.5f, 757.5f, 757.5f, "[2015, 7, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule3 = new LoanDisbursementTestBuilder( "[2015, 9, 1]", 0.0f,
-     * 0.0f, null, null, 5000.0f, null, null, null);
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule4 = new LoanDisbursementTestBuilder( "[2015, 9, 1]", 800.0f,
-     * 800.0f, 34.92f, 765.08f, 7727.42f, 765.08f, 765.08f, "[2015, 8, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule5 = new LoanDisbursementTestBuilder( "[2015, 10, 1]",
-     * 800.0f, 800.0f, 77.27f, 722.73f, 7004.69f, 722.73f, 722.73f, "[2015, 9, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule6 = new LoanDisbursementTestBuilder( "[2015, 11, 1]",
-     * 800.0f, 800.0f, 70.05f, 729.95f, 6274.74f, 729.95f, 729.95f, "[2015, 10, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule7 = new LoanDisbursementTestBuilder( "[2015, 12, 1]",
-     * 800.0f, 800.0f, 62.75f, 737.25f, 5537.49f, 737.25f, 737.25f, "[2015, 11, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule8 = new LoanDisbursementTestBuilder( "[2016, 1, 1]", 800.0f,
-     * 800.0f, 55.37f, 744.63f, 4792.86f, 744.63f, 744.63f, "[2015, 12, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule9 = new LoanDisbursementTestBuilder( "[2016, 2, 1]", 800.0f,
-     * 800.0f, 47.93f, 752.07f, 4040.79f, 752.07f, 752.07f, "[2016, 1, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule10 = new LoanDisbursementTestBuilder( "[2016, 3, 1]",
-     * 800.0f, 800.0f, 40.41f, 759.59f, 3281.2f, 759.59f, 759.59f, "[2016, 2, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule11 = new LoanDisbursementTestBuilder( "[2016, 4, 1]",
-     * 800.0f, 800.0f, 32.81f, 767.19f, 2514.01f, 767.19f, 767.19f, "[2016, 3, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule12 = new LoanDisbursementTestBuilder( "[2016, 5, 1]",
-     * 800.0f, 800.0f, 25.14f, 774.86f, 1739.15f, 774.86f, 774.86f, "[2016, 4, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule13 = new LoanDisbursementTestBuilder( "[2016, 6, 1]",
-     * 800.0f, 800.0f, 17.39f, 782.61f, 956.54f, 782.61f, 782.61f, "[2016, 5, 1]");
-     *
-     * LoanDisbursementTestBuilder expectedRepaymentSchedule14 = new LoanDisbursementTestBuilder( "[2016, 7, 1]",
-     * 966.11f, 966.11f, 9.57f, 956.54f, 0.0f, 956.54f, 956.54f, "[2016, 6, 1]");
-     *
-     * ArrayList<LoanDisbursementTestBuilder> list = new ArrayList<LoanDisbursementTestBuilder>();
-     * list.add(expectedRepaymentSchedule0); list.add(expectedRepaymentSchedule1); list.add(expectedRepaymentSchedule2);
-     * list.add(expectedRepaymentSchedule3); list.add(expectedRepaymentSchedule4); list.add(expectedRepaymentSchedule5);
-     * list.add(expectedRepaymentSchedule6); list.add(expectedRepaymentSchedule7); list.add(expectedRepaymentSchedule8);
-     * list.add(expectedRepaymentSchedule9); list.add(expectedRepaymentSchedule10);
-     * list.add(expectedRepaymentSchedule11); list.add(expectedRepaymentSchedule12);
-     * list.add(expectedRepaymentSchedule13); list.add(expectedRepaymentSchedule14);
-     *
-     * for (int i = 0; i < list.size(); i++) { this.assertRepaymentScheduleValuesWithoutEMI(periods.get(i), list.get(i),
-     * i); } }
-     *
-     * private void assertRepaymentScheduleValuesWithoutEMI(HashMap period, LoanDisbursementTestBuilder
-     * expectedRepaymentSchedule, int position) {
-     *
-     * assertEquals(period.get("dueDate").toString(), expectedRepaymentSchedule.getDueDate());
-     * assertEquals(period.get("principalLoanBalanceOutstanding"),
-     * expectedRepaymentSchedule.getPrincipalLoanBalanceOutstanding());
-     * assertEquals(period.get("totalOriginalDueForPeriod"), expectedRepaymentSchedule.getTotalOriginalDueForPeriod());
-     * assertEquals(period.get("totalOutstandingForPeriod"), expectedRepaymentSchedule.getTotalOutstandingForPeriod());
-     *
-     * if (position != 0 && position != 3) {
-     *
-     * assertEquals(period.get("interestOutstanding"), expectedRepaymentSchedule.getInterestOutstanding());
-     * assertEquals(period.get("principalOutstanding"), expectedRepaymentSchedule.getPrincipalOutstanding());
-     * assertEquals(period.get("principalDue"), expectedRepaymentSchedule.getPrincipalDue());
-     * assertEquals(period.get("principalOriginalDue"), expectedRepaymentSchedule.getPrincipalOriginalDue());
-     * assertEquals(period.get("fromDate").toString(), expectedRepaymentSchedule.getFromDate()); } }
-     */
-    private Integer applyForLoanApplicationWithEmiAmount(final Integer clientID, final Integer loanProductID, final String proposedAmount,
+    private Integer applyForLoanApplicationWithEmiAmount(final Integer clientId, final Integer loanProductId, final String proposedAmount,
             List<HashMap> tranches, final String installmentAmount) {
 
-        LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
+        log.info("----------------APPLYING FOR LOAN APPLICATION");
         List<HashMap> collaterals = new ArrayList<>();
         final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec);
         Assertions.assertNotNull(collateralId);
         final Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(this.requestSpec, this.responseSpec,
-                clientID.toString(), collateralId);
+                clientId.toString(), collateralId);
         Assertions.assertNotNull(clientCollateralId);
         addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1));
 
-        final String loanApplicationJSON = new LoanApplicationTestBuilder()
-                //
-                .withPrincipal(proposedAmount)
-                //
-                .withLoanTermFrequency("12")
-                //
-                .withLoanTermFrequencyAsMonths()
-                //
-                .withNumberOfRepayments("12").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
+        final String loanApplicationJSON = new LoanApplicationTestBuilder() //
+                .withPrincipal(proposedAmount) //
+                .withLoanTermFrequency("12") //
+                .withLoanTermFrequencyAsMonths() //
+                .withNumberOfRepayments("12") //
+                .withRepaymentEveryAfter("1") //
+                .withRepaymentFrequencyTypeAsMonths() //
                 .withInterestRatePerPeriod("1") //
                 .withExpectedDisbursementDate("01 June 2015") //
                 .withTranches(tranches) //
@@ -337,12 +263,55 @@ public class LoanDisbursementDetailsIntegrationTest {
                 .withInterestTypeAsDecliningBalance() //
                 .withSubmittedOnDate("01 June 2015") //
                 .withAmortizationTypeAsEqualInstallments() //
-                .withCollaterals(collaterals).build(clientID.toString(), loanProductID.toString(), null);
+                .withCollaterals(collaterals).build(clientId.toString(), loanProductId.toString(), null);
 
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
 
     }
 
+    @Test
+    public void validateEqualInstallmentsForMultiTrancheLoan() {
+        List<HashMap> emptyTranches = new ArrayList<>();
+
+        final String operationDate = "01 January 2014";
+        final String principal = "1000";
+        final String disbursedPrincipal = "900";
+
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, operationDate);
+        log.info("-----------------CLIENT CREATED WITH ID------------------- {}", clientId);
+
+        final String loanProductJSON = new LoanProductTestBuilder().withAmortizationTypeAsEqualInstallments() //
+                .withInterestTypeAsDecliningBalance().withMoratorium("", "").withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
+                .withInterestTypeAsDecliningBalance() //
+                .withMultiDisburse() //
+                .withDisallowExpectectedDisbursements(true) //
+                .build(null);
+        log.info("Product {}", loanProductJSON);
+        final Integer loanProductId = this.loanTransactionHelper.getLoanProductId(loanProductJSON);
+        log.info("------------------LOAN PRODUCT CREATED WITH ID----------- {}", loanProductId);
+
+        final Integer loanId = applyForMultiTrancheLoanApplication(clientId.toString(), loanProductId.toString(), principal, operationDate);
+
+        log.info("-------------------LOAN CREATED WITH loanId----------------- {}", loanId);
+
+        this.loanTransactionHelper.approveLoanWithApproveAmount(operationDate, expectedDisbursementDate, principal, loanId, emptyTranches);
+        log.info("-------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY-------");
+
+        GetLoansLoanIdResponse getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
+        assertNotNull(getLoansLoanIdResponse);
+
+        this.loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
+
+        loanTransactionHelper.disburseLoanWithTransactionAmount(operationDate, loanId, disbursedPrincipal);
+        log.info("-------------------MULTI DISBURSAL LOAN DISBURSED SUCCESSFULLY-------");
+        getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
+        assertNotNull(getLoansLoanIdResponse);
+        this.loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
+        final Double limit = 2.0;
+        evaluateEqualInstallmentsForRepaymentSchedule(getLoansLoanIdResponse.getRepaymentSchedule(), limit);
+        log.info("-----------MULTI DISBURSAL LOAN EQUAL INSTALLMENTS SUCCESSFULLY-------");
+    }
+
     @Test
     public void createApproveAndValidateMultiDisburseLoan() throws ParseException {
 
@@ -351,28 +320,29 @@ public class LoanDisbursementDetailsIntegrationTest {
         createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 March 2014", "1000"));
 
         final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
-        LOG.info("---------------------------------CLIENT CREATED WITH ID--------------------------------------------------- {}", clientID);
+        log.info("---------------------------------CLIENT CREATED WITH ID--------------------------------------------------- {}", clientID);
 
         final Integer loanProductID = this.loanTransactionHelper
                 .getLoanProductId(new LoanProductTestBuilder().withInterestTypeAsDecliningBalance().withTranches(true)
                         .withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null));
-        LOG.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
+        log.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
                 loanProductID);
 
-        this.loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
-        LOG.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}", loanID);
+        this.loanId = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
+        log.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}",
+                this.loanId);
 
-        HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+        HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId);
         LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
 
-        LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+        log.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
         loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount,
-                loanID, createTranches);
+                this.loanId, createTranches);
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
-        LOG.info("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------");
+        log.info("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------");
         ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
-                this.responseSpec, this.loanID, "disbursementDetails");
+                this.responseSpec, this.loanId, "disbursementDetails");
         this.disbursementId = (Integer) disbursementDetails.get(0).get("id");
         this.editLoanDisbursementDetails();
     }
@@ -386,7 +356,7 @@ public class LoanDisbursementDetailsIntegrationTest {
     private void addNewDisbursementDetails() throws ParseException {
         List<HashMap> addTranches = new ArrayList<>();
         ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
-                this.responseSpec, this.loanID, "disbursementDetails");
+                this.responseSpec, this.loanId, "disbursementDetails");
         ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(0).get("expectedDisbursementDate");
         String date = formatExpectedDisbursementDate(expectedDisbursementDate.toString());
 
@@ -397,14 +367,14 @@ public class LoanDisbursementDetailsIntegrationTest {
         addTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "04 March 2014", "500"));
 
         /* Add disbursement detail */
-        this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanID, this.approvalAmount, this.expectedDisbursementDate,
+        this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanId, this.approvalAmount, this.expectedDisbursementDate,
                 addTranches, "");
     }
 
     private void deleteDisbursmentDetails() throws ParseException {
         List<HashMap> deleteTranches = new ArrayList<>();
         ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
-                this.responseSpec, this.loanID, "disbursementDetails");
+                this.responseSpec, this.loanId, "disbursementDetails");
         /* Delete the last tranche */
         for (int i = 0; i < disbursementDetails.size() - 1; i++) {
             ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(i).get("expectedDisbursementDate");
@@ -414,7 +384,7 @@ public class LoanDisbursementDetailsIntegrationTest {
         }
 
         /* Add disbursement detail */
-        this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanID, this.approvalAmount, this.expectedDisbursementDate,
+        this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanId, this.approvalAmount, this.expectedDisbursementDate,
                 deleteTranches, "");
     }
 
@@ -422,11 +392,11 @@ public class LoanDisbursementDetailsIntegrationTest {
         String updatedExpectedDisbursementDate = "01 March 2014";
         String updatedPrincipal = "900";
         /* Update */
-        this.loanTransactionHelper.editDisbursementDetail(this.loanID, this.disbursementId, this.approvalAmount,
+        this.loanTransactionHelper.editDisbursementDetail(this.loanId, this.disbursementId, this.approvalAmount,
                 this.expectedDisbursementDate, updatedExpectedDisbursementDate, updatedPrincipal, "");
         /* Validate Edit */
         ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
-                this.responseSpec, this.loanID, "disbursementDetails");
+                this.responseSpec, this.loanId, "disbursementDetails");
         assertEquals(Float.parseFloat(updatedPrincipal), disbursementDetails.get(0).get("principal"));
         ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(0).get("expectedDisbursementDate");
         String date = formatExpectedDisbursementDate(expectedDisbursementDate.toString());
@@ -435,7 +405,6 @@ public class LoanDisbursementDetailsIntegrationTest {
     }
 
     private String formatExpectedDisbursementDate(String expectedDisbursementDate) throws ParseException {
-
         SimpleDateFormat source = new SimpleDateFormat("[yyyy, MM, dd]");
         SimpleDateFormat target = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
         String date = target.format(source.parse(expectedDisbursementDate));
@@ -443,32 +412,53 @@ public class LoanDisbursementDetailsIntegrationTest {
         return date;
     }
 
-    private Integer applyForLoanApplicationWithTranches(final Integer clientID, final Integer loanProductID, String principal,
+    private Integer applyForLoanApplicationWithTranches(final Integer clientId, final Integer loanProductId, String principal,
             List<HashMap> tranches) {
-        LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
+        log.info("----------------APPLYING FOR LOAN APPLICATION");
         List<HashMap> collaterals = new ArrayList<>();
         final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec);
         Assertions.assertNotNull(collateralId);
         final Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(this.requestSpec, this.responseSpec,
-                clientID.toString(), collateralId);
+                clientId.toString(), collateralId);
         Assertions.assertNotNull(clientCollateralId);
         addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1));
-        final String loanApplicationJSON = new LoanApplicationTestBuilder()
-                //
-                .withPrincipal(principal)
-                //
-                .withLoanTermFrequency("5")
-                //
-                .withLoanTermFrequencyAsMonths()
-                //
-                .withNumberOfRepayments("5").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
+        final String loanApplicationJSON = new LoanApplicationTestBuilder() //
+                .withPrincipal(principal) //
+                .withLoanTermFrequency("5") //
+                .withLoanTermFrequencyAsMonths() //
+                .withNumberOfRepayments("5") //
+                .withRepaymentEveryAfter("1") //
+                .withRepaymentFrequencyTypeAsMonths() //
                 .withInterestRatePerPeriod("2") //
                 .withExpectedDisbursementDate("01 March 2014") //
                 .withTranches(tranches) //
                 .withInterestTypeAsDecliningBalance() //
                 .withSubmittedOnDate("01 March 2014") //
-                .withCollaterals(collaterals).build(clientID.toString(), loanProductID.toString(), null);
+                .withCollaterals(collaterals).build(clientId.toString(), loanProductId.toString(), null);
+
+        return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
+    }
+
+    private Integer applyForMultiTrancheLoanApplication(final String clientId, final String loanProductId, String principal,
+            String operationDate) {
+        log.info("----------------APPLYING FOR MULTI TRANCHE LOAN APPLICATION");
+        List<HashMap> emptyData = new ArrayList<>();
+        final String loanApplicationJSON = new LoanApplicationTestBuilder() //
+                .withPrincipal(principal) //
+                .withLoanTermFrequency("3") //
+                .withLoanTermFrequencyAsMonths() //
+                .withNumberOfRepayments("3") //
+                .withRepaymentEveryAfter("1") //
+                .withRepaymentFrequencyTypeAsMonths() //
+                .withInterestRatePerPeriod("0") //
+                .withExpectedDisbursementDate(operationDate) //
+                .withTranches(emptyData) //
+                .withInterestTypeAsDecliningBalance() //
+                .withSubmittedOnDate(operationDate) //
+                .withCollaterals(emptyData) //
+                .build(clientId, loanProductId, null);
 
+        log.info("Loan account {}", loanApplicationJSON);
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
     }
 
@@ -483,4 +473,24 @@ public class LoanDisbursementDetailsIntegrationTest {
         return collateral;
     }
 
+    public void evaluateEqualInstallmentsForRepaymentSchedule(GetLoansLoanIdRepaymentSchedule getLoanRepaymentSchedule, Double limit) {
+        Double totalOutstandingForPeriod = 0.0;
+        Double totalInstallmentAmountForPeriod = 0.0;
+        if (getLoanRepaymentSchedule != null) {
+            log.info("Loan with {} periods", getLoanRepaymentSchedule.getPeriods().size());
+            for (GetLoansLoanIdRepaymentPeriod period : getLoanRepaymentSchedule.getPeriods()) {
+                if (period.getPeriod() != null) {
+                    log.info("Period number {} for due date {} and outstanding {} {}", period.getPeriod(), period.getDueDate(),
+                            period.getTotalOutstandingForPeriod(), period.getTotalInstallmentAmountForPeriod());
+                    if (period.getPeriod() == 1) {
+                        totalOutstandingForPeriod = period.getTotalOutstandingForPeriod();
+                        totalInstallmentAmountForPeriod = period.getTotalInstallmentAmountForPeriod();
+                    } else {
+                        assertTrue(Math.abs(period.getTotalOutstandingForPeriod() - totalOutstandingForPeriod) <= limit);
+                        assertTrue(Math.abs(period.getTotalInstallmentAmountForPeriod() - totalInstallmentAmountForPeriod) <= limit);
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentRescheduleAtDisbursementTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentRescheduleAtDisbursementTest.java
index 1e4efa84b..9afe6f55f 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentRescheduleAtDisbursementTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentRescheduleAtDisbursementTest.java
@@ -245,7 +245,7 @@ public class LoanRepaymentRescheduleAtDisbursementTest {
                 .withInterestCalculationPeriodTypeAsDays() //
                 .withExpectedDisbursementDate(disbursementDate) //
                 .withSubmittedOnDate(disbursementDate) //
-                .withwithRepaymentStrategy(repaymentStrategy) //
+                .withRepaymentStrategy(repaymentStrategy) //
                 .withCollaterals(collaterals).withCharges(charges)//
                 .build(clientID.toString(), loanProductID.toString(), null);
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleWithAdvancePaymentTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleWithAdvancePaymentTest.java
index 2e8616f06..0f78248d8 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleWithAdvancePaymentTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleWithAdvancePaymentTest.java
@@ -204,7 +204,7 @@ public class LoanRescheduleWithAdvancePaymentTest {
                 .withRepaymentFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestCalculationPeriodTypeAsDays()
                 .withInterestRatePerPeriod("12").withInterestTypeAsDecliningBalance().withSubmittedOnDate(submittedDate)
                 .withExpectedDisbursementDate(submittedDate).withFirstRepaymentDate(firstRepaymentDate)
-                .withwithRepaymentStrategy(LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY)
+                .withRepaymentStrategy(LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY)
                 .withinterestChargedFromDate(submittedDate).build(this.clientId.toString(), this.loanProductId.toString(), null);
 
         this.loanId = this.loanTransactionHelper.getLoanId(loanApplicationJSON);
@@ -318,7 +318,7 @@ public class LoanRescheduleWithAdvancePaymentTest {
                 .withRepaymentFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestCalculationPeriodTypeAsDays()
                 .withInterestRatePerPeriod("12").withInterestTypeAsDecliningBalance().withSubmittedOnDate(submittedDate)
                 .withExpectedDisbursementDate(submittedDate).withFirstRepaymentDate(firstRepaymentDate)
-                .withwithRepaymentStrategy(LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY)
+                .withRepaymentStrategy(LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY)
                 .withinterestChargedFromDate(submittedDate).build(this.clientId.toString(), this.loanProductId.toString(), null);
 
         this.loanId = this.loanTransactionHelper.getLoanId(loanApplicationJSON);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java
index b2db9dd80..8c1ebbd6f 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java
@@ -409,7 +409,7 @@ public class LoanReschedulingWithinCenterTest {
                 .withInterestCalculationPeriodTypeAsDays() //
                 .withExpectedDisbursementDate(disbursementDate) //
                 .withSubmittedOnDate(disbursementDate) //
-                .withwithRepaymentStrategy(repaymentStrategy) //
+                .withRepaymentStrategy(repaymentStrategy) //
                 .withCollaterals(collaterals).withCharges(charges)//
                 .build(clientID.toString(), groupId.toString(), loanProductID.toString(), null);
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionAuditingIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionAuditingIntegrationTest.java
index 8475f84ba..4817046e2 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionAuditingIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionAuditingIntegrationTest.java
@@ -187,7 +187,7 @@ public class LoanTransactionAuditingIntegrationTest {
                 .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
                 .withExpectedDisbursementDate(submittedOnDate) //
                 .withSubmittedOnDate(submittedOnDate) //
-                .withwithRepaymentStrategy(repaymentStrategy) //
+                .withRepaymentStrategy(repaymentStrategy) //
                 .withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId);
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
     }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
index a480de000..94ae8bf60 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
@@ -335,7 +335,7 @@ public class LoanApplicationTestBuilder {
         return this;
     }
 
-    public LoanApplicationTestBuilder withwithRepaymentStrategy(final String transactionProcessingStrategy) {
+    public LoanApplicationTestBuilder withRepaymentStrategy(final String transactionProcessingStrategy) {
         this.transactionProcessingID = transactionProcessingStrategy;
         return this;
     }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
index 4d9ff06bd..936dee5f4 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -98,6 +98,7 @@ public class LoanProductTestBuilder {
     private Boolean allowApprovedDisbursedAmountsOverApplied = false;
     private String overAppliedCalculationType = null;
     private Integer overAppliedNumber = null;
+    private Boolean isEqualAmortization = false;
 
     private Boolean isInterestRecalculationEnabled = false;
     private String daysInYearType = "1";
@@ -168,6 +169,7 @@ public class LoanProductTestBuilder {
         map.put("accountingRule", this.accountingRule);
         map.put("minPrincipal", this.minPrincipal);
         map.put("maxPrincipal", this.maxPrincipal);
+        map.put("isEqualAmortization", this.isEqualAmortization);
         map.put("overdueDaysForNPA", this.overdueDaysForNPA);
         if (this.minimumDaysBetweenDisbursalAndFirstRepayment != null) {
             map.put("minimumDaysBetweenDisbursalAndFirstRepayment", this.minimumDaysBetweenDisbursalAndFirstRepayment);
@@ -382,6 +384,11 @@ public class LoanProductTestBuilder {
         return this;
     }
 
+    public LoanProductTestBuilder withEqualAmortization(boolean isEqualAmortization) {
+        this.isEqualAmortization = isEqualAmortization;
+        return this;
+    }
+
     public LoanProductTestBuilder withMultiDisburse() {
         this.multiDisburseLoan = true;
         return this;
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
index ae7379972..890d2d6f2 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
@@ -42,6 +42,8 @@ import javax.ws.rs.core.MediaType;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.client.models.GetDelinquencyTagHistoryResponse;
 import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
+import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
+import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
 import org.apache.fineract.client.util.JSON;
@@ -1062,4 +1064,16 @@ public class LoanTransactionHelper {
                 "---------------------------------GET A LOAN TRANSACTION ENTITY AUDIT FIELDS---------------------------------------------");
         return Utils.performServerGet(requestSpec, responseSpec, GET_LOAN_TRANSACTION_URL, jsonReturn);
     }
+
+    public void printRepaymentSchedule(GetLoansLoanIdResponse getLoansLoanIdResponse) {
+        GetLoansLoanIdRepaymentSchedule getLoanRepaymentSchedule = getLoansLoanIdResponse.getRepaymentSchedule();
+        if (getLoanRepaymentSchedule != null) {
+            log.info("Loan with {} periods", getLoanRepaymentSchedule.getPeriods().size());
+            for (GetLoansLoanIdRepaymentPeriod period : getLoanRepaymentSchedule.getPeriods()) {
+                log.info("Period number {} for due date {} and outstanding {}", period.getPeriod(), period.getDueDate(),
+                        period.getTotalOutstandingForPeriod());
+            }
+        }
+    }
+
 }