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

commit 5d62cfef04dd800ae9ad2305c349765a3d94fcfd
Author: Adam Saghy <[email protected]>
AuthorDate: Mon Oct 30 20:28:09 2023 +0100

    FINERACT-1968: Adv.paym.disbursement
---
 ...dvancedPaymentScheduleTransactionProcessor.java | 46 +++++++++-
 .../domain/LoanTermVariationParams.java            | 18 ++++
 .../domain/ScheduleCurrentPeriodParams.java        | 18 ++++
 .../starter/LoanAccountAutoStarter.java            |  5 +-
 ...PaymentAllocationLoanRepaymentScheduleTest.java | 99 +++++++++++++++++++---
 5 files changed, 168 insertions(+), 18 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
index feaac762c..57fc21f19 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
@@ -49,10 +49,7 @@ import 
org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail
 import 
org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationTransactionType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.jetbrains.annotations.NotNull;
-import org.springframework.context.annotation.Profile;
 
-//TODO: remove `test` profile when it is finished
-@Profile("test")
 @Slf4j
 public class AdvancedPaymentScheduleTransactionProcessor extends 
AbstractLoanRepaymentScheduleTransactionProcessor {
 
@@ -182,6 +179,7 @@ public class AdvancedPaymentScheduleTransactionProcessor 
extends AbstractLoanRep
     public void processLatestTransaction(LoanTransaction loanTransaction, 
MonetaryCurrency currency,
             List<LoanRepaymentScheduleInstallment> installments, 
Set<LoanCharge> charges, Money overpaidAmount) {
         switch (loanTransaction.getTypeOf()) {
+            case DISBURSEMENT -> handleDisbursement(loanTransaction, currency, 
installments);
             case WRITEOFF -> handleWriteOff(loanTransaction, currency, 
installments);
             case REFUND_FOR_ACTIVE_LOAN -> handleRefund(loanTransaction, 
currency, installments, charges);
             case CHARGEBACK -> handleChargeback(loanTransaction, currency, 
overpaidAmount, installments);
@@ -197,6 +195,48 @@ public class AdvancedPaymentScheduleTransactionProcessor 
extends AbstractLoanRep
         }
     }
 
+    private void handleDisbursement(LoanTransaction loanTransaction, 
MonetaryCurrency currency,
+            List<LoanRepaymentScheduleInstallment> installments) {
+        updateLoanSchedule(loanTransaction, currency, installments);
+    }
+
+    private void updateLoanSchedule(LoanTransaction disbursementTransaction, 
MonetaryCurrency currency,
+            List<LoanRepaymentScheduleInstallment> installments) {
+        final MathContext mc = MoneyHelper.getMathContext();
+        List<LoanRepaymentScheduleInstallment> candidateRepaymentInstallments 
= installments.stream()
+                .filter(i -> 
!i.getDueDate().isBefore(disbursementTransaction.getTransactionDate()) && 
!i.isDownPayment()).toList();
+        int noCandidateRepaymentInstallments = 
candidateRepaymentInstallments.size();
+        LoanProductRelatedDetail loanProductRelatedDetail = 
disbursementTransaction.getLoan().getLoanRepaymentScheduleDetail();
+        Integer installmentAmountInMultiplesOf = 
disbursementTransaction.getLoan().getLoanProduct().getInstallmentAmountInMultiplesOf();
+        Money downPaymentAmount = Money.zero(currency);
+        if (loanProductRelatedDetail.isEnableDownPayment()) {
+            LoanRepaymentScheduleInstallment downPaymentInstallment = 
installments.stream()
+                    .filter(i -> i.isDownPayment() && 
i.getPrincipal(currency).isZero()).findFirst().orElseThrow();
+            BigDecimal downPaymentAmt = 
MathUtil.percentageOf(disbursementTransaction.getAmount(),
+                    
loanProductRelatedDetail.getDisbursedAmountPercentageForDownPayment(), mc);
+            if (installmentAmountInMultiplesOf != null) {
+                downPaymentAmt = Money.roundToMultiplesOf(downPaymentAmt, 
installmentAmountInMultiplesOf);
+            }
+            downPaymentAmount = Money.of(currency, downPaymentAmt);
+            
downPaymentInstallment.addToPrincipal(disbursementTransaction.getTransactionDate(),
 downPaymentAmount);
+
+        }
+        Money amortizableAmount = 
disbursementTransaction.getAmount(currency).minus(downPaymentAmount);
+        Money increasePrincipalBy = 
amortizableAmount.dividedBy(noCandidateRepaymentInstallments, 
mc.getRoundingMode());
+        if (installmentAmountInMultiplesOf != null) {
+            increasePrincipalBy = 
Money.roundToMultiplesOf(increasePrincipalBy, installmentAmountInMultiplesOf);
+        }
+        Money remainingAmount = 
increasePrincipalBy.multiplyRetainScale(noCandidateRepaymentInstallments, 
mc.getRoundingMode())
+                .minus(amortizableAmount);
+
+        Money finalIncreasePrincipalBy = increasePrincipalBy;
+        candidateRepaymentInstallments
+                .forEach(i -> 
i.addToPrincipal(disbursementTransaction.getTransactionDate(), 
finalIncreasePrincipalBy));
+        // Hence the rounding, we might need to amend the last installment 
amount
+        candidateRepaymentInstallments.get(noCandidateRepaymentInstallments - 
1)
+                .addToPrincipal(disbursementTransaction.getTransactionDate(), 
remainingAmount);
+    }
+
     @Override
     public Money handleRepaymentSchedule(List<LoanTransaction> 
transactionsPostDisbursement, MonetaryCurrency currency,
             List<LoanRepaymentScheduleInstallment> installments, 
Set<LoanCharge> loanCharges) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanTermVariationParams.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanTermVariationParams.java
index 951ba0d36..1651c04b3 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanTermVariationParams.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanTermVariationParams.java
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
 
 import java.time.LocalDate;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduleCurrentPeriodParams.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduleCurrentPeriodParams.java
index da427a4d5..58ac9a9b1 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduleCurrentPeriodParams.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduleCurrentPeriodParams.java
@@ -1,3 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
 
 import java.math.BigDecimal;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountAutoStarter.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountAutoStarter.java
index bef337cb6..68b39629b 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountAutoStarter.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountAutoStarter.java
@@ -31,7 +31,6 @@ import 
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.imp
 import 
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.InterestPrincipalPenaltyFeesOrderLoanRepaymentScheduleTransactionProcessor;
 import 
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.PrincipalInterestPenaltyFeesOrderLoanRepaymentScheduleTransactionProcessor;
 import 
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.RBILoanRepaymentScheduleTransactionProcessor;
-import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Conditional;
@@ -104,8 +103,8 @@ public class LoanAccountAutoStarter {
 
     @Bean
     @Conditional(AdvancedPaymentScheduleTransactionProcessorCondition.class)
-    public AdvancedPaymentScheduleTransactionProcessor 
advancedPaymentScheduleTransactionProcessor(LoanUtilService loanUtilService) {
-        return new 
AdvancedPaymentScheduleTransactionProcessor(loanUtilService);
+    public AdvancedPaymentScheduleTransactionProcessor 
advancedPaymentScheduleTransactionProcessor() {
+        return new AdvancedPaymentScheduleTransactionProcessor();
     }
 
 }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
index e8e496f08..a5deb6d74 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
@@ -29,9 +29,11 @@ import io.restassured.specification.ResponseSpecification;
 import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.fineract.client.models.AdvancedPaymentData;
 import org.apache.fineract.client.models.BusinessDateRequest;
+import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.PaymentAllocationOrder;
 import org.apache.fineract.client.models.PostClientsResponse;
@@ -51,6 +53,7 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Disabled;
@@ -89,7 +92,7 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
         final Account expenseAccount = accountHelper.createExpenseAccount();
         final Account overpaymentAccount = 
accountHelper.createLiabilityAccount();
 
-        commonLoanProductId = createLoanProduct("500", "15", "4", 
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
+        commonLoanProductId = createLoanProduct("500", "15", "4", true, 
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
         client = 
clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
     }
 
@@ -1710,6 +1713,72 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
         }
     }
 
+    // UC101: Multiple disbursement test
+    // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+    // 1. Disburse the loan
+    // 3. Pay over the down payment
+    // 3. Disburse again
+    @Test
+    public void uc101() {
+        try {
+
+            GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.TRUE);
+            businessDateHelper.updateBusinessDate(new 
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
+                    .date("2023.02.20").dateFormat("yyyy.MM.dd").locale("en"));
+
+            final Account assetAccount = accountHelper.createAssetAccount();
+            final Account incomeAccount = accountHelper.createIncomeAccount();
+            final Account expenseAccount = 
accountHelper.createExpenseAccount();
+            final Account overpaymentAccount = 
accountHelper.createLiabilityAccount();
+            Integer localLoanProductId = createLoanProduct("500", "15", "4", 
false, assetAccount, incomeAccount, expenseAccount,
+                    overpaymentAccount);
+            final PostLoansResponse loanResponse = 
applyForLoanApplication(client.getClientId(), localLoanProductId, 500L, 45, 15, 
3, 0,
+                    "01 January 2023", "01 January 2023");
+
+            loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
+                    new 
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
+                            .approvedOnDate("01 January 2023").locale("en"));
+
+            loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+                    new PostLoansLoanIdRequest().actualDisbursementDate("01 
January 2023").dateFormat(DATETIME_PATTERN)
+                            
.transactionAmount(BigDecimal.valueOf(500.00)).locale("en"));
+
+            GetLoansLoanIdResponse loanDetails = 
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+            validateLoanSummaryBalances(loanDetails, 500.0, 0.0, 500.0, 0.0, 
null);
+            validateRepaymentPeriod(loanDetails, 1, 125.0, 0.0, 125.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 2, 125.0, 0.0, 125.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 3, 125.0, 0.0, 125.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 4, 125.0, 0.0, 125.0, 0.0, 
0.0);
+            assertTrue(loanDetails.getStatus().getActive());
+
+            loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), 
new PostLoansLoanIdTransactionsRequest()
+                    .dateFormat(DATETIME_PATTERN).transactionDate("04 January 
2023").locale("en").transactionAmount(175.0));
+            loanDetails = 
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+            validateLoanSummaryBalances(loanDetails, 325.0, 175.0, 325.0, 
175.0, null);
+            validateRepaymentPeriod(loanDetails, 1, 125.0, 125.0, 0.0, 0.0, 
125.0);
+            validateRepaymentPeriod(loanDetails, 2, 125.0, 50.0, 75.0, 50.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 3, 125.0, 0.0, 125.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 4, 125.0, 0.0, 125.0, 0.0, 
0.0);
+            validateLoanTransaction(loanDetails, 1, 175.0, 175.0, 0.0, 325.0);
+            assertTrue(loanDetails.getStatus().getActive());
+
+            loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+                    new PostLoansLoanIdRequest().actualDisbursementDate("05 
January 2023").dateFormat(DATETIME_PATTERN)
+                            
.transactionAmount(BigDecimal.valueOf(500.00)).locale("en"));
+            loanDetails = 
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+            validateLoanSummaryBalances(loanDetails, 825.0, 175.0, 825.0, 
175.0, null);
+            validateRepaymentPeriod(loanDetails, 1, 125.0, 125.0, 0.0, 0.0, 
125.0);
+            validateRepaymentPeriod(loanDetails, 2, 125.0, 0.0, 125.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 3, 250.0, 50.0, 200.0, 50.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 4, 250.0, 0.0, 250.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 5, 250.0, 0.0, 250.0, 0.0, 
0.0);
+            assertTrue(loanDetails.getStatus().getActive());
+
+        } finally {
+            GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.FALSE);
+        }
+    }
+
     private static void validateLoanSummaryBalances(GetLoansLoanIdResponse 
loanDetails, Double totalOutstanding, Double totalRepayment,
             Double principalOutstanding, Double principalPaid, Double 
totalOverpaid) {
         assertEquals(totalOutstanding, 
loanDetails.getSummary().getTotalOutstanding());
@@ -1760,7 +1829,7 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
     }
 
     private static Integer createLoanProduct(final String principal, final 
String repaymentAfterEvery, final String numberOfRepayments,
-            final Account... accounts) {
+            boolean autoPayForDownPayment, final Account... accounts) {
         AdvancedPaymentData defaultAllocation = 
createDefaultPaymentAllocation();
         AdvancedPaymentData goodwillCreditAllocation = 
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT");
         AdvancedPaymentData merchantIssuedRefundAllocation = 
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION");
@@ -1768,22 +1837,27 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
         LOG.info("------------------------------CREATING NEW LOAN PRODUCT 
---------------------------------------");
         final String loanProductJSON = new 
LoanProductTestBuilder().withMinPrincipal(principal).withPrincipal(principal)
                 
.withRepaymentTypeAsDays().withRepaymentAfterEvery(repaymentAfterEvery).withNumberOfRepayments(numberOfRepayments)
-                .withEnableDownPayment(true, "25", 
true).withinterestRatePerPeriod("0").withInterestRateFrequencyTypeAsMonths()
+                .withEnableDownPayment(true, "25", 
autoPayForDownPayment).withinterestRatePerPeriod("0")
+                .withInterestRateFrequencyTypeAsMonths()
                 
.withRepaymentStrategy(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
                 
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
                 .addAdvancedPaymentAllocation(defaultAllocation, 
goodwillCreditAllocation, merchantIssuedRefundAllocation,
                         payoutRefundAllocation)
-                
.withDaysInMonth("30").withDaysInYear("365").withMoratorium("0", 
"0").build(null);
+                
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true).withInterestTypeAsDecliningBalance().withMultiDisburse()
+                
.withDisallowExpectedDisbursements(true).withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withDaysInMonth("30")
+                .withDaysInYear("365").withMoratorium("0", "0").build(null);
         return loanTransactionHelper.getLoanProductId(loanProductJSON);
     }
 
-    private static void validateRepaymentPeriod(GetLoansLoanIdResponse 
loanDetails, int index, double principalDue, double principalPaid,
-            double principalOutstanding, double paidInAdvance, double 
paidLate) {
-        assertEquals(principalDue, 
loanDetails.getRepaymentSchedule().getPeriods().get(index).getPrincipalDue());
-        assertEquals(principalPaid, 
loanDetails.getRepaymentSchedule().getPeriods().get(index).getPrincipalPaid());
-        assertEquals(principalOutstanding, 
loanDetails.getRepaymentSchedule().getPeriods().get(index).getPrincipalOutstanding());
-        assertEquals(paidInAdvance, 
loanDetails.getRepaymentSchedule().getPeriods().get(index).getTotalPaidInAdvanceForPeriod());
-        assertEquals(paidLate, 
loanDetails.getRepaymentSchedule().getPeriods().get(index).getTotalPaidLateForPeriod());
+    private static void validateRepaymentPeriod(GetLoansLoanIdResponse 
loanDetails, Integer index, double principalDue,
+            double principalPaid, double principalOutstanding, double 
paidInAdvance, double paidLate) {
+        GetLoansLoanIdRepaymentPeriod period = 
loanDetails.getRepaymentSchedule().getPeriods().stream()
+                .filter(p -> Objects.equals(p.getPeriod(), 
index)).findFirst().orElseThrow();
+        assertEquals(principalDue, period.getPrincipalDue());
+        assertEquals(principalPaid, period.getPrincipalPaid());
+        assertEquals(principalOutstanding, period.getPrincipalOutstanding());
+        assertEquals(paidInAdvance, period.getTotalPaidInAdvanceForPeriod());
+        assertEquals(paidLate, period.getTotalPaidLateForPeriod());
     }
 
     private static PostLoansResponse applyForLoanApplication(final Long 
clientId, final Integer loanProductId, final Long principal,
@@ -1796,7 +1870,8 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
                 
.locale("en").submittedOnDate(submittedOnDate).amortizationType(1).interestRatePerPeriod(interestRate)
                 
.interestCalculationPeriodType(1).interestType(0).repaymentFrequencyType(0).repaymentEvery(repaymentAfterEvery)
                 
.repaymentFrequencyType(0).numberOfRepayments(numberOfRepayments).loanTermFrequency(loanTermFrequency)
-                
.loanTermFrequencyType(0).principal(BigDecimal.valueOf(principal)).loanType("individual"));
+                
.loanTermFrequencyType(0).principal(BigDecimal.valueOf(principal)).loanType("individual")
+                .maxOutstandingLoanBalance(BigDecimal.valueOf(35000)));
     }
 
     private static void validateLoanTransaction(GetLoansLoanIdResponse 
loanDetails, int index, double transactionAmount,

Reply via email to