FINERACT-1981: Embeddable Progressive Loan Schedule generator

This commit is contained in:
Janos Meszaros
2024-12-10 15:04:16 +01:00
committed by Adam Saghy
parent d0006a2169
commit bb8480a03d
41 changed files with 849 additions and 439 deletions
@@ -48,7 +48,7 @@ public class ProgressiveTransactionCtx extends TransactionCtx {
Set<LoanCharge> charges, MoneyHolder overpaymentHolder, ChangedTransactionDetail changedTransactionDetail,
ProgressiveLoanInterestScheduleModel model) {
super(currency, installments, charges, overpaymentHolder, changedTransactionDetail);
sumOfInterestRefundAmount = model.getZero();
sumOfInterestRefundAmount = model.zero();
this.model = model;
}
}
@@ -91,7 +91,7 @@ public class InterestPeriod implements Comparable<InterestPeriod> {
.multipliedBy(getRateFactorTillPeriodDueDate(), mc).getAmount() //
.divide(BigDecimal.valueOf(lengthTillPeriodDueDate), mc) //
.multiply(BigDecimal.valueOf(getLength()), mc); //
return Money.of(outstandingLoanBalance.getCurrency(), interestDueTillRepaymentDueDate, mc);
return Money.of(outstandingLoanBalance.getCurrencyData(), interestDueTillRepaymentDueDate, mc);
}
public long getLength() {
@@ -75,7 +75,7 @@ public class LoanSchedulePlan {
});
return new LoanSchedulePlan(periods, //
model.getApplicationCurrency().toData(), //
model.getCurrency(), //
model.getLoanTermInDays(), //
model.getTotalPrincipalDisbursed().getAmount(), //
model.getTotalPrincipalExpected(), //
@@ -34,7 +34,7 @@ import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
@Data
@Accessors(fluent = true)
@@ -42,26 +42,31 @@ public class ProgressiveLoanInterestScheduleModel {
private final List<RepaymentPeriod> repaymentPeriods;
private final TreeSet<InterestRate> interestRates;
private final LoanProductRelatedDetail loanProductRelatedDetail;
private final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail;
private final Integer installmentAmountInMultiplesOf;
private MathContext mc;
private final MathContext mc;
private final Money zero;
public ProgressiveLoanInterestScheduleModel(List<RepaymentPeriod> repaymentPeriods, LoanProductRelatedDetail loanProductRelatedDetail,
Integer installmentAmountInMultiplesOf, MathContext mc) {
public ProgressiveLoanInterestScheduleModel(final List<RepaymentPeriod> repaymentPeriods,
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail, final Integer installmentAmountInMultiplesOf,
final MathContext mc) {
this.repaymentPeriods = repaymentPeriods;
this.interestRates = new TreeSet<>(Collections.reverseOrder());
this.loanProductRelatedDetail = loanProductRelatedDetail;
this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf;
this.mc = mc;
this.zero = Money.zero(loanProductRelatedDetail.getCurrencyData(), mc);
}
private ProgressiveLoanInterestScheduleModel(List<RepaymentPeriod> repaymentPeriods, final TreeSet<InterestRate> interestRates,
LoanProductRelatedDetail loanProductRelatedDetail, Integer installmentAmountInMultiplesOf, MathContext mc) {
private ProgressiveLoanInterestScheduleModel(final List<RepaymentPeriod> repaymentPeriods, final TreeSet<InterestRate> interestRates,
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail, final Integer installmentAmountInMultiplesOf,
final MathContext mc) {
this.mc = mc;
this.repaymentPeriods = copyRepaymentPeriods(repaymentPeriods);
this.interestRates = new TreeSet<>(interestRates);
this.loanProductRelatedDetail = loanProductRelatedDetail;
this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf;
this.zero = Money.zero(loanProductRelatedDetail.getCurrencyData(), mc);
}
public ProgressiveLoanInterestScheduleModel deepCopy(MathContext mc) {
@@ -197,30 +202,26 @@ public class ProgressiveLoanInterestScheduleModel {
previousInterestPeriod.addDisbursementAmount(disbursedAmount);
previousInterestPeriod.addBalanceCorrectionAmount(correctionAmount);
final InterestPeriod interestPeriod = new InterestPeriod(repaymentPeriod, previousInterestPeriod.getDueDate(), originalDueDate,
BigDecimal.ZERO, BigDecimal.ZERO, getZero(), getZero(), getZero(), mc);
BigDecimal.ZERO, BigDecimal.ZERO, zero, zero, zero, mc);
repaymentPeriod.getInterestPeriods().add(interestPeriod);
}
public Money getZero() {
return Money.zero(loanProductRelatedDetail.getCurrency(), mc);
}
public Money getTotalDueInterest() {
return repaymentPeriods().stream().flatMap(rp -> rp.getInterestPeriods().stream().map(InterestPeriod::getCalculatedDueInterest))
.reduce(getZero(), Money::plus);
.reduce(zero(), Money::plus);
}
public Money getTotalDuePrincipal() {
return repaymentPeriods.stream().flatMap(rp -> rp.getInterestPeriods().stream().map(InterestPeriod::getDisbursementAmount))
.reduce(getZero(), Money::plus);
.reduce(zero(), Money::plus);
}
public Money getTotalPaidInterest() {
return repaymentPeriods().stream().map(RepaymentPeriod::getPaidInterest).reduce(getZero(), Money::plus);
return repaymentPeriods().stream().map(RepaymentPeriod::getPaidInterest).reduce(zero, Money::plus);
}
public Money getTotalPaidPrincipal() {
return repaymentPeriods().stream().map(RepaymentPeriod::getPaidPrincipal).reduce(getZero(), Money::plus);
return repaymentPeriods().stream().map(RepaymentPeriod::getPaidPrincipal).reduce(zero, Money::plus);
}
public Optional<RepaymentPeriod> findRepaymentPeriod(@NotNull LocalDate transactionDate) {
@@ -31,9 +31,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
@@ -55,7 +54,6 @@ import org.apache.fineract.portfolio.loanproduct.calc.EMICalculator;
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
@@ -72,11 +70,10 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
public LoanScheduleModel generate(final MathContext mc, final LoanApplicationTerms loanApplicationTerms,
final Set<LoanCharge> loanCharges, final HolidayDetailDTO holidayDetailDTO) {
final ApplicationCurrency applicationCurrency = loanApplicationTerms.getApplicationCurrency();
// determine the total charges due at time of disbursement
final BigDecimal chargesDueAtTimeOfDisbursement = deriveTotalChargesDueAtTimeOfDisbursement(loanCharges);
final MonetaryCurrency currency = loanApplicationTerms.getCurrency();
final CurrencyData currency = loanApplicationTerms.getCurrency();
LocalDate periodStartDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(loanApplicationTerms.getRepaymentStartDateType())
? loanApplicationTerms.getExpectedDisbursementDate()
: loanApplicationTerms.getSubmittedOnDate();
@@ -92,7 +89,7 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
final List<LoanScheduleModelRepaymentPeriod> expectedRepaymentPeriods = scheduledDateGenerator.generateRepaymentPeriods(mc,
periodStartDate, loanApplicationTerms, holidayDetailDTO);
final ProgressiveLoanInterestScheduleModel interestScheduleModel = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanApplicationTerms.toLoanProductRelatedDetail(),
expectedRepaymentPeriods, loanApplicationTerms.toLoanProductRelatedDetailMinimumData(),
loanApplicationTerms.getInstallmentAmountInMultiplesOf(), mc);
final List<LoanScheduleModelPeriod> periods = new ArrayList<>(expectedRepaymentPeriods.size());
@@ -141,7 +138,7 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
final BigDecimal totalPrincipalPaid = BigDecimal.ZERO;
final BigDecimal totalOutstanding = BigDecimal.ZERO;
return LoanScheduleModel.from(periods, applicationCurrency, interestScheduleModel.getLoanTermInDays(),
return LoanScheduleModel.from(periods, currency, interestScheduleModel.getLoanTermInDays(),
scheduleParams.getPrincipalToBeScheduled().plus(loanApplicationTerms.getDownPaymentAmount(), mc),
scheduleParams.getTotalCumulativePrincipal().plus(loanApplicationTerms.getDownPaymentAmount(), mc).getAmount(),
totalPrincipalPaid, scheduleParams.getTotalCumulativeInterest().getAmount(),
@@ -308,7 +305,7 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
}
private void applyChargesForCurrentPeriod(final LoanScheduleModelRepaymentPeriod repaymentPeriod, final Set<LoanCharge> loanCharges,
final LoanScheduleParams scheduleParams, final MonetaryCurrency currency, final MathContext mc) {
final LoanScheduleParams scheduleParams, final CurrencyData currency, final MathContext mc) {
final PrincipalInterest principalInterest = new PrincipalInterest(repaymentPeriod.getPrincipalDue(),
repaymentPeriod.getInterestDue(), null);
@@ -325,10 +322,10 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
}
private Money cumulativeFeeChargesDueWithin(final LocalDate periodStart, final LocalDate periodEnd, final Set<LoanCharge> loanCharges,
final MonetaryCurrency monetaryCurrency, final PrincipalInterest principalInterestForThisPeriod, final Money principalDisbursed,
final CurrencyData currency, final PrincipalInterest principalInterestForThisPeriod, final Money principalDisbursed,
final Money totalInterestChargedForFullLoanTerm, boolean isInstallmentChargeApplicable, final boolean isFirstPeriod,
final MathContext mc) {
Money cumulative = Money.zero(monetaryCurrency, mc);
Money cumulative = Money.zero(currency, mc);
if (loanCharges != null) {
for (final LoanCharge loanCharge : loanCharges) {
if (!loanCharge.isDueAtDisbursement() && loanCharge.isFeeCharge()) {
@@ -358,11 +355,10 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
}
private Money cumulativePenaltyChargesDueWithin(final LocalDate periodStart, final LocalDate periodEnd,
final Set<LoanCharge> loanCharges, final MonetaryCurrency monetaryCurrency,
final PrincipalInterest principalInterestForThisPeriod, final Money principalDisbursed,
final Money totalInterestChargedForFullLoanTerm, boolean isInstallmentChargeApplicable, final boolean isFirstPeriod,
final MathContext mc) {
Money cumulative = Money.zero(monetaryCurrency, mc);
final Set<LoanCharge> loanCharges, final CurrencyData currency, final PrincipalInterest principalInterestForThisPeriod,
final Money principalDisbursed, final Money totalInterestChargedForFullLoanTerm, boolean isInstallmentChargeApplicable,
final boolean isFirstPeriod, final MathContext mc) {
Money cumulative = Money.zero(currency, mc);
if (loanCharges != null) {
for (final LoanCharge loanCharge : loanCharges) {
if (loanCharge.isPenaltyCharge()) {
@@ -409,7 +405,7 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
return cumulative;
}
private void updatePeriodsWithCharges(final MonetaryCurrency currency, LoanScheduleParams scheduleParams,
private void updatePeriodsWithCharges(final CurrencyData currency, LoanScheduleParams scheduleParams,
final Collection<LoanScheduleModelPeriod> periods, final Set<LoanCharge> nonCompoundingCharges, MathContext mc) {
for (LoanScheduleModelPeriod loanScheduleModelPeriod : periods) {
if (loanScheduleModelPeriod.isRepaymentPeriod()) {
@@ -31,18 +31,20 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.PeriodDueDeta
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.ProgressiveLoanInterestScheduleModel;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.RepaymentPeriod;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelRepaymentPeriod;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
public interface EMICalculator {
@NotNull
ProgressiveLoanInterestScheduleModel generatePeriodInterestScheduleModel(@NotNull List<LoanScheduleModelRepaymentPeriod> periods,
@NotNull LoanProductRelatedDetail loanProductRelatedDetail, Integer installmentAmountInMultiplesOf, MathContext mc);
@NotNull LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail, Integer installmentAmountInMultiplesOf,
MathContext mc);
@NotNull
ProgressiveLoanInterestScheduleModel generateInstallmentInterestScheduleModel(
@NotNull List<LoanRepaymentScheduleInstallment> installments, @NotNull LoanProductRelatedDetail loanProductRelatedDetail,
Integer installmentAmountInMultiplesOf, MathContext mc);
@NotNull List<LoanRepaymentScheduleInstallment> installments,
@NotNull LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail, Integer installmentAmountInMultiplesOf,
MathContext mc);
Optional<RepaymentPeriod> findRepaymentPeriod(ProgressiveLoanInterestScheduleModel scheduleModel, LocalDate dueDate);
@@ -43,7 +43,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.PeriodDueDeta
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.ProgressiveLoanInterestScheduleModel;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.RepaymentPeriod;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelRepaymentPeriod;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
import org.springframework.stereotype.Component;
@Component
@@ -56,8 +56,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
@Override
@NotNull
public ProgressiveLoanInterestScheduleModel generatePeriodInterestScheduleModel(@NotNull List<LoanScheduleModelRepaymentPeriod> periods,
@NotNull LoanProductRelatedDetail loanProductRelatedDetail, final Integer installmentAmountInMultiplesOf,
final MathContext mc) {
@NotNull LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail,
final Integer installmentAmountInMultiplesOf, final MathContext mc) {
return generateInterestScheduleModel(periods, LoanScheduleModelRepaymentPeriod::periodFromDate,
LoanScheduleModelRepaymentPeriod::periodDueDate, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
}
@@ -65,7 +65,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
@Override
@NotNull
public ProgressiveLoanInterestScheduleModel generateInstallmentInterestScheduleModel(
@NotNull List<LoanRepaymentScheduleInstallment> installments, @NotNull LoanProductRelatedDetail loanProductRelatedDetail,
@NotNull List<LoanRepaymentScheduleInstallment> installments,
@NotNull LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail,
final Integer installmentAmountInMultiplesOf, final MathContext mc) {
installments = installments.stream().filter(installment -> !installment.isDownPayment() && !installment.isAdditional()).toList();
return generateInterestScheduleModel(installments, LoanRepaymentScheduleInstallment::getFromDate,
@@ -74,9 +75,9 @@ public final class ProgressiveEMICalculator implements EMICalculator {
@NotNull
private <T> ProgressiveLoanInterestScheduleModel generateInterestScheduleModel(@NotNull List<T> periods, Function<T, LocalDate> from,
Function<T, LocalDate> to, @NotNull LoanProductRelatedDetail loanProductRelatedDetail,
Function<T, LocalDate> to, @NotNull LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail,
final Integer installmentAmountInMultiplesOf, final MathContext mc) {
final Money zero = Money.zero(loanProductRelatedDetail.getCurrency(), mc);
final Money zero = Money.zero(loanProductRelatedDetail.getCurrencyData(), mc);
final AtomicReference<RepaymentPeriod> prev = new AtomicReference<>();
List<RepaymentPeriod> repaymentPeriods = periods.stream().map(e -> {
RepaymentPeriod rp = new RepaymentPeriod(prev.get(), from.apply(e), to.apply(e), zero, mc);
@@ -101,7 +102,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
@Override
public void addDisbursement(final ProgressiveLoanInterestScheduleModel scheduleModel, final LocalDate disbursementDueDate,
final Money disbursedAmount) {
scheduleModel.changeOutstandingBalanceAndUpdateInterestPeriods(disbursementDueDate, disbursedAmount, scheduleModel.getZero())
scheduleModel.changeOutstandingBalanceAndUpdateInterestPeriods(disbursementDueDate, disbursedAmount, scheduleModel.zero())
.ifPresent((repaymentPeriod) -> calculateEMIValueAndRateFactors(
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, disbursementDueDate), scheduleModel));
}
@@ -127,8 +128,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
final LocalDate interestRateChangeEffectiveDate = newInterestSubmittedOnDate.minusDays(1);
scheduleModel.addInterestRate(interestRateChangeEffectiveDate, newInterestRate);
scheduleModel
.changeOutstandingBalanceAndUpdateInterestPeriods(interestRateChangeEffectiveDate, scheduleModel.getZero(),
scheduleModel.getZero())
.changeOutstandingBalanceAndUpdateInterestPeriods(interestRateChangeEffectiveDate, scheduleModel.zero(),
scheduleModel.zero())
.ifPresent(repaymentPeriod -> calculateEMIValueAndRateFactors(
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, interestRateChangeEffectiveDate), scheduleModel));
}
@@ -136,8 +137,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
@Override
public void addBalanceCorrection(ProgressiveLoanInterestScheduleModel scheduleModel, LocalDate balanceCorrectionDate,
Money balanceCorrectionAmount) {
scheduleModel
.changeOutstandingBalanceAndUpdateInterestPeriods(balanceCorrectionDate, scheduleModel.getZero(), balanceCorrectionAmount)
scheduleModel.changeOutstandingBalanceAndUpdateInterestPeriods(balanceCorrectionDate, scheduleModel.zero(), balanceCorrectionAmount)
.ifPresent(repaymentPeriod -> {
calculateRateFactorForRepaymentPeriod(repaymentPeriod, scheduleModel);
calculateOutstandingBalance(scheduleModel);
@@ -296,13 +296,13 @@ public final class ProgressiveEMICalculator implements EMICalculator {
private void calculateLastUnpaidRepaymentPeriodEMI(ProgressiveLoanInterestScheduleModel scheduleModel) {
MathContext mc = scheduleModel.mc();
Money totalDueInterest = scheduleModel.repaymentPeriods().stream().map(RepaymentPeriod::getDueInterest)
.reduce(Money.zero(scheduleModel.loanProductRelatedDetail().getCurrency(), mc), (m1, m2) -> m1.plus(m2, mc)); // 1.46
Money totalEMI = scheduleModel.repaymentPeriods().stream().map(RepaymentPeriod::getEmi)
.reduce(Money.zero(scheduleModel.loanProductRelatedDetail().getCurrency(), mc), (m1, m2) -> m1.plus(m2, mc)); // 101.48
Money totalDueInterest = scheduleModel.repaymentPeriods().stream().map(RepaymentPeriod::getDueInterest).reduce(scheduleModel.zero(),
(m1, m2) -> m1.plus(m2, mc)); // 1.46
Money totalEMI = scheduleModel.repaymentPeriods().stream().map(RepaymentPeriod::getEmi).reduce(scheduleModel.zero(),
(m1, m2) -> m1.plus(m2, mc)); // 101.48
Money totalDisbursedAmount = scheduleModel.repaymentPeriods().stream()
.flatMap(rp -> rp.getInterestPeriods().stream().map(InterestPeriod::getDisbursementAmount))
.reduce(Money.zero(scheduleModel.loanProductRelatedDetail().getCurrency(), mc), (m1, m2) -> m1.plus(m2, mc)); // 100
.reduce(scheduleModel.zero(), (m1, m2) -> m1.plus(m2, mc)); // 100
Money diff = totalDisbursedAmount.plus(totalDueInterest, mc).minus(totalEMI, mc);
Optional<RepaymentPeriod> findLastUnpaidRepaymentPeriod = scheduleModel.repaymentPeriods().stream().filter(rp -> !rp.isFullyPaid())
@@ -400,7 +400,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
BigDecimal calculateRateFactorPerPeriod(final ProgressiveLoanInterestScheduleModel scheduleModel, final RepaymentPeriod repaymentPeriod,
final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate) {
final MathContext mc = scheduleModel.mc();
final LoanProductRelatedDetail loanProductRelatedDetail = scheduleModel.loanProductRelatedDetail();
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail = scheduleModel.loanProductRelatedDetail();
final BigDecimal interestRate = calcNominalInterestRatePercentage(scheduleModel.getInterestRate(interestPeriodFromDate),
scheduleModel.mc());
final DaysInYearType daysInYearType = DaysInYearType.fromInt(loanProductRelatedDetail.getDaysInYearType());
@@ -493,7 +493,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
// TODO: double check
final Money outstandingBalance = startPeriod.getInitialBalanceForEmiRecalculation();
final Money equalMonthlyInstallment = Money.of(outstandingBalance.getCurrency(),
final Money equalMonthlyInstallment = Money.of(outstandingBalance.getCurrencyData(),
calculateEMIValue(rateFactorN, outstandingBalance.getAmount(), fnResult, mc), mc);
final Money finalEqualMonthlyInstallment = applyInstallmentAmountInMultiplesOf(scheduleModel, equalMonthlyInstallment);
@@ -732,7 +732,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
return scheduleModel.repaymentPeriods().stream().map(RepaymentPeriod::getDueDate) //
.map(repaymentPeriodDueDate -> getDueAmounts(scheduleModel, repaymentPeriodDueDate, subjectDate) //
.getDueInterest()) //
.reduce(scheduleModel.getZero(), Money::add); //
.reduce(scheduleModel.zero(), Money::add); //
}
private long getUncountablePeriods(final List<RepaymentPeriod> relatedRepaymentPeriods, final Money originalEmi) {
@@ -561,7 +561,7 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
@Test
public void calculateChargebackAllocationMap() {
Map<AllocationType, Money> result;
MonetaryCurrency currency = mock(MonetaryCurrency.class);
MonetaryCurrency currency = new MonetaryCurrency("usd", 2, null);
result = underTest.calculateChargebackAllocationMap(allocationMap(50.0, 100.0, 200.0, 12.0, currency), BigDecimal.valueOf(50.0),
List.of(PRINCIPAL, INTEREST, FEE, PENALTY), currency);
@@ -24,6 +24,7 @@ import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
@@ -38,6 +39,7 @@ class LoanScheduleGeneratorTest {
private static final ProgressiveEMICalculator emiCalculator = new ProgressiveEMICalculator();
private static final ApplicationCurrency APPLICATION_CURRENCY = new ApplicationCurrency("USD", "USD", 2, 1, "USD", "$");
private static final CurrencyData CURRENCY = APPLICATION_CURRENCY.toData();
private static final BigDecimal DISBURSEMENT_AMOUNT = BigDecimal.valueOf(192.22);
private static final BigDecimal DISBURSEMENT_AMOUNT_100 = BigDecimal.valueOf(100);
private static final BigDecimal NOMINAL_INTEREST_RATE = BigDecimal.valueOf(9.99);
@@ -50,7 +52,7 @@ class LoanScheduleGeneratorTest {
@Test
void testGenerateLoanSchedule() {
LoanRepaymentScheduleModelData modelData = new LoanRepaymentScheduleModelData(LocalDate.of(2024, 1, 1), APPLICATION_CURRENCY,
LoanRepaymentScheduleModelData modelData = new LoanRepaymentScheduleModelData(LocalDate.of(2024, 1, 1), CURRENCY,
DISBURSEMENT_AMOUNT, DISBURSEMENT_DATE, NUMBER_OF_REPAYMENTS, REPAYMENT_FREQUENCY, REPAYMENT_FREQUENCY_TYPE,
NOMINAL_INTEREST_RATE, false, DaysInMonthType.DAYS_30, DaysInYearType.DAYS_360, null, null, null);
@@ -85,7 +87,7 @@ class LoanScheduleGeneratorTest {
@Test
void testGenerateLoanScheduleWithDownPayment() {
LoanRepaymentScheduleModelData modelData = new LoanRepaymentScheduleModelData(LocalDate.of(2024, 1, 1), APPLICATION_CURRENCY,
LoanRepaymentScheduleModelData modelData = new LoanRepaymentScheduleModelData(LocalDate.of(2024, 1, 1), CURRENCY,
DISBURSEMENT_AMOUNT_100, LocalDate.of(2024, 1, 1), NUMBER_OF_REPAYMENTS, REPAYMENT_FREQUENCY, REPAYMENT_FREQUENCY_TYPE,
NOMINAL_INTEREST_RATE, true, DaysInMonthType.DAYS_30, DaysInYearType.DAYS_360, DOWN_PAYMENT_PORTION, null, null);
@@ -26,8 +26,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
@@ -39,7 +38,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.PeriodDueDeta
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.ProgressiveLoanInterestScheduleModel;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.RepaymentPeriod;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelRepaymentPeriod;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
@@ -59,10 +58,10 @@ class ProgressiveEMICalculatorTest {
private static MockedStatic<ThreadLocalContextUtil> threadLocalContextUtil = Mockito.mockStatic(ThreadLocalContextUtil.class);
private static MockedStatic<MoneyHelper> moneyHelper = Mockito.mockStatic(MoneyHelper.class);
private static MathContext mc = new MathContext(12, RoundingMode.HALF_EVEN);
private static LoanProductRelatedDetail loanProductRelatedDetail = Mockito.mock(LoanProductRelatedDetail.class);
private static LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail = Mockito
.mock(LoanProductMinimumRepaymentScheduleRelatedDetail.class);
private static final MonetaryCurrency monetaryCurrency = MonetaryCurrency
.fromApplicationCurrency(new ApplicationCurrency("USD", "USD", 2, 1, "USD", "$"));
private static final CurrencyData currency = new CurrencyData("USD", "USD", 2, 1, "$", "USD");
private static List<LoanRepaymentScheduleInstallment> periods;
private final BigDecimal interestRate = BigDecimal.valueOf(0.094822);
@@ -166,7 +165,7 @@ class ProgressiveEMICalculatorTest {
expectedRepaymentPeriods.add(repayment(3, LocalDate.of(2024, 3, 1), LocalDate.of(2024, 4, 1)));
expectedRepaymentPeriods.add(repayment(4, LocalDate.of(2024, 4, 1), LocalDate.of(2024, 5, 1)));
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestScheduleModel = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -205,7 +204,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -249,7 +248,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -285,7 +284,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -321,7 +320,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -367,7 +366,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -403,7 +402,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 14));
@@ -445,7 +444,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 14));
@@ -492,7 +491,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 14));
@@ -538,7 +537,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 14));
@@ -584,7 +583,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 15));
@@ -663,7 +662,7 @@ class ProgressiveEMICalculatorTest {
Assertions.assertEquals(0.1, toDouble(repaymentDetails4th.getDueInterest()));
// balance update on the last period, check the right interest interval split
emiCalculator.addBalanceCorrection(interestSchedule, LocalDate.of(2024, 6, 10), Money.of(monetaryCurrency, BigDecimal.ZERO));
emiCalculator.addBalanceCorrection(interestSchedule, LocalDate.of(2024, 6, 10), Money.of(currency, BigDecimal.ZERO));
final RepaymentPeriod lastRepaymentPeriod = interestSchedule.repaymentPeriods().get(interestSchedule.repaymentPeriods().size() - 1);
Assertions.assertEquals(2, lastRepaymentPeriod.getInterestPeriods().size());
Assertions.assertEquals(LocalDate.of(2024, 6, 1), lastRepaymentPeriod.getInterestPeriods().get(0).getFromDate());
@@ -691,7 +690,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 15));
@@ -762,7 +761,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 15));
@@ -841,7 +840,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -890,7 +889,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -939,7 +938,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -983,7 +982,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -1017,7 +1016,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -1050,7 +1049,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.WEEKS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -1083,7 +1082,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.WEEKS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(2);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -1116,7 +1115,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.INVALID.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.DAYS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(15);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -1148,7 +1147,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestModel = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -1210,7 +1209,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
final ProgressiveLoanInterestScheduleModel interestModel = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
@@ -1266,7 +1265,7 @@ class ProgressiveEMICalculatorTest {
}
private static LoanScheduleModelRepaymentPeriod repayment(int periodNumber, LocalDate fromDate, LocalDate dueDate) {
final Money zeroAmount = Money.zero(monetaryCurrency);
final Money zeroAmount = Money.zero(currency);
return LoanScheduleModelRepaymentPeriod.repayment(periodNumber, fromDate, dueDate, zeroAmount, zeroAmount, zeroAmount, zeroAmount,
zeroAmount, zeroAmount, false, mc);
}
@@ -1326,6 +1325,6 @@ class ProgressiveEMICalculatorTest {
}
private static Money toMoney(final double value) {
return Money.of(monetaryCurrency, BigDecimal.valueOf(value));
return Money.of(currency, BigDecimal.valueOf(value));
}
}