FINERACT-1981: Fix interest calculation when applies multi disbursement
This commit is contained in:
committed by
Adam Saghy
parent
6e6ac8ffd6
commit
8ab9c9ea9a
+52
-3
@@ -26,9 +26,12 @@ import java.math.MathContext;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
@@ -62,7 +65,8 @@ public class ProgressiveLoanInterestScheduleModel {
|
||||
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail, final Integer installmentAmountInMultiplesOf,
|
||||
final MathContext mc) {
|
||||
this.mc = mc;
|
||||
this.repaymentPeriods = copyRepaymentPeriods(repaymentPeriods);
|
||||
this.repaymentPeriods = copyRepaymentPeriods(repaymentPeriods,
|
||||
(previousPeriod, repaymentPeriod) -> new RepaymentPeriod(previousPeriod, repaymentPeriod, mc));
|
||||
this.interestRates = new TreeSet<>(interestRates);
|
||||
this.loanProductRelatedDetail = loanProductRelatedDetail;
|
||||
this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf;
|
||||
@@ -74,11 +78,20 @@ public class ProgressiveLoanInterestScheduleModel {
|
||||
installmentAmountInMultiplesOf, mc);
|
||||
}
|
||||
|
||||
private List<RepaymentPeriod> copyRepaymentPeriods(final List<RepaymentPeriod> repaymentPeriods) {
|
||||
public ProgressiveLoanInterestScheduleModel emptyCopy() {
|
||||
final List<RepaymentPeriod> repaymentPeriodCopies = copyRepaymentPeriods(repaymentPeriods,
|
||||
(previousPeriod, repaymentPeriod) -> new RepaymentPeriod(previousPeriod, repaymentPeriod.getFromDate(),
|
||||
repaymentPeriod.getDueDate(), repaymentPeriod.getEmi().zero(), mc));
|
||||
return new ProgressiveLoanInterestScheduleModel(repaymentPeriodCopies, interestRates, loanProductRelatedDetail,
|
||||
installmentAmountInMultiplesOf, mc);
|
||||
}
|
||||
|
||||
private List<RepaymentPeriod> copyRepaymentPeriods(final List<RepaymentPeriod> repaymentPeriods,
|
||||
final BiFunction<RepaymentPeriod, RepaymentPeriod, RepaymentPeriod> repaymentCopyFunction) {
|
||||
final List<RepaymentPeriod> repaymentCopies = new ArrayList<>(repaymentPeriods.size());
|
||||
RepaymentPeriod previousPeriod = null;
|
||||
for (RepaymentPeriod repaymentPeriod : repaymentPeriods) {
|
||||
RepaymentPeriod currentPeriod = new RepaymentPeriod(previousPeriod, repaymentPeriod, mc);
|
||||
RepaymentPeriod currentPeriod = repaymentCopyFunction.apply(previousPeriod, repaymentPeriod);
|
||||
previousPeriod = currentPeriod;
|
||||
repaymentCopies.add(currentPeriod);
|
||||
}
|
||||
@@ -229,4 +242,40 @@ public class ProgressiveLoanInterestScheduleModel {
|
||||
.filter(period -> isInPeriod(transactionDate, period.getFromDate(), period.getDueDate(), period.isFirstRepaymentPeriod()))//
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return repaymentPeriods.stream() //
|
||||
.filter(rp -> !rp.getEmi().isZero()) //
|
||||
.findFirst() //
|
||||
.isEmpty(); //
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gives you repayment pairs to copy attributes.
|
||||
*
|
||||
* @param periodFromDueDate
|
||||
* Copy from this due periods.
|
||||
* @param copyFromPeriods
|
||||
* Copy source
|
||||
* @param copyConsumer
|
||||
* Consumer to copy attributes. Params: (from, to)
|
||||
*/
|
||||
public void copyPeriodsFrom(final LocalDate periodFromDueDate, List<RepaymentPeriod> copyFromPeriods,
|
||||
BiConsumer<RepaymentPeriod, RepaymentPeriod> copyConsumer) {
|
||||
if (copyFromPeriods.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final Iterator<RepaymentPeriod> actualIterator = repaymentPeriods.iterator();
|
||||
final Iterator<RepaymentPeriod> copyFromIterator = copyFromPeriods.iterator();
|
||||
while (actualIterator.hasNext()) {
|
||||
final RepaymentPeriod copyFromPeriod = copyFromIterator.next();
|
||||
RepaymentPeriod actualPeriod = actualIterator.next();
|
||||
while (actualIterator.hasNext() && !copyFromPeriod.getDueDate().isEqual(actualPeriod.getDueDate())) {
|
||||
actualPeriod = actualIterator.next();
|
||||
}
|
||||
if (!actualPeriod.getDueDate().isBefore(periodFromDueDate)) {
|
||||
copyConsumer.accept(copyFromPeriod, actualPeriod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanproduct.calc;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class EmiChangeOperation {
|
||||
|
||||
public enum Action {
|
||||
DISBURSEMENT, INTEREST_RATE_CHANGE
|
||||
}
|
||||
|
||||
private final Action action;
|
||||
private final LocalDate submittedOnDate;
|
||||
|
||||
private final Money amount;
|
||||
private final BigDecimal interestRate;
|
||||
|
||||
public static EmiChangeOperation disburse(final LocalDate disbursementDueDate, final Money disbursedAmount) {
|
||||
return new EmiChangeOperation(EmiChangeOperation.Action.DISBURSEMENT, disbursementDueDate, disbursedAmount, null);
|
||||
}
|
||||
|
||||
public static EmiChangeOperation changeInterestRate(final LocalDate newInterestSubmittedOnDate, final BigDecimal newInterestRate) {
|
||||
return new EmiChangeOperation(EmiChangeOperation.Action.INTEREST_RATE_CHANGE, newInterestSubmittedOnDate, null, newInterestRate);
|
||||
}
|
||||
}
|
||||
+66
-29
@@ -102,9 +102,16 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
@Override
|
||||
public void addDisbursement(final ProgressiveLoanInterestScheduleModel scheduleModel, final LocalDate disbursementDueDate,
|
||||
final Money disbursedAmount) {
|
||||
scheduleModel.changeOutstandingBalanceAndUpdateInterestPeriods(disbursementDueDate, disbursedAmount, scheduleModel.zero())
|
||||
addDisbursement(scheduleModel, EmiChangeOperation.disburse(disbursementDueDate, disbursedAmount));
|
||||
}
|
||||
|
||||
private void addDisbursement(final ProgressiveLoanInterestScheduleModel scheduleModel, final EmiChangeOperation operation) {
|
||||
scheduleModel
|
||||
.changeOutstandingBalanceAndUpdateInterestPeriods(operation.getSubmittedOnDate(), operation.getAmount(),
|
||||
scheduleModel.zero())
|
||||
.ifPresent((repaymentPeriod) -> calculateEMIValueAndRateFactors(
|
||||
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, disbursementDueDate), scheduleModel));
|
||||
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, operation.getSubmittedOnDate()), scheduleModel,
|
||||
operation));
|
||||
}
|
||||
|
||||
private LocalDate getEffectiveRepaymentDueDate(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||
@@ -125,13 +132,18 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
@Override
|
||||
public void changeInterestRate(final ProgressiveLoanInterestScheduleModel scheduleModel, final LocalDate newInterestSubmittedOnDate,
|
||||
final BigDecimal newInterestRate) {
|
||||
final LocalDate interestRateChangeEffectiveDate = newInterestSubmittedOnDate.minusDays(1);
|
||||
scheduleModel.addInterestRate(interestRateChangeEffectiveDate, newInterestRate);
|
||||
changeInterestRate(scheduleModel, EmiChangeOperation.changeInterestRate(newInterestSubmittedOnDate, newInterestRate));
|
||||
}
|
||||
|
||||
private void changeInterestRate(final ProgressiveLoanInterestScheduleModel scheduleModel, final EmiChangeOperation operation) {
|
||||
final LocalDate interestRateChangeEffectiveDate = operation.getSubmittedOnDate().minusDays(1);
|
||||
scheduleModel.addInterestRate(interestRateChangeEffectiveDate, operation.getInterestRate());
|
||||
scheduleModel
|
||||
.changeOutstandingBalanceAndUpdateInterestPeriods(interestRateChangeEffectiveDate, scheduleModel.zero(),
|
||||
scheduleModel.zero())
|
||||
.ifPresent(repaymentPeriod -> calculateEMIValueAndRateFactors(
|
||||
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, interestRateChangeEffectiveDate), scheduleModel));
|
||||
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, interestRateChangeEffectiveDate), scheduleModel,
|
||||
operation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,15 +295,24 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
/**
|
||||
* Calculate Equal Monthly Installment value and Rate Factor -1 values for calculate Interest
|
||||
*/
|
||||
void calculateEMIValueAndRateFactors(final LocalDate calculateFromRepaymentPeriodDueDate,
|
||||
final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||
private void calculateEMIValueAndRateFactors(final LocalDate calculateFromRepaymentPeriodDueDate,
|
||||
final ProgressiveLoanInterestScheduleModel scheduleModel, final EmiChangeOperation operation) {
|
||||
final List<RepaymentPeriod> relatedRepaymentPeriods = scheduleModel.getRelatedRepaymentPeriods(calculateFromRepaymentPeriodDueDate);
|
||||
final boolean onlyOnActualModelShouldApply = scheduleModel.isEmpty()
|
||||
|| operation.getAction() == EmiChangeOperation.Action.INTEREST_RATE_CHANGE;
|
||||
|
||||
calculateRateFactorForPeriods(relatedRepaymentPeriods, scheduleModel);
|
||||
calculateOutstandingBalance(scheduleModel);
|
||||
calculateEMIOnPeriods(relatedRepaymentPeriods, scheduleModel);
|
||||
if (onlyOnActualModelShouldApply) {
|
||||
calculateEMIOnActualModel(relatedRepaymentPeriods, scheduleModel);
|
||||
} else {
|
||||
calculateEMIOnNewEmptyModelAndMerge(relatedRepaymentPeriods, scheduleModel, operation);
|
||||
}
|
||||
calculateOutstandingBalance(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||
checkAndAdjustEmiIfNeededOnRelatedRepaymentPeriods(scheduleModel, relatedRepaymentPeriods);
|
||||
if (onlyOnActualModelShouldApply) {
|
||||
checkAndAdjustEmiIfNeededOnRelatedRepaymentPeriods(scheduleModel, relatedRepaymentPeriods);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateLastUnpaidRepaymentPeriodEMI(ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||
@@ -378,19 +399,19 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
*
|
||||
* @return Rate Interest Rate in fraction format
|
||||
*/
|
||||
BigDecimal calcNominalInterestRatePercentage(final BigDecimal interestRate, MathContext mc) {
|
||||
private BigDecimal calcNominalInterestRatePercentage(final BigDecimal interestRate, MathContext mc) {
|
||||
return MathUtil.nullToZero(interestRate).divide(DIVISOR_100, mc);
|
||||
}
|
||||
|
||||
/**
|
||||
* * Calculate rate factors from ONLY repayment periods
|
||||
*/
|
||||
void calculateRateFactorForPeriods(final List<RepaymentPeriod> repaymentPeriods,
|
||||
private void calculateRateFactorForPeriods(final List<RepaymentPeriod> repaymentPeriods,
|
||||
final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||
repaymentPeriods.forEach(repaymentPeriod -> calculateRateFactorForRepaymentPeriod(repaymentPeriod, scheduleModel));
|
||||
}
|
||||
|
||||
void calculateRateFactorForRepaymentPeriod(final RepaymentPeriod repaymentPeriod,
|
||||
private void calculateRateFactorForRepaymentPeriod(final RepaymentPeriod repaymentPeriod,
|
||||
final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||
repaymentPeriod.getInterestPeriods().forEach(interestPeriod -> {
|
||||
interestPeriod.setRateFactor(calculateRateFactorPerPeriod(scheduleModel, repaymentPeriod, interestPeriod.getFromDate(),
|
||||
@@ -403,8 +424,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
/**
|
||||
* Calculate Rate Factor for an exact Period
|
||||
*/
|
||||
BigDecimal calculateRateFactorPerPeriod(final ProgressiveLoanInterestScheduleModel scheduleModel, final RepaymentPeriod repaymentPeriod,
|
||||
final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate) {
|
||||
private BigDecimal calculateRateFactorPerPeriod(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||
final RepaymentPeriod repaymentPeriod, final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate) {
|
||||
final MathContext mc = scheduleModel.mc();
|
||||
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail = scheduleModel.loanProductRelatedDetail();
|
||||
final BigDecimal interestRate = calcNominalInterestRatePercentage(scheduleModel.getInterestRate(interestPeriodFromDate),
|
||||
@@ -443,7 +464,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
* @param interestPeriodDueDate
|
||||
* @return
|
||||
*/
|
||||
BigDecimal calculatePeriodFractions(final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate, MathContext mc) {
|
||||
private BigDecimal calculatePeriodFractions(final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate,
|
||||
MathContext mc) {
|
||||
BigDecimal cumulatedRateFactor = BigDecimal.ZERO;
|
||||
int actualYear = interestPeriodFromDate.getYear();
|
||||
int endYear = interestPeriodDueDate.getYear();
|
||||
@@ -473,7 +495,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
* @param calculatedDaysInPeriod
|
||||
* @return
|
||||
*/
|
||||
BigDecimal calculateRateFactorPerPeriodBasedOnRepaymentFrequency(final BigDecimal interestRate,
|
||||
private BigDecimal calculateRateFactorPerPeriodBasedOnRepaymentFrequency(final BigDecimal interestRate,
|
||||
final PeriodFrequencyType repaymentFrequency, final BigDecimal repaymentEvery, final BigDecimal daysInMonth,
|
||||
final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod,
|
||||
final MathContext mc) {
|
||||
@@ -488,7 +510,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
};
|
||||
}
|
||||
|
||||
void calculateEMIOnPeriods(final List<RepaymentPeriod> repaymentPeriods, final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||
private void calculateEMIOnActualModel(List<RepaymentPeriod> repaymentPeriods, ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||
if (repaymentPeriods.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -496,7 +518,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
final BigDecimal rateFactorN = MathUtil.stripTrailingZeros(calculateRateFactorPlus1N(repaymentPeriods, mc));
|
||||
final BigDecimal fnResult = MathUtil.stripTrailingZeros(calculateFnResult(repaymentPeriods, mc));
|
||||
final RepaymentPeriod startPeriod = repaymentPeriods.get(0);
|
||||
// TODO: double check
|
||||
|
||||
final Money outstandingBalance = startPeriod.getInitialBalanceForEmiRecalculation();
|
||||
|
||||
final Money equalMonthlyInstallment = Money.of(outstandingBalance.getCurrencyData(),
|
||||
@@ -511,7 +533,22 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
});
|
||||
}
|
||||
|
||||
Money applyInstallmentAmountInMultiplesOf(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||
private void calculateEMIOnNewEmptyModelAndMerge(List<RepaymentPeriod> repaymentPeriods,
|
||||
ProgressiveLoanInterestScheduleModel scheduleModel, final EmiChangeOperation operation) {
|
||||
if (repaymentPeriods.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final ProgressiveLoanInterestScheduleModel scheduleModelCopy = scheduleModel.emptyCopy();
|
||||
addDisbursement(scheduleModelCopy, operation);
|
||||
|
||||
final LocalDate firstDueDate = repaymentPeriods.get(0).getDueDate();
|
||||
scheduleModel.copyPeriodsFrom(firstDueDate, scheduleModelCopy.repaymentPeriods(), (newRepaymentPeriod, actualRepaymentPeriod) -> {
|
||||
actualRepaymentPeriod.setEmi(actualRepaymentPeriod.getEmi().plus(newRepaymentPeriod.getEmi()));
|
||||
actualRepaymentPeriod.setOriginalEmi(actualRepaymentPeriod.getOriginalEmi().plus(newRepaymentPeriod.getOriginalEmi()));
|
||||
});
|
||||
}
|
||||
|
||||
private Money applyInstallmentAmountInMultiplesOf(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||
final Money equalMonthlyInstallment) {
|
||||
return scheduleModel.installmentAmountInMultiplesOf() != null
|
||||
? Money.roundToMultiplesOf(equalMonthlyInstallment, scheduleModel.installmentAmountInMultiplesOf())
|
||||
@@ -534,7 +571,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
/**
|
||||
* Calculate Rate Factor Product from rate factors
|
||||
*/
|
||||
BigDecimal calculateRateFactorPlus1N(final List<RepaymentPeriod> periods, MathContext mc) {
|
||||
private BigDecimal calculateRateFactorPlus1N(final List<RepaymentPeriod> periods, MathContext mc) {
|
||||
return periods.stream().map(RepaymentPeriod::getRateFactorPlus1).reduce(BigDecimal.ONE,
|
||||
(BigDecimal acc, BigDecimal value) -> acc.multiply(value, mc));
|
||||
}
|
||||
@@ -542,7 +579,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
/**
|
||||
* Summarize Fn values
|
||||
*/
|
||||
BigDecimal calculateFnResult(final List<RepaymentPeriod> periods, final MathContext mc) {
|
||||
private BigDecimal calculateFnResult(final List<RepaymentPeriod> periods, final MathContext mc) {
|
||||
return periods.stream()//
|
||||
.skip(1)//
|
||||
.map(RepaymentPeriod::getRateFactorPlus1)//
|
||||
@@ -552,8 +589,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
/**
|
||||
* Calculate the EMI (Equal Monthly Installment) value
|
||||
*/
|
||||
BigDecimal calculateEMIValue(final BigDecimal rateFactorPlus1N, final BigDecimal outstandingBalanceForRest, final BigDecimal fnResult,
|
||||
MathContext mc) {
|
||||
private BigDecimal calculateEMIValue(final BigDecimal rateFactorPlus1N, final BigDecimal outstandingBalanceForRest,
|
||||
final BigDecimal fnResult, MathContext mc) {
|
||||
return rateFactorPlus1N.multiply(outstandingBalanceForRest, mc).divide(fnResult, mc);
|
||||
}
|
||||
|
||||
@@ -581,8 +618,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
*
|
||||
* @return Rate Factor for period
|
||||
*/
|
||||
BigDecimal rateFactorByRepaymentEveryDay(final BigDecimal interestRate, final BigDecimal repaymentEvery, final BigDecimal daysInYear,
|
||||
final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod, MathContext mc) {
|
||||
private BigDecimal rateFactorByRepaymentEveryDay(final BigDecimal interestRate, final BigDecimal repaymentEvery,
|
||||
final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod, MathContext mc) {
|
||||
return rateFactorByRepaymentPeriod(interestRate, BigDecimal.ONE, repaymentEvery, daysInYear, actualDaysInPeriod,
|
||||
calculatedDaysInPeriod, mc);
|
||||
}
|
||||
@@ -611,8 +648,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
*
|
||||
* @return Rate Factor for period
|
||||
*/
|
||||
BigDecimal rateFactorByRepaymentEveryWeek(final BigDecimal interestRate, final BigDecimal repaymentEvery, final BigDecimal daysInYear,
|
||||
final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod, MathContext mc) {
|
||||
private BigDecimal rateFactorByRepaymentEveryWeek(final BigDecimal interestRate, final BigDecimal repaymentEvery,
|
||||
final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod, MathContext mc) {
|
||||
return rateFactorByRepaymentPeriod(interestRate, ONE_WEEK_IN_DAYS, repaymentEvery, daysInYear, actualDaysInPeriod,
|
||||
calculatedDaysInPeriod, mc);
|
||||
}
|
||||
@@ -678,7 +715,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
*
|
||||
* @return Rate Factor for period
|
||||
*/
|
||||
BigDecimal rateFactorByRepaymentPeriod(final BigDecimal interestRate, final BigDecimal repaymentPeriodMultiplierInDays,
|
||||
private BigDecimal rateFactorByRepaymentPeriod(final BigDecimal interestRate, final BigDecimal repaymentPeriodMultiplierInDays,
|
||||
final BigDecimal repaymentEvery, final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod,
|
||||
final BigDecimal calculatedDaysInPeriod, final MathContext mc) {
|
||||
if (MathUtil.isZero(calculatedDaysInPeriod)) {
|
||||
@@ -697,7 +734,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
* Calculate Rate Factor based on Partial Period
|
||||
*
|
||||
*/
|
||||
BigDecimal rateFactorByRepaymentPartialPeriod(final BigDecimal interestRate, final BigDecimal repaymentEvery,
|
||||
private BigDecimal rateFactorByRepaymentPartialPeriod(final BigDecimal interestRate, final BigDecimal repaymentEvery,
|
||||
final BigDecimal cumulatedPeriodRatio, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod,
|
||||
final MathContext mc) {
|
||||
if (MathUtil.isZero(calculatedDaysInPeriod)) {
|
||||
|
||||
Reference in New Issue
Block a user