This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new ea68edce2 FINERACT-1981: Order disbursements and repayment periods
properly
ea68edce2 is described below
commit ea68edce2db1b9c638c60e52218eecf6ed187a4e
Author: Adam Saghy <[email protected]>
AuthorDate: Tue Nov 28 18:07:04 2023 +0100
FINERACT-1981: Order disbursements and repayment periods properly
---
.../loanaccount/data/DisbursementData.java | 14 +-
...dvancedPaymentScheduleTransactionProcessor.java | 2 +-
.../loanschedule/domain/LoanScheduleType.java | 7 +
.../loanaccount/api/LoansApiResource.java | 8 +-
.../AbstractProgressiveLoanScheduleGenerator.java | 106 +---
.../domain/ProgressiveLoanScheduleGenerator.java | 39 +-
.../LoanScheduleHistoryReadPlatformService.java | 3 +-
...LoanScheduleHistoryReadPlatformServiceImpl.java | 12 +-
.../service/LoanReadPlatformService.java | 4 +-
.../service/LoanReadPlatformServiceImpl.java | 106 ++--
...PaymentAllocationLoanRepaymentScheduleTest.java | 581 ++++++++++++---------
.../integrationtests/BaseLoanIntegrationTest.java | 5 +
...ChargeOffWithAdvancedPaymentAllocationTest.java | 26 +-
...nWithOverlappingDownPaymentInstallmentTest.java | 54 +-
...ProductRepaymentStartDateConfigurationTest.java | 84 +--
15 files changed, 532 insertions(+), 519 deletions(-)
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DisbursementData.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DisbursementData.java
index 243426ddd..53e318fff 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DisbursementData.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DisbursementData.java
@@ -23,6 +23,7 @@ import java.time.LocalDate;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.service.DateUtils;
+import
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
/**
* Immutable data object representing disbursement information.
@@ -89,9 +90,12 @@ public final class DisbursementData implements
Comparable<DisbursementData> {
return DateUtils.compare(obj.expectedDisbursementDate,
this.expectedDisbursementDate);
}
- public boolean isDueForDisbursement(final LocalDate fromNotInclusive,
final LocalDate upToAndInclusive) {
+ public boolean isDueForDisbursement(LoanScheduleType loanScheduleType,
final LocalDate fromDate, final LocalDate toDate) {
final LocalDate dueDate = disbursementDate();
- return occursOnDayFromAndUpToAndIncluding(fromNotInclusive,
upToAndInclusive, dueDate);
+ return switch (loanScheduleType) {
+ case CUMULATIVE -> occursOnDayFromAndUpToAndIncluding(fromDate,
toDate, dueDate);
+ case PROGRESSIVE -> occursOnDayFromAndIncludingAndUpTo(fromDate,
toDate, dueDate);
+ };
}
private boolean occursOnDayFromAndUpToAndIncluding(final LocalDate
fromNotInclusive, final LocalDate upToAndInclusive,
@@ -99,6 +103,12 @@ public final class DisbursementData implements
Comparable<DisbursementData> {
return DateUtils.isAfter(target, fromNotInclusive) &&
!DateUtils.isAfter(target, upToAndInclusive);
}
+ private boolean occursOnDayFromAndIncludingAndUpTo(final LocalDate
fromInclusive, final LocalDate upToNotInclusive,
+ final LocalDate target) {
+ return (DateUtils.isEqual(target, fromInclusive) ||
DateUtils.isAfter(target, fromInclusive))
+ && DateUtils.isBefore(target, upToNotInclusive);
+ }
+
public BigDecimal getWaivedChargeAmount() {
return this.waivedChargeAmount == null ? BigDecimal.ZERO :
this.waivedChargeAmount;
}
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
index 9994201e7..fefbd022c 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
@@ -282,7 +282,7 @@ public class AdvancedPaymentScheduleTransactionProcessor
extends AbstractLoanRep
List<LoanRepaymentScheduleInstallment> installments) {
final MathContext mc = MoneyHelper.getMathContext();
List<LoanRepaymentScheduleInstallment> candidateRepaymentInstallments
= installments.stream().filter(
- i ->
!i.getDueDate().isBefore(disbursementTransaction.getTransactionDate()) &&
!i.isDownPayment() && !i.isAdditional())
+ i ->
i.getDueDate().isAfter(disbursementTransaction.getTransactionDate()) &&
!i.isDownPayment() && !i.isAdditional())
.toList();
int noCandidateRepaymentInstallments =
candidateRepaymentInstallments.size();
LoanProductRelatedDetail loanProductRelatedDetail =
disbursementTransaction.getLoan().getLoanRepaymentScheduleDetail();
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleType.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleType.java
index f56173377..d9a704684 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleType.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleType.java
@@ -39,4 +39,11 @@ public enum LoanScheduleType {
public EnumOptionData asEnumOptionData() {
return new EnumOptionData((long) this.ordinal(), this.name(),
this.humanReadableName);
}
+
+ public static LoanScheduleType fromEnumOptionData(EnumOptionData
enumOptionData) {
+ if (enumOptionData == null) {
+ return null;
+ }
+ return valueOf(enumOptionData.getCode());
+ }
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java
index e379e841b..7f6da6f65 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java
@@ -47,7 +47,6 @@ import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
import java.io.InputStream;
-import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -953,7 +952,7 @@ public class LoansApiResource {
loanBasicDetails.getFeeChargesAtDisbursementCharged());
repaymentSchedule =
this.loanReadPlatformService.retrieveRepaymentSchedule(resolvedLoanId,
repaymentScheduleRelatedData,
disbursementData,
loanBasicDetails.isInterestRecalculationEnabled(),
- loanBasicDetails.getSummary() != null ?
loanBasicDetails.getSummary().getFeeChargesPaid() : BigDecimal.ZERO);
+
LoanScheduleType.fromEnumOptionData(loanBasicDetails.getLoanScheduleType()));
if
(associationParameters.contains(DataTableApiConstant.futureScheduleAssociateParamName)
&& loanBasicDetails.isInterestRecalculationEnabled()) {
@@ -965,8 +964,9 @@ public class LoansApiResource {
&& loanBasicDetails.isInterestRecalculationEnabled()
&&
LoanStatus.fromInt(loanBasicDetails.getStatus().getId().intValue()).isActive())
{
mandatoryResponseParameters.add(DataTableApiConstant.originalScheduleAssociateParamName);
- LoanScheduleData loanScheduleData =
this.loanScheduleHistoryReadPlatformService
- .retrieveRepaymentArchiveSchedule(resolvedLoanId,
repaymentScheduleRelatedData, disbursementData);
+ LoanScheduleData loanScheduleData =
this.loanScheduleHistoryReadPlatformService.retrieveRepaymentArchiveSchedule(
+ resolvedLoanId, repaymentScheduleRelatedData,
disbursementData,
+
LoanScheduleType.fromEnumOptionData(loanBasicDetails.getLoanScheduleType()));
loanBasicDetails =
LoanAccountData.withOriginalSchedule(loanBasicDetails, loanScheduleData);
}
}
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 d0c1ba0cb..2399093a6 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
@@ -28,7 +28,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeMap;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
@@ -85,26 +84,6 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
boolean isFirstRepayment = true;
- if (loanApplicationTerms.isMultiDisburseLoan()) {
- /* fetches the first tranche amount and also updates other tranche
details to map */
- Money disburseAmt = Money.of(currency,
getDisbursementAmount(loanApplicationTerms, scheduleParams.getPeriodStartDate(),
- scheduleParams.getDisburseDetailMap(),
scheduleParams.applyInterestRecalculation()));
- Money downPaymentAmt = Money.zero(currency);
- if (loanApplicationTerms.isDownPaymentEnabled()) {
- downPaymentAmt = Money.of(currency,
MathUtil.percentageOf(disburseAmt.getAmount(),
-
loanApplicationTerms.getDisbursedAmountPercentageForDownPayment(), 19));
- if (loanApplicationTerms.getInstallmentAmountInMultiplesOf()
!= null) {
- downPaymentAmt = Money.roundToMultiplesOf(downPaymentAmt,
loanApplicationTerms.getInstallmentAmountInMultiplesOf());
- }
- }
- Money remainingPrincipalAmt = disburseAmt.minus(downPaymentAmt);
- scheduleParams.setPrincipalToBeScheduled(remainingPrincipalAmt);
- loanApplicationTerms.setPrincipal(remainingPrincipalAmt);
- scheduleParams.setOutstandingBalance(remainingPrincipalAmt);
-
scheduleParams.setOutstandingBalanceAsPerRest(remainingPrincipalAmt);
- loanApplicationTerms.resetFixedEmiAmount();
- }
-
// charges which depends on total loan interest will be added to this
// set and handled separately after all installments generated
final Set<LoanCharge> nonCompoundingCharges =
separateTotalCompoundingPercentageCharges(loanCharges);
@@ -134,13 +113,8 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
}
// 5 determine principal,interest of repayment period
- PrincipalInterest principalInterestForThisPeriod =
calculatePrincipalInterestComponentsForPeriod(
- getPaymentPeriodsInOneYearCalculator(),
currentPeriodParams.getInterestCalculationGraceOnRepaymentPeriodFraction(),
-
scheduleParams.getTotalCumulativePrincipal().minus(scheduleParams.getReducePrincipal()),
- scheduleParams.getTotalCumulativeInterest(),
loanApplicationTerms.getTotalInterestDue(),
-
scheduleParams.getTotalOutstandingInterestPaymentDueToGrace(),
scheduleParams.getOutstandingBalanceAsPerRest(),
- loanApplicationTerms, scheduleParams.getPeriodNumber(),
mc, null, scheduleParams.getCompoundingMap(), null,
- scheduledDueDate, null);
+ PrincipalInterest principalInterestForThisPeriod =
calculatePrincipalInterestComponentsForPeriod(loanApplicationTerms,
+ scheduleParams, mc);
// update cumulative fields for principal
currentPeriodParams.setPrincipalForThisPeriod(principalInterestForThisPeriod.principal());
@@ -241,12 +215,8 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
public abstract PaymentPeriodsInOneYearCalculator
getPaymentPeriodsInOneYearCalculator();
- public abstract PrincipalInterest
calculatePrincipalInterestComponentsForPeriod(PaymentPeriodsInOneYearCalculator
calculator,
- BigDecimal interestCalculationGraceOnRepaymentPeriodFraction,
Money totalCumulativePrincipal, Money totalCumulativeInterest,
- Money totalInterestDueForLoan, Money
cumulatingInterestPaymentDueToGrace, Money outstandingBalance,
- LoanApplicationTerms loanApplicationTerms, int periodNumber,
MathContext mc, TreeMap<LocalDate, Money> principalVariation,
- Map<LocalDate, Money> compoundingMap, LocalDate periodStartDate,
LocalDate periodEndDate,
- Collection<LoanTermVariationsData> termVariations);
+ public abstract PrincipalInterest
calculatePrincipalInterestComponentsForPeriod(LoanApplicationTerms
loanApplicationTerms,
+ LoanScheduleParams loanScheduleParams, MathContext mc);
// Private, internal methods
private BigDecimal deriveTotalChargesDueAtTimeOfDisbursement(final
Set<LoanCharge> loanCharges) {
@@ -266,7 +236,8 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
Money principalToBeScheduled;
if (loanApplicationTerms.isMultiDisburseLoan()) {
if
(loanApplicationTerms.getTotalDisbursedAmount().isGreaterThanZero()) {
- principalToBeScheduled =
loanApplicationTerms.getTotalMultiDisbursedAmount();
+ principalToBeScheduled =
Money.of(loanApplicationTerms.getCurrency(),
+
loanApplicationTerms.getDisbursementDatas().get(0).getPrincipal());
} else if
(loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) {
principalToBeScheduled =
loanApplicationTerms.getApprovedPrincipal();
} else {
@@ -300,6 +271,9 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
loanScheduleParams,
loanApplicationTerms.getExpectedDisbursementDate(),
disbursementData.getPrincipal());
periods.add(downPaymentPeriod);
}
+ } else {
+
loanScheduleParams.getDisburseDetailMap().put(disbursementData.disbursementDate(),
+ Money.of(loanApplicationTerms.getCurrency(),
disbursementData.getPrincipal()));
}
}
@@ -313,14 +287,19 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
if (loanApplicationTerms.getInstallmentAmountInMultiplesOf() != null) {
downPaymentAmount = Money.roundToMultiplesOf(downPaymentAmount,
loanApplicationTerms.getInstallmentAmountInMultiplesOf());
}
- LoanScheduleModelDownPaymentPeriod installment =
LoanScheduleModelDownPaymentPeriod
- .downPayment(scheduleParams.getInstalmentNumber(), date,
downPaymentAmount, scheduleParams.getOutstandingBalance());
+ LoanScheduleModelDownPaymentPeriod installment =
LoanScheduleModelDownPaymentPeriod.downPayment(
+ scheduleParams.getInstalmentNumber(), date, downPaymentAmount,
+
scheduleParams.getOutstandingBalance().minus(downPaymentAmount));
addLoanRepaymentScheduleInstallment(scheduleParams.getInstallments(),
installment);
scheduleParams.incrementInstalmentNumber();
scheduleParams.addTotalRepaymentExpected(downPaymentAmount);
-
+ scheduleParams.reduceOutstandingBalance(downPaymentAmount);
+ scheduleParams.reduceOutstandingBalanceAsPerRest(downPaymentAmount);
+
scheduleParams.setPrincipalToBeScheduled(scheduleParams.getPrincipalToBeScheduled().minus(downPaymentAmount));
+
loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().minus(downPaymentAmount));
+ loanApplicationTerms.resetFixedEmiAmount();
return installment;
}
@@ -345,8 +324,9 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
private void processDisbursements(final LoanApplicationTerms
loanApplicationTerms, final BigDecimal chargesDueAtTimeOfDisbursement,
LoanScheduleParams scheduleParams, final
Collection<LoanScheduleModelPeriod> periods, final LocalDate scheduledDueDate) {
for (Map.Entry<LocalDate, Money> disburseDetail :
scheduleParams.getDisburseDetailMap().entrySet()) {
- if
(disburseDetail.getKey().isAfter(scheduleParams.getPeriodStartDate())
- && !disburseDetail.getKey().isAfter(scheduledDueDate)) {
+ 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();
@@ -378,11 +358,10 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
}
// updates actual outstanding balance with new
// disbursement detail
- Money remainingPrincipal =
disburseDetail.getValue().minus(downPaymentAmt);
- scheduleParams.addOutstandingBalance(remainingPrincipal);
-
scheduleParams.addOutstandingBalanceAsPerRest(remainingPrincipal);
- scheduleParams.addPrincipalToBeScheduled(remainingPrincipal);
-
loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().plus(remainingPrincipal));
+
scheduleParams.addOutstandingBalance(disburseDetail.getValue());
+
scheduleParams.addOutstandingBalanceAsPerRest(disburseDetail.getValue());
+
scheduleParams.addPrincipalToBeScheduled(disburseDetail.getValue());
+
loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().plus(disburseDetail.getValue()));
loanApplicationTerms.resetFixedEmiAmount();
}
}
@@ -585,43 +564,6 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
return interestCharges;
}
- private BigDecimal getDisbursementAmount(final LoanApplicationTerms
loanApplicationTerms, LocalDate disbursementDate,
- final Map<LocalDate, Money> disburseDetails, final boolean
excludePastUnDisbursed) {
-
- // this method relates to multi-disbursement loans
- BigDecimal principal = BigDecimal.ZERO;
- if (loanApplicationTerms.getDisbursementDatas().size() == 0) {
- // non tranche loans have no disbursement data entries in
submitted and approved status
- // the appropriate approved amount or applied for amount is used
to show a proposed schedule
- if
(loanApplicationTerms.getApprovedPrincipal().getAmount().compareTo(BigDecimal.ZERO)
> 0) {
- principal =
loanApplicationTerms.getApprovedPrincipal().getAmount();
- } else {
- principal = loanApplicationTerms.getPrincipal().getAmount();
- }
- } else {
- MonetaryCurrency currency =
loanApplicationTerms.getPrincipal().getCurrency();
- for (DisbursementData disbursementData :
loanApplicationTerms.getDisbursementDatas()) {
- if
(disbursementData.disbursementDate().equals(disbursementDate)) {
- principal = principal.add(disbursementData.getPrincipal());
- } else if (!excludePastUnDisbursed ||
disbursementData.isDisbursed()
- ||
!disbursementData.disbursementDate().isBefore(DateUtils.getBusinessLocalDate()))
{
- /*
- * JW: sums up amounts by disbursal date in case of
side-effect issues. Original assumed that there
- * were no duplicate disbursal dates and 'put' each amount
into the map keyed by date
- */
- Money previousSum =
disburseDetails.get(disbursementData.disbursementDate());
- BigDecimal sumToNow = BigDecimal.ZERO;
- if (previousSum != null) {
- sumToNow = previousSum.getAmount();
- }
- sumToNow = sumToNow.add(disbursementData.getPrincipal());
- disburseDetails.put(disbursementData.disbursementDate(),
Money.of(currency, sumToNow));
- }
- }
- }
- return principal;
- }
-
private void updateOutstandingBalance(LoanScheduleParams scheduleParams,
ScheduleCurrentPeriodParams currentPeriodParams) {
// update outstandingLoanBlance using current period
// 'principalDue'
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java
index 99a106e2d..f05675e3c 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ProgressiveLoanScheduleGenerator.java
@@ -20,13 +20,9 @@ package
org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
import java.math.BigDecimal;
import java.math.MathContext;
-import java.time.LocalDate;
-import java.util.Collection;
-import java.util.Map;
-import java.util.TreeMap;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.organisation.monetary.domain.Money;
-import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
+import
org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleParams;
import org.springframework.stereotype.Component;
@Component
@@ -47,21 +43,30 @@ public class ProgressiveLoanScheduleGenerator extends
AbstractProgressiveLoanSch
}
@Override
- public PrincipalInterest
calculatePrincipalInterestComponentsForPeriod(PaymentPeriodsInOneYearCalculator
calculator,
- BigDecimal interestCalculationGraceOnRepaymentPeriodFraction,
Money totalCumulativePrincipal, Money totalCumulativeInterest,
- Money totalInterestDueForLoan, Money
cumulatingInterestPaymentDueToGrace, Money outstandingBalance,
- LoanApplicationTerms loanApplicationTerms, int periodNumber,
MathContext mc, TreeMap<LocalDate, Money> principalVariation,
- Map<LocalDate, Money> compoundingMap, LocalDate periodStartDate,
LocalDate periodEndDate,
- Collection<LoanTermVariationsData> termVariations) {
+ public PrincipalInterest
calculatePrincipalInterestComponentsForPeriod(LoanApplicationTerms
loanApplicationTerms,
+ LoanScheduleParams loanScheduleParams, MathContext mc) {
// TODO: handle interest calculation
- Money principalForThisInstallment =
loanApplicationTerms.calculateTotalPrincipalForPeriod(calculator,
outstandingBalance,
- periodNumber, mc,
Money.zero(loanApplicationTerms.getCurrency()));
- final Money totalCumulativePrincipalToDate =
totalCumulativePrincipal.plus(principalForThisInstallment);
+ int periodNumber = loanScheduleParams.getPeriodNumber();
+ BigDecimal fixedEMIAmount = loanApplicationTerms.getFixedEmiAmount();
+ Money calculatedPrincipal;
+ if (fixedEMIAmount == null) {
+ int noRemainingPeriod =
loanApplicationTerms.getActualNoOfRepaymnets() - periodNumber + 1;
+ calculatedPrincipal =
loanScheduleParams.getOutstandingBalance().dividedBy(noRemainingPeriod,
mc.getRoundingMode());
+ if (loanApplicationTerms.getInstallmentAmountInMultiplesOf() !=
null) {
+ calculatedPrincipal =
Money.roundToMultiplesOf(calculatedPrincipal,
+
loanApplicationTerms.getInstallmentAmountInMultiplesOf());
+ }
+
loanApplicationTerms.setFixedEmiAmount(calculatedPrincipal.getAmount());
+ } else {
+ calculatedPrincipal = Money.of(loanApplicationTerms.getCurrency(),
fixedEMIAmount);
+ }
// adjust if needed
- principalForThisInstallment =
loanApplicationTerms.adjustPrincipalIfLastRepaymentPeriod(principalForThisInstallment,
- totalCumulativePrincipalToDate, periodNumber);
+ if (periodNumber == loanApplicationTerms.getActualNoOfRepaymnets()) {
+ Money remainingAmount =
loanScheduleParams.getOutstandingBalance().minus(calculatedPrincipal);
+ calculatedPrincipal = calculatedPrincipal.plus(remainingAmount);
+ }
- return new PrincipalInterest(principalForThisInstallment,
Money.zero(loanApplicationTerms.getCurrency()),
+ return new PrincipalInterest(calculatedPrincipal,
Money.zero(loanApplicationTerms.getCurrency()),
Money.zero(loanApplicationTerms.getCurrency()));
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformService.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformService.java
index 22270a17b..3b25c5027 100755
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformService.java
@@ -23,13 +23,14 @@ import java.util.Map;
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
import
org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
import
org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
+import
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
public interface LoanScheduleHistoryReadPlatformService {
Integer fetchCurrentVersionNumber(Long loanId);
LoanScheduleData retrieveRepaymentArchiveSchedule(Long loanId,
RepaymentScheduleRelatedLoanData repaymentScheduleRelatedLoanData,
- Collection<DisbursementData> disbursementData);
+ Collection<DisbursementData> disbursementData, LoanScheduleType
loanScheduleType);
Map<String, Object> fetchOldAuditDates(Long id);
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformServiceImpl.java
index d098c63d8..8b35fef47 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformServiceImpl.java
@@ -37,6 +37,7 @@ import
org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLo
import
org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
import
org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
import
org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
+import
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
@@ -68,7 +69,8 @@ public class LoanScheduleHistoryReadPlatformServiceImpl
implements LoanScheduleH
@Override
public LoanScheduleData retrieveRepaymentArchiveSchedule(final Long loanId,
- final RepaymentScheduleRelatedLoanData
repaymentScheduleRelatedLoanData, Collection<DisbursementData>
disbursementData) {
+ final RepaymentScheduleRelatedLoanData
repaymentScheduleRelatedLoanData, Collection<DisbursementData> disbursementData,
+ LoanScheduleType loanScheduleType) {
try {
this.context.authenticatedUser();
@@ -77,7 +79,7 @@ public class LoanScheduleHistoryReadPlatformServiceImpl
implements LoanScheduleH
return null;
}
final LoanScheduleArchiveResultSetExtractor fullResultsetExtractor
= new LoanScheduleArchiveResultSetExtractor(
- repaymentScheduleRelatedLoanData, disbursementData);
+ repaymentScheduleRelatedLoanData, disbursementData,
loanScheduleType);
final String sql = "select " + fullResultsetExtractor.schema()
+ " where ls.loan_id = ? and ls.version = ? order by
ls.loan_id, ls.installment";
@@ -99,17 +101,19 @@ public class LoanScheduleHistoryReadPlatformServiceImpl
implements LoanScheduleH
private final DisbursementData disbursement;
private final BigDecimal totalFeeChargesDueAtDisbursement;
private final Collection<DisbursementData> disbursementData;
+ private final LoanScheduleType loanScheduleType;
private LocalDate lastDueDate;
private BigDecimal outstandingLoanPrincipalBalance;
LoanScheduleArchiveResultSetExtractor(final
RepaymentScheduleRelatedLoanData repaymentScheduleRelatedLoanData,
- Collection<DisbursementData> disbursementData) {
+ Collection<DisbursementData> disbursementData,
LoanScheduleType loanScheduleType) {
this.currency = repaymentScheduleRelatedLoanData.getCurrency();
this.disbursement =
repaymentScheduleRelatedLoanData.disbursementData();
this.totalFeeChargesDueAtDisbursement =
repaymentScheduleRelatedLoanData.getTotalFeeChargesAtDisbursement();
this.lastDueDate = this.disbursement.disbursementDate();
this.outstandingLoanPrincipalBalance =
this.disbursement.getPrincipal();
this.disbursementData = disbursementData;
+ this.loanScheduleType = loanScheduleType;
}
public String schema() {
@@ -163,7 +167,7 @@ public class LoanScheduleHistoryReadPlatformServiceImpl
implements LoanScheduleH
data.getPrincipal(),
this.totalFeeChargesDueAtDisbursement, data.isDisbursed());
periods.add(periodData);
this.outstandingLoanPrincipalBalance =
this.outstandingLoanPrincipalBalance.add(data.getPrincipal());
- } else if (data.isDueForDisbursement(fromDate, dueDate)
+ } else if (data.isDueForDisbursement(loanScheduleType,
fromDate, dueDate)
&&
this.outstandingLoanPrincipalBalance.compareTo(BigDecimal.ZERO) > 0) {
principal = principal.add(data.getPrincipal());
final LoanSchedulePeriodData periodData =
LoanSchedulePeriodData.disbursementOnlyPeriod(data.disbursementDate(),
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
index 235b6b87f..1b0c64e4d 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
@@ -18,7 +18,6 @@
*/
package org.apache.fineract.portfolio.loanaccount.service;
-import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Collection;
import java.util.List;
@@ -43,6 +42,7 @@ import
org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
import
org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
import
org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
import
org.apache.fineract.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
+import
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
public interface LoanReadPlatformService {
@@ -51,7 +51,7 @@ public interface LoanReadPlatformService {
LoanAccountData fetchRepaymentScheduleData(LoanAccountData accountData);
LoanScheduleData retrieveRepaymentSchedule(Long loanId,
RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData,
- Collection<DisbursementData> disbursementData, boolean
isInterestRecalculationEnabled, BigDecimal totalPaidFeeCharges);
+ Collection<DisbursementData> disbursementData, boolean
isInterestRecalculationEnabled, LoanScheduleType loanScheduleType);
Collection<LoanTransactionData> retrieveLoanTransactions(Long loanId);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
index f0d024031..6adaa9975 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
@@ -245,7 +245,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService, Loa
final Collection<DisbursementData> disbursementData =
retrieveLoanDisbursementDetails(accountData.getId());
final LoanScheduleData repaymentSchedule =
retrieveRepaymentSchedule(accountData.getId(), repaymentScheduleRelatedData,
disbursementData, accountData.isInterestRecalculationEnabled(),
- accountData.getSummary() != null ?
accountData.getSummary().getFeeChargesPaid() : BigDecimal.ZERO);
+
LoanScheduleType.fromEnumOptionData(accountData.getLoanScheduleType()));
accountData.setRepaymentSchedule(repaymentSchedule);
return accountData;
}
@@ -253,13 +253,13 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService, Loa
@Override
public LoanScheduleData retrieveRepaymentSchedule(final Long loanId,
final RepaymentScheduleRelatedLoanData
repaymentScheduleRelatedLoanData, Collection<DisbursementData> disbursementData,
- boolean isInterestRecalculationEnabled, BigDecimal
totalPaidFeeCharges) {
+ boolean isInterestRecalculationEnabled, LoanScheduleType
loanScheduleType) {
try {
this.context.authenticatedUser();
final LoanScheduleResultSetExtractor fullResultsetExtractor = new
LoanScheduleResultSetExtractor(
- repaymentScheduleRelatedLoanData, disbursementData,
isInterestRecalculationEnabled);
+ repaymentScheduleRelatedLoanData, disbursementData,
isInterestRecalculationEnabled, loanScheduleType);
final String sql = "select " + fullResultsetExtractor.schema() + "
where ls.loan_id = ? order by ls.loan_id, ls.installment";
return this.jdbcTemplate.query(sql, fullResultsetExtractor,
loanId); // NOSONAR
@@ -1123,19 +1123,21 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService, Loa
private final DisbursementData disbursement;
private final BigDecimal totalFeeChargesDueAtDisbursement;
private final Collection<DisbursementData> disbursementData;
+ private final LoanScheduleType loanScheduleType;
private LocalDate lastDueDate;
private BigDecimal outstandingLoanPrincipalBalance;
- private boolean excludePastUndisbursed;
+ private boolean excludePastUnDisbursed;
LoanScheduleResultSetExtractor(final RepaymentScheduleRelatedLoanData
repaymentScheduleRelatedLoanData,
- Collection<DisbursementData> disbursementData, boolean
isInterestRecalculationEnabled) {
+ Collection<DisbursementData> disbursementData, boolean
isInterestRecalculationEnabled, LoanScheduleType loanScheduleType) {
this.currency = repaymentScheduleRelatedLoanData.getCurrency();
this.disbursement =
repaymentScheduleRelatedLoanData.disbursementData();
this.totalFeeChargesDueAtDisbursement =
repaymentScheduleRelatedLoanData.getTotalFeeChargesAtDisbursement();
this.lastDueDate = this.disbursement.disbursementDate();
this.outstandingLoanPrincipalBalance =
this.disbursement.getPrincipal();
this.disbursementData = disbursementData;
- this.excludePastUndisbursed = isInterestRecalculationEnabled;
+ this.excludePastUnDisbursed = isInterestRecalculationEnabled;
+ this.loanScheduleType = loanScheduleType;
}
public String schema() {
@@ -1160,7 +1162,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService, Loa
this.disbursement.disbursementDate(),
this.disbursement.getPrincipal(), this.totalFeeChargesDueAtDisbursement,
this.disbursement.isDisbursed());
- final Collection<LoanSchedulePeriodData> periods = new
ArrayList<>();
+ final List<LoanSchedulePeriodData> periods = new ArrayList<>();
final MonetaryCurrency monCurrency = new
MonetaryCurrency(this.currency.getCode(), this.currency.getDecimalPlaces(),
this.currency.getInMultiplesOf());
BigDecimal totalPrincipalDisbursed = BigDecimal.ZERO;
@@ -1170,7 +1172,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService, Loa
totalPrincipalDisbursed = Money.of(monCurrency,
this.disbursement.getPrincipal()).getAmount();
} else {
if (!this.disbursement.isDisbursed()) {
- excludePastUndisbursed = false;
+ excludePastUnDisbursed = false;
}
for (DisbursementData data : disbursementData) {
if (data.getChargeAmount() != null) {
@@ -1211,56 +1213,11 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService, Loa
final LocalDate obligationsMetOnDate =
JdbcSupport.getLocalDate(rs, "obligationsMetOnDate");
final boolean complete = rs.getBoolean("complete");
final boolean isAdditional = rs.getBoolean("isAdditional");
- BigDecimal principal = BigDecimal.ZERO;
+ BigDecimal disbursedAmount = BigDecimal.ZERO;
if (!isAdditional) {
- for (final DisbursementData data : disbursementData) {
- if
(fromDate.equals(this.disbursement.disbursementDate()) &&
data.disbursementDate().equals(fromDate)
- &&
!disbursementPeriodIds.contains(data.getId())) {
- principal = principal.add(data.getPrincipal());
- LoanSchedulePeriodData periodData = null;
- if (data.getChargeAmount() == null) {
- periodData =
LoanSchedulePeriodData.disbursementOnlyPeriod(data.disbursementDate(),
data.getPrincipal(),
- disbursementChargeAmount,
data.isDisbursed());
- } else {
- periodData =
LoanSchedulePeriodData.disbursementOnlyPeriod(data.disbursementDate(),
data.getPrincipal(),
-
disbursementChargeAmount.add(data.getChargeAmount()).subtract(waivedChargeAmount),
- data.isDisbursed());
- }
- periods.add(periodData);
- this.outstandingLoanPrincipalBalance =
this.outstandingLoanPrincipalBalance.add(data.getPrincipal());
- disbursementPeriodIds.add(data.getId());
- } else if (data.isDueForDisbursement(fromDate,
dueDate) && !disbursementPeriodIds.contains(data.getId())) {
- if (!excludePastUndisbursed || data.isDisbursed()
|| !DateUtils.isBeforeBusinessDate(data.disbursementDate())) {
- principal = principal.add(data.getPrincipal());
- LoanSchedulePeriodData periodData;
- if (data.getChargeAmount() == null) {
- periodData =
LoanSchedulePeriodData.disbursementOnlyPeriod(data.disbursementDate(),
data.getPrincipal(),
- BigDecimal.ZERO,
data.isDisbursed());
- } else {
- periodData =
LoanSchedulePeriodData.disbursementOnlyPeriod(data.disbursementDate(),
data.getPrincipal(),
- data.getChargeAmount(),
data.isDisbursed());
- }
- periods.add(periodData);
- this.outstandingLoanPrincipalBalance =
this.outstandingLoanPrincipalBalance.add(data.getPrincipal());
- disbursementPeriodIds.add(data.getId());
- }
- } else if (fromDate.equals(dueDate) &&
data.disbursementDate().equals(fromDate)
- &&
!disbursementPeriodIds.contains(data.getId())) {
- principal = principal.add(data.getPrincipal());
- LoanSchedulePeriodData periodData = null;
- if (data.getChargeAmount() == null) {
- periodData =
LoanSchedulePeriodData.disbursementOnlyPeriod(data.disbursementDate(),
data.getPrincipal(),
- disbursementChargeAmount,
data.isDisbursed());
- } else {
- periodData =
LoanSchedulePeriodData.disbursementOnlyPeriod(data.disbursementDate(),
data.getPrincipal(),
-
disbursementChargeAmount.add(data.getChargeAmount()).subtract(waivedChargeAmount),
- data.isDisbursed());
- }
- periods.add(periodData);
- this.outstandingLoanPrincipalBalance =
this.outstandingLoanPrincipalBalance.add(data.getPrincipal());
- disbursementPeriodIds.add(data.getId());
- }
- }
+ disbursedAmount =
processDisbursementData(loanScheduleType, disbursementData, fromDate, dueDate,
disbursementPeriodIds,
+ disbursementChargeAmount, waivedChargeAmount,
periods);
+
}
// Add the Charge back or Credits to the initial amount to
avoid negative balance
final BigDecimal credits =
JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "totalCredits");
@@ -1268,7 +1225,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService, Loa
this.outstandingLoanPrincipalBalance =
this.outstandingLoanPrincipalBalance.add(credits);
}
- totalPrincipalDisbursed =
totalPrincipalDisbursed.add(principal);
+ totalPrincipalDisbursed =
totalPrincipalDisbursed.add(disbursedAmount);
Integer daysInPeriod = 0;
if (fromDate != null) {
@@ -1379,6 +1336,39 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService, Loa
totalPaidLate.getAmount(), totalOutstanding.getAmount(),
totalCredits.getAmount());
}
+ private BigDecimal processDisbursementData(LoanScheduleType
loanScheduleType, Collection<DisbursementData> disbursementData,
+ LocalDate fromDate, LocalDate dueDate, Set<Long>
disbursementPeriodIds, BigDecimal disbursementChargeAmount,
+ BigDecimal waivedChargeAmount, List<LoanSchedulePeriodData>
periods) {
+ BigDecimal disbursedAmount = BigDecimal.ZERO;
+ for (final DisbursementData data : disbursementData) {
+ boolean isDueForDisbursement =
data.isDueForDisbursement(loanScheduleType, fromDate, dueDate);
+ if (((fromDate.equals(this.disbursement.disbursementDate()) &&
data.disbursementDate().equals(fromDate))
+ || (fromDate.equals(dueDate) &&
data.disbursementDate().equals(fromDate))
+ || canAddDisbursementData(data, isDueForDisbursement,
excludePastUnDisbursed))
+ && !disbursementPeriodIds.contains(data.getId())) {
+ disbursedAmount = disbursedAmount.add(data.getPrincipal());
+ LoanSchedulePeriodData periodData =
createLoanSchedulePeriodData(data, disbursementChargeAmount,
waivedChargeAmount);
+ periods.add(periodData);
+ this.outstandingLoanPrincipalBalance =
this.outstandingLoanPrincipalBalance.add(periodData.getPrincipalDisbursed());
+ disbursementPeriodIds.add(data.getId());
+ }
+ }
+ return disbursedAmount;
+ }
+
+ private LoanSchedulePeriodData createLoanSchedulePeriodData(final
DisbursementData data, BigDecimal disbursementChargeAmount,
+ BigDecimal waivedChargeAmount) {
+ BigDecimal chargeAmount = data.getChargeAmount() == null ?
disbursementChargeAmount
+ :
disbursementChargeAmount.add(data.getChargeAmount()).subtract(waivedChargeAmount);
+ return
LoanSchedulePeriodData.disbursementOnlyPeriod(data.disbursementDate(),
data.getPrincipal(), chargeAmount,
+ data.isDisbursed());
+ }
+
+ private boolean canAddDisbursementData(DisbursementData data, boolean
isDueForDisbursement, boolean excludePastUnDisbursed) {
+ return (!excludePastUnDisbursed || data.isDisbursed() ||
!DateUtils.isBeforeBusinessDate(data.disbursementDate()))
+ && isDueForDisbursement;
+ }
+
}
private static final class LoanTransactionsMapper implements
RowMapper<LoanTransactionData> {
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 64c51a6c0..e587e126d 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
@@ -57,7 +57,6 @@ import
org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
-import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
import org.apache.fineract.integrationtests.common.LoanRescheduleRequestHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account;
@@ -78,7 +77,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ExtendWith(LoanTestLifecycleExtension.class)
-public class AdvancedPaymentAllocationLoanRepaymentScheduleTest {
+public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends
BaseLoanIntegrationTest {
private static final Logger LOG =
LoggerFactory.getLogger(AdvancedPaymentAllocationLoanRepaymentScheduleTest.class);
private static final String DATETIME_PATTERN = "dd MMMM yyyy";
@@ -122,10 +121,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
@Test
public void uc1() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -182,9 +178,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 0.0,
0.0);
validateLoanTransaction(loanDetails, 4, 125.0, 125.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC2: Overpayment1
// ADVANCED_PAYMENT_ALLOCATION_STRATEGY
@@ -195,10 +189,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
@Test
public void uc2() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -255,9 +246,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 25.0,
0.0);
validateLoanTransaction(loanDetails, 4, 125.0, 100.0, 25.0, 0.0);
assertTrue(loanDetails.getStatus().getOverpaid());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC3: Overpayment2
// ADVANCED_PAYMENT_ALLOCATION_STRATEGY
@@ -267,10 +256,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
@Test
public void uc3() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -327,9 +313,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 25.0,
0.0);
validateLoanTransaction(loanDetails, 4, 125.0, 100.0, 25.0, 0.0);
assertTrue(loanDetails.getStatus().getOverpaid());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC4: Delinquent balance
// ADVANCED_PAYMENT_ALLOCATION_STRATEGY
@@ -340,10 +324,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
@Test
public void uc4() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -419,9 +400,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 0.0,
0.0);
validateLoanTransaction(loanDetails, 5, 360.0, 360.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC5: Refund past due
@@ -432,10 +411,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay rest on time
@Test
public void uc5() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -507,9 +483,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 58.34,
0.0);
validateLoanTransaction(loanDetails, 5, 66.66, 66.66, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC7: Refund & due reamortization
@@ -521,10 +495,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay rest on time
@Test
public void uc7() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -594,9 +565,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 100.0,
0.0);
validateLoanTransaction(loanDetails, 5, 25.0, 25.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC8: Refund after due & past due
@@ -608,10 +577,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay rest on time
@Test
public void uc8() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -686,9 +652,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 25.0,
0.0);
validateLoanTransaction(loanDetails, 5, 100.0, 100.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC9: Refund next installment
@@ -699,10 +663,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay rest on time
@Test
public void uc9() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -759,9 +720,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 0.0,
0.0);
validateLoanTransaction(loanDetails, 4, 125.0, 125.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC10: Refund PD and next installment
@@ -773,10 +732,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay rest on time
@Test
public void uc10() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -848,9 +804,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 0.0,
0.0);
validateLoanTransaction(loanDetails, 5, 125.0, 125.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC11: Refund Past, pay in advance installments
@@ -861,10 +815,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay rest on time
@Test
public void uc11() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -913,9 +864,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 25.0,
0.0);
validateLoanTransaction(loanDetails, 3, 100.0, 100.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC12: Refund last installment
@@ -926,10 +875,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay rest on time
@Test
public void uc12() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -986,9 +932,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 125.0,
0.0);
validateLoanTransaction(loanDetails, 3, 125.0, 125.0, 0.0, 50.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC13: Due apply last installment
@@ -1000,10 +944,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 5. Pay rest on time
@Test
public void uc13() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1074,9 +1015,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 75.0,
0.0);
validateLoanTransaction(loanDetails, 5, 50.0, 50.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC14: Refund PD
@@ -1088,10 +1027,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 5. Pay rest on time
@Test
public void uc14() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1164,9 +1100,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 0.0,
0.0);
validateLoanTransaction(loanDetails, 5, 175.0, 175.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC15: Goodwill credit PD
@@ -1178,10 +1112,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 5. Pay rest on time
@Test
public void uc15() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1251,9 +1182,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 75.0,
0.0);
validateLoanTransaction(loanDetails, 5, 50.0, 50.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC17a: Full refund with CBR
@@ -1265,10 +1194,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 5. CBR
@Test
public void uc17a() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1312,9 +1238,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 125.0,
0.0);
validateLoanTransaction(loanDetails, 3, 125.0, 0.0, 125.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC17b: Full refund with CBR
@@ -1326,10 +1250,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 5. CBR
@Test
public void uc17b() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1373,9 +1294,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 125.0,
0.0);
validateLoanTransaction(loanDetails, 3, 125.0, 0.0, 125.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC17c: Full refund with CBR
@@ -1387,10 +1306,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 5. CBR
@Test
public void uc17c() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1434,9 +1350,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 125.0,
0.0);
validateLoanTransaction(loanDetails, 3, 125.0, 0.0, 125.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC18: Full refund with CBR (N+1)
@@ -1448,10 +1362,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 5. CBR
@Test
public void uc18() {
- 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"));
+ runAt("20 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1530,9 +1441,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 0.0,
0.0);
validateLoanTransaction(loanDetails, 6, 500.0, 0.0, 500.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC24: Merchant issued credit reverse-replay
@@ -1546,10 +1455,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 7. Payments
@Test
public void uc24() {
- 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"));
+ runAt("20 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1651,9 +1557,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 125.0, 0.0, 0.0,
0.0);
validateLoanTransaction(loanDetails, 7, 125.0, 125.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC25: Merchant issued credit reverse-replay with uneven balances
@@ -1665,10 +1569,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 5. Merchant issued credit
@Test
public void uc25() {
- 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"));
+ runAt("20 February 2023", () -> {
final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
@@ -1725,9 +1626,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, 125.0, 115.0, 10.0, 115.0,
0.0);
validateLoanTransaction(loanDetails, 4, 40.0, 40.0, 0.0, 10.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC101: Multiple disbursement test
@@ -1737,11 +1636,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 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"));
+ runAt("20 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -1808,9 +1703,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 6, LocalDate.of(2023, 2, 22),
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0, 0.0, 100.0, 0.0, 0.0,
0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC102: Multiple disbursement & reschedule test
@@ -1822,11 +1715,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Reschedule the 3rd period to be later than the 2nd disbursement
@Test
public void uc102() {
- 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"));
+ runAt("20 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -1907,9 +1796,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 25),
218.75, 100.0, 118.75, 100.0, 0.0);
validateRepaymentPeriod(loanDetails, 5, LocalDate.of(2023, 3, 12),
218.75, 0.0, 218.75, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC103: Advanced payment allocation, add charge after maturity -> N+1
installment, repay the loan
@@ -1919,11 +1806,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 3. Fully repay the loan
@Test
public void uc103() {
- try {
-
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -1978,9 +1861,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 5, LocalDate.of(2023, 2, 22),
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0, 100.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC104: Advanced payment allocation, horizontal repayment processing
@@ -1991,11 +1872,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay little more than the principal of 1st installment and charge of
2nd installment
@Test
public void uc104() {
- try {
-
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2063,9 +1940,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
125.0, 0.0, 125.0, 0.0, 0.0, 0.0, 25.0, 0.0, 25.0, 0.0, 0.0,
0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC105: Advanced payment allocation, vertical repayment processing
@@ -2076,11 +1951,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 4. Pay little more than the charges
@Test
public void uc105() {
- try {
-
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2148,9 +2019,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
125.0, 0.0, 125.0, 0.0, 0.0, 0.0, 25.0, 25.0, 0.0, 0.0, 0.0,
0.0, 0.0, 25.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC106: Advanced payment allocation, horizontal repayment processing,
mixed grouping of allocation rules
@@ -2158,11 +2027,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 1. Create a Loan product, but the allocation rules are mixed -> expect
validation error
@Test
public void uc106() {
- try {
-
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2176,9 +2041,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
assertNotNull(loanProductErrorData);
assertEquals("mixed.due.type.allocation.rules.are.not.supported.with.horizontal.installment.processing",
loanProductErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC107: Advanced payment allocation, vertical repayment processing,
mixed grouping of allocation rules
@@ -2188,11 +2051,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 3. Change to HORIZONTAL loan schedule processing and allocation rules
are mixed - > expect validation error
@Test
public void uc107() {
- try {
-
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2220,9 +2079,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
assertEquals(400, exception.getResponse().code());
assertTrue(exception.getMessage()
.contains("mixed.due.type.allocation.rules.are.not.supported.with.horizontal.installment.processing"));
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC108: Advanced payment allocation, progressive loan schedule handling,
rounding test
@@ -2231,10 +2088,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 2. Submit the loan, and check the generated repayment schedule
@Test
public void uc108() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2313,9 +2167,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 6, LocalDate.of(2023, 4, 1),
166.65, 0.0, 166.65, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC109: Advanced payment allocation, cumulative loan schedule handling,
rounding test
@@ -2324,10 +2176,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 2. Submit the loan, and check the generated repayment schedule
@Test
public void uc109() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2406,9 +2255,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 6, LocalDate.of(2023, 4, 1),
166.65, 0.0, 166.65, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC110: Advanced payment allocation, progressive loan schedule handling,
rounding test
@@ -2417,10 +2264,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 2. Submit the loan, and check the generated repayment schedule
@Test
public void uc110() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2462,9 +2306,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
10.13, 0.0, 10.13, 0.0, 0.0);
validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
10.12, 0.0, 10.12, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC111: Advanced payment allocation, cumulative loan schedule handling,
rounding test
@@ -2473,10 +2315,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 2. Submit the loan, and check the generated repayment schedule
@Test
public void uc111() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.02.22").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("22 February 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2518,9 +2357,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
10.13, 0.0, 10.13, 0.0, 0.0);
validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
10.12, 0.0, 10.12, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC112: Advanced payment allocation, horizontal repayment processing
@@ -2534,10 +2371,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 7. Do goodwill credit (in advance payment)
@Test
public void uc112() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.09.01").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("01 September 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2629,9 +2463,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateLoanCharge(loanDetails, 1, LocalDate.of(2023, 10, 16),
20.0, 20.0, 0.0);
validateLoanCharge(loanDetails, 2, LocalDate.of(2023, 10, 17),
20.0, 20.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC113: Advanced payment allocation, vertical repayment processing
@@ -2645,10 +2477,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 7. Do goodwill credit (in advance payment)
@Test
public void uc113() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.09.01").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("01 September 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2739,9 +2568,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateLoanCharge(loanDetails, 1, LocalDate.of(2023, 10, 16),
20.0, 20.0, 0.0);
validateLoanCharge(loanDetails, 2, LocalDate.of(2023, 10, 17),
20.0, 20.0, 0.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC114: Advanced payment allocation, horizontal repayment processing
@@ -2755,10 +2582,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 7. Do merchant issued refund (in advance payment)
@Test
public void uc114() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.09.01").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("01 September 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2849,9 +2673,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateLoanCharge(loanDetails, 1, LocalDate.of(2023, 10, 16),
20.0, 10.0, 10.0);
validateLoanCharge(loanDetails, 2, LocalDate.of(2023, 10, 17),
20.0, 10.0, 10.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
}
// UC115: Advanced payment allocation, vertical repayment processing
@@ -2865,10 +2687,7 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
// 7. Do merchant issued refund (in advance payment)
@Test
public void uc115() {
- try {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
- businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
- .date("2023.09.01").dateFormat("yyyy.MM.dd").locale("en"));
+ runAt("01 September 2023", () -> {
final Account assetAccount = accountHelper.createAssetAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
@@ -2957,9 +2776,239 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
validateLoanCharge(loanDetails, 1, LocalDate.of(2023, 10, 16),
20.0, 10.0, 10.0);
validateLoanCharge(loanDetails, 2, LocalDate.of(2023, 10, 17),
20.0, 10.0, 10.0);
assertTrue(loanDetails.getStatus().getActive());
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.FALSE);
- }
+ });
+ }
+
+ // UC116: Advanced payment allocation, horizontal repayment processing,
disbursement on due date of an installment
+ // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+ // 1. Disburse the loan (1000)
+ // 2. Add charge on disbursement date(50)
+ // 3. Repay down payment fully on disbursement date (250)
+ // 4. Disburse on 1st installment due date (400)
+ @Test
+ public void uc116() {
+ runAt("01 January 2023", () -> {
+ final Account assetAccount = accountHelper.createAssetAccount();
+ final Account incomeAccount = accountHelper.createIncomeAccount();
+ final Account expenseAccount =
accountHelper.createExpenseAccount();
+ final Account overpaymentAccount =
accountHelper.createLiabilityAccount();
+ Integer localLoanProductId = createLoanProduct("1000", "15", "3",
true, "25", false, LoanScheduleType.PROGRESSIVE,
+ LoanScheduleProcessingType.HORIZONTAL, assetAccount,
incomeAccount, expenseAccount, overpaymentAccount);
+ final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), localLoanProductId,
+ BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
+
+ loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
+ new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).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(1000.0)).locale("en"));
+
+ GetLoansLoanIdResponse loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 1000.0, 0.0, 1000.0, 0.0,
null);
+ validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 1, 16),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
250.0, 0.0, 250.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ // Add Charge Fee
+ Integer fee = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"50", false));
+
loanTransactionHelper.addChargesForLoan(loanResponse.getLoanId().intValue(),
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee),
"01 January 2023", "50"));
+
+ loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 1050.0, 0.0, 1000.0, 0.0,
null);
+ validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 1, 16),
250.0, 0.0, 250.0, 50.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
250.0, 0.0, 250.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(),
new PostLoansLoanIdTransactionsRequest()
+ .dateFormat(DATETIME_PATTERN).transactionDate("01 January
2023").locale("en").transactionAmount(250.0));
+ loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 800.0, 250.0, 750.0,
250.0, null);
+ validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
250.0, 250.0, 0.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 1, 16),
250.0, 0.0, 250.0, 50.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
250.0, 0.0, 250.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ updateBusinessDate("16 January 2023");
+ loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+ new PostLoansLoanIdRequest().actualDisbursementDate("16
January 2023").dateFormat(DATETIME_PATTERN)
+
.transactionAmount(BigDecimal.valueOf(400.0)).locale("en"));
+ loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 1200.0, 250.0, 1150.0,
250.0, null);
+ validatePeriod(loanDetails, 0, LocalDate.of(2023, 1, 1), null,
1000.0, null, null, null, 0.0, 0.0, null, null, null, null, null,
+ null, null, null, null);
+ validatePeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
LocalDate.of(2023, 1, 1), 750.0, 250.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 2, LocalDate.of(2023, 1, 16), null,
500.0, 250.0, 0.0, 250.0, 50.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 3, LocalDate.of(2023, 1, 16), null,
400.0, null, null, null, 0.0, 0.0, null, null, null, null, null,
+ null, null, null, null);
+ validatePeriod(loanDetails, 4, LocalDate.of(2023, 1, 16), null,
800.0, 100.0, 0.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 5, LocalDate.of(2023, 1, 31), null,
400.0, 400.0, 0.0, 400.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 6, LocalDate.of(2023, 2, 15), null,
0.0, 400.0, 0.0, 400.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+ });
+ }
+
+ // UC117: Advanced payment allocation, horizontal repayment processing,
multi disbursement on due date of an
+ // installment
+ // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+ // 1. Disburse the loan (1000)
+ // 2. Add charge on disbursement date(50)
+ // 3. Repay down payment fully on disbursement date (250)
+ // 4. Disburse on 1st installment due date (400)
+ // 4. Disburse on 1st installment due date (80)
+ @Test
+ public void uc117() {
+ runAt("01 January 2023", () -> {
+ final Account assetAccount = accountHelper.createAssetAccount();
+ final Account incomeAccount = accountHelper.createIncomeAccount();
+ final Account expenseAccount =
accountHelper.createExpenseAccount();
+ final Account overpaymentAccount =
accountHelper.createLiabilityAccount();
+ Integer localLoanProductId = createLoanProduct("1000", "15", "3",
true, "25", false, LoanScheduleType.PROGRESSIVE,
+ LoanScheduleProcessingType.HORIZONTAL, assetAccount,
incomeAccount, expenseAccount, overpaymentAccount);
+ final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), localLoanProductId,
+ BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
+
+ loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
+ new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).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(1000.0)).locale("en"));
+
+ GetLoansLoanIdResponse loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 1000.0, 0.0, 1000.0, 0.0,
null);
+ validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 1, 16),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
250.0, 0.0, 250.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ // Add Charge Fee
+ Integer fee = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"50", false));
+
loanTransactionHelper.addChargesForLoan(loanResponse.getLoanId().intValue(),
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee),
"01 January 2023", "50"));
+
+ loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 1050.0, 0.0, 1000.0, 0.0,
null);
+ validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 1, 16),
250.0, 0.0, 250.0, 50.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
250.0, 0.0, 250.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(),
new PostLoansLoanIdTransactionsRequest()
+ .dateFormat(DATETIME_PATTERN).transactionDate("01 January
2023").locale("en").transactionAmount(250.0));
+ loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 800.0, 250.0, 750.0,
250.0, null);
+ validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
250.0, 250.0, 0.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 1, 16),
250.0, 0.0, 250.0, 50.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
250.0, 0.0, 250.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ updateBusinessDate("16 January 2023");
+ loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+ new PostLoansLoanIdRequest().actualDisbursementDate("16
January 2023").dateFormat(DATETIME_PATTERN)
+
.transactionAmount(BigDecimal.valueOf(400.0)).locale("en"));
+ loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+ new PostLoansLoanIdRequest().actualDisbursementDate("16
January 2023").dateFormat(DATETIME_PATTERN)
+
.transactionAmount(BigDecimal.valueOf(80.0)).locale("en"));
+ loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 1280.0, 250.0, 1230.0,
250.0, null);
+ validatePeriod(loanDetails, 0, LocalDate.of(2023, 1, 1), null,
1000.0, null, null, null, 0.0, 0.0, null, null, null, null, null,
+ null, null, null, null);
+ validatePeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
LocalDate.of(2023, 1, 1), 750.0, 250.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 2, LocalDate.of(2023, 1, 16), null,
500.0, 250.0, 0.0, 250.0, 50.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 3, LocalDate.of(2023, 1, 16), null,
400.0, null, null, null, 0.0, 0.0, null, null, null, null, null,
+ null, null, null, null);
+ validatePeriod(loanDetails, 4, LocalDate.of(2023, 1, 16), null,
80.0, null, null, null, 0.0, 0.0, null, null, null, null, null,
+ null, null, null, null);
+ validatePeriod(loanDetails, 5, LocalDate.of(2023, 1, 16), null,
880.0, 100.0, 0.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 6, LocalDate.of(2023, 1, 16), null,
860.0, 20.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 7, LocalDate.of(2023, 1, 31), null,
430.0, 430.0, 0.0, 430.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 8, LocalDate.of(2023, 2, 15), null,
0.0, 430.0, 0.0, 430.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+ });
+ }
+
+ // UC118: Advanced payment allocation, horizontal repayment processing,
multi disbursement on disbursement date
+ // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+ // 1. Disburse the loan (1000)
+ // 2. Disburse on disbursement date (400)
+ @Test
+ public void uc118() {
+ runAt("01 January 2023", () -> {
+ final Account assetAccount = accountHelper.createAssetAccount();
+ final Account incomeAccount = accountHelper.createIncomeAccount();
+ final Account expenseAccount =
accountHelper.createExpenseAccount();
+ final Account overpaymentAccount =
accountHelper.createLiabilityAccount();
+ Integer localLoanProductId = createLoanProduct("1000", "15", "3",
true, "25", false, LoanScheduleType.PROGRESSIVE,
+ LoanScheduleProcessingType.HORIZONTAL, assetAccount,
incomeAccount, expenseAccount, overpaymentAccount);
+ final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), localLoanProductId,
+ BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 January
2023", "01 January 2023");
+
+ loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
+ new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).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(1000.0)).locale("en"));
+
+ GetLoansLoanIdResponse loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 1000.0, 0.0, 1000.0, 0.0,
null);
+ validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 1, 16),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 1, 31),
250.0, 0.0, 250.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2023, 2, 15),
250.0, 0.0, 250.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+ new PostLoansLoanIdRequest().actualDisbursementDate("01
January 2023").dateFormat(DATETIME_PATTERN)
+
.transactionAmount(BigDecimal.valueOf(400.0)).locale("en"));
+ loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 1400.0, 0.0, 1400.0, 0.0,
null);
+ validatePeriod(loanDetails, 0, LocalDate.of(2023, 1, 1), null,
1000.0, null, null, null, 0.0, 0.0, null, null, null, null, null,
+ null, null, null, null);
+ validatePeriod(loanDetails, 1, LocalDate.of(2023, 1, 1), null,
400.0, null, null, null, 0.0, 0.0, null, null, null, null, null,
+ null, null, null, null);
+ validatePeriod(loanDetails, 2, LocalDate.of(2023, 1, 1), null,
1150.0, 250.0, 0.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 3, LocalDate.of(2023, 1, 1), null,
1050.0, 100.0, 0.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 4, LocalDate.of(2023, 1, 16), null,
700.0, 350.0, 0.0, 350.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 5, LocalDate.of(2023, 1, 31), null,
350.0, 350.0, 0.0, 350.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 6, LocalDate.of(2023, 2, 15), null,
0.0, 350.0, 0.0, 350.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+ });
}
private static void validateLoanSummaryBalances(GetLoansLoanIdResponse
loanDetails, Double totalOutstanding, Double totalRepayment,
@@ -3085,6 +3134,30 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
return loanTransactionHelper.getLoanProductId(loanProductJSON);
}
+ private static void validatePeriod(GetLoansLoanIdResponse loanDetails,
Integer index, LocalDate dueDate, LocalDate paidDate,
+ Double balanceOfLoan, Double principalDue, Double principalPaid,
Double principalOutstanding, Double feeDue, Double feePaid,
+ Double feeOutstanding, Double penaltyDue, Double penaltyPaid,
Double penaltyOutstanding, Double interestDue,
+ Double interestPaid, Double interestOutstanding, Double
paidInAdvance, Double paidLate) {
+ GetLoansLoanIdRepaymentPeriod period =
loanDetails.getRepaymentSchedule().getPeriods().get(index);
+ assertEquals(dueDate, period.getDueDate());
+ assertEquals(paidDate, period.getObligationsMetOnDate());
+ assertEquals(balanceOfLoan,
period.getPrincipalLoanBalanceOutstanding());
+ assertEquals(principalDue, period.getPrincipalDue());
+ assertEquals(principalPaid, period.getPrincipalPaid());
+ assertEquals(principalOutstanding, period.getPrincipalOutstanding());
+ assertEquals(feeDue, period.getFeeChargesDue());
+ assertEquals(feePaid, period.getFeeChargesPaid());
+ assertEquals(feeOutstanding, period.getFeeChargesOutstanding());
+ assertEquals(penaltyDue, period.getPenaltyChargesDue());
+ assertEquals(penaltyPaid, period.getPenaltyChargesPaid());
+ assertEquals(penaltyOutstanding,
period.getPenaltyChargesOutstanding());
+ assertEquals(interestDue, period.getInterestDue());
+ assertEquals(interestPaid, period.getInterestPaid());
+ assertEquals(interestOutstanding, period.getInterestOutstanding());
+ assertEquals(paidInAdvance, period.getTotalPaidInAdvanceForPeriod());
+ assertEquals(paidLate, period.getTotalPaidLateForPeriod());
+ }
+
private static void validateRepaymentPeriod(GetLoansLoanIdResponse
loanDetails, Integer index, LocalDate dueDate, double principalDue,
double principalPaid, double principalOutstanding, double
paidInAdvance, double paidLate) {
GetLoansLoanIdRepaymentPeriod period =
loanDetails.getRepaymentSchedule().getPeriods().stream()
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 6d8ec7b7c..469f3f339 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
@@ -498,4 +498,9 @@ public abstract class BaseLoanIntegrationTest {
public static final Integer MONTHS = 2;
public static final Integer YEARS = 3;
}
+
+ public void updateBusinessDate(String date) {
+ businessDateHelper.updateBusinessDate(
+ new
BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
+ }
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java
index 06275fb93..ecbc6970e 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java
@@ -18,9 +18,6 @@
*/
package org.apache.fineract.integrationtests;
-import static java.lang.Boolean.FALSE;
-import static java.lang.Boolean.TRUE;
-import static
org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -42,7 +39,6 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.AllowAttributeOverrides;
-import org.apache.fineract.client.models.BusinessDateRequest;
import org.apache.fineract.client.models.ChargeData;
import org.apache.fineract.client.models.ChargeToGLAccountMapper;
import
org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
@@ -61,7 +57,6 @@ import
org.apache.fineract.client.models.PostPaymentTypesRequest;
import org.apache.fineract.client.models.PostPaymentTypesResponse;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
-import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
import org.apache.fineract.integrationtests.common.PaymentTypeHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account;
@@ -83,7 +78,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(LoanTestLifecycleExtension.class)
-public class LoanAccountChargeOffWithAdvancedPaymentAllocationTest {
+public class LoanAccountChargeOffWithAdvancedPaymentAllocationTest extends
BaseLoanIntegrationTest {
private static final DateTimeFormatter DATE_FORMATTER = new
DateTimeFormatterBuilder().appendPattern("dd MMMM yyyy").toFormatter();
private ResponseSpecification responseSpec;
@@ -777,23 +772,4 @@ public class
LoanAccountChargeOffWithAdvancedPaymentAllocationTest {
return paymentAllocationOrder;
}).toList();
}
-
- private void runAt(String date, Runnable runnable) {
- try {
-
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(requestSpec,
responseSpec, 42, true);
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, TRUE);
- businessDateHelper.updateBusinessDate(
- new
BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
- runnable.run();
- } finally {
- GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, FALSE);
-
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(requestSpec,
responseSpec, 42, false);
- }
- }
-
- private void updateBusinessDate(String date) {
- businessDateHelper.updateBusinessDate(
- new
BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
- }
-
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTest.java
index 9a9ec44a6..34f17cf22 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTest.java
@@ -724,16 +724,16 @@ public class
LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTe
// down payment period [1]
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(1), 1,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
LocalDate.of(2023, 3, 3), LocalDate.of(2023, 3, 3));
- // disbursement period [2]
-
verifyDisbursementPeriod(loanDetails.getRepaymentSchedule().getPeriods().get(2),
LocalDate.of(2023, 4, 3), 200.0);
- // down payment period [3]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(3), 2,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
- LocalDate.of(2023, 4, 3), LocalDate.of(2023, 4, 3));
- // regular installment [4]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(4), 3,
150.0, 0.0, 0.0, 150.0, 0.0, 0.0, 0.0, 0.0,
+ // regular installment [2]
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(2), 2,
75.0, 50.0, 50.0, 25.0, 0.0, 0.0, 0.0, 0.0,
false, LocalDate.of(2023, 3, 3), LocalDate.of(2023, 4, 3));
+ // disbursement period [3]
+
verifyDisbursementPeriod(loanDetails.getRepaymentSchedule().getPeriods().get(3),
LocalDate.of(2023, 4, 3), 200.0);
+ // down payment period [4]
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(4), 3,
50.0, 0.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, false,
+ LocalDate.of(2023, 4, 3), LocalDate.of(2023, 4, 3));
// regular installment [5]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(5), 4,
150.0, 0.0, 0.0, 150.0, 0.0, 0.0, 0.0, 0.0,
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(5), 4,
225.0, 0.0, 0.0, 225.0, 0.0, 0.0, 0.0, 0.0,
false, LocalDate.of(2023, 4, 3), LocalDate.of(2023, 5, 3));
// same day third disbursement with overlapping installment i.e
same due date as regular repayment due date
@@ -758,21 +758,21 @@ public class
LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTe
// down payment period [1]
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(1), 1,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
LocalDate.of(2023, 3, 3), LocalDate.of(2023, 3, 3));
- // disbursement period [2]
-
verifyDisbursementPeriod(loanDetails.getRepaymentSchedule().getPeriods().get(2),
LocalDate.of(2023, 4, 3), 200.0);
+ // regular installment [2]
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(2), 2,
75.0, 75.0, 75.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
+ LocalDate.of(2023, 3, 3), LocalDate.of(2023, 4, 3));
// disbursement period [3]
verifyDisbursementPeriod(loanDetails.getRepaymentSchedule().getPeriods().get(3),
LocalDate.of(2023, 4, 3), 200.0);
- // down payment period [4]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(4), 2,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
- LocalDate.of(2023, 4, 3), LocalDate.of(2023, 4, 3));
+ // disbursement period [4]
+
verifyDisbursementPeriod(loanDetails.getRepaymentSchedule().getPeriods().get(4),
LocalDate.of(2023, 4, 3), 200.0);
// down payment period [5]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(5), 3,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(5), 3,
50.0, 25.0, 25.0, 25.0, 0.0, 0.0, 0.0, 0.0,
+ false, LocalDate.of(2023, 4, 3), LocalDate.of(2023, 4, 3));
+ // down payment period [6]
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(6), 4,
50.0, 0.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, false,
LocalDate.of(2023, 4, 3), LocalDate.of(2023, 4, 3));
- // regular installment [6]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(6), 4,
225.0, 0.0, 0.0, 225.0, 0.0, 0.0, 0.0, 0.0,
- false, LocalDate.of(2023, 3, 3), LocalDate.of(2023, 4, 3));
// regular installment [7]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(7), 5,
225.0, 0.0, 0.0, 225.0, 0.0, 0.0, 0.0, 0.0,
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(7), 5,
375.0, 0.0, 0.0, 375.0, 0.0, 0.0, 0.0, 0.0,
false, LocalDate.of(2023, 4, 3), LocalDate.of(2023, 5, 3));
// make repayment for fully paying and verify that regular
installment gets fully paid on 3rd april
@@ -791,21 +791,21 @@ public class
LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTe
// down payment period [1]
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(1), 1,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
LocalDate.of(2023, 3, 3), LocalDate.of(2023, 3, 3));
- // disbursement period [2]
-
verifyDisbursementPeriod(loanDetails.getRepaymentSchedule().getPeriods().get(2),
LocalDate.of(2023, 4, 3), 200.0);
+ // regular installment [2]
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(2), 2,
75.0, 75.0, 75.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
+ LocalDate.of(2023, 3, 3), LocalDate.of(2023, 4, 3));
// disbursement period [3]
verifyDisbursementPeriod(loanDetails.getRepaymentSchedule().getPeriods().get(3),
LocalDate.of(2023, 4, 3), 200.0);
- // down payment period [4]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(4), 2,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
- LocalDate.of(2023, 4, 3), LocalDate.of(2023, 4, 3));
+ // disbursement period [4]
+
verifyDisbursementPeriod(loanDetails.getRepaymentSchedule().getPeriods().get(4),
LocalDate.of(2023, 4, 3), 200.0);
// down payment period [5]
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(5), 3,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
LocalDate.of(2023, 4, 3), LocalDate.of(2023, 4, 3));
- // regular installment [6]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(6), 4,
225.0, 225.0, 225.0, 0.0, 0.0, 0.0, 0.0, 0.0,
- true, LocalDate.of(2023, 3, 3), LocalDate.of(2023, 4, 3));
+ // down payment period [6]
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(6), 4,
50.0, 50.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, true,
+ LocalDate.of(2023, 4, 3), LocalDate.of(2023, 4, 3));
// regular installment [7]
-
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(7), 5,
225.0, 0.0, 0.0, 225.0, 0.0, 0.0, 0.0, 0.0,
+
verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(7), 5,
375.0, 150.0, 150.0, 225.0, 0.0, 0.0, 0.0, 0.0,
false, LocalDate.of(2023, 4, 3), LocalDate.of(2023, 5, 3));
} finally {
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductRepaymentStartDateConfigurationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductRepaymentStartDateConfigurationTest.java
index c13939f80..5cbf0e594 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductRepaymentStartDateConfigurationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductRepaymentStartDateConfigurationTest.java
@@ -124,7 +124,7 @@ public class LoanProductRepaymentStartDateConfigurationTest
{
try {
// Set business date
- LocalDate businessDate = LocalDate.of(2023, 03, 3);
+ LocalDate businessDate = LocalDate.of(2023, 3, 3);
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec,
BusinessDateType.BUSINESS_DATE, businessDate);
@@ -169,25 +169,25 @@ public class
LoanProductRepaymentStartDateConfigurationTest {
// first period [2023-03-03 to 2023-04-03]
assertEquals(1,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
- assertEquals(LocalDate.of(2023, 03, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
- assertEquals(LocalDate.of(2023, 04, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(LocalDate.of(2023, 3, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
assertEquals(333.33,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
// second period [2023-04-03 to 2023-05-03]
assertEquals(2,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
- assertEquals(LocalDate.of(2023, 04, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
- assertEquals(LocalDate.of(2023, 05, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
+ assertEquals(LocalDate.of(2023, 4, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
assertEquals(333.33,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());
// third period [2023-05-03 to 2023-06-03]
assertEquals(3,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
- assertEquals(LocalDate.of(2023, 05, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
- assertEquals(LocalDate.of(2023, 06, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
+ assertEquals(LocalDate.of(2023, 5, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
+ assertEquals(LocalDate.of(2023, 6, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(333.34,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
// first disbursement on a future date (7 March 2023)
- LocalDate disbursementDate = LocalDate.of(2023, 03, 7);
+ LocalDate disbursementDate = LocalDate.of(2023, 3, 7);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec,
BusinessDateType.BUSINESS_DATE, disbursementDate);
@@ -208,25 +208,25 @@ public class
LoanProductRepaymentStartDateConfigurationTest {
// first period [2023-03-03 to 2023-04-03]
assertEquals(1,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
- assertEquals(LocalDate.of(2023, 03, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
- assertEquals(LocalDate.of(2023, 04, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(LocalDate.of(2023, 3, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
assertEquals(166.67,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
// second period [2023-04-03 to 2023-05-03]
assertEquals(2,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
- assertEquals(LocalDate.of(2023, 04, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
- assertEquals(LocalDate.of(2023, 05, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
+ assertEquals(LocalDate.of(2023, 4, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
assertEquals(166.67,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());
// third period [2023-05-03 to 2023-06-03]
assertEquals(3,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
- assertEquals(LocalDate.of(2023, 05, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
- assertEquals(LocalDate.of(2023, 06, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
+ assertEquals(LocalDate.of(2023, 5, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
+ assertEquals(LocalDate.of(2023, 6, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(166.66,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
// second disbursement next month (7 April 2023)
- disbursementDate = LocalDate.of(2023, 04, 7);
+ disbursementDate = LocalDate.of(2023, 4, 7);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec,
BusinessDateType.BUSINESS_DATE, disbursementDate);
@@ -248,20 +248,20 @@ public class
LoanProductRepaymentStartDateConfigurationTest {
// first period [2023-03-03 to 2023-04-03]
assertEquals(1,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
- assertEquals(LocalDate.of(2023, 03, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
- assertEquals(LocalDate.of(2023, 04, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(LocalDate.of(2023, 3, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
assertEquals(166.67,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
// second period [2023-04-03 to 2023-05-03]
assertEquals(2,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
- assertEquals(LocalDate.of(2023, 04, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
- assertEquals(LocalDate.of(2023, 05, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
+ assertEquals(LocalDate.of(2023, 4, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(333.33,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
// third period [2023-05-03 to 2023-06-03]
assertEquals(3,
loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
- assertEquals(LocalDate.of(2023, 05, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
- assertEquals(LocalDate.of(2023, 06, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
+ assertEquals(LocalDate.of(2023, 5, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
+ assertEquals(LocalDate.of(2023, 6, 3),
loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
assertEquals(500.00,
loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());
} finally {
@@ -278,7 +278,7 @@ public class LoanProductRepaymentStartDateConfigurationTest
{
try {
// Set business date
- LocalDate businessDate = LocalDate.of(2023, 03, 3);
+ LocalDate businessDate = LocalDate.of(2023, 3, 3);
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec,
BusinessDateType.BUSINESS_DATE, businessDate);
@@ -324,25 +324,25 @@ public class
LoanProductRepaymentStartDateConfigurationTest {
// first period [2023-03-07 to 2023-04-07]
assertEquals(1,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
- assertEquals(LocalDate.of(2023, 03, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
- assertEquals(LocalDate.of(2023, 04, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(LocalDate.of(2023, 3, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
assertEquals(333.33,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
// second period [2023-04-07 to 2023-05-07]
assertEquals(2,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
- assertEquals(LocalDate.of(2023, 04, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
- assertEquals(LocalDate.of(2023, 05, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
+ assertEquals(LocalDate.of(2023, 4, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
assertEquals(333.33,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());
// third period [2023-05-07 to 2023-06-07]
assertEquals(3,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
- assertEquals(LocalDate.of(2023, 05, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
- assertEquals(LocalDate.of(2023, 06, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
+ assertEquals(LocalDate.of(2023, 5, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
+ assertEquals(LocalDate.of(2023, 6, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(333.34,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
// first disbursement (7 March 2023)
- LocalDate disbursementDate = LocalDate.of(2023, 03, 7);
+ LocalDate disbursementDate = LocalDate.of(2023, 3, 7);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec,
BusinessDateType.BUSINESS_DATE, disbursementDate);
@@ -364,25 +364,25 @@ public class
LoanProductRepaymentStartDateConfigurationTest {
// first period [2023-03-07 to 2023-04-07]
assertEquals(1,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
- assertEquals(LocalDate.of(2023, 03, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
- assertEquals(LocalDate.of(2023, 04, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(LocalDate.of(2023, 3, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
assertEquals(166.67,
loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
// second period [2023-04-07 to 2023-05-07]
assertEquals(2,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
- assertEquals(LocalDate.of(2023, 04, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
- assertEquals(LocalDate.of(2023, 05, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
+ assertEquals(LocalDate.of(2023, 4, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
assertEquals(166.67,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());
// third period [2023-05-07 to 2023-06-07]
assertEquals(3,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
- assertEquals(LocalDate.of(2023, 05, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
- assertEquals(LocalDate.of(2023, 06, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
+ assertEquals(LocalDate.of(2023, 5, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
+ assertEquals(LocalDate.of(2023, 6, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(166.66,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
// second disbursement next month (7 April 2023)
- disbursementDate = LocalDate.of(2023, 04, 7);
+ disbursementDate = LocalDate.of(2023, 4, 7);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec,
BusinessDateType.BUSINESS_DATE, disbursementDate);
@@ -405,20 +405,20 @@ public class
LoanProductRepaymentStartDateConfigurationTest {
// first period [2023-03-07 to 2023-04-07]
assertEquals(1,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
- assertEquals(LocalDate.of(2023, 03, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
- assertEquals(LocalDate.of(2023, 04, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
+ assertEquals(LocalDate.of(2023, 3, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
assertEquals(333.33,
loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());
// second period [2023-04-07 to 2023-05-07]
assertEquals(2,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
- assertEquals(LocalDate.of(2023, 04, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
- assertEquals(LocalDate.of(2023, 05, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
+ assertEquals(LocalDate.of(2023, 4, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(333.33,
loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
// third period [2023-05-07 to 2023-06-07]
assertEquals(3,
loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
- assertEquals(LocalDate.of(2023, 05, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
- assertEquals(LocalDate.of(2023, 06, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
+ assertEquals(LocalDate.of(2023, 5, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
+ assertEquals(LocalDate.of(2023, 6, 7),
loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
assertEquals(333.34,
loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());
} finally {