FINERACT-2174: Calculate fraction period - In case interestRecognitionFromDisbursementDate is true, we need to include from date and exclude due date

This commit is contained in:
Soma Sörös
2025-02-17 09:48:14 +01:00
committed by Adam Saghy
parent 7dc5dc279b
commit ff21304cac
9 changed files with 179 additions and 16 deletions
@@ -254,6 +254,8 @@ public final class LoanApplicationTerms {
this.seedDate = builder.seedDate;
this.isDownPaymentEnabled = builder.isDownPaymentEnabled;
this.disbursedAmountPercentageForDownPayment = builder.downPaymentPercentage;
this.interestRecognitionOnDisbursementDate = builder.interestRecognitionOnDisbursementDate != null
&& builder.interestRecognitionOnDisbursementDate;
if (isDownPaymentEnabled) {
this.downPaymentAmount = Money.of(getCurrency(),
MathUtil.percentageOf(getPrincipal().getAmount(), getDisbursedAmountPercentageForDownPayment(), builder.mc),
@@ -291,6 +293,7 @@ public final class LoanApplicationTerms {
private LocalDate submittedOnDate;
private LocalDate seedDate;
private MathContext mc;
private Boolean interestRecognitionOnDisbursementDate;
public Builder currency(CurrencyData currency) {
this.currency = currency;
@@ -402,6 +405,11 @@ public final class LoanApplicationTerms {
return this;
}
public Builder interestRecognitionOnDisbursementDate(boolean value) {
this.interestRecognitionOnDisbursementDate = value;
return this;
}
public LoanApplicationTerms build() {
return new LoanApplicationTerms(this);
}
@@ -430,7 +438,8 @@ public final class LoanApplicationTerms {
.daysInMonthType(modelData.daysInMonth()).daysInYearType(modelData.daysInYear()).fixedLength(modelData.fixedLength())
.inArrearsTolerance(Money.zero(modelData.currency(), mc)).disbursementDatas(new ArrayList<>())
.isDownPaymentEnabled(modelData.downPaymentEnabled()).downPaymentPercentage(downPaymentPercentage)
.submittedOnDate(modelData.scheduleGenerationStartDate()).seedDate(seedDate).mc(mc).build();
.submittedOnDate(modelData.scheduleGenerationStartDate()).seedDate(seedDate)
.interestRecognitionOnDisbursementDate(modelData.interestRecognitionOnDisbursementDate()).mc(mc).build();
}
public static LoanApplicationTerms assembleFrom(final CurrencyData currency, final Integer loanTermFrequency,
@@ -1557,7 +1566,8 @@ public final class LoanApplicationTerms {
return new LoanProductRelatedDetailMinimumData(currency, interestRatePerPeriod, annualNominalInterestRate, interestChargingGrace,
interestPaymentGrace, principalGrace, recurringMoratoriumOnPrincipalPeriods, interestMethod,
interestCalculationPeriodMethod, daysInYearType, daysInMonthType, amortizationMethod, repaymentPeriodFrequencyType,
repaymentEvery, numberOfRepayments);
repaymentEvery, numberOfRepayments,
isInterestChargedFromDateSameAsDisbursalDateEnabled != null && isInterestChargedFromDateSameAsDisbursalDateEnabled);
}
public Integer getLoanTermFrequency() {
@@ -30,5 +30,16 @@ public record LoanRepaymentScheduleModelData(@NotNull LocalDate scheduleGenerati
@NotNull BigDecimal disbursementAmount, @NotNull LocalDate disbursementDate, @NotNull int numberOfRepayments,
@NotNull int repaymentFrequency, @NotBlank String repaymentFrequencyType, @NotNull BigDecimal annualNominalInterestRate,
@NotNull boolean downPaymentEnabled, @NotNull DaysInMonthType daysInMonth, @NotNull DaysInYearType daysInYear,
BigDecimal downPaymentPercentage, Integer installmentAmountInMultiplesOf, Integer fixedLength) {
BigDecimal downPaymentPercentage, Integer installmentAmountInMultiplesOf, Integer fixedLength,
@NotNull Boolean interestRecognitionOnDisbursementDate) {
LoanRepaymentScheduleModelData(@NotNull LocalDate scheduleGenerationStartDate, @NotNull CurrencyData currency,
@NotNull BigDecimal disbursementAmount, @NotNull LocalDate disbursementDate, @NotNull int numberOfRepayments,
@NotNull int repaymentFrequency, @NotBlank String repaymentFrequencyType, @NotNull BigDecimal annualNominalInterestRate,
@NotNull boolean downPaymentEnabled, @NotNull DaysInMonthType daysInMonth, @NotNull DaysInYearType daysInYear,
BigDecimal downPaymentPercentage, Integer installmentAmountInMultiplesOf, Integer fixedLength) {
this(scheduleGenerationStartDate, currency, disbursementAmount, disbursementDate, numberOfRepayments, repaymentFrequency,
repaymentFrequencyType, annualNominalInterestRate, downPaymentEnabled, daysInMonth, daysInYear, downPaymentPercentage,
installmentAmountInMultiplesOf, fixedLength, false);
}
}
@@ -45,13 +45,14 @@ public class LoanProductRelatedDetailMinimumData implements LoanProductMinimumRe
private final PeriodFrequencyType repaymentPeriodFrequencyType;
private final Integer repaymentEvery;
private final Integer numberOfRepayments;
private final boolean interestRecognitionOnDisbursementDate;
public LoanProductRelatedDetailMinimumData(CurrencyData currency, BigDecimal interestRatePerPeriod,
BigDecimal annualNominalInterestRate, Integer interestChargingGrace, Integer interestPaymentGrace, Integer principalGrace,
Integer recurringMoratoriumOnPrincipalPeriods, InterestMethod interestMethod,
InterestCalculationPeriodMethod interestCalculationPeriodMethod, DaysInYearType daysInYearType, DaysInMonthType daysInMonthType,
AmortizationMethod amortizationMethod, PeriodFrequencyType repaymentPeriodFrequencyType, Integer repaymentEvery,
Integer numberOfRepayments) {
Integer numberOfRepayments, boolean interestRecognitionOnDisbursementDate) {
this.currency = currency;
this.interestRatePerPeriod = interestRatePerPeriod;
this.annualNominalInterestRate = annualNominalInterestRate;
@@ -67,6 +68,7 @@ public class LoanProductRelatedDetailMinimumData implements LoanProductMinimumRe
this.repaymentPeriodFrequencyType = repaymentPeriodFrequencyType;
this.repaymentEvery = repaymentEvery;
this.numberOfRepayments = numberOfRepayments;
this.interestRecognitionOnDisbursementDate = interestRecognitionOnDisbursementDate;
}
private Integer defaultToNullIfZero(final Integer value) {
@@ -161,4 +163,9 @@ public class LoanProductRelatedDetailMinimumData implements LoanProductMinimumRe
public Integer getDaysInYearType() {
return daysInYearType.getValue();
}
@Override
public boolean isInterestRecognitionOnDisbursementDate() {
return interestRecognitionOnDisbursementDate;
}
}
@@ -60,4 +60,6 @@ public interface LoanProductMinimumRepaymentScheduleRelatedDetail {
Integer getDaysInMonthType();
Integer getDaysInYearType();
boolean isInterestRecognitionOnDisbursementDate();
}
@@ -55,8 +55,9 @@ public class Main {
final DaysInYearType daysInYearType = DaysInYearType.DAYS_360;
final Integer installmentAmountInMultiplesOf = null;
final Integer fixedLength = null;
final Boolean interestRecognitionOnDisbursementDate = false;
var config = new LoanRepaymentScheduleModelData(startDate, currency, disbursedAmount, disbursementDate, noRepayments, repaymentFrequency, repaymentFrequencyType, annualNominalInterestRate, isDownPaymentEnabled, daysInMonthType, daysInYearType, downPaymentPercentage, installmentAmountInMultiplesOf, fixedLength);
var config = new LoanRepaymentScheduleModelData(startDate, currency, disbursedAmount, disbursementDate, noRepayments, repaymentFrequency, repaymentFrequencyType, annualNominalInterestRate, isDownPaymentEnabled, daysInMonthType, daysInYearType, downPaymentPercentage, installmentAmountInMultiplesOf, fixedLength, interestRecognitionOnDisbursementDate);
final LoanSchedulePlan plan = calculator.generate(mc, config);
printPlan(plan);
@@ -54,10 +54,11 @@ class EmbeddableProgressiveLoanScheduleGeneratorTest {
final DaysInYearType daysInYearType = DaysInYearType.DAYS_360;
final Integer installmentAmountInMultiplesOf = null;
final Integer fixedLength = null;
final Boolean interestRecognitionOnDisbursementDate = false;
var config = new LoanRepaymentScheduleModelData(startDate, currency, disbursedAmount, disbursementDate, noRepayments,
repaymentFrequency, repaymentFrequencyType, annualNominalInterestRate, isDownPaymentEnabled, daysInMonthType,
daysInYearType, downPaymentPercentage, installmentAmountInMultiplesOf, fixedLength);
daysInYearType, downPaymentPercentage, installmentAmountInMultiplesOf, fixedLength, interestRecognitionOnDisbursementDate);
final LoanSchedulePlan plan = calculator.generate(mc, config);
@@ -511,7 +511,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
// TODO review: (repayment frequency: days, weeks, years; validation day is month fix 30)
// TODO refactor this logic to represent in interest period
if (partialPeriodCalculationNeeded) {
final BigDecimal cumulatedPeriodFractions = calculatePeriodFractions(interestPeriodFromDate, interestPeriodDueDate, mc);
final BigDecimal cumulatedPeriodFractions = calculatePeriodFractions(scheduleModel, interestPeriodFromDate,
interestPeriodDueDate, mc);
return rateFactorByRepaymentPartialPeriod(interestRate, BigDecimal.ONE, cumulatedPeriodFractions, BigDecimal.ONE,
BigDecimal.ONE, mc);
}
@@ -623,7 +624,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
// TODO review: (repayment frequency: days, weeks, years; validation day is month fix 30)
// TODO refactor this logic to represent in interest period
if (partialPeriodCalculationNeeded) {
final BigDecimal cumulatedPeriodFractions = calculatePeriodFractions(interestPeriodFromDate, interestPeriodDueDate, mc);
final BigDecimal cumulatedPeriodFractions = calculatePeriodFractions(scheduleModel, interestPeriodFromDate,
interestPeriodDueDate, mc);
return rateFactorByRepaymentPartialPeriod(interestRate, BigDecimal.ONE, cumulatedPeriodFractions, BigDecimal.ONE,
BigDecimal.ONE, mc);
}
@@ -640,29 +642,47 @@ public final class ProgressiveEMICalculator implements EMICalculator {
/**
* Calculate Period fractions part based on how much year has in the period
*
* @param scheduleModel
* @param interestPeriodFromDate
* @param interestPeriodDueDate
* @return
*/
private BigDecimal calculatePeriodFractions(final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate,
MathContext mc) {
public BigDecimal calculatePeriodFractions(ProgressiveLoanInterestScheduleModel scheduleModel, final LocalDate interestPeriodFromDate,
final LocalDate interestPeriodDueDate, MathContext mc) {
BigDecimal cumulatedRateFactor = BigDecimal.ZERO;
int actualYear = interestPeriodFromDate.getYear();
int endYear = interestPeriodDueDate.getYear();
LocalDate actualDate = interestPeriodFromDate;
LocalDate endOfActualYear;
LocalDate fractionPeriodDueDate;
while (actualYear <= endYear) {
endOfActualYear = actualYear == endYear ? interestPeriodDueDate : LocalDate.of(actualYear, 12, 31);
fractionPeriodDueDate = actualYear == endYear ? interestPeriodDueDate
: getFractionPeriodDueDateForEndOfYear(scheduleModel, actualYear);
BigDecimal numberOfDaysInYear = BigDecimal.valueOf(Year.of(actualYear).length());
BigDecimal calculatedDaysInActualYear = BigDecimal.valueOf(DateUtils.getDifferenceInDays(actualDate, endOfActualYear));
BigDecimal calculatedDaysInActualYear = BigDecimal.valueOf(DateUtils.getDifferenceInDays(actualDate, fractionPeriodDueDate));
cumulatedRateFactor = cumulatedRateFactor.add(calculatedDaysInActualYear.divide(numberOfDaysInYear, mc), mc);
actualDate = endOfActualYear;
actualDate = fractionPeriodDueDate;
actualYear++;
}
return cumulatedRateFactor;
}
/**
* Determines the last date of the year for interest calculation depending on the
* isInterestRecognitionOnDisbursementDate flag.
*
* @param scheduleModel
* @param year
* @return
*/
private LocalDate getFractionPeriodDueDateForEndOfYear(ProgressiveLoanInterestScheduleModel scheduleModel, int year) {
if (scheduleModel.loanProductRelatedDetail().isInterestRecognitionOnDisbursementDate()) {
return LocalDate.of(year + 1, 1, 1);
} else {
return LocalDate.of(year, 12, 31);
}
}
/**
* Calculate Rate Factor based on Repayment Frequency Type
*
@@ -54,7 +54,7 @@ class LoanScheduleGeneratorTest {
void testGenerateLoanSchedule() {
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);
NOMINAL_INTEREST_RATE, false, DaysInMonthType.DAYS_30, DaysInYearType.DAYS_360, null, null, null, false);
ScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
ProgressiveLoanScheduleGenerator generator = new ProgressiveLoanScheduleGenerator(scheduledDateGenerator, emiCalculator);
@@ -89,7 +89,7 @@ class LoanScheduleGeneratorTest {
void testGenerateLoanScheduleWithDownPayment() {
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);
NOMINAL_INTEREST_RATE, true, DaysInMonthType.DAYS_30, DaysInYearType.DAYS_360, DOWN_PAYMENT_PORTION, null, null, false);
ScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
ProgressiveLoanScheduleGenerator generator = new ProgressiveLoanScheduleGenerator(scheduledDateGenerator, emiCalculator);
@@ -208,6 +208,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -252,6 +253,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -288,6 +290,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -324,6 +327,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -370,6 +374,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 14));
@@ -412,6 +417,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 14));
@@ -459,6 +465,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 14));
@@ -505,6 +512,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 14));
@@ -551,6 +559,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 15));
@@ -658,6 +667,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 15));
@@ -729,6 +739,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 15));
@@ -808,6 +819,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -857,6 +869,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -906,6 +919,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -952,6 +966,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -988,6 +1003,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1030,6 +1046,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1063,6 +1080,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.WEEKS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1096,6 +1114,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.WEEKS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(2);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1129,6 +1148,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.DAYS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(15);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1171,6 +1191,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1219,6 +1240,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestModel = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1348,6 +1370,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestModel = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1421,6 +1444,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1459,6 +1483,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1497,6 +1522,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
@@ -1536,6 +1562,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
@@ -1575,6 +1602,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
@@ -1614,6 +1642,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
@@ -1653,6 +1682,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
@@ -1695,6 +1725,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
@@ -1740,6 +1771,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
@@ -1781,6 +1813,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
@@ -1819,6 +1852,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariationsData = List.of(//
new LoanTermVariationsData(1L, LoanTermVariationType.DUE_DATE.getValue(), //
LocalDate.of(2024, 2, 1), null, //
@@ -1858,6 +1892,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariationsData = List.of(//
new LoanTermVariationsData(1L, LoanTermVariationType.DUE_DATE.getValue(), //
LocalDate.of(2024, 2, 1), null, //
@@ -1900,6 +1935,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
List<LoanTermVariationsData> loanTermVariationsData = List.of(//
new LoanTermVariationsData(1L, LoanTermVariationType.DUE_DATE.getValue(), //
LocalDate.of(2024, 3, 1), null, //
@@ -1940,6 +1976,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -1989,6 +2026,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -2033,6 +2071,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -2082,6 +2121,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -2119,6 +2159,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -2156,6 +2197,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(2);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -2193,6 +2235,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -2230,6 +2273,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -2267,6 +2311,7 @@ class ProgressiveEMICalculatorTest {
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generatePeriodInterestScheduleModel(
expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), installmentAmountInMultiplesOf, mc);
@@ -2284,6 +2329,72 @@ class ProgressiveEMICalculatorTest {
checkPeriod(interestSchedule, 5, 867.65, 10.03, 857.62, 0.00, false);
}
@Test
public void test_actual_actual_fraction_period_calculation_with_interestRecognitionFromDisbursementDate_false() {
MathContext mc = new MathContext(12, RoundingMode.HALF_UP);
final List<LoanScheduleModelRepaymentPeriod> expectedRepaymentPeriods = List.of(
repayment(1, LocalDate.of(2023, 11, 13), LocalDate.of(2023, 12, 13)),
repayment(2, LocalDate.of(2023, 12, 13), LocalDate.of(2024, 1, 13)),
repayment(3, LocalDate.of(2024, 1, 13), LocalDate.of(2024, 2, 13)),
repayment(4, LocalDate.of(2024, 2, 13), LocalDate.of(2024, 3, 13)),
repayment(5, LocalDate.of(2024, 3, 13), LocalDate.of(2024, 4, 13)),
repayment(6, LocalDate.of(2024, 4, 13), LocalDate.of(2024, 5, 13)));
final BigDecimal interestRate = BigDecimal.valueOf(9.99);
Mockito.when(loanProductRelatedDetail.getAnnualNominalInterestRate()).thenReturn(interestRate);
Mockito.when(loanProductRelatedDetail.getDaysInYearType()).thenReturn(DaysInYearType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(false);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator
.generatePeriodInterestScheduleModel(expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), null, mc);
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2023, 11, 13), Money.of(currency, BigDecimal.valueOf(5000), mc));
checkPeriod(interestSchedule, 0, 857.71, 41.05, 816.66, 4183.34, false);
checkPeriod(interestSchedule, 1, 857.71, 35.45, 822.26, 3361.08, false);
checkPeriod(interestSchedule, 2, 857.71, 28.44, 829.27, 2531.81, false);
checkPeriod(interestSchedule, 3, 857.71, 20.04, 837.67, 1694.14, false);
checkPeriod(interestSchedule, 4, 857.71, 14.33, 843.38, 850.76, false);
checkPeriod(interestSchedule, 5, 857.73, 6.97, 850.76, 0.00, false);
}
@Test
public void test_actual_actual_fraction_period_calculation_with_interestRecognitionFromDisbursementDate_true() {
MathContext mc = new MathContext(12, RoundingMode.HALF_UP);
final List<LoanScheduleModelRepaymentPeriod> expectedRepaymentPeriods = List.of(
repayment(1, LocalDate.of(2023, 11, 13), LocalDate.of(2023, 12, 13)),
repayment(2, LocalDate.of(2023, 12, 13), LocalDate.of(2024, 1, 13)),
repayment(3, LocalDate.of(2024, 1, 13), LocalDate.of(2024, 2, 13)),
repayment(4, LocalDate.of(2024, 2, 13), LocalDate.of(2024, 3, 13)),
repayment(5, LocalDate.of(2024, 3, 13), LocalDate.of(2024, 4, 13)),
repayment(6, LocalDate.of(2024, 4, 13), LocalDate.of(2024, 5, 13)));
final BigDecimal interestRate = BigDecimal.valueOf(9.99);
Mockito.when(loanProductRelatedDetail.getAnnualNominalInterestRate()).thenReturn(interestRate);
Mockito.when(loanProductRelatedDetail.getDaysInYearType()).thenReturn(DaysInYearType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.ACTUAL.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrencyData()).thenReturn(currency);
Mockito.when(loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate()).thenReturn(true);
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator
.generatePeriodInterestScheduleModel(expectedRepaymentPeriods, loanProductRelatedDetail, List.of(), null, mc);
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2023, 11, 13), Money.of(currency, BigDecimal.valueOf(5000), mc));
checkPeriod(interestSchedule, 0, 857.72, 41.05, 816.67, 4183.33, false);
checkPeriod(interestSchedule, 1, 857.72, 35.46, 822.26, 3361.07, false);
checkPeriod(interestSchedule, 2, 857.72, 28.44, 829.28, 2531.79, false);
checkPeriod(interestSchedule, 3, 857.72, 20.04, 837.68, 1694.11, false);
checkPeriod(interestSchedule, 4, 857.72, 14.33, 843.39, 850.72, false);
checkPeriod(interestSchedule, 5, 857.69, 6.97, 850.72, 0.00, false);
}
@Nested
class ChargeBackPrincipalAmt100DayInYears360DaysInMonth30RepayEvery1MonthTests {