FINERACT-1981: Order disbursements and repayment periods properly
This commit is contained in:
+12
-2
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+7
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-82
@@ -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'
|
||||
|
||||
+22
-17
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -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);
|
||||
}
|
||||
|
||||
+8
-4
@@ -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(),
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
|
||||
+48
-58
@@ -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> {
|
||||
|
||||
+327
-254
File diff suppressed because it is too large
Load Diff
+5
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-25
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+27
-27
@@ -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 {
|
||||
|
||||
+42
-42
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user