in service/src/main/java/org/apache/fineract/cn/individuallending/internal/service/costcomponent/CostComponentService.java [178:219]
public static BigDecimal getLoanPaymentSize(
final BigDecimal maximumBalanceSize,
final BigDecimal disbursementSize,
final BigDecimal interest,
final int minorCurrencyUnitDigits,
final List<ScheduledCharge> scheduledCharges) {
final int precision = disbursementSize.precision() - disbursementSize.scale() + minorCurrencyUnitDigits + EXTRA_PRECISION;
final Map<Period, BigDecimal> accrualRatesByPeriod
= PeriodChargeCalculator.getPeriodAccrualInterestRate(interest, scheduledCharges, precision);
final int periodCount = accrualRatesByPeriod.size();
if (periodCount == 0)
return disbursementSize;
final BigDecimal geometricMeanAccrualRate = accrualRatesByPeriod.values().stream()
.collect(RateCollectors.geometricMean(precision));
final List<ScheduledCharge> disbursementFees = scheduledCharges.stream()
.filter(x -> x.getScheduledAction().getAction().equals(Action.DISBURSE))
.collect(Collectors.toList());
final PaymentBuilder paymentBuilder = getCostComponentsForScheduledCharges(
disbursementFees,
maximumBalanceSize,
new SimulatedRunningBalances(),
BigDecimal.ZERO, //Contractual repayment not determined yet here.
disbursementSize,
BigDecimal.ZERO,
interest,
minorCurrencyUnitDigits,
false
);
final BigDecimal finalDisbursementSize = paymentBuilder.getBalanceAdjustment(
AccountDesignators.CUSTOMER_LOAN_PRINCIPAL,
AccountDesignators.CUSTOMER_LOAN_FEES).negate();
final BigDecimal presentValue = AnnuityPayment.calculate(
finalDisbursementSize,
geometricMeanAccrualRate,
periodCount,
minorCurrencyUnitDigits);
return presentValue.setScale(minorCurrencyUnitDigits, BigDecimal.ROUND_HALF_EVEN);
}