diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java index df7aa3b70a8..57b2528158a 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java @@ -1417,10 +1417,14 @@ public boolean isMultiDisburseLoan() { } @NotNull - public Money getMaxOutstandingBalance() { + public Money getMaxOutstandingBalanceMoney() { return Money.of(getCurrency(), this.maxOutstandingBalance); } + public BigDecimal getMaxOutstandingBalance() { + return maxOutstandingBalance; + } + public BigDecimal getFixedEmiAmount() { BigDecimal fixedEmiAmount = this.fixedEmiAmount; if (getCurrentPeriodFixedEmiAmount() != null) { @@ -1882,4 +1886,7 @@ public void updateVariationDays(final long daysToAdd) { this.variationDays += daysToAdd; } + public LocalDate getLoanEndDate() { + return loanEndDate; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java index 7a01ba34c66..fbe32e9b9df 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java @@ -1005,11 +1005,13 @@ private void processDisbursements(final LoanApplicationTerms loanApplicationTerm && !DateUtils.isAfter(disburseDetail.getKey(), scheduledDueDate)) { // validation check for amount not exceeds specified max // amount as per the configuration - Money maxOutstandingBalance = loanApplicationTerms.getMaxOutstandingBalance(); - if (scheduleParams.getOutstandingBalance().plus(disburseDetail.getValue()).isGreaterThan(maxOutstandingBalance)) { - String errorMsg = "Outstanding balance must not exceed the amount: " + maxOutstandingBalance; - throw new MultiDisbursementOutstandingAmoutException(errorMsg, maxOutstandingBalance.getAmount(), - disburseDetail.getValue()); + if (loanApplicationTerms.getMaxOutstandingBalance() != null) { + Money maxOutstandingBalance = loanApplicationTerms.getMaxOutstandingBalanceMoney(); + if (scheduleParams.getOutstandingBalance().plus(disburseDetail.getValue()).isGreaterThan(maxOutstandingBalance)) { + String errorMsg = "Outstanding balance must not exceed the amount: " + maxOutstandingBalance; + throw new MultiDisbursementOutstandingAmoutException(errorMsg, maxOutstandingBalance.getAmount(), + disburseDetail.getValue()); + } } // creates and add disbursement detail to the repayments diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java index 1f0380e520d..4984ed51473 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -77,8 +78,7 @@ public LoanScheduleModel generate(final MathContext mc, final LoanApplicationTer : loanApplicationTerms.getSubmittedOnDate(); LoanScheduleParams scheduleParams = LoanScheduleParams.createLoanScheduleParams(currency, - Money.of(currency, chargesDueAtTimeOfDisbursement), periodStartDate, - getPrincipalToBeScheduled(loanApplicationTerms, periodStartDate)); + Money.of(currency, chargesDueAtTimeOfDisbursement), periodStartDate, Money.zero(currency)); List periods = createNewLoanScheduleListWithDisbursementDetails(loanApplicationTerms, scheduleParams, chargesDueAtTimeOfDisbursement); @@ -90,7 +90,9 @@ public LoanScheduleModel generate(final MathContext mc, final LoanApplicationTer final Set nonCompoundingCharges = separateTotalCompoundingPercentageCharges(loanCharges); boolean isNextRepaymentAvailable = true; - while (!scheduleParams.getOutstandingBalance().isZero()) { + boolean thereIsDisbursementBeforeOrOnLoanEndDate = scheduleParams.getDisburseDetailMap().entrySet().stream() + .anyMatch(d -> !d.getKey().isAfter(loanApplicationTerms.getLoanEndDate())); + while (!scheduleParams.getOutstandingBalance().isZero() || thereIsDisbursementBeforeOrOnLoanEndDate) { scheduleParams.setActualRepaymentDate(getScheduledDateGenerator().generateNextRepaymentDate( scheduleParams.getActualRepaymentDate(), loanApplicationTerms, isFirstRepayment, scheduleParams.getPeriodNumber())); AdjustedDateDetailsDTO adjustedDateDetailsDTO = getScheduledDateGenerator() @@ -109,9 +111,7 @@ public LoanScheduleModel generate(final MathContext mc, final LoanApplicationTer ScheduleCurrentPeriodParams currentPeriodParams = new ScheduleCurrentPeriodParams(currency, BigDecimal.ZERO); - if (loanApplicationTerms.isMultiDisburseLoan()) { - processDisbursements(loanApplicationTerms, chargesDueAtTimeOfDisbursement, scheduleParams, periods, scheduledDueDate); - } + processDisbursements(loanApplicationTerms, chargesDueAtTimeOfDisbursement, scheduleParams, periods, scheduledDueDate); // 5 determine principal,interest of repayment period PrincipalInterest principalInterestForThisPeriod = calculatePrincipalInterestComponentsForPeriod(loanApplicationTerms, @@ -179,6 +179,8 @@ public LoanScheduleModel generate(final MathContext mc, final LoanApplicationTer // adjustInstallmentOrPrincipalAmount(loanApplicationTerms, scheduleParams.getTotalCumulativePrincipal(), // scheduleParams.getPeriodNumber(), mc); // } + thereIsDisbursementBeforeOrOnLoanEndDate = scheduleParams.getDisburseDetailMap().entrySet().stream() + .anyMatch(d -> !d.getKey().isAfter(loanApplicationTerms.getLoanEndDate())); } // If the disbursement happened after maturity date @@ -237,28 +239,6 @@ private BigDecimal deriveTotalChargesDueAtTimeOfDisbursement(final Set d.getActualDisbursementDate().equals(periodStartDate)).map(DisbursementData::getPrincipal) - .reduce(BigDecimal.ZERO, BigDecimal::add); - principalToBeScheduled = Money.of(loanApplicationTerms.getCurrency(), totalDisbursalAmountsOnThe); - } else if (loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) { - principalToBeScheduled = loanApplicationTerms.getApprovedPrincipal(); - } else { - principalToBeScheduled = loanApplicationTerms.getPrincipal(); - } - } else { - principalToBeScheduled = loanApplicationTerms.getPrincipal(); - } - return principalToBeScheduled; - } - private List createNewLoanScheduleListWithDisbursementDetails(final LoanApplicationTerms loanApplicationTerms, final LoanScheduleParams loanScheduleParams, final BigDecimal chargesDueAtTimeOfDisbursement) { List periods = new ArrayList<>(); @@ -271,11 +251,17 @@ private List createNewLoanScheduleListWithDisbursementD null, null)); } for (DisbursementData disbursementData : loanApplicationTerms.getDisbursementDatas()) { + Money principalMoney = Money.of(loanApplicationTerms.getCurrency(), disbursementData.getPrincipal()); if (disbursementData.disbursementDate().equals(loanScheduleParams.getPeriodStartDate())) { final LoanScheduleModelDisbursementPeriod disbursementPeriod = LoanScheduleModelDisbursementPeriod.disbursement( disbursementData.disbursementDate(), Money.of(loanScheduleParams.getCurrency(), disbursementData.getPrincipal()), chargesDueAtTimeOfDisbursement); periods.add(disbursementPeriod); + loanScheduleParams.addOutstandingBalance(principalMoney); + loanScheduleParams.addOutstandingBalanceAsPerRest(principalMoney); + loanScheduleParams.addPrincipalToBeScheduled(principalMoney); + loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().plus(principalMoney)); + loanApplicationTerms.resetFixedEmiAmount(); if (loanApplicationTerms.isDownPaymentEnabled()) { final LoanScheduleModelDownPaymentPeriod downPaymentPeriod = createDownPaymentPeriod(loanApplicationTerms, loanScheduleParams, loanApplicationTerms.getExpectedDisbursementDate(), disbursementData.getPrincipal()); @@ -284,8 +270,7 @@ private List createNewLoanScheduleListWithDisbursementD } else { Money disbursedAmount = loanScheduleParams.getDisburseDetailMap().getOrDefault(disbursementData.disbursementDate(), Money.zero(loanApplicationTerms.getCurrency())); - loanScheduleParams.getDisburseDetailMap().put(disbursementData.disbursementDate(), - disbursedAmount.add(Money.of(loanApplicationTerms.getCurrency(), disbursementData.getPrincipal()))); + loanScheduleParams.getDisburseDetailMap().put(disbursementData.disbursementDate(), disbursedAmount.add(principalMoney)); } } @@ -335,18 +320,21 @@ private LoanRepaymentScheduleInstallment addLoanRepaymentScheduleInstallment(fin */ private void processDisbursements(final LoanApplicationTerms loanApplicationTerms, final BigDecimal chargesDueAtTimeOfDisbursement, LoanScheduleParams scheduleParams, final Collection periods, final LocalDate scheduledDueDate) { - for (Map.Entry disburseDetail : scheduleParams.getDisburseDetailMap().entrySet()) { + Iterator> iter = scheduleParams.getDisburseDetailMap().entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry disburseDetail = iter.next(); if ((disburseDetail.getKey().isEqual(scheduleParams.getPeriodStartDate()) || disburseDetail.getKey().isAfter(scheduleParams.getPeriodStartDate())) && disburseDetail.getKey().isBefore(scheduledDueDate)) { // validation check for amount not exceeds specified max // amount as per the configuration - loanApplicationTerms.getMaxOutstandingBalance(); - if (scheduleParams.getOutstandingBalance().plus(disburseDetail.getValue()) - .isGreaterThan(loanApplicationTerms.getMaxOutstandingBalance())) { - String errorMsg = "Outstanding balance must not exceed the amount: " + loanApplicationTerms.getMaxOutstandingBalance(); - throw new MultiDisbursementOutstandingAmoutException(errorMsg, - loanApplicationTerms.getMaxOutstandingBalance().getAmount(), disburseDetail.getValue()); + if (loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.getMaxOutstandingBalance() != null) { + Money maxOutstandingBalance = loanApplicationTerms.getMaxOutstandingBalanceMoney(); + if (scheduleParams.getOutstandingBalance().plus(disburseDetail.getValue()).isGreaterThan(maxOutstandingBalance)) { + String errorMsg = "Outstanding balance must not exceed the amount: " + maxOutstandingBalance; + throw new MultiDisbursementOutstandingAmoutException(errorMsg, loanApplicationTerms.getMaxOutstandingBalance(), + disburseDetail.getValue()); + } } // creates and add disbursement detail to the repayments @@ -356,6 +344,13 @@ private void processDisbursements(final LoanApplicationTerms loanApplicationTerm periods.add(disbursementPeriod); BigDecimal downPaymentAmt = BigDecimal.ZERO; + // updates actual outstanding balance with new + // disbursement detail + scheduleParams.addOutstandingBalance(disburseDetail.getValue()); + scheduleParams.addOutstandingBalanceAsPerRest(disburseDetail.getValue()); + scheduleParams.addPrincipalToBeScheduled(disburseDetail.getValue()); + loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().plus(disburseDetail.getValue())); + loanApplicationTerms.resetFixedEmiAmount(); if (loanApplicationTerms.isDownPaymentEnabled()) { // get list of disbursements done on same day and create down payment periods List disbursementsOnSameDate = loanApplicationTerms.getDisbursementDatas().stream() @@ -368,13 +363,7 @@ private void processDisbursements(final LoanApplicationTerms loanApplicationTerm downPaymentAmt = downPaymentAmt.add(downPaymentPeriod.principalDue()); } } - // updates actual outstanding balance with new - // disbursement detail - scheduleParams.addOutstandingBalance(disburseDetail.getValue()); - scheduleParams.addOutstandingBalanceAsPerRest(disburseDetail.getValue()); - scheduleParams.addPrincipalToBeScheduled(disburseDetail.getValue()); - loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().plus(disburseDetail.getValue())); - loanApplicationTerms.resetFixedEmiAmount(); + iter.remove(); } } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java index 0a6bfeee023..a0eedefb49d 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java @@ -525,7 +525,7 @@ protected void verifyRepaymentSchedule(Long loanId, Installment... installments) "Expected installments are not matching with the installments configured on the loan"); int installmentNumber = 0; - for (int i = 1; i < installments.length; i++) { + for (int i = 0; i < installments.length; i++) { GetLoansLoanIdRepaymentPeriod period = loanResponse.getRepaymentSchedule().getPeriods().get(i); Double principalDue = period.getPrincipalDue(); Double amount = installments[i].principalAmount; @@ -673,6 +673,11 @@ protected PostLoansLoanIdRequest approveLoanRequest(Double amount, String approv .approvedOnDate(approvalDate).locale("en"); } + protected PostLoansLoanIdRequest approveLoanRequest(Double amount, String approvalDate, String expectedDisbursementDate) { + return new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(amount)) + .expectedDisbursementDate(expectedDisbursementDate).dateFormat(DATETIME_PATTERN).approvedOnDate(approvalDate).locale("en"); + } + protected Long applyAndApproveLoan(Long clientId, Long loanProductId, String loanDisbursementDate, Double amount, int numberOfRepayments) { return applyAndApproveLoan(clientId, loanProductId, loanDisbursementDate, amount, numberOfRepayments, null); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java index d2a29aa94ab..67876ec0643 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java @@ -75,7 +75,7 @@ public void testSnapshotEventGenerationWhenLoanInstallmentIsNotPayed() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "31 January 2023"), // installment(313.0, false, "02 March 2023"), // installment(313.0, false, "01 April 2023"), // @@ -123,7 +123,7 @@ public void testNoSnapshotEventGenerationWhenLoanInstallmentIsPayed() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "31 January 2023"), // installment(313.0, false, "02 March 2023"), // installment(313.0, false, "01 April 2023"), // @@ -134,7 +134,7 @@ public void testNoSnapshotEventGenerationWhenLoanInstallmentIsPayed() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, true, "31 January 2023"), // installment(313.0, false, "02 March 2023"), // installment(313.0, false, "01 April 2023"), // @@ -180,7 +180,7 @@ public void testNoSnapshotEventGenerationWhenWhenCustomSnapshotEventCOBTaskIsNot // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "31 January 2023"), // installment(313.0, false, "02 March 2023"), // installment(313.0, false, "01 April 2023"), // @@ -226,7 +226,7 @@ public void testNoSnapshotEventGenerationWhenCOBDateIsNotMatchingWithInstallment // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "31 January 2023"), // installment(313.0, false, "02 March 2023"), // installment(313.0, false, "01 April 2023"), // @@ -270,7 +270,7 @@ public void testNoSnapshotEventGenerationWhenCustomSnapshotEventIsDisabled() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "31 January 2023"), // installment(313.0, false, "02 March 2023"), // installment(313.0, false, "01 April 2023"), // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java index d34ff454c45..7a426c52ab6 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java @@ -73,7 +73,7 @@ public void testInstallmentLevelDelinquencyFourRangesInTheBucket() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "31 January 2023"), // 120 days delinquent -> range4 installment(313.0, false, "02 March 2023"), // 90 days delinquent -> range4 installment(313.0, false, "01 April 2023"), // 60 days delinquent -> range3 @@ -134,7 +134,7 @@ public void testInstallmentLevelDelinquencyTwoRangesInTheBucket() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "31 January 2023"), // 120 days delinquent -> range2 installment(313.0, false, "02 March 2023"), // 90 days delinquent -> range2 installment(313.0, false, "01 April 2023"), // 60 days delinquent -> range1 @@ -184,7 +184,7 @@ public void testInstallmentLevelDelinquencyIsTurnedOff() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "31 January 2023"), // 120 days delinquent -> range2 installment(313.0, false, "02 March 2023"), // 90 days delinquent -> range2 installment(313.0, false, "01 April 2023"), // 60 days delinquent -> range1 @@ -223,7 +223,7 @@ public void testInstallmentLevelDelinquencyUpdatedWhenCOBIsExecuted() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), installment(313.0, false, "31 January 2023"), + installment(1250.0, null, "01 January 2023"), installment(313.0, false, "31 January 2023"), installment(313.0, false, "02 March 2023"), installment(313.0, false, "01 April 2023"), installment(311.0, false, "01 May 2023")); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountDisbursementToSavingsWithAutoDownPaymentTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountDisbursementToSavingsWithAutoDownPaymentTest.java index e95f6efd38a..d3bbc8550ff 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountDisbursementToSavingsWithAutoDownPaymentTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountDisbursementToSavingsWithAutoDownPaymentTest.java @@ -87,7 +87,7 @@ public void loanDisbursementToSavingsWithAutoDownPaymentAndStandingInstructionsT // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, true, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java index ba35a5dac41..c6a87649db7 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java @@ -69,7 +69,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -83,7 +83,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -102,7 +102,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -132,7 +132,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -146,7 +146,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -167,7 +167,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0, true, "01 February 2023"), // installment(343.0, 0, 50, 20, 413.0, false, "01 March 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -197,7 +197,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -211,7 +211,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -232,7 +232,7 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -258,7 +258,7 @@ public void chargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOnNPlusO disburseLoan(loanId, BigDecimal.valueOf(1250.0), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -284,7 +284,7 @@ public void chargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOnNPlusO Long repaymentTransaction = addRepaymentForLoan(loanId, 381.0, "20 April 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // @@ -308,7 +308,7 @@ public void chargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOnNPlusO ); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // @@ -339,7 +339,7 @@ public void chargebackWithCreditAllocationAndReverseReplayWithBackdatedPayment() Long penaltyId = addCharge(loanId, true, 20, "15 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -353,7 +353,7 @@ public void chargebackWithCreditAllocationAndReverseReplayWithBackdatedPayment() Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -373,7 +373,7 @@ public void chargebackWithCreditAllocationAndReverseReplayWithBackdatedPayment() // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -414,7 +414,7 @@ public void chargebackWithCreditAllocationReverseReplayedWithBackdatedPayment() Long penaltyId = addCharge(loanId, true, 20, "15 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -428,7 +428,7 @@ public void chargebackWithCreditAllocationReverseReplayedWithBackdatedPayment() Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -448,7 +448,7 @@ public void chargebackWithCreditAllocationReverseReplayedWithBackdatedPayment() // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -494,7 +494,7 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenalty() { Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -508,7 +508,7 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenalty() { Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -526,7 +526,7 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenalty() { // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(413.0, 0, 50, 20, 100.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -558,7 +558,7 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenaltyWhenOverpai Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -573,7 +573,7 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenaltyWhenOverpai // overpayment verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // @@ -595,7 +595,7 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenaltyWhenOverpai // Verify Repayment Schedule // DEFAULT payment allocation is ..., DUE_PENALTY, DUE_FEE, DUE_PRINCIPAL, ... verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 0, true, "01 March 2023"), // installment(313.0, 0, 0, 0, 0, true, "01 April 2023"), // @@ -626,7 +626,7 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -641,7 +641,7 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai // overpayment verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // @@ -661,7 +661,7 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai // Verify Repayment Schedule, // DEFAULT payment allocation is ..., DUE_PENALTY, DUE_FEE, DUE_PRINCIPAL, ... verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(343.0, 0, 100, 40, outstanding(30.0, 20.0, 0.0, 50.0), false, "01 February 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // @@ -693,7 +693,7 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -708,7 +708,7 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai // overpayment verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // @@ -728,7 +728,7 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai // Verify Repayment Schedule, // DEFAULT payment allocation is ..., DUE_PRINCIPAL, DUE_FEE, DUE_PENALTY ... verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(343.0, 0, 100, 40, outstanding(0.0, 30.0, 20.0, 50.0), false, "01 February 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // @@ -760,7 +760,7 @@ public void doubleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -774,7 +774,7 @@ public void doubleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -793,7 +793,7 @@ public void doubleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -813,7 +813,7 @@ public void doubleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(443.0, 0, 100, 40, 200.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -844,7 +844,7 @@ public void doubleChargebackReverseReplayedBothFeeAndPenaltyPayedWithCreditAlloc Long penaltyId = addCharge(loanId, true, 20, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -858,7 +858,7 @@ public void doubleChargebackReverseReplayedBothFeeAndPenaltyPayedWithCreditAlloc Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -877,7 +877,7 @@ public void doubleChargebackReverseReplayedBothFeeAndPenaltyPayedWithCreditAlloc // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -897,7 +897,7 @@ public void doubleChargebackReverseReplayedBothFeeAndPenaltyPayedWithCreditAlloc // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(443.0, 0, 100, 40, 200.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -938,7 +938,7 @@ public void doubleChargebackReverseReplayedOnlyPenaltyPayedWithCreditAllocationP Long penaltyId = addCharge(loanId, true, 20, "15 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -952,7 +952,7 @@ public void doubleChargebackReverseReplayedOnlyPenaltyPayedWithCreditAllocationP Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -971,7 +971,7 @@ public void doubleChargebackReverseReplayedOnlyPenaltyPayedWithCreditAllocationP // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -991,7 +991,7 @@ public void doubleChargebackReverseReplayedOnlyPenaltyPayedWithCreditAllocationP // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(443.0, 0, 100, 40, 200.0, false, "01 February 2023"), installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // @@ -1028,7 +1028,7 @@ public void testAccountingChargebackOnPrincipal() { disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1100,7 +1100,7 @@ public void testAccountingChargebackOnPrincipalAndFees() { Long feeId = addCharge(loanId, false, 30, "15 February 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 30, 0, 280.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1178,7 +1178,7 @@ public void testAccountingChargebackOnPrincipalAndPenalties() { Long feeId = addCharge(loanId, true, 30, "15 February 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 30.0, 280.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1254,7 +1254,7 @@ public void testAccountingOverpaymentAmountIsSmallerThanChargeback() { disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1326,7 +1326,7 @@ public void testAccountingOverpaymentAmountIsBiggerThanChargeback() { disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1397,7 +1397,7 @@ public void testAccountingOverpaidLoansWithFeesWhenOverpaymentAmountIsBiggerThan disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1477,7 +1477,7 @@ public void testAccountingChargebackOnChargeOffWithPrincipal() { disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1547,7 +1547,7 @@ public void testAccountingChargebackOnChargeOffFraudWithPrincipal() { disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1618,7 +1618,7 @@ public void testAccountingChargebackOnChargeOffWithFees() { disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // @@ -1705,7 +1705,7 @@ public void testAccountingChargebackOnChargeOffWithPenalties() { disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023"); verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(750.0, null, "01 January 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), // installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDelinquencyDetailsNextPaymentDateConfigurationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDelinquencyDetailsNextPaymentDateConfigurationTest.java index 656017a6f26..1cdc11f1ed2 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDelinquencyDetailsNextPaymentDateConfigurationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDelinquencyDetailsNextPaymentDateConfigurationTest.java @@ -69,7 +69,7 @@ public void testNextPaymentDateForUnpaidInstallmentsWithNPlusOneTest() { // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 November 2023"), // + installment(1000.0, null, "01 November 2023"), // installment(250.0, false, "01 November 2023"), // installment(250.0, false, "16 November 2023"), // installment(250.0, false, "01 December 2023"), // @@ -103,7 +103,7 @@ public void testNextPaymentDateForUnpaidInstallmentsWithNPlusOneTest() { // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 November 2023"), // + installment(1000.0, null, "01 November 2023"), // installment(250.0, false, "01 November 2023"), // installment(250.0, false, "16 November 2023"), // installment(250.0, false, "01 December 2023"), // @@ -155,7 +155,7 @@ public void testNextPaymentDateFor2Paid1PartiallyPaidInstallmentsWithNPlusOneTes // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 November 2023"), // + installment(1000.0, null, "01 November 2023"), // installment(250.0, true, "01 November 2023"), // installment(250.0, false, "16 November 2023"), // installment(250.0, false, "01 December 2023"), // @@ -177,7 +177,7 @@ public void testNextPaymentDateFor2Paid1PartiallyPaidInstallmentsWithNPlusOneTes // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 November 2023"), // + installment(1000.0, null, "01 November 2023"), // installment(250.0, true, "01 November 2023"), // installment(250.0, true, "16 November 2023"), // installment(250.0, false, "01 December 2023"), // @@ -198,7 +198,7 @@ public void testNextPaymentDateFor2Paid1PartiallyPaidInstallmentsWithNPlusOneTes // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 November 2023"), // + installment(1000.0, null, "01 November 2023"), // installment(250.0, true, "01 November 2023"), // installment(250.0, true, "16 November 2023"), // installment(250.0, 0.0, 150.0, false, "01 December 2023"), // @@ -219,7 +219,7 @@ public void testNextPaymentDateFor2Paid1PartiallyPaidInstallmentsWithNPlusOneTes // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 November 2023"), // + installment(1000.0, null, "01 November 2023"), // installment(250.0, true, "01 November 2023"), // installment(250.0, true, "16 November 2023"), // installment(250.0, 0.0, 150.0, false, "01 December 2023"), // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java index 2b8f7b01584..546e44cca72 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java @@ -57,7 +57,7 @@ public void loanDownPaymentTransactionChargebackTest() { // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // @@ -79,7 +79,7 @@ public void loanDownPaymentTransactionChargebackTest() { // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, true, "01 March 2023"), // installment(300.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // @@ -116,7 +116,7 @@ public void loanDownPaymentTransactionChargebackForAdvancedPaymentAllocationTest // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // @@ -138,7 +138,7 @@ public void loanDownPaymentTransactionChargebackForAdvancedPaymentAllocationTest // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, true, "01 March 2023"), // installment(300.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDueCalculationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDueCalculationTest.java index 132ab63869a..6700364f757 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDueCalculationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDueCalculationTest.java @@ -160,7 +160,8 @@ public void dueDateBasedOnSubmittedOnDate(String repaymentProcessor) { .loanTermFrequency(4).loanTermFrequencyType(2).submittedOnDate("2024-01-31").dateFormat("yyyy-MM-dd"); }); PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(loanRequest); - verifyRepaymentSchedule(postLoansResponse.getLoanId(), installment(1000.0, null, "31 January 2024"), // + verifyRepaymentSchedule(postLoansResponse.getLoanId(), // + installment(1000.0, null, "01 February 2024"), // installment(250.0, false, "29 February 2024"), // installment(250.0, false, "31 March 2024"), // installment(250.0, false, "30 April 2024"), // @@ -169,7 +170,8 @@ public void dueDateBasedOnSubmittedOnDate(String repaymentProcessor) { loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), approveLoanRequest(1000.0, "31 January 2024")); - verifyRepaymentSchedule(postLoansResponse.getLoanId(), installment(1000.0, null, "31 January 2024"), // + verifyRepaymentSchedule(postLoansResponse.getLoanId(), // + installment(1000.0, null, "01 February 2024"), // installment(250.0, false, "29 February 2024"), // installment(250.0, false, "31 March 2024"), // installment(250.0, false, "30 April 2024"), // @@ -178,7 +180,8 @@ public void dueDateBasedOnSubmittedOnDate(String repaymentProcessor) { disburseLoan(postLoansResponse.getLoanId(), BigDecimal.valueOf(1000.00), "03 February 2024"); - verifyRepaymentSchedule(postLoansResponse.getLoanId(), installment(1000.0, null, "01 February 2024"), // + verifyRepaymentSchedule(postLoansResponse.getLoanId(), // + installment(1000.0, null, "03 February 2024"), // installment(250.0, false, "29 February 2024"), // installment(250.0, false, "31 March 2024"), // installment(250.0, false, "30 April 2024"), // @@ -208,7 +211,7 @@ public void dueDateBasedOnSubmittedOnDateButThereShallBeMinimumDaysBetweenDisbur .loanTermFrequency(4).loanTermFrequencyType(2).submittedOnDate("2024-01-31").dateFormat("yyyy-MM-dd"); }); PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(loanRequest); - verifyRepaymentSchedule(postLoansResponse.getLoanId(), installment(1000.0, null, "31 January 2024"), // + verifyRepaymentSchedule(postLoansResponse.getLoanId(), installment(1000.0, null, "26 February 2024"), // installment(250.0, false, "07 March 2024"), // installment(250.0, false, "07 April 2024"), // installment(250.0, false, "07 May 2024"), // @@ -217,7 +220,7 @@ public void dueDateBasedOnSubmittedOnDateButThereShallBeMinimumDaysBetweenDisbur loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), approveLoanRequest(1000.0, "31 January 2024")); - verifyRepaymentSchedule(postLoansResponse.getLoanId(), installment(1000.0, null, "31 January 2024"), // + verifyRepaymentSchedule(postLoansResponse.getLoanId(), installment(1000.0, null, "26 February 2024"), // installment(250.0, false, "07 March 2024"), // installment(250.0, false, "07 April 2024"), // installment(250.0, false, "07 May 2024"), // @@ -283,4 +286,57 @@ public void dueDateBasedOnExpectedDisbursalDateButThereShallBeMinimumDaysBetween ; }); } + + // Repayment dates are calculated based on `repayment start date type` configuration(=Submitted on date). Submitted + // on date is `2024-01-31`, and even the expected disbursement date is `2024-02-01`, the generated repayment + // schedule honors the submitted on date + // when it got approved and new expected disbursement date is `2024-02-02`, the repayment schedule due dates got no + // changed + // when it got disbursed on `2024-02-03`, the repayment schedule due dates got no changed. + @ParameterizedTest + @MethodSource("processingStrategy") + public void dueDateBasedOnSubmittedOnDateButChangingExpectedDisbursementAtApproval(String repaymentProcessor) { + runAt("03 February 2024", () -> { + // Client and Loan account creation + final Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId(); + PostLoanProductsRequest loanProductsRequest = create4Period1MonthLongWithoutInterestProduct(repaymentProcessor) + .repaymentStartDateType(RepaymentStartDateType.SUBMITTED_ON_DATE.getValue()); + PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(loanProductsRequest); + + PostLoansRequest loanRequest = applyLoanRequest(clientId, loanProductResponse.getResourceId(), "2024-02-01", 1000.0, 4, + (postLoansRequest) -> { + postLoansRequest.transactionProcessingStrategyCode(repaymentProcessor).repaymentEvery(1).repaymentFrequencyType(2) + .loanTermFrequency(4).loanTermFrequencyType(2).submittedOnDate("2024-01-31").dateFormat("yyyy-MM-dd"); + }); + PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(loanRequest); + verifyRepaymentSchedule(postLoansResponse.getLoanId(), // + installment(1000.0, null, "01 February 2024"), // + installment(250.0, false, "29 February 2024"), // + installment(250.0, false, "31 March 2024"), // + installment(250.0, false, "30 April 2024"), // + installment(250.0, false, "31 May 2024")) // + ; + + loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), + approveLoanRequest(1000.0, "31 January 2024", "02 February 2024")); + + verifyRepaymentSchedule(postLoansResponse.getLoanId(), // + installment(1000.0, null, "02 February 2024"), // + installment(250.0, false, "29 February 2024"), // + installment(250.0, false, "31 March 2024"), // + installment(250.0, false, "30 April 2024"), // + installment(250.0, false, "31 May 2024")) // + ; + + disburseLoan(postLoansResponse.getLoanId(), BigDecimal.valueOf(1000.00), "03 February 2024"); + + verifyRepaymentSchedule(postLoansResponse.getLoanId(), // + installment(1000.0, null, "03 February 2024"), // + installment(250.0, false, "29 February 2024"), // + installment(250.0, false, "31 March 2024"), // + installment(250.0, false, "30 April 2024"), // + installment(250.0, false, "31 May 2024")) // + ; + }); + } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInstallmentMultiplesOfTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInstallmentMultiplesOfTest.java index 9d72e8a61ef..cbde7e33465 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInstallmentMultiplesOfTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInstallmentMultiplesOfTest.java @@ -77,7 +77,7 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenNoInterest_ButInt // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "01 February 2023"), // installment(313.0, false, "01 March 2023"), // installment(313.0, false, "01 April 2023"), // @@ -89,7 +89,7 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenNoInterest_ButInt // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(313.0, false, "01 February 2023"), // installment(313.0, false, "01 March 2023"), // installment(313.0, false, "01 April 2023"), // @@ -141,7 +141,7 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenInterestIsPresent // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(417.5, 12.5, 430.0, false, "01 February 2023"), // installment(417.5, 12.5, 430.0, false, "01 March 2023"), // installment(415.0, 12.5, 427.5, false, "01 April 2023") // @@ -152,7 +152,7 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenInterestIsPresent // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(417.5, 12.5, 430.0, false, "01 February 2023"), // installment(417.5, 12.5, 430.0, false, "01 March 2023"), // installment(415.0, 12.5, 427.5, false, "01 April 2023") // @@ -204,7 +204,7 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenInterestIsPresent // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(427.5, 12.5, 440.0, false, "01 February 2023"), // installment(427.5, 12.5, 440.0, false, "01 March 2023"), // installment(395.0, 12.5, 407.5, false, "01 April 2023") // @@ -215,7 +215,7 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenInterestIsPresent // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(427.5, 12.5, 440.0, false, "01 February 2023"), // installment(427.5, 12.5, 440.0, false, "01 March 2023"), // installment(395.0, 12.5, 407.5, false, "01 April 2023") // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleForChargesAfterMaturityTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleForChargesAfterMaturityTest.java index 0159ed53954..43abd6637e7 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleForChargesAfterMaturityTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleForChargesAfterMaturityTest.java @@ -55,7 +55,7 @@ public void loanNPlusOneInstallmentIsRetainedAfterLoanRescheduleTest() { // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "15 April 2023"), // @@ -67,7 +67,7 @@ public void loanNPlusOneInstallmentIsRetainedAfterLoanRescheduleTest() { // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "15 April 2023"), // @@ -89,7 +89,7 @@ public void loanNPlusOneInstallmentIsRetainedAfterLoanRescheduleTest() { // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "30 April 2023"), // @@ -119,7 +119,7 @@ public void loanNPlusOneInstallmentIsAdjustedAfterRescheduleIfDateFallBeforeMatu // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "15 April 2023"), // @@ -132,7 +132,7 @@ public void loanNPlusOneInstallmentIsAdjustedAfterRescheduleIfDateFallBeforeMatu // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "15 April 2023"), // @@ -154,7 +154,7 @@ public void loanNPlusOneInstallmentIsAdjustedAfterRescheduleIfDateFallBeforeMatu // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "30 April 2023"), // @@ -186,7 +186,7 @@ public void loanNPlusOneInstallmentIsRetainedAfterLoanRescheduleForAdvancedPayme // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "15 April 2023"), // @@ -198,7 +198,7 @@ public void loanNPlusOneInstallmentIsRetainedAfterLoanRescheduleForAdvancedPayme // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "15 April 2023"), // @@ -220,7 +220,7 @@ public void loanNPlusOneInstallmentIsRetainedAfterLoanRescheduleForAdvancedPayme // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "30 April 2023"), // @@ -251,7 +251,7 @@ public void loanNPlusOneInstallmentIsAdjustedAfterRescheduleIfDateFallBeforeMatu // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "15 April 2023"), // @@ -264,7 +264,7 @@ public void loanNPlusOneInstallmentIsAdjustedAfterRescheduleIfDateFallBeforeMatu // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "15 April 2023"), // @@ -286,7 +286,7 @@ public void loanNPlusOneInstallmentIsAdjustedAfterRescheduleIfDateFallBeforeMatu // verify repayment schedule verifyRepaymentSchedule(loanId, // - installment(0, null, "01 March 2023"), // + installment(1000.0, null, "01 March 2023"), // installment(250.0, false, "16 March 2023"), // installment(250.0, false, "31 March 2023"), // installment(250.0, false, "30 April 2023"), // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java index 450553ff873..a6b41dd31d6 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java @@ -278,7 +278,7 @@ public void testRescheduleAddExtraInstallmentsDisbursementWithDownPaymentWithInt // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(12000.0, null, "01 January 2023"), // + installment(15000.0, null, "01 January 2023"), // installment(3000.00, false, "01 January 2023"), // installment(1764.21, false, "01 February 2023"), // installment(1852.42, false, "01 March 2023"), // @@ -357,7 +357,7 @@ public void testRescheduleAddExtraInstallmentsMultipleDisbursementWithDownPaymen // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(12000.0, null, "01 January 2023"), // + installment(15000.0, null, "01 January 2023"), // installment(3000.00, false, "01 January 2023"), // installment(1764.21, false, "01 February 2023"), // installment(1852.42, false, "01 March 2023"), // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWaiveChargeTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWaiveChargeTest.java index 8c01cccaa18..742ca90f494 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWaiveChargeTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWaiveChargeTest.java @@ -91,7 +91,7 @@ public void test_LoanPaidByDateIsCorrect_WhenNPlusOneInstallmentCharge_IsWaived( // verify schedule verifyRepaymentSchedule(loanId, // - installment(0.0, null, "01 January 2023"), // + installment(1000.0, null, "01 January 2023"), // installment(1000.0, 0.0, 0.0, 1000.0, false, "31 January 2023")); }); runAt("02 February 2023", () -> { @@ -108,7 +108,7 @@ public void test_LoanPaidByDateIsCorrect_WhenNPlusOneInstallmentCharge_IsWaived( // verify N+1 installment in schedule verifyRepaymentSchedule(loanId, // - installment(0.0, null, "01 January 2023"), // + installment(1000.0, null, "01 January 2023"), // installment(1000.0, 0.0, 0.0, 1000.0, false, "31 January 2023"), // installment(0.0, 0.0, 100.0, 100.0, false, "01 February 2023") // ); @@ -128,7 +128,7 @@ public void test_LoanPaidByDateIsCorrect_WhenNPlusOneInstallmentCharge_IsWaived( // verify N+1 installment completion verifyRepaymentSchedule(loanId, // - installment(0.0, null, "01 January 2023"), // + installment(1000.0, null, "01 January 2023"), // installment(1000.0, 0.0, 0.0, 0.0, true, "31 January 2023"), // installment(0.0, 0.0, 100.0, 0.0, true, "01 February 2023") // ); @@ -184,7 +184,7 @@ public void accrualIsCalculatedWhenThereIsWaivedChargeAndLoanIsClosed(boolean ad // verify schedule verifyRepaymentSchedule(loanId, // - installment(0.0, null, "01 January 2023"), // + installment(1000.0, null, "01 January 2023"), // installment(1000.0, 0.0, 0.0, 1000.0, false, "31 January 2023")); }); @@ -201,7 +201,7 @@ public void accrualIsCalculatedWhenThereIsWaivedChargeAndLoanIsClosed(boolean ad this.schedulerJobHelper.executeAndAwaitJob(LoanCoBJobName); verifyRepaymentSchedule(loanId, // - installment(0.0, null, "01 January 2023"), // + installment(1000.0, null, "01 January 2023"), // installment(1000.0, 0.0, 10.0, 1010.0, false, "31 January 2023") // ); @@ -231,7 +231,7 @@ public void accrualIsCalculatedWhenThereIsWaivedChargeAndLoanIsClosed(boolean ad ); verifyRepaymentSchedule(loanId, // - installment(0.0, null, "01 January 2023"), // + installment(1000.0, null, "01 January 2023"), // installment(1000.0, 0.0, 19.0, 1010.0, false, "31 January 2023") // ); }); @@ -260,7 +260,7 @@ public void accrualIsCalculatedWhenThereIsWaivedChargeAndLoanIsClosed(boolean ad ); verifyRepaymentSchedule(loanId, // - installment(0.0, null, "01 January 2023"), // + installment(1000.0, null, "01 January 2023"), // installment(1000.0, 0.0, 27.0, 0.0, true, "31 January 2023") // ); }); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/reamortization/LoanReAmortizationIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/reamortization/LoanReAmortizationIntegrationTest.java index bb5d7a877c7..fb555ad4a8a 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/reamortization/LoanReAmortizationIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/reamortization/LoanReAmortizationIntegrationTest.java @@ -85,7 +85,7 @@ public void test_LoanReAmortizeTransaction_Works() { // verify schedule verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(625.0, false, "01 February 2023"), // installment(625.0, false, "01 March 2023") // ); @@ -102,7 +102,7 @@ public void test_LoanReAmortizeTransaction_Works() { ); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(0.0, true, "01 February 2023"), // installment(1250.0, false, "01 March 2023") // ); @@ -152,7 +152,7 @@ public void test_LoanUndoReAmortizeTransaction_Works() { // verify schedule verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(625.0, false, "01 February 2023"), // installment(625.0, false, "01 March 2023") // ); @@ -180,7 +180,7 @@ public void test_LoanUndoReAmortizeTransaction_Works() { ); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(1250.0, null, "01 January 2023"), // installment(625.0, false, "01 February 2023"), // installment(625.0, false, "01 March 2023") // ); @@ -204,7 +204,7 @@ public void reAmortizeLoanRepaymentScheduleTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -215,7 +215,7 @@ public void reAmortizeLoanRepaymentScheduleTest() { addCharge(loanId.get(), false, 10.0, "05 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, 0.0, 10.0, 135.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -226,7 +226,7 @@ public void reAmortizeLoanRepaymentScheduleTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, 0.0, 10.0, 10.0, false, "16 January 2023"), // installment(187.5, false, "31 January 2023"), // @@ -259,7 +259,7 @@ public void completePastDueReAmortizationTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -271,7 +271,7 @@ public void completePastDueReAmortizationTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, true, "16 January 2023"), // installment(0.0, true, "31 January 2023"), // @@ -304,7 +304,7 @@ public void partiallyPaidReAmortizationTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -325,7 +325,7 @@ public void partiallyPaidReAmortizationTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(50.0, true, "16 January 2023"), // installment(162.5, false, "31 January 2023"), // @@ -359,7 +359,7 @@ public void reAmortizationOnSameDayOfInstallmentTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -370,7 +370,7 @@ public void reAmortizationOnSameDayOfInstallmentTest() { addCharge(loanId.get(), false, 10.0, "05 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, 0.0, 10.0, 135.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -381,7 +381,7 @@ public void reAmortizationOnSameDayOfInstallmentTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, 0.0, 10.0, 10.0, false, "16 January 2023"), // installment(0.0, true, "31 January 2023"), // @@ -414,7 +414,7 @@ public void reAmortizationNPlusOneInstallmentTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -427,7 +427,7 @@ public void reAmortizationNPlusOneInstallmentTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, true, "16 January 2023"), // installment(0.0, true, "31 January 2023"), // @@ -461,7 +461,7 @@ public void reAmortizationBackdatedRepaymentAndReplayTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -472,7 +472,7 @@ public void reAmortizationBackdatedRepaymentAndReplayTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, true, "16 January 2023"), // installment(0.0, true, "31 January 2023"), // @@ -491,7 +491,7 @@ public void reAmortizationBackdatedRepaymentAndReplayTest() { addRepaymentForLoan(loanId.get(), 125.0, "15 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, true, "16 January 2023"), // installment(0.0, true, "31 January 2023"), // @@ -525,7 +525,7 @@ public void reAmortizationUndoRepaymentAndReplayTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -537,7 +537,7 @@ public void reAmortizationUndoRepaymentAndReplayTest() { repaymentTransactionId.set(addRepaymentForLoan(loanId.get(), 125.0, "15 January 2023")); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, true, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -555,7 +555,7 @@ public void reAmortizationUndoRepaymentAndReplayTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, true, "16 January 2023"), // installment(0.0, true, "31 January 2023"), // @@ -573,7 +573,7 @@ public void reAmortizationUndoRepaymentAndReplayTest() { loanTransactionHelper.reverseRepayment(loanId.intValue(), repaymentTransactionId.intValue(), "01 February 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, true, "16 January 2023"), // installment(0.0, true, "31 January 2023"), // @@ -607,7 +607,7 @@ public void reverseReAmortizationTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -619,7 +619,7 @@ public void reverseReAmortizationTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, true, "16 January 2023"), // installment(0.0, true, "31 January 2023"), // @@ -638,7 +638,7 @@ public void reverseReAmortizationTest() { undoReAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -671,7 +671,7 @@ public void reAmortizationDivisionTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(100.0, true, "01 January 2023"), // installment(100.0, false, "16 January 2023"), // installment(100.0, false, "31 January 2023"), // @@ -683,7 +683,7 @@ public void reAmortizationDivisionTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(100.0, true, "01 January 2023"), // installment(0.0, true, "16 January 2023"), // installment(133.33, false, "31 January 2023"), // @@ -717,7 +717,7 @@ public void secondDisbursementAfterReAmortizationTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(125.0, false, "16 January 2023"), // installment(125.0, false, "31 January 2023"), // @@ -732,7 +732,7 @@ public void secondDisbursementAfterReAmortizationTest() { reAmortizeLoan(loanId.get()); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, 0.0, 10.0, 10.0, false, "16 January 2023"), // installment(187.5, false, "31 January 2023"), // @@ -750,7 +750,7 @@ public void secondDisbursementAfterReAmortizationTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "26 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(0.0, 0.0, 10.0, 0.0, true, "16 January 2023"), // installment(500.0, null, "26 January 2023"), // @@ -773,7 +773,7 @@ public void secondDisbursementAfterReAmortizationTest() { disburseLoan(loanId.get(), BigDecimal.valueOf(100.0), "10 January 2023"); verifyRepaymentSchedule(loanId.get(), // - installment(0, null, "01 January 2023"), // + installment(500, null, "01 January 2023"), // installment(125.0, true, "01 January 2023"), // installment(100.0, null, "10 January 2023"), // installment(25.0, true, "10 January 2023"), //