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 d2e56edba FINERACT-1692: Allow disbursement transaction when the loan 
is fully paid/overpaid
d2e56edba is described below

commit d2e56edba61ea8c55faac8580261a7bdd3f86e3f
Author: Adam Saghy <[email protected]>
AuthorDate: Fri Aug 19 16:57:47 2022 +0200

    FINERACT-1692: Allow disbursement transaction when the loan is fully 
paid/overpaid
---
 .../sms/service/SmsCampaignDomainServiceImpl.java  |  30 ++--
 .../domain/ConfigurationDomainService.java         |   2 +-
 .../domain/ConfigurationDomainServiceJpa.java      |   6 +-
 .../domain/DefaultLoanLifecycleStateMachine.java   |   2 +-
 .../portfolio/loanaccount/domain/Loan.java         |  21 +--
 .../portfolio/loanaccount/domain/LoanCharge.java   |   8 +-
 .../service/GuarantorDomainServiceImpl.java        |   8 +-
 ...LoanScheduleCalculationPlatformServiceImpl.java |   2 +-
 .../LoanWritePlatformServiceJpaRepositoryImpl.java |  92 ++++++----
 .../integrationtests/AccountTransferTest.java      |   4 +-
 .../AccountingScenarioIntegrationTest.java         |  12 +-
 .../ClientLoanChargeExternalIntegrationTest.java   |   4 +-
 .../ClientLoanChargeRefundIntegrationTest.java     |   2 +-
 ...lanceRefundandRepaymentTypeIntegrationTest.java |   2 +-
 .../ClientLoanIntegrationTest.java                 |  66 +++----
 ...ntLoanMultipleDisbursementsIntegrationTest.java | 199 +++++++++++++++++++--
 ...rancheMultipleDisbursementsIntegrationTest.java |  10 +-
 .../ConcurrencyIntegrationTest.java                |   2 +-
 .../DisbursalAndRepaymentScheduleTest.java         |   4 +-
 .../fineract/integrationtests/GroupTest.java       |   2 +-
 .../LoanApplicationUndoLastTrancheTest.java        |   6 +-
 .../LoanDisbursalDateValidationTest.java           |   2 +-
 .../LoanRescheduleOnDecliningBalanceLoanTest.java  |   2 +-
 .../LoanRescheduleRequestTest.java                 |   2 +-
 .../LoanRescheduleWithAdvancePaymentTest.java      |   2 +-
 .../LoanReschedulingWithinCenterTest.java          |   6 +-
 .../LoanTransactionAuditingIntegrationTest.java    |   2 +-
 ...ithWaiveInterestAndWriteOffIntegrationTest.java |   6 +-
 ...mDaysBetweenDisbursalAndFirstRepaymentTest.java |   2 +-
 .../fineract/integrationtests/NotesTest.java       |   9 +-
 .../integrationtests/SchedulerJobsTestResults.java |  18 +-
 .../common/ProvisioningIntegrationTest.java        |   2 +-
 .../common/loans/LoanTransactionHelper.java        |  14 +-
 .../integrationtests/guarantor/GuarantorTest.java  |  10 +-
 34 files changed, 393 insertions(+), 168 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
index a7b2aae0d..b08ba403d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
@@ -26,6 +26,7 @@ import java.security.InvalidParameterException;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -44,6 +45,7 @@ import 
org.apache.fineract.infrastructure.sms.domain.SmsMessageRepository;
 import 
org.apache.fineract.infrastructure.sms.scheduler.SmsMessageScheduledJobService;
 import org.apache.fineract.organisation.office.domain.Office;
 import org.apache.fineract.organisation.office.domain.OfficeRepository;
+import 
org.apache.fineract.organisation.office.exception.OfficeNotFoundException;
 import org.apache.fineract.portfolio.businessevent.BusinessEventListener;
 import 
org.apache.fineract.portfolio.businessevent.domain.client.ClientActivateBusinessEvent;
 import 
org.apache.fineract.portfolio.businessevent.domain.client.ClientRejectBusinessEvent;
@@ -58,6 +60,7 @@ import 
org.apache.fineract.portfolio.businessevent.service.BusinessEventNotifier
 import org.apache.fineract.portfolio.client.domain.Client;
 import org.apache.fineract.portfolio.group.domain.Group;
 import org.apache.fineract.portfolio.group.domain.GroupRepository;
+import org.apache.fineract.portfolio.group.exception.GroupNotFoundException;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
 import 
org.apache.fineract.portfolio.loanaccount.exception.InvalidLoanTypeException;
@@ -169,13 +172,16 @@ public class SmsCampaignDomainServiceImpl implements 
SmsCampaignDomainService {
                         throw new InvalidLoanTypeException("Loan Type cannot 
be Invalid for the Triggered Sms Campaign");
                     }
                     if (loan.isGroupLoan()) {
-                        Group group = 
this.groupRepository.findById(loan.getGroupId()).orElse(null);
+                        Group group = 
this.groupRepository.findById(loan.getGroupId())
+                                .orElseThrow(() -> new 
GroupNotFoundException(loan.getGroupId()));
                         groupClients.addAll(group.getClientMembers());
                     } else {
                         groupClients.add(loan.client());
                     }
                     HashMap<String, String> campaignParams = new 
ObjectMapper().readValue(smsCampaign.getParamValue(),
-                            new TypeReference<HashMap<String, String>>() {});
+                            new TypeReference<>() {
+
+                            });
 
                     if (groupClients.size() > 0) {
                         for (Client client : groupClients) {
@@ -189,7 +195,9 @@ public class SmsCampaignDomainServiceImpl implements 
SmsCampaignDomainService {
                                 }
                                 if (spkeycheck && !(value.equals("-1") || 
spvalue.equals(value))) {
                                     if (key.equals("officeId")) {
-                                        Office campaignOffice = 
this.officeRepository.findById(Long.valueOf(value)).orElse(null);
+                                        Long officeId = Long.valueOf(value);
+                                        Office campaignOffice = 
this.officeRepository.findById(Long.valueOf(value))
+                                                .orElseThrow(() -> new 
OfficeNotFoundException(officeId));
                                         if 
(campaignOffice.doesNotHaveAnOfficeInHierarchyWithId(client.getOffice().getId()))
 {
                                             throw new 
SmsRuntimeException("error.msg.no.office", "Office not found for the id");
                                         }
@@ -208,10 +216,8 @@ public class SmsCampaignDomainServiceImpl implements 
SmsCampaignDomainService {
                                 }
                                 SmsMessage smsMessage = 
SmsMessage.pendingSms(null, null, client, null, message, mobileNumber, 
smsCampaign,
                                         smsCampaign.isNotification());
-                                Collection<SmsMessage> messages = new 
ArrayList<>();
-                                messages.add(smsMessage);
                                 Map<SmsCampaign, Collection<SmsMessage>> 
smsDataMap = new HashMap<>();
-                                smsDataMap.put(smsCampaign, messages);
+                                smsDataMap.put(smsCampaign, 
Collections.singletonList(smsMessage));
                                 
this.smsMessageScheduledJobService.sendTriggeredMessages(smsDataMap);
                             }
                         }
@@ -234,7 +240,9 @@ public class SmsCampaignDomainServiceImpl implements 
SmsCampaignDomainService {
                     final SavingsAccount savingsAccount = 
savingsTransaction.getSavingsAccount();
                     final Client client = savingsAccount.getClient();
                     HashMap<String, String> campaignParams = new 
ObjectMapper().readValue(smsCampaign.getParamValue(),
-                            new TypeReference<HashMap<String, String>>() {});
+                            new TypeReference<>() {
+
+                            });
                     HashMap<String, Object> smsParams = 
processSavingsTransactionDataForSms(savingsTransaction, client);
                     for (String key : campaignParams.keySet()) {
                         String value = campaignParams.get(key);
@@ -245,7 +253,9 @@ public class SmsCampaignDomainServiceImpl implements 
SmsCampaignDomainService {
                         }
                         if (spkeycheck && !(value.equals("-1") || 
spvalue.equals(value))) {
                             if (key.equals("officeId")) {
-                                Office campaignOffice = 
this.officeRepository.findById(Long.valueOf(value)).orElse(null);
+                                Long officeId = Long.valueOf(value);
+                                Office campaignOffice = 
this.officeRepository.findById(officeId)
+                                        .orElseThrow(() -> new 
OfficeNotFoundException(officeId));
                                 if 
(campaignOffice.doesNotHaveAnOfficeInHierarchyWithId(client.getOffice().getId()))
 {
                                     throw new 
SmsRuntimeException("error.msg.no.office", "Office not found for the id");
                                 }
@@ -308,7 +318,7 @@ public class SmsCampaignDomainServiceImpl implements 
SmsCampaignDomainService {
         smsParams.put("lastname", client.getLastname());
         smsParams.put("FullName", client.getDisplayName());
         smsParams.put("mobileNo", client.mobileNo());
-        smsParams.put("LoanAmount", loan.getPrincpal());
+        smsParams.put("LoanAmount", loan.getPrincipal());
         smsParams.put("LoanOutstanding", 
loanTransaction.getOutstandingLoanBalance());
         smsParams.put("loanId", loan.getId());
         smsParams.put("LoanAccountId", loan.getAccountNumber());
@@ -340,7 +350,7 @@ public class SmsCampaignDomainServiceImpl implements 
SmsCampaignDomainService {
         // {{balance}}
 
         // transactionDate
-        HashMap<String, Object> smsParams = new HashMap<String, Object>();
+        HashMap<String, Object> smsParams = new HashMap<>();
         SavingsAccount savingsAccount = 
savingsAccountTransaction.getSavingsAccount();
         DateTimeFormatter dateFormatter = 
DateTimeFormatter.ofPattern("MMM:d:yyyy");
         smsParams.put("clientId", client.getId());
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
index 14b92f646..f87ec0f32 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
@@ -69,7 +69,7 @@ public interface ConfigurationDomainService {
 
     LocalDate retrieveOrganisationStartDate();
 
-    boolean isPaymnetypeApplicableforDisbursementCharge();
+    boolean isPaymentTypeApplicableForDisbursementCharge();
 
     boolean isInterestChargedFromDateSameAsDisbursementDate();
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
index d77071f55..f7f7b5f1b 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
@@ -245,7 +245,7 @@ public class ConfigurationDomainServiceJpa implements 
ConfigurationDomainService
     }
 
     @Override
-    public boolean isPaymnetypeApplicableforDisbursementCharge() {
+    public boolean isPaymentTypeApplicableForDisbursementCharge() {
         final String propertyName = 
"paymenttype-applicable-for-disbursement-charges";
         final GlobalConfigurationPropertyData property = 
getGlobalConfigurationPropertyData(propertyName);
         return property.isEnabled();
@@ -372,13 +372,13 @@ public class ConfigurationDomainServiceJpa implements 
ConfigurationDomainService
         final String propertyName = 
"allow-backdated-transaction-before-interest-posting-date-for-days";
         final GlobalConfigurationPropertyData property = 
getGlobalConfigurationPropertyData(propertyName);
         if (property.getValue() == null) {
-            return Long.valueOf(0);
+            return 0L;
         }
         return property.getValue();
     }
 
     @Cacheable(value = "configByName", key = 
"T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#propertyName)")
-    private GlobalConfigurationPropertyData 
getGlobalConfigurationPropertyData(final String propertyName) {
+    public GlobalConfigurationPropertyData 
getGlobalConfigurationPropertyData(final String propertyName) {
         String identifier = 
ThreadLocalContextUtil.getTenant().getTenantIdentifier();
         String key = identifier + "_" + propertyName;
         if (!configurations.containsKey(key)) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachine.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachine.java
index 1da59cc4c..be0a5cd3c 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachine.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachine.java
@@ -55,7 +55,7 @@ public class DefaultLoanLifecycleStateMachine implements 
LoanLifecycleStateMachi
                 }
             break;
             case LOAN_DISBURSED:
-                if (from.hasStateOf(LoanStatus.APPROVED)) {
+                if (anyOfAllowedWhenComingFrom(from, LoanStatus.APPROVED, 
LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.OVERPAID)) {
                     newState = stateOf(LoanStatus.ACTIVE, 
this.allowedLoanStatuses);
                 }
             break;
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 e651117c6..5ca69a919 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
@@ -902,7 +902,7 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
                 if (isMultiDisburmentLoan() && 
loanCharge.isDisbursementCharge()) {
                     amount = 
getTotalAllTrancheDisbursementAmount().getAmount().add(totalInterestCharged);
                 } else {
-                    amount = 
getPrincpal().getAmount().add(totalInterestCharged);
+                    amount = 
getPrincipal().getAmount().add(totalInterestCharged);
                 }
             break;
             case PERCENT_OF_INTEREST:
@@ -912,7 +912,7 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
                 if (loanCharge.getTrancheDisbursementCharge() != null) {
                     amount = 
loanCharge.getTrancheDisbursementCharge().getloanDisbursementDetails().principal();
                 } else {
-                    amount = getPrincpal().getAmount();
+                    amount = getPrincipal().getAmount();
                 }
             break;
             default:
@@ -1306,7 +1306,6 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
             if 
(loanTransaction.getInterestPortion(getCurrency()).isGreaterThanZero()) {
                 if 
(loanTransaction.getInterestPortion(getCurrency()).isNotEqualTo(interestApplied))
 {
                     loanTransaction.reverse();
-                    final LocalDateTime currentDateTime = 
DateUtils.getLocalDateTimeOfTenant();
                     final LoanTransaction interestAppliedTransaction = 
LoanTransaction.accrueInterest(getOffice(), this, interestApplied,
                             getDisbursementDate());
                     addLoanTransaction(interestAppliedTransaction);
@@ -2537,7 +2536,9 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
                 LoanStatus.fromInt(this.loanStatus));
 
         boolean isMultiTrancheDisburse = false;
-        if (LoanStatus.fromInt(this.loanStatus).isActive() && 
isAllTranchesNotDisbursed()) {
+        LoanStatus actualLoanStatus = LoanStatus.fromInt(this.loanStatus);
+        if ((actualLoanStatus.isActive() || 
actualLoanStatus.isClosedObligationsMet() || actualLoanStatus.isOverpaid())
+                && isAllTranchesNotDisbursed()) {
             LoanDisbursementDetails details = fetchLastDisburseDetail();
 
             if (details != null) {
@@ -2550,7 +2551,7 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
             }
             isMultiTrancheDisburse = true;
         }
-        return !statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus)) || 
isMultiTrancheDisburse;
+        return !statusEnum.hasStateOf(actualLoanStatus) || 
isMultiTrancheDisburse;
     }
 
     public Money adjustDisburseAmount(final JsonCommand command, final 
LocalDate actualDisbursementDate) {
@@ -4021,9 +4022,9 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
     }
 
     private boolean isAllTranchesNotDisbursed() {
-        return this.loanProduct.isMultiDisburseLoan()
-                && (LoanStatus.fromInt(this.loanStatus).isActive() || 
LoanStatus.fromInt(this.loanStatus).isApproved())
-                && isDisbursementAllowed();
+        LoanStatus actualLoanStatus = LoanStatus.fromInt(this.loanStatus);
+        return this.loanProduct.isMultiDisburseLoan() && 
(actualLoanStatus.isActive() || actualLoanStatus.isApproved()
+                || actualLoanStatus.isClosedObligationsMet() || 
actualLoanStatus.isOverpaid()) && isDisbursementAllowed();
     }
 
     private boolean hasDisbursementTransaction() {
@@ -4193,7 +4194,7 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
         return this.interestChargedFromDate;
     }
 
-    public Money getPrincpal() {
+    public Money getPrincipal() {
         return this.loanRepaymentScheduleDetail.getPrincipal();
     }
 
@@ -6399,7 +6400,7 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom {
                     }
                 }
             } else {
-                amount = getPrincpal().getAmount();
+                amount = getPrincipal().getAmount();
             }
         }
         return amount;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java
index 9d04250cf..09079b4ca 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java
@@ -158,7 +158,7 @@ public class LoanCharge extends AbstractPersistableCustom {
                 if (command.hasParameter("principal")) {
                     amountPercentageAppliedTo = 
command.bigDecimalValueOfParameterNamed("principal");
                 } else {
-                    amountPercentageAppliedTo = loan.getPrincpal().getAmount();
+                    amountPercentageAppliedTo = 
loan.getPrincipal().getAmount();
                 }
             break;
             case PERCENT_OF_AMOUNT_AND_INTEREST:
@@ -166,7 +166,7 @@ public class LoanCharge extends AbstractPersistableCustom {
                     amountPercentageAppliedTo = 
command.bigDecimalValueOfParameterNamed("principal")
                             
.add(command.bigDecimalValueOfParameterNamed("interest"));
                 } else {
-                    amountPercentageAppliedTo = 
loan.getPrincpal().getAmount().add(loan.getTotalInterest());
+                    amountPercentageAppliedTo = 
loan.getPrincipal().getAmount().add(loan.getTotalInterest());
                 }
             break;
             case PERCENT_OF_INTEREST:
@@ -448,11 +448,11 @@ public class LoanCharge extends AbstractPersistableCustom 
{
                             }
                         }
                     } else {
-                        amountPercentageAppliedTo = 
this.loan.getPrincpal().getAmount();
+                        amountPercentageAppliedTo = 
this.loan.getPrincipal().getAmount();
                     }
                 break;
                 case PERCENT_OF_AMOUNT_AND_INTEREST:
-                    amountPercentageAppliedTo = 
this.loan.getPrincpal().getAmount().add(this.loan.getTotalInterest());
+                    amountPercentageAppliedTo = 
this.loan.getPrincipal().getAmount().add(this.loan.getTotalInterest());
                 break;
                 case PERCENT_OF_INTEREST:
                     amountPercentageAppliedTo = this.loan.getTotalInterest();
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorDomainServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorDomainServiceImpl.java
index 4c795b962..0a651af89 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorDomainServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorDomainServiceImpl.java
@@ -99,7 +99,7 @@ public class GuarantorDomainServiceImpl implements 
GuarantorDomainService {
     @Override
     public void validateGuarantorBusinessRules(Loan loan) {
         LoanProduct loanProduct = loan.loanProduct();
-        BigDecimal principal = loan.getPrincpal().getAmount();
+        BigDecimal principal = loan.getPrincipal().getAmount();
         if (loanProduct.isHoldGuaranteeFundsEnabled()) {
             LoanProductGuaranteeDetails guaranteeData = 
loanProduct.getLoanProductGuaranteeDetails();
             final List<Guarantor> existGuarantorList = 
this.guarantorRepository.findByLoan(loan);
@@ -241,8 +241,8 @@ public class GuarantorDomainServiceImpl implements 
GuarantorDomainService {
                     releaseLoanIds.put(loanId, 
guarantorFundingDetails.getId());
                     try {
                         BigDecimal remainingAmount = 
guarantorFundingDetails.getAmountRemaining();
-                        if 
(loan.getGuaranteeAmount().compareTo(loan.getPrincpal().getAmount()) > 0) {
-                            remainingAmount = 
remainingAmount.multiply(loan.getPrincpal().getAmount()).divide(loan.getGuaranteeAmount(),
+                        if 
(loan.getGuaranteeAmount().compareTo(loan.getPrincipal().getAmount()) > 0) {
+                            remainingAmount = 
remainingAmount.multiply(loan.getPrincipal().getAmount()).divide(loan.getGuaranteeAmount(),
                                     MoneyHelper.getRoundingMode());
                         }
                         AccountTransferDTO accountTransferDTO = new 
AccountTransferDTO(transactionDate, remainingAmount, fromAccountType,
@@ -393,7 +393,7 @@ public class GuarantorDomainServiceImpl implements 
GuarantorDomainService {
 
             BigDecimal amountForRelease = 
loanTransaction.getPrincipalPortion();
             BigDecimal totalGuaranteeAmount = loan.getGuaranteeAmount();
-            BigDecimal principal = loan.getPrincpal().getAmount();
+            BigDecimal principal = loan.getPrincipal().getAmount();
             if ((amountForRelease != null) && (totalGuaranteeAmount != null)) {
                 amountForRelease = 
amountForRelease.multiply(totalGuaranteeAmount).divide(principal, 
MoneyHelper.getRoundingMode());
                 List<DepositAccountOnHoldTransaction> 
accountOnHoldTransactions = new ArrayList<>();
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
index 2dbaaa154..c10ea9182 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
@@ -218,7 +218,7 @@ public class LoanScheduleCalculationPlatformServiceImpl 
implements LoanScheduleC
         Collection<LoanRepaymentScheduleInstallment> installments = 
loan.getRepaymentScheduleInstallments();
         final List<LoanSchedulePeriodData> installmentData = new ArrayList<>();
         final MonetaryCurrency currency = loan.getCurrency();
-        Money outstanding = loan.getPrincpal();
+        Money outstanding = loan.getPrincipal();
 
         List<LoanDisbursementDetails> disbursementDetails = new ArrayList<>();
         if (loan.isMultiDisburmentLoan()) {
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 833c4c3e4..aba9c411d 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
@@ -166,6 +166,7 @@ import 
org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtio
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanOverdueInstallmentCharge;
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
+import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository;
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
@@ -266,6 +267,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
     private final RepaymentWithPostDatedChecksAssembler 
repaymentWithPostDatedChecksAssembler;
     private final PostDatedChecksRepository postDatedChecksRepository;
 
+    private final LoanRepaymentScheduleInstallmentRepository 
loanRepaymentScheduleInstallmentRepository;
+
     private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
         final List<LoanStatus> allowedLoanStatuses = 
Arrays.asList(LoanStatus.values());
         return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses);
@@ -307,16 +310,25 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             
this.loanEventApiJsonValidator.validateDisbursementWithPostDatedChecks(command.json(),
 loanId);
         }
 
-        final Loan loan = this.loanAssembler.assembleFrom(loanId);
+        Loan loan = this.loanAssembler.assembleFrom(loanId);
+        // Fail fast if client/group is not active or actual loan status 
disallows disbursal
+        checkClientOrGroupActive(loan);
         if (loan.loanProduct().isDisallowExpectedDisbursements()) {
-            // create artificial 'tranche/expected disbursal' as current 
disburse code expects it for multi-disbursal
-            // products
-            final LocalDate artificialExpectedDate = 
loan.getExpectedDisbursedOnLocalDate();
-            LoanDisbursementDetails disbursementDetail = new 
LoanDisbursementDetails(artificialExpectedDate, null,
-                    loan.getDisbursedAmount(), null);
-            disbursementDetail.updateLoan(loan);
-            loan.getDisbursementDetails().add(disbursementDetail);
+            List<LoanDisbursementDetails> filteredList = 
loan.getDisbursementDetails().stream()
+                    .filter(disbursementDetails -> 
disbursementDetails.actualDisbursementDate() == null).toList();
+            // Check whether a new LoanDisbursementDetails is required
+            if (filteredList.isEmpty()) {
+                // create artificial 'tranche/expected disbursal' as current 
disburse code expects it for
+                // multi-disbursal
+                // products
+                final LocalDate artificialExpectedDate = 
loan.getExpectedDisbursedOnLocalDate();
+                LoanDisbursementDetails disbursementDetail = new 
LoanDisbursementDetails(artificialExpectedDate, null,
+                        loan.getDisbursedAmount(), null);
+                disbursementDetail.updateLoan(loan);
+                loan.getDisbursementDetails().add(disbursementDetail);
+            }
         }
+        loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
 
         // Get disbursedAmount
         final BigDecimal disbursedAmount = loan.getDisbursedAmount();
@@ -348,7 +360,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
         if (loanProduct.syncExpectedWithDisbursementDate()) {
             syncExpectedDateWithActualDisbursementDate(loan, 
actualDisbursementDate);
         }
-        checkClientOrGroupActive(loan);
 
         final LocalDate nextPossibleRepaymentDate = 
loan.getNextPossibleRepaymentDateForRescheduling();
         final LocalDate rescheduledRepaymentDate = 
command.localDateValueOfParameterNamed("adjustRepaymentDate");
@@ -382,13 +393,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             BigDecimal transactionAmount = 
command.bigDecimalValueOfParameterNamed("transactionAmount");
             
this.cashierTransactionDataValidator.validateOnLoanDisbursal(currentUser, 
loan.getCurrencyCode(), transactionAmount);
         }
-        final Boolean isPaymnetypeApplicableforDisbursementCharge = 
configurationDomainService
-                .isPaymnetypeApplicableforDisbursementCharge();
+        final boolean isPaymentTypeApplicableForDisbursementCharge = 
configurationDomainService
+                .isPaymentTypeApplicableForDisbursementCharge();
 
         // Recalculate first repayment date based in actual disbursement date.
         updateLoanCounters(loan, actualDisbursementDate);
-        Money amountBeforeAdjust = loan.getPrincpal();
-        loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
+        Money amountBeforeAdjust = loan.getPrincipal();
         boolean canDisburse = loan.canDisburse(actualDisbursementDate);
         ChangedTransactionDetail changedTransactionDetail = null;
         if (canDisburse) {
@@ -401,7 +411,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             }
             Money disburseAmount = loan.adjustDisburseAmount(command, 
actualDisbursementDate);
             Money amountToDisburse = disburseAmount.copy();
-            boolean recalculateSchedule = 
amountBeforeAdjust.isNotEqualTo(loan.getPrincpal());
+            boolean recalculateSchedule = 
amountBeforeAdjust.isNotEqualTo(loan.getPrincipal());
             final String txnExternalId = 
command.stringValueOfParameterNamedAllowingNull("externalId");
 
             if (loan.isTopup() && loan.getClientId() != null) {
@@ -456,7 +466,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             if 
(loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
                 createAndSaveLoanScheduleArchive(loan, scheduleGeneratorDTO);
             }
-            if (isPaymnetypeApplicableforDisbursementCharge) {
+            if (isPaymentTypeApplicableForDisbursementCharge) {
                 changedTransactionDetail = loan.disburse(currentUser, command, 
changes, scheduleGeneratorDTO, paymentDetail);
             } else {
                 changedTransactionDetail = loan.disburse(currentUser, command, 
changes, scheduleGeneratorDTO, null);
@@ -465,7 +475,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             loan.adjustNetDisbursalAmount(amountToDisburse.getAmount());
         }
         if (!changes.isEmpty()) {
-            saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
+
+            loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
 
             final String noteText = 
command.stringValueOfParameterNamed("note");
             if (StringUtils.isNotBlank(noteText)) {
@@ -609,9 +620,17 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
 
     }
 
-    private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan 
loan) {
+    private Loan saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan 
loan) {
+        /*
+         * Due to the "saveAndFlushLoanWithDataIntegrityViolationChecks" 
method the loan is saved and flushed in the
+         * middle of the transaction. EclipseLink is in some situations are 
saving inconsistently the newly created
+         * associations, like the newly created repayment schedule 
installments. The save and flush cannot be removed
+         * safely till any native queries are used as part of this transaction 
either. See:
+         * this.loanAccountDomainService.recalculateAccruals(loan);
+         */
         try {
-            this.loanRepositoryWrapper.saveAndFlush(loan);
+            
loanRepaymentScheduleInstallmentRepository.saveAll(loan.getRepaymentScheduleInstallments());
+            return this.loanRepositoryWrapper.saveAndFlush(loan);
         } catch (final JpaSystemException | DataIntegrityViolationException e) 
{
             final Throwable realCause = e.getCause();
             final List<ApiParameterError> dataValidationErrors = new 
ArrayList<>();
@@ -623,6 +642,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
                 throw new 
PlatformApiDataValidationException("validation.msg.validation.errors.exist", 
"Validation errors exist.",
                         dataValidationErrors, e);
             }
+            throw e;
         }
     }
 
@@ -664,7 +684,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
         final LocalDate rescheduledRepaymentDate = null;
 
         for (final SingleDisbursalCommand singleLoanDisbursalCommand : 
disbursalCommand) {
-            final Loan loan = 
this.loanAssembler.assembleFrom(singleLoanDisbursalCommand.getLoanId());
+            Loan loan = 
this.loanAssembler.assembleFrom(singleLoanDisbursalCommand.getLoanId());
             final LocalDate actualDisbursementDate = 
command.localDateValueOfParameterNamed("actualDisbursementDate");
 
             // validate ActualDisbursement Date Against Expected Disbursement
@@ -692,9 +712,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             boolean canDisburse = loan.canDisburse(actualDisbursementDate);
             ChangedTransactionDetail changedTransactionDetail = null;
             if (canDisburse) {
-                Money amountBeforeAdjust = loan.getPrincpal();
+                Money amountBeforeAdjust = loan.getPrincipal();
                 Money disburseAmount = loan.adjustDisburseAmount(command, 
actualDisbursementDate);
-                boolean recalculateSchedule = 
amountBeforeAdjust.isNotEqualTo(loan.getPrincpal());
+                boolean recalculateSchedule = 
amountBeforeAdjust.isNotEqualTo(loan.getPrincipal());
                 final String txnExternalId = 
command.stringValueOfParameterNamedAllowingNull("externalId");
                 if (isAccountTransfer) {
                     disburseLoanToSavings(loan, command, disburseAmount, 
paymentDetail);
@@ -716,7 +736,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
                 if 
(loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
                     createAndSaveLoanScheduleArchive(loan, 
scheduleGeneratorDTO);
                 }
-                if 
(configurationDomainService.isPaymnetypeApplicableforDisbursementCharge()) {
+                if 
(configurationDomainService.isPaymentTypeApplicableForDisbursementCharge()) {
                     changedTransactionDetail = loan.disburse(currentUser, 
command, changes, scheduleGeneratorDTO, paymentDetail);
                 } else {
                     changedTransactionDetail = loan.disburse(currentUser, 
command, changes, scheduleGeneratorDTO, null);
@@ -724,7 +744,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             }
             if (!changes.isEmpty()) {
 
-                saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
+                loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
 
                 final String noteText = 
command.stringValueOfParameterNamed("note");
                 if (StringUtils.isNotBlank(noteText)) {
@@ -800,7 +820,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
     @Override
     public CommandProcessingResult undoLoanDisbursal(final Long loanId, final 
JsonCommand command) {
 
-        final Loan loan = this.loanAssembler.assembleFrom(loanId);
+        Loan loan = this.loanAssembler.assembleFrom(loanId);
         checkClientOrGroupActive(loan);
         businessEventNotifierService.notifyPreBusinessEvent(new 
LoanUndoDisbursalBusinessEvent(loan));
         removeLoanCycle(loan);
@@ -830,7 +850,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
                 BigDecimal netDisbursalAmount = 
loan.getApprovedPrincipal().subtract(loanOutstanding);
                 loan.adjustNetDisbursalAmount(netDisbursalAmount);
             }
-            saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
+            loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
             
this.accountTransfersWritePlatformService.reverseAllTransactions(loanId, 
PortfolioAccountType.LOAN);
             String noteText = null;
             if (command.hasParameter("note")) {
@@ -1010,7 +1030,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
 
         this.loanEventApiJsonValidator.validateTransaction(command.json());
 
-        final Loan loan = this.loanAssembler.assembleFrom(loanId);
+        Loan loan = this.loanAssembler.assembleFrom(loanId);
         if (loan.status().isClosed() && loan.getLoanSubStatus() != null
                 && 
loan.getLoanSubStatus().equals(LoanSubStatus.FORECLOSED.getValue())) {
             final String defaultUserMessage = "The loan cannot reopend as it 
is foreclosed.";
@@ -1076,7 +1096,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
                 defaultLoanLifecycleStateMachine(), transactionToAdjust, 
existingTransactionIds, existingReversedTransactionIds,
                 scheduleGeneratorDTO, reversalExternalId);
 
-        if 
(newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
+        if 
(newTransactionDetail.isGreaterThanZero(loan.getPrincipal().getCurrency())) {
             if (paymentDetail != null) {
                 
this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail);
             }
@@ -1088,7 +1108,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
          * time being, not a major issue for now as this loop is entered only 
in edge cases (when a adjustment is made
          * before the latest payment recorded against the loan)
          ***/
-        saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
+        loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
         if (changedTransactionDetail != null) {
             for (final Map.Entry<Long, LoanTransaction> mapEntry : 
changedTransactionDetail.getNewTransactionMappings().entrySet()) {
                 this.loanTransactionRepository.save(mapEntry.getValue());
@@ -1105,7 +1125,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             /**
              * If a new transaction is not created, associate note with the 
transaction to be adjusted
              **/
-            if 
(newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
+            if 
(newTransactionDetail.isGreaterThanZero(loan.getPrincipal().getCurrency())) {
                 note = Note.loanTransactionNote(loan, newTransactionDetail, 
noteText);
             } else {
                 note = Note.loanTransactionNote(loan, transactionToAdjust, 
noteText);
@@ -1131,7 +1151,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
 
         this.loanAccountDomainService.recalculateAccruals(loan);
         LoanAdjustTransactionBusinessEvent.Data eventData = new 
LoanAdjustTransactionBusinessEvent.Data(transactionToAdjust);
-        if (newTransactionDetail.isRepaymentType() && 
newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
+        if (newTransactionDetail.isRepaymentType() && 
newTransactionDetail.isGreaterThanZero(loan.getPrincipal().getCurrency())) {
             eventData.setNewTransactionDetail(newTransactionDetail);
         }
         businessEventNotifierService.notifyPostBusinessEvent(new 
LoanAdjustTransactionBusinessEvent(eventData));
@@ -1157,7 +1177,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
         final LocalDate transactionDate = 
command.localDateValueOfParameterNamed("transactionDate");
         final BigDecimal transactionAmount = 
command.bigDecimalValueOfParameterNamed("transactionAmount");
 
-        final Loan loan = this.loanAssembler.assembleFrom(loanId);
+        Loan loan = this.loanAssembler.assembleFrom(loanId);
         checkClientOrGroupActive(loan);
 
         final List<Long> existingTransactionIds = new ArrayList<>();
@@ -1192,7 +1212,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
          * time being, not a major issue for now as this loop is entered only 
in edge cases (when a waiver is made
          * before the latest payment recorded against the loan)
          ***/
-        saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
+        loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
         if (changedTransactionDetail != null) {
             for (final Map.Entry<Long, LoanTransaction> mapEntry : 
changedTransactionDetail.getNewTransactionMappings().entrySet()) {
                 this.loanTransactionRepository.save(mapEntry.getValue());
@@ -2961,7 +2981,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
 
     }
 
-    private CommandProcessingResult processLoanDisbursementDetail(final Loan 
loan, Long loanId, JsonCommand command,
+    private CommandProcessingResult processLoanDisbursementDetail(Loan loan, 
Long loanId, JsonCommand command,
             LoanDisbursementDetails loanDisbursementDetails) {
         final List<Long> existingTransactionIds = new ArrayList<>();
         final List<Long> existingReversedTransactionIds = new ArrayList<>();
@@ -2998,7 +3018,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             }
         }
 
-        saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
+        loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
 
         if (command.entityId() != null && changedTransactionDetail != null) {
             for (Map.Entry<Long, LoanTransaction> mapEntry : 
changedTransactionDetail.getNewTransactionMappings().entrySet()) {
@@ -3275,7 +3295,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
     @Transactional
     public CommandProcessingResult undoLastLoanDisbursal(Long loanId, 
JsonCommand command) {
 
-        final Loan loan = this.loanAssembler.assembleFrom(loanId);
+        Loan loan = this.loanAssembler.assembleFrom(loanId);
         final LocalDate recalculateFromDate = loan.getLastRepaymentDate();
         validateIsMultiDisbursalLoanAndDisbursedMoreThanOneTranche(loan);
         checkClientOrGroupActive(loan);
@@ -3291,7 +3311,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
         final Map<String, Object> changes = 
loan.undoLastDisbursal(scheduleGeneratorDTO, existingTransactionIds,
                 existingReversedTransactionIds, loan);
         if (!changes.isEmpty()) {
-            saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
+            loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
             String noteText = null;
             if (command.hasParameter("note")) {
                 noteText = command.stringValueOfParameterNamed("note");
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java
index eec29b43f..110901d6f 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java
@@ -271,7 +271,7 @@ public class AccountTransferTest {
         LoanStatusChecker.verifyLoanIsApproved(toLoanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
toLoanID);
-        toLoanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSAL_DATE, toLoanID,
+        toLoanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSAL_DATE,
 toLoanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(toLoanStatusHashMap);
 
@@ -391,7 +391,7 @@ public class AccountTransferTest {
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSAL_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSAL_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountingScenarioIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountingScenarioIntegrationTest.java
index a0ae3bf2d..81c3fb52f 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountingScenarioIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountingScenarioIntegrationTest.java
@@ -165,7 +165,7 @@ public class AccountingScenarioIntegrationTest {
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(EXPECTED_DISBURSAL_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -601,7 +601,7 @@ public class AccountingScenarioIntegrationTest {
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(EXPECTED_DISBURSAL_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -725,7 +725,7 @@ public class AccountingScenarioIntegrationTest {
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(EXPECTED_DISBURSAL_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -818,7 +818,7 @@ public class AccountingScenarioIntegrationTest {
         zonedDate = currentDate.minusDays(2);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -924,7 +924,7 @@ public class AccountingScenarioIntegrationTest {
         todayDate.add(Calendar.DATE, -2);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -1026,7 +1026,7 @@ public class AccountingScenarioIntegrationTest {
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(EXPECTED_DISBURSAL_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanChargeExternalIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanChargeExternalIntegrationTest.java
index 115c3471f..4e52851d7 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanChargeExternalIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanChargeExternalIntegrationTest.java
@@ -75,7 +75,7 @@ public class ClientLoanChargeExternalIntegrationTest {
         final Integer loanID = applyForLoanApplication(clientID, 
loanProductID, null, null, "12,000.00", collaterals);
         HashMap loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 
September 2011", loanID);
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID, "12,000.00");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID, "12,000.00");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
         final Integer charge = ChargesHelper.createCharges(requestSpec, 
responseSpec, ChargesHelper
@@ -105,7 +105,7 @@ public class ClientLoanChargeExternalIntegrationTest {
         final Integer loanID = applyForLoanApplication(clientID, 
loanProductID, null, null, "12,000.00", collaterals);
         HashMap loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 
September 2011", loanID);
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID, "12,000.00");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID, "12,000.00");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
         final Integer charge = ChargesHelper.createCharges(requestSpec, 
responseSpec, ChargesHelper
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanChargeRefundIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanChargeRefundIntegrationTest.java
index 2d8619216..bfc707771 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanChargeRefundIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanChargeRefundIntegrationTest.java
@@ -460,7 +460,7 @@ public class ClientLoanChargeRefundIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE LOAN 
-------------------------------------------"); //
         // String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(submitApproveDisburseDate, loanID, 
principal);
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(submitApproveDisburseDate,
 loanID, principal);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
         return loanID;
     }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java
index a31a568ec..d1a0ba88d 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java
@@ -153,7 +153,7 @@ public class 
ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE LOAN 
-------------------------------------------"); //
         // String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(submitApproveDisburseDate, loanID, 
principal);
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(submitApproveDisburseDate,
 loanID, principal);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
         return loanID;
     }
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 632b24bbe..05589ef69 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
@@ -312,7 +312,7 @@ public class ClientLoanIntegrationTest {
 
         // DISBURSE
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID, "10000",
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID, "10000",
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap.toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -353,7 +353,7 @@ public class ClientLoanIntegrationTest {
 
         // DISBURSE on todays date so that loan can't be in arrears
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, "10000",
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID, "10000",
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap.toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -500,7 +500,7 @@ public class ClientLoanIntegrationTest {
 
         // DISBURSE
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID, "10000",
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID, "10000",
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap.toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -750,7 +750,7 @@ public class ClientLoanIntegrationTest {
 
         // DISBURSE
         String loanDetail = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID, "10000",
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID, "10000",
                 
JsonPath.from(loanDetail).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap.toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -989,13 +989,13 @@ public class ClientLoanIntegrationTest {
 
         // DISBURSE first Tranche
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 March 
2014", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 March 2014", 
loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
         // DISBURSE Second Tranche
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("23 April 
2014", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("23 April 2014", 
loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap.toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -1590,7 +1590,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -1781,7 +1781,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -1973,7 +1973,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -2161,7 +2161,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -2370,7 +2370,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -2568,7 +2568,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -2773,7 +2773,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -2975,7 +2975,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -3179,7 +3179,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -3400,7 +3400,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -3551,7 +3551,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -3661,7 +3661,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -3746,7 +3746,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -3843,7 +3843,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -3977,7 +3977,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -4111,7 +4111,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -4205,7 +4205,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -4317,7 +4317,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -4418,7 +4418,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -4503,7 +4503,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -4593,7 +4593,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -4859,7 +4859,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(fourMonthsfromNow,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -5044,7 +5044,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(fourMonthsfromNow,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -5240,7 +5240,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(fourMonthsfromNow,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -5472,7 +5472,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("----------------------------------- DISBURSE LOAN 
----------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID, "10,000.00",
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID, "10,000.00",
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -5540,7 +5540,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -5655,7 +5655,7 @@ public class ClientLoanIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(LOAN_DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanMultipleDisbursementsIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanMultipleDisbursementsIntegrationTest.java
index e50b79061..aac19d677 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanMultipleDisbursementsIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanMultipleDisbursementsIntegrationTest.java
@@ -93,7 +93,7 @@ public class ClientLoanMultipleDisbursementsIntegrationTest {
                 .withNumberOfRepayments("4") //
                 .withRepaymentEveryAfter("1") //
                 .withRepaymentFrequencyTypeAsMonths() //
-                .withInterestRatePerPeriod("2") //
+                .withInterestRatePerPeriod("0") //
                 .withAmortizationTypeAsEqualInstallments() //
                 .withInterestTypeAsDecliningBalance() //
                 .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
@@ -160,21 +160,21 @@ public class 
ClientLoanMultipleDisbursementsIntegrationTest {
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
 
         LOG.info("-------------------------------DISBURSE 8 LOANS 
-------------------------------------------");
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("12 
January 2021", loanID, "1");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("12 January 
2021", loanID, "1");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("12 
January 2021", loanID, "2");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("12 January 
2021", loanID, "2");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("12 
January 2021", loanID, "4");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("12 January 
2021", loanID, "4");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("13 
January 2021", loanID, "8");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("13 January 
2021", loanID, "8");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("14 
January 2021", loanID, "16");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("14 January 
2021", loanID, "16");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("14 
January 2021", loanID, "32");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("14 January 
2021", loanID, "32");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("15 
January 2021", loanID, "64");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("15 January 
2021", loanID, "64");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("15 
January 2021", loanID, "128");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("15 January 
2021", loanID, "128");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
         ArrayList<HashMap> loanSchedule = 
this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, 
this.responseSpec, loanID);
@@ -200,7 +200,6 @@ public class ClientLoanMultipleDisbursementsIntegrationTest 
{
                 disbursalCount += 1;
                 totalPrincipalDisbursed = 
totalPrincipalDisbursed.add(principalDisbursed);
             }
-            // LOG.info(loanSchedule.get(i).toString());
         }
         assertEquals(expectedDisbursals, disbursalCount, "Checking for eight 
disbursals");
         assertEquals(expectedTotalPrincipalDisbursed, totalPrincipalDisbursed, 
"Checking Principal Disburse is 255");
@@ -215,4 +214,184 @@ public class 
ClientLoanMultipleDisbursementsIntegrationTest {
 
     }
 
+    @Test
+    public void 
checkThatAllMultiDisbursalsAppearOnLoanScheduleAndOutStandingBalanceIsZeroButLoanGotReopenedTest()
 {
+        this.loanTransactionHelper = new 
LoanTransactionHelper(this.requestSpec, this.responseSpec);
+
+        final Integer clientID = ClientHelper.createClient(this.requestSpec, 
this.responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, 
this.responseSpec, clientID);
+
+        /***
+         * Create loan product with allowing multiple disbursals
+         */
+        boolean allowMultipleDisbursals = true;
+        final Integer loanProductID = 
createLoanProduct(allowMultipleDisbursals);
+        Assertions.assertNotNull(loanProductID);
+
+        /***
+         * Apply for loan application and verify loan status
+         */
+        final String savingsId = null;
+        final String principal = "12,000.00";
+
+        LOG.info("-----------------------------------2 
Tranches--------------------------------------");
+        List<HashMap> tranches = new ArrayList<>();
+        tranches.add(createTrancheDetail("01 January 2021", "1"));
+        tranches.add(createTrancheDetail("02 January 2021", "2"));
+        String submitDate = "01 January 2021";
+
+        final Integer loanID = applyForLoanApplicationWithTranches(clientID, 
loanProductID, savingsId, principal, tranches, submitDate);
+        Assertions.assertNotNull(loanID);
+        HashMap loanStatusHashMap = 
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+        LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+        LOG.info("-----------------------------------APPROVE 
LOAN-----------------------------------------");
+        loanStatusHashMap = this.loanTransactionHelper.approveLoan("01 January 
2021", loanID);
+        LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+        LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+
+        LOG.info(
+                "-------------------------------DISBURSE 1, repay fully, 
disburse again LOANS -------------------------------------------");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithTransactionAmount("12 January 2021", 
loanID, "1");
+        LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
+        HashMap repaymentDetails = 
this.loanTransactionHelper.makeRepayment("13 January 2021", 1.0f, loanID);
+        loanStatusHashMap = 
this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, 
loanID, "status");
+        LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithTransactionAmount("14 January 2021", 
loanID, "2");
+        LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
+
+        ArrayList<HashMap> loanSchedule = 
this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, 
this.responseSpec, loanID);
+        final int loanScheduleLineCount = loanSchedule.size();
+        final int expectedLoanScheduleLineCount = 3;
+        final int expectedDisbursals = 2;
+        final BigDecimal expectedTotalPrincipalDisbursed = 
BigDecimal.valueOf(3.0);
+        final BigDecimal expectedPrincipalDue = BigDecimal.valueOf(3.0);
+        final BigDecimal expectedPrincipalPaid = BigDecimal.valueOf(1.0);
+        final BigDecimal expectedPrincipalOutstanding = 
BigDecimal.valueOf(2.0);
+        final BigDecimal expectedPrincipalLoanBalanceOutstanding = 
BigDecimal.valueOf(0.0);
+
+        assertEquals(expectedLoanScheduleLineCount, loanScheduleLineCount, 
"Checking 3 lines in schedule");
+
+        int disbursalCount = 0;
+        BigDecimal totalPrincipalDisbursed = BigDecimal.ZERO;
+        // First 8 lines should be disbursals
+        for (int i = 0; i < loanScheduleLineCount - 1; i++) {
+            final Integer period = (Integer) loanSchedule.get(i).get("period");
+            final BigDecimal principalDisbursed = BigDecimal
+                    
.valueOf(Double.parseDouble(loanSchedule.get(i).get("principalDisbursed").toString()));
+
+            if (period == null) {
+                disbursalCount += 1;
+                totalPrincipalDisbursed = 
totalPrincipalDisbursed.add(principalDisbursed);
+            }
+            // LOG.info(loanSchedule.get(i).toString());
+        }
+        assertEquals(expectedDisbursals, disbursalCount, "Checking for 2 
disbursals");
+        assertEquals(expectedTotalPrincipalDisbursed, totalPrincipalDisbursed, 
"Checking Principal Disburse is 3");
+
+        final BigDecimal principalDue = 
BigDecimal.valueOf(Double.parseDouble(loanSchedule.get(2).get("principalDue").toString()));
+        assertEquals(expectedPrincipalDue, principalDue, "Checking Principal 
Due is 3");
+        final BigDecimal principalPaid = 
BigDecimal.valueOf(Double.parseDouble(loanSchedule.get(2).get("principalPaid").toString()));
+        assertEquals(expectedPrincipalPaid, principalPaid, "Checking Principal 
Paid is 1");
+        final BigDecimal principalOutstanding = BigDecimal
+                
.valueOf(Double.parseDouble(loanSchedule.get(2).get("principalOutstanding").toString()));
+        assertEquals(expectedPrincipalOutstanding, principalOutstanding, 
"Checking Principal Due is 2");
+
+        final BigDecimal principalLoanBalanceOutstanding = BigDecimal
+                
.valueOf(Double.parseDouble(loanSchedule.get(2).get("principalLoanBalanceOutstanding").toString()));
+        assertEquals(expectedPrincipalLoanBalanceOutstanding, 
principalLoanBalanceOutstanding,
+                "Checking Principal Loan Balance Outstanding is zero");
+
+    }
+
+    @Test
+    public void 
checkThatAllMultiDisbursalsAppearOnLoanScheduleAndOutStandingBalanceIsZeroButLoanGotReopenedFromOverPaidTest()
 {
+        this.loanTransactionHelper = new 
LoanTransactionHelper(this.requestSpec, this.responseSpec);
+
+        final Integer clientID = ClientHelper.createClient(this.requestSpec, 
this.responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, 
this.responseSpec, clientID);
+
+        /***
+         * Create loan product with allowing multiple disbursals
+         */
+        boolean allowMultipleDisbursals = true;
+        final Integer loanProductID = 
createLoanProduct(allowMultipleDisbursals);
+        Assertions.assertNotNull(loanProductID);
+
+        /***
+         * Apply for loan application and verify loan status
+         */
+        final String savingsId = null;
+        final String principal = "12,000.00";
+
+        LOG.info("-----------------------------------2 
Tranches--------------------------------------");
+        List<HashMap> tranches = new ArrayList<>();
+        tranches.add(createTrancheDetail("01 January 2021", "1"));
+        tranches.add(createTrancheDetail("02 January 2021", "2"));
+        String submitDate = "01 January 2021";
+
+        final Integer loanID = applyForLoanApplicationWithTranches(clientID, 
loanProductID, savingsId, principal, tranches, submitDate);
+        Assertions.assertNotNull(loanID);
+        HashMap loanStatusHashMap = 
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+        LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+        LOG.info("-----------------------------------APPROVE 
LOAN-----------------------------------------");
+        loanStatusHashMap = this.loanTransactionHelper.approveLoan("01 January 
2021", loanID);
+        LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+        LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+
+        LOG.info(
+                "-------------------------------DISBURSE 1, repay fully, 
disburse again LOANS -------------------------------------------");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithTransactionAmount("12 January 2021", 
loanID, "1");
+        LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
+        HashMap repaymentDetails = 
this.loanTransactionHelper.makeRepayment("13 January 2021", 2.0f, loanID);
+        loanStatusHashMap = 
this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, 
loanID, "status");
+        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithTransactionAmount("14 January 2021", 
loanID, "2");
+        LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
+
+        ArrayList<HashMap> loanSchedule = 
this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, 
this.responseSpec, loanID);
+        final int loanScheduleLineCount = loanSchedule.size();
+        final int expectedLoanScheduleLineCount = 3;
+        final int expectedDisbursals = 2;
+        final BigDecimal expectedTotalPrincipalDisbursed = 
BigDecimal.valueOf(3.0);
+        final BigDecimal expectedPrincipalDue = BigDecimal.valueOf(3.0);
+        final BigDecimal expectedPrincipalPaid = BigDecimal.valueOf(2.0);
+        final BigDecimal expectedPrincipalOutstanding = 
BigDecimal.valueOf(1.0);
+        final BigDecimal expectedPrincipalLoanBalanceOutstanding = 
BigDecimal.valueOf(0.0);
+
+        assertEquals(expectedLoanScheduleLineCount, loanScheduleLineCount, 
"Checking nine lines in schedule");
+
+        int disbursalCount = 0;
+        BigDecimal totalPrincipalDisbursed = BigDecimal.ZERO;
+        // First 8 lines should be disbursals
+        for (int i = 0; i < loanScheduleLineCount - 1; i++) {
+            final Integer period = (Integer) loanSchedule.get(i).get("period");
+            final BigDecimal principalDisbursed = BigDecimal
+                    
.valueOf(Double.parseDouble(loanSchedule.get(i).get("principalDisbursed").toString()));
+
+            if (period == null) {
+                disbursalCount += 1;
+                totalPrincipalDisbursed = 
totalPrincipalDisbursed.add(principalDisbursed);
+            }
+            // LOG.info(loanSchedule.get(i).toString());
+        }
+        assertEquals(expectedDisbursals, disbursalCount, "Checking for 2 
disbursals");
+        assertEquals(expectedTotalPrincipalDisbursed, totalPrincipalDisbursed, 
"Checking Principal Disburse is 3");
+
+        final BigDecimal principalDue = 
BigDecimal.valueOf(Double.parseDouble(loanSchedule.get(2).get("principalDue").toString()));
+        assertEquals(expectedPrincipalDue, principalDue, "Checking Principal 
Due is 3");
+        final BigDecimal principalPaid = 
BigDecimal.valueOf(Double.parseDouble(loanSchedule.get(2).get("principalPaid").toString()));
+        assertEquals(expectedPrincipalPaid, principalPaid, "Checking Principal 
Paid is 1");
+        final BigDecimal principalOutstanding = BigDecimal
+                
.valueOf(Double.parseDouble(loanSchedule.get(2).get("principalOutstanding").toString()));
+        assertEquals(expectedPrincipalOutstanding, principalOutstanding, 
"Checking Principal Due is 2");
+
+        final BigDecimal principalLoanBalanceOutstanding = BigDecimal
+                
.valueOf(Double.parseDouble(loanSchedule.get(2).get("principalLoanBalanceOutstanding").toString()));
+        assertEquals(expectedPrincipalLoanBalanceOutstanding, 
principalLoanBalanceOutstanding,
+                "Checking Principal Loan Balance Outstanding is zero");
+
+    }
+
 }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanNonTrancheMultipleDisbursementsIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanNonTrancheMultipleDisbursementsIntegrationTest.java
index a33f7402c..c4646906e 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanNonTrancheMultipleDisbursementsIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanNonTrancheMultipleDisbursementsIntegrationTest.java
@@ -160,7 +160,8 @@ public class 
ClientLoanNonTrancheMultipleDisbursementsIntegrationTest {
 
         LOG.info("-------------------------------DISBURSE non-tranch 
multi-disbursal loan       ----------");
         final String netDisbursedAmt = null;
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(submitDate, loanID, 
approved.toString(), netDisbursedAmt);
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(submitDate, 
loanID, approved.toString(),
+                netDisbursedAmt);
 
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
         loanSchedule = 
this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, 
this.responseSpec, loanID);
@@ -173,7 +174,8 @@ public class 
ClientLoanNonTrancheMultipleDisbursementsIntegrationTest {
 
         LOG.info("------------------------------- 2nd DISBURSE non-tranch 
multi-disbursal loan       ----------");
         final Float anotherDisbursalAmount = 900.00f;
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(submitDate, loanID, 
anotherDisbursalAmount.toString(), netDisbursedAmt);
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(submitDate, 
loanID,
+                anotherDisbursalAmount.toString(), netDisbursedAmt);
 
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
         loanSchedule = 
this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, 
this.responseSpec, loanID);
@@ -188,8 +190,8 @@ public class 
ClientLoanNonTrancheMultipleDisbursementsIntegrationTest {
         LOG.info("------------------------------- 3rd DISBURSE non-tranch 
multi-disbursal loan       ----------");
         final Float thirdDisbursalAmount = 500.00f;
         String thirdDisbursalDate = "03 February 2021";
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(thirdDisbursalDate, loanID, 
thirdDisbursalAmount.toString(),
-                netDisbursedAmt);
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(thirdDisbursalDate,
 loanID,
+                thirdDisbursalAmount.toString(), netDisbursedAmt);
 
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
         loanSchedule = 
this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, 
this.responseSpec, loanID);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ConcurrencyIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ConcurrencyIntegrationTest.java
index b5afe109b..6a5e35930 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ConcurrencyIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ConcurrencyIntegrationTest.java
@@ -77,7 +77,7 @@ public class ConcurrencyIntegrationTest {
         final Integer loanID = applyForLoanApplication(clientID, 
loanProductID, "12,000.00");
         this.loanTransactionHelper.approveLoan("20 September 2011", loanID);
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, 
"12,000.00",
+        this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 
September 2011", loanID, "12,000.00",
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
         Calendar date = Calendar.getInstance();
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DisbursalAndRepaymentScheduleTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DisbursalAndRepaymentScheduleTest.java
index 54e2d4e66..ed3d0d125 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DisbursalAndRepaymentScheduleTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DisbursalAndRepaymentScheduleTest.java
@@ -159,7 +159,7 @@ public class DisbursalAndRepaymentScheduleTest {
 
         // Test for loan account approved can be disbursed
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
this.loanId);
-        this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId,
+        
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disbursalDate, 
this.loanId,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         loanStatusHashMap = 
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, 
this.loanId);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -317,7 +317,7 @@ public class DisbursalAndRepaymentScheduleTest {
 
         // Test for loan account approved can be disbursed
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
this.loanId);
-        this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId,
+        
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disbursalDate, 
this.loanId,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         loanStatusHashMap = 
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, 
this.loanId);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java
index 618dd4230..01bacd274 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java
@@ -138,7 +138,7 @@ public class GroupTest {
 
         this.loanTransactionHelper.approveLoan("20 September 2014", loanId);
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanId);
-        this.loanTransactionHelper.disburseLoan("20 September 2014", loanId,
+        this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 
September 2014", loanId,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
 
         final HashMap assignStaffAndInheritStaffForClientAccounts = (HashMap) 
GroupHelper.assignStaffInheritStaffForClientAccounts(
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java
index e1cbb0329..65740ee72 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java
@@ -108,7 +108,8 @@ public class LoanApplicationUndoLastTrancheTest {
 
         // DISBURSE A LOAN
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        this.loanTransactionHelper.disburseLoan(disbursalDate, loanID, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disbursalDate, 
loanID,
+                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         loanStatusHashMap = 
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
 
         // VALIDATE THE LOAN IS ACTIVE STATUS
@@ -121,7 +122,8 @@ public class LoanApplicationUndoLastTrancheTest {
         LOG.info("-------------Make repayment 3-----------");
         this.loanTransactionHelper.makeRepayment("01 June 2014", 
Float.valueOf("204"), loanID);
         // DISBURSE A SECOND TRANCHE
-        this.loanTransactionHelper.disburseLoan("23 June 2014", loanID, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("23 June 
2014", loanID,
+                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         // UNDO LAST TRANCHE
         Float disbursedAmount = 
this.loanTransactionHelper.undoLastDisbursal(loanID);
         validateDisbursedAmount(disbursedAmount);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursalDateValidationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursalDateValidationTest.java
index 9d8337d15..772604af1 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursalDateValidationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursalDateValidationTest.java
@@ -96,7 +96,7 @@ public class LoanDisbursalDateValidationTest {
         // DISBURSE A LOAN
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
         @SuppressWarnings("unchecked")
-        List<HashMap> disbursalError = (List<HashMap>) 
this.loanTransactionHelper.disburseLoan(disbursalDate, loanID,
+        List<HashMap> disbursalError = (List<HashMap>) 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disbursalDate, 
loanID,
                 this.responseForbiddenError, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
 
         
Assertions.assertEquals(disbursalError.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE),
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleOnDecliningBalanceLoanTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleOnDecliningBalanceLoanTest.java
index 70eeb52f7..df825c504 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleOnDecliningBalanceLoanTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleOnDecliningBalanceLoanTest.java
@@ -218,7 +218,7 @@ public class LoanRescheduleOnDecliningBalanceLoanTest {
 
         if (this.loanId != null) {
             String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
this.loanId);
-            this.loanTransactionHelper.disburseLoan(disburseDate, this.loanId,
+            
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disburseDate, 
this.loanId,
                     
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
             LOG.info("Successfully disbursed loan (ID: {} )", this.loanId);
         }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
index 0e7a86bf7..c49e3f59d 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
@@ -169,7 +169,7 @@ public class LoanRescheduleRequestTest {
 
         if (this.loanId != null) {
             String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
this.loanId);
-            this.loanTransactionHelper.disburseLoan(this.dateString, 
this.loanId,
+            
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(this.dateString, 
this.loanId,
                     
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
             LOG.info("Successfully disbursed loan (ID: {} )", this.loanId);
         }
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 ef3d9f609..2e8616f06 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
@@ -126,7 +126,7 @@ public class LoanRescheduleWithAdvancePaymentTest {
 
         if (this.loanId != null) {
             String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
this.loanId);
-            this.loanTransactionHelper.disburseLoan(disburseDate, this.loanId,
+            
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disburseDate, 
this.loanId,
                     
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
             LOG.info("Successfully disbursed loan (ID: {} )", this.loanId);
         }
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 9c66a5dd3..b2db9dd80 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
@@ -146,7 +146,8 @@ public class LoanReschedulingWithinCenterTest {
 
         // Test for loan account approved can be disbursed
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanId);
-        this.loanTransactionHelper.disburseLoan(disbursalDate, loanId, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disbursalDate, 
loanId,
+                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         loanStatusHashMap = 
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanId);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -299,7 +300,8 @@ public class LoanReschedulingWithinCenterTest {
 
         // DISBURSE A FIRST TRANCHE
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        this.loanTransactionHelper.disburseLoan(disbursementDate, loanID, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disbursementDate, 
loanID,
+                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         loanStatusHashMap = 
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
 
         LOG.info("---------------------------------CHANGING GROUP MEETING DATE 
------------------------------------------");
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 5028b2f35..8475f84ba 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
@@ -99,7 +99,7 @@ public class LoanTransactionAuditingIntegrationTest {
         LOG.info("-----------------------------------APPROVE 
LOAN-----------------------------------------");
         loanStatusHashMap = this.loanTransactionHelper.approveLoan("11 July 
2022", loanID);
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
-        loanStatusHashMap = this.loanTransactionHelper.disburseLoan("11 July 
2022", loanID, "10000");
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("11 July 2022", 
loanID, "10000");
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
         OffsetDateTime now = OffsetDateTime.now(ZoneId.of("Asia/Kolkata"));
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java
index 5001e5a7e..b5c1d796b 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java
@@ -106,7 +106,7 @@ public class 
LoanWithWaiveInterestAndWriteOffIntegrationTest {
 
         // DISBURSE
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap.toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -120,7 +120,7 @@ public class 
LoanWithWaiveInterestAndWriteOffIntegrationTest {
         LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
 
         // DIBURSE AGAIN
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
@@ -168,7 +168,7 @@ public class 
LoanWithWaiveInterestAndWriteOffIntegrationTest {
 
         // DISBURSE
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(DISBURSEMENT_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LOG.info("DISBURSE {}", loanStatusHashMap);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/MinimumDaysBetweenDisbursalAndFirstRepaymentTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/MinimumDaysBetweenDisbursalAndFirstRepaymentTest.java
index 0a013c8b9..f3ac06696 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/MinimumDaysBetweenDisbursalAndFirstRepaymentTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/MinimumDaysBetweenDisbursalAndFirstRepaymentTest.java
@@ -117,7 +117,7 @@ public class 
MinimumDaysBetweenDisbursalAndFirstRepaymentTest {
 
         // Test for loan account approved can be disbursed
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
this.loanId);
-        this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId,
+        
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(disbursalDate, 
this.loanId,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         loanStatusHashMap = 
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, 
this.loanId);
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotesTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotesTest.java
index 1e9a0a89d..3b4d4f1af 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotesTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotesTest.java
@@ -275,7 +275,8 @@ public class NotesTest {
 
         this.loanTransactionHelper.approveLoan("02 April 2012", loanId);
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanId);
-        this.loanTransactionHelper.disburseLoan("02 April 2012", loanId, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 
April 2012", loanId,
+                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         HashMap repayment = this.loanTransactionHelper.makeRepayment("02 April 
2012", 100.0f, loanId);
         Integer loanTransactionId = (Integer) repayment.get("resourceId");
         Assertions.assertNotNull(loanTransactionId);
@@ -299,7 +300,8 @@ public class NotesTest {
 
         this.loanTransactionHelper.approveLoan("02 April 2012", loanId);
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanId);
-        this.loanTransactionHelper.disburseLoan("02 April 2012", loanId, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 
April 2012", loanId,
+                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         HashMap repayment = this.loanTransactionHelper.makeRepayment("02 April 
2012", 100.0f, loanId);
         Integer loanTransactionId = (Integer) repayment.get("resourceId");
         Assertions.assertNotNull(loanTransactionId);
@@ -332,7 +334,8 @@ public class NotesTest {
 
         this.loanTransactionHelper.approveLoan("02 April 2012", loanId);
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanId);
-        this.loanTransactionHelper.disburseLoan("02 April 2012", loanId, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 
April 2012", loanId,
+                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         HashMap repayment = this.loanTransactionHelper.makeRepayment("02 April 
2012", 100.0f, loanId);
         Integer loanTransactionId = (Integer) repayment.get("resourceId");
         Assertions.assertNotNull(loanTransactionId);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java
index 1feee1c62..b7d0435fc 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java
@@ -249,7 +249,7 @@ public class SchedulerJobsTestResults {
         Assertions.assertEquals(1, chargesPendingState.size());
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE,
 loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(AccountTransferTest.LOAN_DISBURSAL_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
         final HashMap summaryBefore = 
this.savingsAccountHelper.getSavingsSummary(savingsId);
@@ -291,7 +291,7 @@ public class SchedulerJobsTestResults {
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE,
 loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(AccountTransferTest.LOAN_DISBURSAL_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -440,7 +440,7 @@ public class SchedulerJobsTestResults {
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
 
         String loanDetails = loanTransactionHelper.getLoanDetails(requestSpec, 
responseSpec, loanID);
-        loanStatusHashMap = 
loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE, 
loanID,
+        loanStatusHashMap = 
loanTransactionHelper.disburseLoanWithNetDisbursalAmount(AccountTransferTest.LOAN_DISBURSAL_DATE,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -570,8 +570,8 @@ public class SchedulerJobsTestResults {
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE,
 loanID,
-                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE,
+                loanID, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
         String JobName = "Apply penalty to overdue loans";
@@ -617,8 +617,8 @@ public class SchedulerJobsTestResults {
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE,
 loanID,
-                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE,
+                loanID, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
         String JobName = "Apply penalty to overdue loans";
@@ -669,8 +669,8 @@ public class SchedulerJobsTestResults {
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
 
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE,
 loanID,
-                
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE,
+                loanID, 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
         final Boolean isNPABefore = (Boolean) 
this.loanTransactionHelper.getLoanDetail(requestSpec, responseSpec, loanID, 
"isNPA");
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java
index 0003d1d76..6801cd888 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java
@@ -97,7 +97,7 @@ public class ProvisioningIntegrationTest {
             
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
             LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
             String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-            loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 
September 2011", loanID,
+            loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 
2011", loanID,
                     
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
             LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
             Assertions.assertNotNull(loanID);
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 326614bb7..4b888e464 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
@@ -151,7 +151,7 @@ public class LoanTransactionHelper {
         return response;
     }
 
-    public Object getLoanDetail(final RequestSpecification requestSpec, final 
ResponseSpecification responseSpec, final Integer loanID,
+    public <T> T getLoanDetail(final RequestSpecification requestSpec, final 
ResponseSpecification responseSpec, final Integer loanID,
             final String param) {
         final String URL = "/fineract-provider/api/v1/loans/" + loanID + 
"?associations=all&" + Utils.TENANT_IDENTIFIER;
         return Utils.performServerGet(requestSpec, responseSpec, URL, param);
@@ -232,11 +232,16 @@ public class LoanTransactionHelper {
         return 
performLoanTransaction(createLoanOperationURL(UNDO_APPROVAL_LOAN_COMMAND, 
loanID), undoBodyJson);
     }
 
-    public HashMap disburseLoan(final String date, final Integer loanID, final 
String netDisbursalAmount) {
+    public HashMap disburseLoanWithNetDisbursalAmount(final String date, final 
Integer loanID, final String netDisbursalAmount) {
         return 
performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID),
                 getDisburseLoanAsJSON(date, null, netDisbursalAmount));
     }
 
+    public HashMap disburseLoanWithTransactionAmount(final String date, final 
Integer loanID, final String transactionAmount) {
+        return 
performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID),
+                getDisburseLoanAsJSON(date, transactionAmount, null));
+    }
+
     public HashMap disburseLoanWithPostDatedChecks(final String date, final 
Integer loanId, final BigDecimal transactionAmount,
             final List<HashMap> postDatedChecks) {
         return 
performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanId),
@@ -264,12 +269,13 @@ public class LoanTransactionHelper {
                 getDisburseLoanWithRepaymentRescheduleAsJSON(date, null, 
adjustRepaymentDate));
     }
 
-    public HashMap disburseLoan(final String date, final Integer loanID, final 
String disburseAmt, final String netDisbursalAmount) {
+    public HashMap disburseLoanWithNetDisbursalAmount(final String date, final 
Integer loanID, final String disburseAmt,
+            final String netDisbursalAmount) {
         return 
performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID),
                 getDisburseLoanAsJSON(date, disburseAmt, netDisbursalAmount));
     }
 
-    public Object disburseLoan(final String date, final Integer loanID, 
ResponseSpecification responseValidationError,
+    public Object disburseLoanWithNetDisbursalAmount(final String date, final 
Integer loanID, ResponseSpecification responseValidationError,
             final String netDisbursalAmount) {
         return 
performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID),
                 getDisburseLoanAsJSON(date, null, netDisbursalAmount), 
responseValidationError);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/guarantor/GuarantorTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/guarantor/GuarantorTest.java
index 5dd74fa68..1f90461f6 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/guarantor/GuarantorTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/guarantor/GuarantorTest.java
@@ -181,7 +181,7 @@ public class GuarantorTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(loanDisbursementDate,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -377,7 +377,7 @@ public class GuarantorTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(loanDisbursementDate,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -483,7 +483,7 @@ public class GuarantorTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(loanDisbursementDate,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -559,7 +559,7 @@ public class GuarantorTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(loanDisbursementDate,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 
@@ -631,7 +631,7 @@ public class GuarantorTest {
 
         LOG.info("-------------------------------DISBURSE 
LOAN-------------------------------------------");
         String loanDetails = 
this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, 
loanID);
-        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID,
+        loanStatusHashMap = 
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(loanDisbursementDate,
 loanID,
                 
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
 

Reply via email to