calculate total interest based on etered loan term.
This commit is contained in:
@@ -147,10 +147,8 @@ public class LoansApiResource {
|
|||||||
SubmitLoanApplicationCommand command = this.apiDataConversionService
|
SubmitLoanApplicationCommand command = this.apiDataConversionService
|
||||||
.convertJsonToSubmitLoanApplicationCommand(jsonRequestBody);
|
.convertJsonToSubmitLoanApplicationCommand(jsonRequestBody);
|
||||||
|
|
||||||
CalculateLoanScheduleCommand calculateLoanScheduleCommand = command
|
CalculateLoanScheduleCommand calculateLoanScheduleCommand = command.toCalculateLoanScheduleCommand();
|
||||||
.toCalculateLoanScheduleCommand();
|
LoanSchedule loanSchedule = this.calculationPlatformService.calculateLoanSchedule(calculateLoanScheduleCommand);
|
||||||
LoanSchedule loanSchedule = this.calculationPlatformService
|
|
||||||
.calculateLoanSchedule(calculateLoanScheduleCommand);
|
|
||||||
|
|
||||||
// for now just auto generating the loan schedule and setting support
|
// for now just auto generating the loan schedule and setting support
|
||||||
// for 'manual' loan schedule creation later.
|
// for 'manual' loan schedule creation later.
|
||||||
@@ -160,8 +158,7 @@ public class LoansApiResource {
|
|||||||
return Response.ok().entity(loanSchedule).build();
|
return Response.ok().entity(loanSchedule).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityIdentifier identifier = this.loanWritePlatformService
|
EntityIdentifier identifier = this.loanWritePlatformService.submitLoanApplication(command);
|
||||||
.submitLoanApplication(command);
|
|
||||||
|
|
||||||
return Response.ok().entity(identifier).build();
|
return Response.ok().entity(identifier).build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,8 +186,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
LocalDate interestChargedFromDate,
|
LocalDate interestChargedFromDate,
|
||||||
LoanLifecycleStateMachine lifecycleStateMachine) {
|
LoanLifecycleStateMachine lifecycleStateMachine) {
|
||||||
|
|
||||||
this.loanStatus = lifecycleStateMachine.transition(
|
this.loanStatus = lifecycleStateMachine.transition(LoanEvent.LOAN_CREATED, this.loanStatus);
|
||||||
LoanEvent.LOAN_CREATED, this.loanStatus);
|
|
||||||
|
|
||||||
this.submittedOnDate = submittedOn.toDateTimeAtCurrentTime().toDate();
|
this.submittedOnDate = submittedOn.toDateTimeAtCurrentTime().toDate();
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -67,9 +67,14 @@ public class CalculationPlatformServiceImpl implements
|
|||||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyType());
|
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyType());
|
||||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestType());
|
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestType());
|
||||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodType());
|
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodType());
|
||||||
|
|
||||||
|
final Integer loanTermFrequency = command.getLoanTermFrequency();
|
||||||
|
final PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.fromInt(command.getLoanTermFrequencyType());
|
||||||
|
|
||||||
|
final Integer defaultNumberOfInstallments = command.getNumberOfRepayments();
|
||||||
final Integer repayEvery = command.getRepaymentEvery();
|
final Integer repayEvery = command.getRepaymentEvery();
|
||||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequencyType());
|
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequencyType());
|
||||||
final Integer defaultNumberOfInstallments = command.getNumberOfRepayments();
|
|
||||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationType());
|
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationType());
|
||||||
|
|
||||||
final BigDecimal defaultAnnualNominalInterestRate = this.aprCalculator.calculateFrom(interestPeriodFrequencyType, defaultNominalInterestRatePerPeriod);
|
final BigDecimal defaultAnnualNominalInterestRate = this.aprCalculator.calculateFrom(interestPeriodFrequencyType, defaultNominalInterestRatePerPeriod);
|
||||||
@@ -96,7 +101,7 @@ public class CalculationPlatformServiceImpl implements
|
|||||||
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(), currency.getDigitsAfterDecimal(),
|
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(), currency.getDigitsAfterDecimal(),
|
||||||
applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
||||||
|
|
||||||
return loanScheduleGenerator.generate(loanScheduleInfo, command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate(),
|
return loanScheduleGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType, command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate(),
|
||||||
command.getInterestChargedFromDate(), currencyData);
|
command.getInterestChargedFromDate(), currencyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
@@ -14,6 +14,7 @@ import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
|||||||
import org.mifosng.platform.currency.domain.Money;
|
import org.mifosng.platform.currency.domain.Money;
|
||||||
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
||||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||||
|
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||||
|
|
||||||
public class DecliningBalanceMethodLoanScheduleGenerator implements
|
public class DecliningBalanceMethodLoanScheduleGenerator implements
|
||||||
LoanScheduleGenerator {
|
LoanScheduleGenerator {
|
||||||
@@ -26,6 +27,8 @@ public class DecliningBalanceMethodLoanScheduleGenerator implements
|
|||||||
@Override
|
@Override
|
||||||
public LoanSchedule generate(
|
public LoanSchedule generate(
|
||||||
final LoanProductRelatedDetail loanScheduleInfo,
|
final LoanProductRelatedDetail loanScheduleInfo,
|
||||||
|
final Integer loanTermFrequency,
|
||||||
|
final PeriodFrequencyType loanTermFrequencyType,
|
||||||
final LocalDate disbursementDate,
|
final LocalDate disbursementDate,
|
||||||
final LocalDate firstRepaymentDate,
|
final LocalDate firstRepaymentDate,
|
||||||
final LocalDate interestCalculatedFrom, CurrencyData currencyData) {
|
final LocalDate interestCalculatedFrom, CurrencyData currencyData) {
|
||||||
@@ -43,6 +46,10 @@ public class DecliningBalanceMethodLoanScheduleGenerator implements
|
|||||||
final Money totalDuePerInstallment = this.pmtCalculator.calculatePaymentForOnePeriodFrom(loanScheduleInfo, periodInterestRateForRepaymentPeriod, monetaryCurrency);
|
final Money totalDuePerInstallment = this.pmtCalculator.calculatePaymentForOnePeriodFrom(loanScheduleInfo, periodInterestRateForRepaymentPeriod, monetaryCurrency);
|
||||||
final Money totalDue = this.pmtCalculator.calculateTotalRepaymentFrom(loanScheduleInfo, periodInterestRateForRepaymentPeriod, monetaryCurrency);
|
final Money totalDue = this.pmtCalculator.calculateTotalRepaymentFrom(loanScheduleInfo, periodInterestRateForRepaymentPeriod, monetaryCurrency);
|
||||||
|
|
||||||
|
// REVIEW. calculate total interest due based on loan term settings
|
||||||
|
final BigDecimal periodInterestRateForLoanTermPeriod = this.periodicInterestRateCalculator.calculateFrom(loanTermFrequencyType, loanScheduleInfo.getAnnualNominalInterestRate());
|
||||||
|
final Money totalRepaymentDueForLoanTerm = this.pmtCalculator.calculateTotalRepaymentFrom(loanScheduleInfo.getPrincipal(), loanTermFrequency, periodInterestRateForLoanTermPeriod, monetaryCurrency);
|
||||||
|
|
||||||
Money totalInterestDue = totalDue.minus(loanScheduleInfo.getPrincipal());
|
Money totalInterestDue = totalDue.minus(loanScheduleInfo.getPrincipal());
|
||||||
Money outstandingBalance = loanScheduleInfo.getPrincipal();
|
Money outstandingBalance = loanScheduleInfo.getPrincipal();
|
||||||
Money totalPrincipal = Money.zero(monetaryCurrency);
|
Money totalPrincipal = Money.zero(monetaryCurrency);
|
||||||
|
|||||||
+32
-12
@@ -13,6 +13,7 @@ import org.mifosng.platform.api.data.MoneyData;
|
|||||||
import org.mifosng.platform.api.data.ScheduledLoanInstallment;
|
import org.mifosng.platform.api.data.ScheduledLoanInstallment;
|
||||||
import org.mifosng.platform.currency.domain.Money;
|
import org.mifosng.platform.currency.domain.Money;
|
||||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||||
|
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||||
|
|
||||||
public class FlatLoanScheduleGenerator implements LoanScheduleGenerator {
|
public class FlatLoanScheduleGenerator implements LoanScheduleGenerator {
|
||||||
|
|
||||||
@@ -22,6 +23,8 @@ public class FlatLoanScheduleGenerator implements LoanScheduleGenerator {
|
|||||||
@Override
|
@Override
|
||||||
public LoanSchedule generate(
|
public LoanSchedule generate(
|
||||||
final LoanProductRelatedDetail loanScheduleInfo,
|
final LoanProductRelatedDetail loanScheduleInfo,
|
||||||
|
final Integer loanTermFrequency,
|
||||||
|
final PeriodFrequencyType loanTermFrequencyType,
|
||||||
final LocalDate disbursementDate, final LocalDate firstRepaymentDate,
|
final LocalDate disbursementDate, final LocalDate firstRepaymentDate,
|
||||||
final LocalDate interestCalculatedFrom, final CurrencyData currencyData) {
|
final LocalDate interestCalculatedFrom, final CurrencyData currencyData) {
|
||||||
|
|
||||||
@@ -31,40 +34,57 @@ public class FlatLoanScheduleGenerator implements LoanScheduleGenerator {
|
|||||||
|
|
||||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
// FIXME - use the expected loan term to work out interest due
|
BigDecimal loanTermPeriodsInYear = BigDecimal.valueOf(this.paymentPeriodsInOneYearCalculator.calculate(loanTermFrequencyType));
|
||||||
// loan term = 9 months
|
BigDecimal interestRateForLoanTerm = loanScheduleInfo
|
||||||
|
.getAnnualNominalInterestRate()
|
||||||
|
.divide(loanTermPeriodsInYear, mc)
|
||||||
|
.divide(BigDecimal.valueOf(Double.valueOf("100.0")), mc)
|
||||||
|
.multiply(BigDecimal.valueOf(loanTermFrequency));
|
||||||
|
|
||||||
|
Money totalInterestForLoanTerm = loanScheduleInfo.getPrincipal().multiplyRetainScale(interestRateForLoanTerm, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
Money interestPerInstallment = totalInterestForLoanTerm.dividedBy(Long.valueOf(loanScheduleInfo.getNumberOfRepayments()), RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
Money principalPerInstallment = loanScheduleInfo.getPrincipal()
|
Money principalPerInstallment = loanScheduleInfo.getPrincipal()
|
||||||
.dividedBy(loanScheduleInfo.getNumberOfRepayments(),
|
.dividedBy(loanScheduleInfo.getNumberOfRepayments(),
|
||||||
RoundingMode.HALF_EVEN);
|
RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
BigDecimal paymentPeriodsInYear = BigDecimal
|
// BigDecimal paymentPeriodsInYear = BigDecimal
|
||||||
.valueOf(this.paymentPeriodsInOneYearCalculator
|
// .valueOf(this.paymentPeriodsInOneYearCalculator
|
||||||
.calculate(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
// .calculate(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||||
|
|
||||||
BigDecimal periodicInterestRate = loanScheduleInfo
|
// BigDecimal periodicInterestRate = loanScheduleInfo
|
||||||
.getAnnualNominalInterestRate()
|
// .getAnnualNominalInterestRate()
|
||||||
.divide(paymentPeriodsInYear, mc)
|
// .divide(paymentPeriodsInYear, mc)
|
||||||
.divide(BigDecimal.valueOf(Double.valueOf("100.0")), mc)
|
// .divide(BigDecimal.valueOf(Double.valueOf("100.0")), mc)
|
||||||
.multiply(BigDecimal.valueOf(loanScheduleInfo.getRepayEvery()));
|
// .multiply(BigDecimal.valueOf(loanScheduleInfo.getRepayEvery()));
|
||||||
|
|
||||||
Money interestPerInstallment = loanScheduleInfo.getPrincipal().multiplyRetainScale(periodicInterestRate, RoundingMode.HALF_EVEN);
|
// Money interestPerInstallment = loanScheduleInfo.getPrincipal().multiplyRetainScale(periodicInterestRate, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
Money outstandingBalance = loanScheduleInfo.getPrincipal();
|
Money outstandingBalance = loanScheduleInfo.getPrincipal();
|
||||||
Money totalPrincipal = Money.zero(outstandingBalance.getCurrency());
|
Money totalPrincipal = Money.zero(outstandingBalance.getCurrency());
|
||||||
|
Money totalInterest = Money.zero(outstandingBalance.getCurrency());
|
||||||
|
|
||||||
LocalDate startDate = disbursementDate;
|
LocalDate startDate = disbursementDate;
|
||||||
int installmentNumber = 1;
|
int installmentNumber = 1;
|
||||||
for (LocalDate scheduledDueDate : scheduledDates) {
|
for (LocalDate scheduledDueDate : scheduledDates) {
|
||||||
totalPrincipal = totalPrincipal.plus(principalPerInstallment);
|
totalPrincipal = totalPrincipal.plus(principalPerInstallment);
|
||||||
|
totalInterest = totalInterest.plus(interestPerInstallment);
|
||||||
|
|
||||||
if (installmentNumber == loanScheduleInfo.getNumberOfRepayments()) {
|
if (installmentNumber == loanScheduleInfo.getNumberOfRepayments()) {
|
||||||
Money difference = totalPrincipal.minus(loanScheduleInfo.getPrincipal());
|
final Money difference = totalPrincipal.minus(loanScheduleInfo.getPrincipal());
|
||||||
if (difference.isLessThanZero()) {
|
if (difference.isLessThanZero()) {
|
||||||
principalPerInstallment = principalPerInstallment.plus(difference.abs());
|
principalPerInstallment = principalPerInstallment.plus(difference.abs());
|
||||||
} else if (difference.isGreaterThanZero()) {
|
} else if (difference.isGreaterThanZero()) {
|
||||||
principalPerInstallment = principalPerInstallment.minus(difference.abs());
|
principalPerInstallment = principalPerInstallment.minus(difference.abs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Money interestDifference = totalInterest.minus(totalInterestForLoanTerm);
|
||||||
|
if (interestDifference.isLessThanZero()) {
|
||||||
|
interestPerInstallment = interestPerInstallment.plus(interestDifference.abs());
|
||||||
|
} else if (interestDifference.isGreaterThanZero()) {
|
||||||
|
interestPerInstallment = interestPerInstallment.minus(interestDifference.abs());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Money totalInstallmentDue = principalPerInstallment.plus(interestPerInstallment);
|
Money totalInstallmentDue = principalPerInstallment.plus(interestPerInstallment);
|
||||||
|
|||||||
+3
@@ -4,10 +4,13 @@ import org.joda.time.LocalDate;
|
|||||||
import org.mifosng.platform.api.data.CurrencyData;
|
import org.mifosng.platform.api.data.CurrencyData;
|
||||||
import org.mifosng.platform.api.data.LoanSchedule;
|
import org.mifosng.platform.api.data.LoanSchedule;
|
||||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||||
|
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||||
|
|
||||||
public interface LoanScheduleGenerator {
|
public interface LoanScheduleGenerator {
|
||||||
|
|
||||||
LoanSchedule generate(LoanProductRelatedDetail loanScheduleInfo,
|
LoanSchedule generate(LoanProductRelatedDetail loanScheduleInfo,
|
||||||
|
Integer loanTermFrequency,
|
||||||
|
PeriodFrequencyType loanTermFrequencyType,
|
||||||
LocalDate disbursementDate, LocalDate firstRepaymentDate, LocalDate interestCalculatedFrom,
|
LocalDate disbursementDate, LocalDate firstRepaymentDate, LocalDate interestCalculatedFrom,
|
||||||
CurrencyData currencyData);
|
CurrencyData currencyData);
|
||||||
|
|
||||||
|
|||||||
+12
-1
@@ -6,12 +6,23 @@ import java.math.RoundingMode;
|
|||||||
|
|
||||||
import org.mifosng.platform.currency.domain.Money;
|
import org.mifosng.platform.currency.domain.Money;
|
||||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||||
|
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||||
|
|
||||||
public class PeriodicInterestRateCalculator {
|
public class PeriodicInterestRateCalculator {
|
||||||
|
|
||||||
private final PaymentPeriodsInOneYearCalculator paymentPeriodsInOneYearCalculator = new DefaultPaymentPeriodsInOneYearCalculator();
|
private final PaymentPeriodsInOneYearCalculator paymentPeriodsInOneYearCalculator = new DefaultPaymentPeriodsInOneYearCalculator();
|
||||||
|
|
||||||
public BigDecimal calculateFrom(LoanProductRelatedDetail loanScheduleInfo) {
|
public BigDecimal calculateFrom(final PeriodFrequencyType loanTermFrequencyType, final BigDecimal annualNominalInterestRate) {
|
||||||
|
|
||||||
|
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
Integer paymentPeriodsInOneYear = this.paymentPeriodsInOneYearCalculator.calculate(loanTermFrequencyType);
|
||||||
|
|
||||||
|
BigDecimal divisor = BigDecimal.valueOf(paymentPeriodsInOneYear * 100);
|
||||||
|
return annualNominalInterestRate.divide(divisor, mc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal calculateFrom(final LoanProductRelatedDetail loanScheduleInfo) {
|
||||||
|
|
||||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
|||||||
+27
-2
@@ -8,7 +8,9 @@ import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
|||||||
|
|
||||||
public class PmtCalculator {
|
public class PmtCalculator {
|
||||||
|
|
||||||
public Money calculatePaymentForOnePeriodFrom(LoanProductRelatedDetail loanScheduleInfo, BigDecimal periodInterestRateForRepaymentPeriod, MonetaryCurrency monetaryCurrency) {
|
public Money calculatePaymentForOnePeriodFrom(final LoanProductRelatedDetail loanScheduleInfo,
|
||||||
|
final BigDecimal periodInterestRateForRepaymentPeriod,
|
||||||
|
final MonetaryCurrency monetaryCurrency) {
|
||||||
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
||||||
|
|
||||||
double futureValue = 0;
|
double futureValue = 0;
|
||||||
@@ -22,7 +24,9 @@ public class PmtCalculator {
|
|||||||
return Money.of(monetaryCurrency, BigDecimal.valueOf(paymentPerInstallment));
|
return Money.of(monetaryCurrency, BigDecimal.valueOf(paymentPerInstallment));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money calculateTotalRepaymentFrom(LoanProductRelatedDetail loanScheduleInfo, BigDecimal periodInterestRateForRepaymentPeriod, MonetaryCurrency monetaryCurrency) {
|
public Money calculateTotalRepaymentFrom(final LoanProductRelatedDetail loanScheduleInfo,
|
||||||
|
final BigDecimal periodInterestRateForRepaymentPeriod,
|
||||||
|
final MonetaryCurrency monetaryCurrency) {
|
||||||
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
||||||
|
|
||||||
double futureValue = 0;
|
double futureValue = 0;
|
||||||
@@ -38,6 +42,27 @@ public class PmtCalculator {
|
|||||||
return Money.of(monetaryCurrency, BigDecimal.valueOf(totalRepayment));
|
return Money.of(monetaryCurrency, BigDecimal.valueOf(totalRepayment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Money calculateTotalRepaymentFrom(
|
||||||
|
final Money principal,
|
||||||
|
final Integer loanTermFrequency,
|
||||||
|
final BigDecimal periodInterestRateForLoanTermPeriod,
|
||||||
|
final MonetaryCurrency monetaryCurrency) {
|
||||||
|
|
||||||
|
double interestRateFraction = periodInterestRateForLoanTermPeriod.doubleValue();
|
||||||
|
|
||||||
|
double futureValue = 0;
|
||||||
|
double numberOfPeriods = loanTermFrequency;
|
||||||
|
double principalAmount = principal.getAmount().multiply(BigDecimal.valueOf(-1)).doubleValue();
|
||||||
|
|
||||||
|
// work out the total payment (principal + interest components) for each installment due.
|
||||||
|
// use the period type and interest as expressed e.g. 2% per month or 24% per year even is 'daily' interest calculation is selected
|
||||||
|
double paymentPerInstallment = pmt(interestRateFraction, numberOfPeriods, principalAmount, futureValue, false);
|
||||||
|
|
||||||
|
double totalRepayment = paymentPerInstallment * loanTermFrequency;
|
||||||
|
|
||||||
|
return Money.of(monetaryCurrency, BigDecimal.valueOf(totalRepayment));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PMT calculates a fixed monthly payment to be paid by borrower every 'period' to ensure loan is paid off in full (with interest).
|
* PMT calculates a fixed monthly payment to be paid by borrower every 'period' to ensure loan is paid off in full (with interest).
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user