mifosx-58: remove deprecated code and tests around it
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
package org.mifosng.platform.api.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public class LoanSchedule {
|
||||
|
||||
private List<ScheduledLoanInstallment> scheduledLoanInstallments = new ArrayList<ScheduledLoanInstallment>();
|
||||
|
||||
private static CurrencyData currencyData(MoneyData moneyData) {
|
||||
String code = moneyData.getCurrencyCode();
|
||||
String name = moneyData.getDefaultName();
|
||||
int decimalPlaces = moneyData.getDigitsAfterDecimal();
|
||||
String displaySymbol = moneyData.getDisplaySymbol();
|
||||
String nameCode = moneyData.getNameCode();
|
||||
return new CurrencyData(code, name, decimalPlaces, displaySymbol, nameCode);
|
||||
}
|
||||
|
||||
public LoanSchedule(final List<ScheduledLoanInstallment> scheduledLoanInstallments) {
|
||||
this.scheduledLoanInstallments = scheduledLoanInstallments;
|
||||
}
|
||||
|
||||
public MoneyData getCumulativePrincipal() {
|
||||
MoneyData cumulative = MoneyData.zero(currencyData(this.scheduledLoanInstallments.get(0).getPrincipalDue()));
|
||||
for (ScheduledLoanInstallment installment : this.scheduledLoanInstallments) {
|
||||
cumulative = cumulative.plus(installment.getPrincipalDue());
|
||||
}
|
||||
return cumulative;
|
||||
}
|
||||
|
||||
public MoneyData getCumulativeInterest() {
|
||||
MoneyData cumulative = MoneyData.zero(currencyData(this.scheduledLoanInstallments.get(0).getPrincipalDue()));
|
||||
for (ScheduledLoanInstallment installment : this.scheduledLoanInstallments) {
|
||||
cumulative = cumulative.plus(installment.getInterestDue());
|
||||
}
|
||||
return cumulative;
|
||||
}
|
||||
|
||||
public MoneyData getCumulativeTotal() {
|
||||
MoneyData cumulative = MoneyData.zero(currencyData(this.scheduledLoanInstallments.get(0).getPrincipalDue()));
|
||||
for (ScheduledLoanInstallment installment : this.scheduledLoanInstallments) {
|
||||
cumulative = cumulative.plus(installment.getTotalInstallmentDue());
|
||||
}
|
||||
return cumulative;
|
||||
}
|
||||
|
||||
public List<ScheduledLoanInstallment> getScheduledLoanInstallments() {
|
||||
return this.scheduledLoanInstallments;
|
||||
}
|
||||
|
||||
public void setScheduledLoanInstallments(
|
||||
final List<ScheduledLoanInstallment> scheduledLoanInstallments) {
|
||||
this.scheduledLoanInstallments = scheduledLoanInstallments;
|
||||
}
|
||||
}
|
||||
-123
@@ -1,123 +0,0 @@
|
||||
package org.mifosng.platform.api.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
@Deprecated
|
||||
public class ScheduledLoanInstallment {
|
||||
|
||||
private Integer installmentNumber;
|
||||
private LocalDate periodStart;
|
||||
private LocalDate periodEnd;
|
||||
private MoneyData principalDue;
|
||||
private MoneyData interestDue;
|
||||
private MoneyData totalInstallmentDue;
|
||||
private MoneyData outStandingBalance;
|
||||
|
||||
public ScheduledLoanInstallment() {
|
||||
//
|
||||
}
|
||||
|
||||
public ScheduledLoanInstallment(final Integer installmentNumber,
|
||||
final LocalDate periodStart, final LocalDate periodEnd,
|
||||
final MoneyData principalDue,
|
||||
final MoneyData interestDue,
|
||||
final MoneyData totalInstallmentDue,
|
||||
final MoneyData outStandingBalance) {
|
||||
this.installmentNumber = installmentNumber;
|
||||
this.periodStart = periodStart;
|
||||
this.periodEnd = periodEnd;
|
||||
this.principalDue = principalDue;
|
||||
this.interestDue = interestDue;
|
||||
this.totalInstallmentDue = totalInstallmentDue;
|
||||
this.outStandingBalance = outStandingBalance;
|
||||
}
|
||||
|
||||
public Integer getInstallmentNumber() {
|
||||
return this.installmentNumber;
|
||||
}
|
||||
|
||||
public LocalDate getPeriodStart() {
|
||||
return this.periodStart;
|
||||
}
|
||||
|
||||
public LocalDate getPeriodEnd() {
|
||||
return this.periodEnd;
|
||||
}
|
||||
|
||||
// @DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
public void setDueDate(final LocalDate dueDate) {
|
||||
this.periodEnd = dueDate;
|
||||
}
|
||||
|
||||
public void setPrincipal(final BigDecimal principal) {
|
||||
CurrencyData currencyData = currencyData(this.principalDue);
|
||||
this.principalDue = MoneyData.of(currencyData, principal);
|
||||
this.totalInstallmentDue = this.principalDue.plus(this.interestDue);
|
||||
}
|
||||
|
||||
private CurrencyData currencyData(MoneyData moneyData) {
|
||||
String code = moneyData.getCurrencyCode();
|
||||
String name = moneyData.getDefaultName();
|
||||
int decimalPlaces = moneyData.getDigitsAfterDecimal();
|
||||
String displaySymbol = moneyData.getDisplaySymbol();
|
||||
String nameCode = moneyData.getNameCode();
|
||||
return new CurrencyData(code, name, decimalPlaces, displaySymbol, nameCode);
|
||||
}
|
||||
|
||||
public void setInterest(final BigDecimal interest) {
|
||||
CurrencyData currencyData = currencyData(this.principalDue);
|
||||
this.interestDue = MoneyData.of(currencyData, interest);
|
||||
this.totalInstallmentDue = this.principalDue.plus(this.interestDue);
|
||||
}
|
||||
|
||||
public void setOutstanding(final BigDecimal outstanding) {
|
||||
CurrencyData currencyData = currencyData(this.principalDue);
|
||||
this.outStandingBalance = MoneyData.of(currencyData, outstanding);
|
||||
}
|
||||
|
||||
public MoneyData getPrincipalDue() {
|
||||
return this.principalDue;
|
||||
}
|
||||
|
||||
public void setPrincipalDue(final MoneyData principalDue) {
|
||||
this.principalDue = principalDue;
|
||||
}
|
||||
|
||||
public MoneyData getInterestDue() {
|
||||
return this.interestDue;
|
||||
}
|
||||
|
||||
public void setInterestDue(final MoneyData interestDue) {
|
||||
this.interestDue = interestDue;
|
||||
}
|
||||
|
||||
public MoneyData getTotalInstallmentDue() {
|
||||
return this.totalInstallmentDue;
|
||||
}
|
||||
|
||||
public void setTotalInstallmentDue(final MoneyData totalInstallmentDue) {
|
||||
this.totalInstallmentDue = totalInstallmentDue;
|
||||
}
|
||||
|
||||
public MoneyData getOutStandingBalance() {
|
||||
return this.outStandingBalance;
|
||||
}
|
||||
|
||||
public void setOutStandingBalance(final MoneyData outStandingBalance) {
|
||||
this.outStandingBalance = outStandingBalance;
|
||||
}
|
||||
|
||||
public void setInstallmentNumber(final Integer installmentNumber) {
|
||||
this.installmentNumber = installmentNumber;
|
||||
}
|
||||
|
||||
public void setPeriodStart(final LocalDate periodStart) {
|
||||
this.periodStart = periodStart;
|
||||
}
|
||||
|
||||
public void setPeriodEnd(final LocalDate periodEnd) {
|
||||
this.periodEnd = periodEnd;
|
||||
}
|
||||
}
|
||||
-12
@@ -5,23 +5,11 @@ import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.NewLoanScheduleData;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.currency.domain.ApplicationCurrency;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
|
||||
public interface AmortizationLoanScheduleGenerator {
|
||||
|
||||
@Deprecated
|
||||
LoanSchedule generate(final LoanProductRelatedDetail loanScheduleInfo,
|
||||
final LocalDate disbursementDate,
|
||||
final LocalDate firstRepaymentDate,
|
||||
final LocalDate interestCalculatedFrom,
|
||||
final CurrencyData currencyData,
|
||||
final BigDecimal periodInterestRateForRepaymentPeriod,
|
||||
final LocalDate idealDisbursementDateBasedOnFirstRepaymentDate,
|
||||
final List<LocalDate> scheduledDates);
|
||||
|
||||
NewLoanScheduleData generate(
|
||||
ApplicationCurrency applicationCurrency,
|
||||
LoanProductRelatedDetail loanScheduleInfo,
|
||||
|
||||
-28
@@ -5,8 +5,6 @@ import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.NewLoanScheduleData;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.currency.domain.ApplicationCurrency;
|
||||
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
@@ -65,30 +63,4 @@ public class DecliningBalanceMethodLoanScheduleGenerator implements LoanSchedule
|
||||
idealDisbursementDateBasedOnFirstRepaymentDate,
|
||||
scheduledDates);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public LoanSchedule generate(
|
||||
final LoanProductRelatedDetail loanScheduleInfo,
|
||||
final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermFrequencyType,
|
||||
final LocalDate disbursementDate,
|
||||
final LocalDate firstRepaymentDate,
|
||||
final LocalDate interestCalculatedFrom,
|
||||
final CurrencyData currencyData) {
|
||||
|
||||
// 1. generate valid set of 'due dates' based on some of the 'loan attributes'
|
||||
List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(loanScheduleInfo, disbursementDate, firstRepaymentDate);
|
||||
|
||||
LocalDate idealDisbursementDateBasedOnFirstRepaymentDate = this.scheduledDateGenerator.idealDisbursementDateBasedOnFirstRepaymentDate(loanScheduleInfo, scheduledDates);
|
||||
|
||||
// 2. determine the 'periodic' interest rate based on the 'repayment periods' so we can use
|
||||
final BigDecimal periodInterestRateForRepaymentPeriod = this.periodicInterestRateCalculator.calculateFrom(loanScheduleInfo);
|
||||
|
||||
// Determine with 'amortisation' approach to use
|
||||
AmortizationLoanScheduleGenerator generator = this.amortizationLoanScheduleGeneratorFactory.createGenerator(loanScheduleInfo.getAmortizationMethod());
|
||||
|
||||
return generator.generate(loanScheduleInfo, disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData,
|
||||
periodInterestRateForRepaymentPeriod, idealDisbursementDateBasedOnFirstRepaymentDate, scheduledDates);
|
||||
}
|
||||
}
|
||||
-96
@@ -9,10 +9,7 @@ import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.NewLoanScheduleData;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.api.data.LoanSchedulePeriodData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
import org.mifosng.platform.api.data.ScheduledLoanInstallment;
|
||||
import org.mifosng.platform.currency.domain.ApplicationCurrency;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
import org.mifosng.platform.currency.domain.Money;
|
||||
@@ -143,97 +140,4 @@ public class EqualInstallmentsAmortizationLoanScheduleGenerator implements Amort
|
||||
return new NewLoanScheduleData(currencyData, periods, loanTermInDays, cumulativePrincipalDisbursed, cumulativePrincipalDue,
|
||||
cumulativePrincipalOutstanding, cumulativeInterestExpected, cumulativeChargesToDate, totalExpectedRepayment);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public LoanSchedule generate(final LoanProductRelatedDetail loanScheduleInfo,
|
||||
final LocalDate disbursementDate,
|
||||
final LocalDate firstRepaymentDate,
|
||||
final LocalDate interestCalculatedFrom,
|
||||
final CurrencyData currencyData,
|
||||
final BigDecimal periodInterestRateForRepaymentPeriod,
|
||||
final LocalDate idealDisbursementDateBasedOnFirstRepaymentDate,
|
||||
final List<LocalDate> scheduledDates) {
|
||||
|
||||
List<ScheduledLoanInstallment> scheduledLoanInstallments = new ArrayList<ScheduledLoanInstallment>();
|
||||
|
||||
// determine 'total payment' for each repayment based on pmt function (and hence the total due overall)
|
||||
final MonetaryCurrency monetaryCurrency = loanScheduleInfo.getPrincipal().getCurrency();
|
||||
final Money totalDuePerInstallment = this.pmtCalculator.calculatePaymentForOnePeriodFrom(loanScheduleInfo, periodInterestRateForRepaymentPeriod, monetaryCurrency);
|
||||
final Money totalRepaymentDueForLoanTerm = this.pmtCalculator.calculateTotalRepaymentFrom(loanScheduleInfo, periodInterestRateForRepaymentPeriod, monetaryCurrency);
|
||||
|
||||
Money totalInterestDue = totalRepaymentDueForLoanTerm.minus(loanScheduleInfo.getPrincipal());
|
||||
Money outstandingBalance = loanScheduleInfo.getPrincipal();
|
||||
Money totalPrincipal = Money.zero(monetaryCurrency);
|
||||
Money totalInterest = Money.zero(monetaryCurrency);
|
||||
|
||||
double interestCalculationGraceOnRepaymentPeriodFraction = this.paymentPeriodsInOneYearCalculator.calculateRepaymentPeriodAsAFractionOfDays(loanScheduleInfo.getRepaymentPeriodFrequencyType(),
|
||||
loanScheduleInfo.getRepayEvery(), interestCalculatedFrom, scheduledDates, idealDisbursementDateBasedOnFirstRepaymentDate);
|
||||
|
||||
LocalDate startDate = disbursementDate;
|
||||
int installmentNumber = 1;
|
||||
for (LocalDate scheduledDueDate : scheduledDates) {
|
||||
|
||||
// number of days from startDate to this scheduledDate
|
||||
int daysInPeriod = Days.daysBetween(startDate.toDateMidnight().toDateTime(), scheduledDueDate.toDateMidnight().toDateTime()).getDays();
|
||||
|
||||
Money interestForInstallment = this.periodicInterestRateCalculator.calculateInterestOn(outstandingBalance, periodInterestRateForRepaymentPeriod, daysInPeriod, loanScheduleInfo);
|
||||
Money principalForInstallment = this.periodicInterestRateCalculator.calculatePrincipalOn(totalDuePerInstallment, interestForInstallment, loanScheduleInfo);
|
||||
|
||||
if (interestCalculationGraceOnRepaymentPeriodFraction >= Integer.valueOf(1).doubleValue()) {
|
||||
Money graceOnInterestForRepaymentPeriod = interestForInstallment;
|
||||
interestForInstallment = interestForInstallment.minus(graceOnInterestForRepaymentPeriod);
|
||||
totalInterestDue = totalInterestDue.minus(graceOnInterestForRepaymentPeriod);
|
||||
interestCalculationGraceOnRepaymentPeriodFraction = interestCalculationGraceOnRepaymentPeriodFraction - Integer.valueOf(1).doubleValue();
|
||||
} else if (interestCalculationGraceOnRepaymentPeriodFraction > Double.valueOf("0.25") && interestCalculationGraceOnRepaymentPeriodFraction < Integer.valueOf(1).doubleValue()) {
|
||||
Money graceOnInterestForRepaymentPeriod = interestForInstallment.multipliedBy(interestCalculationGraceOnRepaymentPeriodFraction);
|
||||
interestForInstallment = interestForInstallment.minus(graceOnInterestForRepaymentPeriod);
|
||||
totalInterestDue = totalInterestDue.minus(graceOnInterestForRepaymentPeriod);
|
||||
interestCalculationGraceOnRepaymentPeriodFraction = Double.valueOf("0");
|
||||
}
|
||||
|
||||
totalPrincipal = totalPrincipal.plus(principalForInstallment);
|
||||
totalInterest = totalInterest.plus(interestForInstallment);
|
||||
|
||||
if (installmentNumber == loanScheduleInfo.getNumberOfRepayments()) {
|
||||
Money principalDifference = totalPrincipal.minus(loanScheduleInfo.getPrincipal());
|
||||
if (principalDifference.isLessThanZero()) {
|
||||
principalForInstallment = principalForInstallment.plus(principalDifference.abs());
|
||||
} else if (principalDifference.isGreaterThanZero()) {
|
||||
principalForInstallment = principalForInstallment.minus(principalDifference.abs());
|
||||
}
|
||||
|
||||
final Money interestDifference = totalInterest.minus(totalInterestDue);
|
||||
if (interestDifference.isLessThanZero()) {
|
||||
interestForInstallment = interestForInstallment.plus(interestDifference.abs());
|
||||
} else if (interestDifference.isGreaterThanZero()) {
|
||||
interestForInstallment = interestForInstallment.minus(interestDifference.abs());
|
||||
}
|
||||
}
|
||||
|
||||
Money totalInstallmentDue = principalForInstallment.plus(interestForInstallment);
|
||||
|
||||
outstandingBalance = outstandingBalance.minus(principalForInstallment);
|
||||
|
||||
MoneyData principalPerInstallmentValue = MoneyData.of(currencyData, principalForInstallment.getAmount());
|
||||
MoneyData interestPerInstallmentValue = MoneyData.of(currencyData, interestForInstallment.getAmount());
|
||||
MoneyData totalInstallmentDueValue = MoneyData.of(currencyData, totalInstallmentDue.getAmount());
|
||||
MoneyData outstandingBalanceValue = MoneyData.of(currencyData, outstandingBalance.getAmount());
|
||||
|
||||
ScheduledLoanInstallment installment = new ScheduledLoanInstallment(
|
||||
Integer.valueOf(installmentNumber), startDate,
|
||||
scheduledDueDate, principalPerInstallmentValue,
|
||||
interestPerInstallmentValue,
|
||||
totalInstallmentDueValue,
|
||||
outstandingBalanceValue);
|
||||
|
||||
scheduledLoanInstallments.add(installment);
|
||||
|
||||
startDate = scheduledDueDate;
|
||||
|
||||
installmentNumber++;
|
||||
}
|
||||
|
||||
return new LoanSchedule(scheduledLoanInstallments);
|
||||
}
|
||||
}
|
||||
-85
@@ -9,10 +9,7 @@ import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.NewLoanScheduleData;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.api.data.LoanSchedulePeriodData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
import org.mifosng.platform.api.data.ScheduledLoanInstallment;
|
||||
import org.mifosng.platform.currency.domain.ApplicationCurrency;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
import org.mifosng.platform.currency.domain.Money;
|
||||
@@ -123,86 +120,4 @@ public class EqualPrincipalAmortizationLoanScheduleGenerator implements Amortiza
|
||||
return new NewLoanScheduleData(currencyData, periods, loanTermInDays, cumulativePrincipalDisbursed, cumulativePrincipalDue,
|
||||
cumulativePrincipalOutstanding, cumulativeInterestExpected, cumulativeChargesToDate, totalExpectedRepayment);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public LoanSchedule generate(final LoanProductRelatedDetail loanScheduleInfo,
|
||||
final LocalDate disbursementDate,
|
||||
final LocalDate firstRepaymentDate,
|
||||
final LocalDate interestCalculatedFrom,
|
||||
final CurrencyData currencyData,
|
||||
final BigDecimal periodInterestRateForRepaymentPeriod,
|
||||
final LocalDate idealDisbursementDateBasedOnFirstRepaymentDate,
|
||||
final List<LocalDate> scheduledDates) {
|
||||
|
||||
List<ScheduledLoanInstallment> scheduledLoanInstallments = new ArrayList<ScheduledLoanInstallment>();
|
||||
|
||||
// 1. we know 'principal' must be equal over repayments so use this to calculate interest and thus total repayment due.
|
||||
final MonetaryCurrency monetaryCurrency = loanScheduleInfo.getPrincipal().getCurrency();
|
||||
Money totalDuePerInstallment = Money.zero(monetaryCurrency);
|
||||
|
||||
Money outstandingBalance = loanScheduleInfo.getPrincipal();
|
||||
Money totalPrincipal = Money.zero(monetaryCurrency);
|
||||
Money totalInterest = Money.zero(monetaryCurrency);
|
||||
|
||||
double interestCalculationGraceOnRepaymentPeriodFraction = this.paymentPeriodsInOneYearCalculator.calculateRepaymentPeriodAsAFractionOfDays(loanScheduleInfo.getRepaymentPeriodFrequencyType(),
|
||||
loanScheduleInfo.getRepayEvery(), interestCalculatedFrom, scheduledDates, idealDisbursementDateBasedOnFirstRepaymentDate);
|
||||
|
||||
LocalDate startDate = disbursementDate;
|
||||
int installmentNumber = 1;
|
||||
for (LocalDate scheduledDueDate : scheduledDates) {
|
||||
|
||||
// number of days from startDate to this scheduledDate
|
||||
int daysInPeriod = Days.daysBetween(startDate.toDateMidnight().toDateTime(), scheduledDueDate.toDateMidnight().toDateTime()).getDays();
|
||||
|
||||
Money interestForInstallment = this.periodicInterestRateCalculator.calculateInterestOn(outstandingBalance, periodInterestRateForRepaymentPeriod, daysInPeriod, loanScheduleInfo);
|
||||
Money principalForInstallment = this.periodicInterestRateCalculator.calculatePrincipalOn(totalDuePerInstallment, interestForInstallment, loanScheduleInfo);
|
||||
|
||||
if (interestCalculationGraceOnRepaymentPeriodFraction >= Integer.valueOf(1).doubleValue()) {
|
||||
Money graceOnInterestForRepaymentPeriod = interestForInstallment;
|
||||
interestForInstallment = interestForInstallment.minus(graceOnInterestForRepaymentPeriod);
|
||||
interestCalculationGraceOnRepaymentPeriodFraction = interestCalculationGraceOnRepaymentPeriodFraction - Integer.valueOf(1).doubleValue();
|
||||
} else if (interestCalculationGraceOnRepaymentPeriodFraction > Double.valueOf("0.25") && interestCalculationGraceOnRepaymentPeriodFraction < Integer.valueOf(1).doubleValue()) {
|
||||
Money graceOnInterestForRepaymentPeriod = interestForInstallment.multipliedBy(interestCalculationGraceOnRepaymentPeriodFraction);
|
||||
interestForInstallment = interestForInstallment.minus(graceOnInterestForRepaymentPeriod);
|
||||
interestCalculationGraceOnRepaymentPeriodFraction = Double.valueOf("0");
|
||||
}
|
||||
|
||||
totalPrincipal = totalPrincipal.plus(principalForInstallment);
|
||||
totalInterest = totalInterest.plus(interestForInstallment);
|
||||
|
||||
if (installmentNumber == loanScheduleInfo.getNumberOfRepayments()) {
|
||||
Money principalDifference = totalPrincipal.minus(loanScheduleInfo.getPrincipal());
|
||||
if (principalDifference.isLessThanZero()) {
|
||||
principalForInstallment = principalForInstallment.plus(principalDifference.abs());
|
||||
} else if (principalDifference.isGreaterThanZero()) {
|
||||
principalForInstallment = principalForInstallment.minus(principalDifference.abs());
|
||||
}
|
||||
}
|
||||
|
||||
Money totalInstallmentDue = principalForInstallment.plus(interestForInstallment);
|
||||
|
||||
outstandingBalance = outstandingBalance.minus(principalForInstallment);
|
||||
|
||||
MoneyData principalPerInstallmentValue = MoneyData.of(currencyData, principalForInstallment.getAmount());
|
||||
MoneyData interestPerInstallmentValue = MoneyData.of(currencyData, interestForInstallment.getAmount());
|
||||
MoneyData totalInstallmentDueValue = MoneyData.of(currencyData, totalInstallmentDue.getAmount());
|
||||
MoneyData outstandingBalanceValue = MoneyData.of(currencyData, outstandingBalance.getAmount());
|
||||
|
||||
ScheduledLoanInstallment installment = new ScheduledLoanInstallment(
|
||||
Integer.valueOf(installmentNumber), startDate,
|
||||
scheduledDueDate, principalPerInstallmentValue,
|
||||
interestPerInstallmentValue,
|
||||
totalInstallmentDueValue,
|
||||
outstandingBalanceValue);
|
||||
|
||||
scheduledLoanInstallments.add(installment);
|
||||
|
||||
startDate = scheduledDueDate;
|
||||
|
||||
installmentNumber++;
|
||||
}
|
||||
|
||||
return new LoanSchedule(scheduledLoanInstallments);
|
||||
}
|
||||
}
|
||||
-82
@@ -11,10 +11,7 @@ import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.NewLoanScheduleData;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.api.data.LoanSchedulePeriodData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
import org.mifosng.platform.api.data.ScheduledLoanInstallment;
|
||||
import org.mifosng.platform.currency.domain.ApplicationCurrency;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
import org.mifosng.platform.currency.domain.Money;
|
||||
@@ -131,83 +128,4 @@ public class FlatMethodLoanScheduleGenerator implements LoanScheduleGenerator {
|
||||
return new NewLoanScheduleData(currencyData, periods, loanTermInDays, cumulativePrincipalDisbursed, cumulativePrincipalDue,
|
||||
cumulativePrincipalOutstanding, cumulativeInterestExpected, cumulativeChargesToDate, totalExpectedRepayment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanSchedule generate(
|
||||
final LoanProductRelatedDetail loanScheduleInfo,
|
||||
final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermFrequencyType,
|
||||
final LocalDate disbursementDate, final LocalDate firstRepaymentDate,
|
||||
final LocalDate interestCalculatedFrom, final CurrencyData currencyData) {
|
||||
|
||||
List<ScheduledLoanInstallment> scheduledLoanInstallments = new ArrayList<ScheduledLoanInstallment>();
|
||||
|
||||
List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(loanScheduleInfo, disbursementDate, firstRepaymentDate);
|
||||
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
|
||||
BigDecimal loanTermPeriodsInYear = BigDecimal.valueOf(this.paymentPeriodsInOneYearCalculator.calculate(loanTermFrequencyType));
|
||||
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()
|
||||
.dividedBy(loanScheduleInfo.getNumberOfRepayments(),
|
||||
RoundingMode.HALF_EVEN);
|
||||
|
||||
Money outstandingBalance = loanScheduleInfo.getPrincipal();
|
||||
Money totalPrincipal = Money.zero(outstandingBalance.getCurrency());
|
||||
Money totalInterest = Money.zero(outstandingBalance.getCurrency());
|
||||
|
||||
LocalDate startDate = disbursementDate;
|
||||
int installmentNumber = 1;
|
||||
for (LocalDate scheduledDueDate : scheduledDates) {
|
||||
totalPrincipal = totalPrincipal.plus(principalPerInstallment);
|
||||
totalInterest = totalInterest.plus(interestPerInstallment);
|
||||
|
||||
if (installmentNumber == loanScheduleInfo.getNumberOfRepayments()) {
|
||||
final Money difference = totalPrincipal.minus(loanScheduleInfo.getPrincipal());
|
||||
if (difference.isLessThanZero()) {
|
||||
principalPerInstallment = principalPerInstallment.plus(difference.abs());
|
||||
} else if (difference.isGreaterThanZero()) {
|
||||
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);
|
||||
outstandingBalance = outstandingBalance.minus(principalPerInstallment);
|
||||
|
||||
MoneyData principalPerInstallmentValue = MoneyData.of(currencyData, principalPerInstallment.getAmount());
|
||||
MoneyData interestPerInstallmentValue = MoneyData.of(currencyData, interestPerInstallment.getAmount());
|
||||
MoneyData totalInstallmentDueValue = MoneyData.of(currencyData, totalInstallmentDue.getAmount());
|
||||
MoneyData outstandingBalanceValue = MoneyData.of(currencyData, outstandingBalance.getAmount());
|
||||
|
||||
ScheduledLoanInstallment installment = new ScheduledLoanInstallment(
|
||||
Integer.valueOf(installmentNumber), startDate,
|
||||
scheduledDueDate, principalPerInstallmentValue,
|
||||
interestPerInstallmentValue, totalInstallmentDueValue,
|
||||
outstandingBalanceValue);
|
||||
|
||||
scheduledLoanInstallments.add(installment);
|
||||
|
||||
startDate = scheduledDueDate;
|
||||
|
||||
installmentNumber++;
|
||||
}
|
||||
|
||||
return new LoanSchedule(scheduledLoanInstallments);
|
||||
}
|
||||
}
|
||||
-9
@@ -2,21 +2,12 @@ package org.mifosng.platform.loanschedule.domain;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.NewLoanScheduleData;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.currency.domain.ApplicationCurrency;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
|
||||
public interface LoanScheduleGenerator {
|
||||
|
||||
@Deprecated
|
||||
LoanSchedule generate(LoanProductRelatedDetail loanScheduleInfo,
|
||||
Integer loanTermFrequency,
|
||||
PeriodFrequencyType loanTermFrequencyType,
|
||||
LocalDate disbursementDate, LocalDate firstRepaymentDate, LocalDate interestCalculatedFrom,
|
||||
CurrencyData currencyData);
|
||||
|
||||
NewLoanScheduleData generate(ApplicationCurrency applicationCurrency,
|
||||
LoanProductRelatedDetail loanScheduleInfo,
|
||||
Integer loanTermFrequency,
|
||||
|
||||
+106
-113
@@ -1,22 +1,15 @@
|
||||
package org.mifosng.platform.loanschedule.domain;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
//import static org.hamcrest.CoreMatchers.*;
|
||||
//import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.api.data.ScheduledLoanInstallment;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DecliningBalanceMethodLoanScheduleGeneratorTest {
|
||||
|
||||
@@ -34,107 +27,107 @@ public class DecliningBalanceMethodLoanScheduleGeneratorTest {
|
||||
decliningBalanceGenerator = new DecliningBalanceMethodLoanScheduleGenerator();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEqualInstallmentAmortisationShouldCalculatePaymentPerInstallmentUsingPmtFunctionAndDerivePrincipalAndInterestComponents() {
|
||||
|
||||
// setup
|
||||
Integer loanTermFrequency = 12;
|
||||
PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForEqualInstallmentAmortizationQuarterly();
|
||||
|
||||
LocalDate disbursementDate = new LocalDate(2011, 1, 11);
|
||||
LocalDate firstRepaymentDate = new LocalDate(2011, 5, 1);
|
||||
LocalDate interestCalculatedFrom = new LocalDate(2011, 2, 1);
|
||||
|
||||
// pre assertions
|
||||
assertThat(loanTermFrequency, is(loanScheduleInfo.getNumberOfRepayments() * loanScheduleInfo.getRepayEvery()));
|
||||
assertThat(loanTermFrequencyType, is(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||
|
||||
// exercise test
|
||||
LoanSchedule schedule = decliningBalanceGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
|
||||
// verification (post assertions)
|
||||
given(schedule).assertHasInstallmentSizeOf(4);
|
||||
given(schedule).assertTotalPaymentDueOf(1, is("57718.30")).assertInterestDueComponentOf(1, is("12000.00")).assertPrincipalDueComponentOf(1, is("45718.30"));
|
||||
given(schedule).assertTotalPaymentDueOf(2, is("57718.30")).assertInterestDueComponentOf(2, is("9256.90")).assertPrincipalDueComponentOf(2, is("48461.40"));
|
||||
given(schedule).assertTotalPaymentDueOf(3, is("57718.30")).assertInterestDueComponentOf(3, is("6349.22")).assertPrincipalDueComponentOf(3, is("51369.08"));
|
||||
given(schedule).assertTotalPaymentDueOf(4, is("57718.29")).assertInterestDueComponentOf(4, is("3267.07")).assertPrincipalDueComponentOf(4, is("54451.22"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEqualPrincipalAmortisationShouldCalculateInterestComponentFromOutstandingPrincipalBlanceResultingInDecliningInterestAndTotalRepayments() {
|
||||
|
||||
// setup
|
||||
Integer loanTermFrequency = 12;
|
||||
PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForEqualPrincipalAmortizationQuarterly();
|
||||
|
||||
LocalDate disbursementDate = new LocalDate(2011, 1, 11);
|
||||
LocalDate firstRepaymentDate = new LocalDate(2011, 5, 1);
|
||||
LocalDate interestCalculatedFrom = new LocalDate(2011, 2, 1);
|
||||
|
||||
// pre assertions
|
||||
assertThat(loanTermFrequency, is(loanScheduleInfo.getNumberOfRepayments() * loanScheduleInfo.getRepayEvery()));
|
||||
assertThat(loanTermFrequencyType, is(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||
|
||||
// exercise test
|
||||
LoanSchedule schedule = decliningBalanceGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
|
||||
// verification (post assertions)
|
||||
given(schedule).assertHasInstallmentSizeOf(4);
|
||||
given(schedule).assertPrincipalDueComponentOf(1, is("50000.00")).assertInterestDueComponentOf(1, is("12000.00")).assertTotalPaymentDueOf(1, is("62000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(2, is("50000.00")).assertInterestDueComponentOf(2, is("9000.00")).assertTotalPaymentDueOf(2, is("59000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(3, is("50000.00")).assertInterestDueComponentOf(3, is("6000.00")).assertTotalPaymentDueOf(3, is("56000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(4, is("50000.00")).assertInterestDueComponentOf(4, is("3000.00")).assertTotalPaymentDueOf(4, is("53000.00"));
|
||||
}
|
||||
|
||||
private LoanScheduleAssertionBuilder given(final LoanSchedule schedule) {
|
||||
return new LoanScheduleAssertionBuilder(schedule);
|
||||
}
|
||||
|
||||
private class LoanScheduleAssertionBuilder {
|
||||
|
||||
private final LoanSchedule schedule;
|
||||
|
||||
public LoanScheduleAssertionBuilder(final LoanSchedule schedule) {
|
||||
this.schedule = schedule;
|
||||
}
|
||||
|
||||
public LoanScheduleAssertionBuilder assertPrincipalDueComponentOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
final Integer installmentIndex = installmentNumber -1;
|
||||
List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
|
||||
assertThat("Expected principal due component for installment " + installmentNumber + " is wrong: ",
|
||||
repaymentInstallment.getPrincipalDue().toString(), matchesExpectedAmount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanScheduleAssertionBuilder assertInterestDueComponentOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
final Integer installmentIndex = installmentNumber -1;
|
||||
List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
|
||||
assertThat("Expected interest due component for installment " + installmentNumber + " is wrong: ",
|
||||
repaymentInstallment.getInterestDue().toString(), matchesExpectedAmount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanScheduleAssertionBuilder assertTotalPaymentDueOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
final Integer installmentIndex = installmentNumber -1;
|
||||
List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
|
||||
assertThat("Expected total payment for installment " + installmentNumber + " is wrong: ",
|
||||
repaymentInstallment.getTotalInstallmentDue().toString(), matchesExpectedAmount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanScheduleAssertionBuilder assertHasInstallmentSizeOf(int expectedInstallmentSize) {
|
||||
assertThat("Expected number of installments is wrong: ", schedule.getScheduledLoanInstallments().size(), is(expectedInstallmentSize));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
// @Test
|
||||
// public void givenEqualInstallmentAmortisationShouldCalculatePaymentPerInstallmentUsingPmtFunctionAndDerivePrincipalAndInterestComponents() {
|
||||
//
|
||||
// // setup
|
||||
// Integer loanTermFrequency = 12;
|
||||
// PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
// loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForEqualInstallmentAmortizationQuarterly();
|
||||
//
|
||||
// LocalDate disbursementDate = new LocalDate(2011, 1, 11);
|
||||
// LocalDate firstRepaymentDate = new LocalDate(2011, 5, 1);
|
||||
// LocalDate interestCalculatedFrom = new LocalDate(2011, 2, 1);
|
||||
//
|
||||
// // pre assertions
|
||||
// assertThat(loanTermFrequency, is(loanScheduleInfo.getNumberOfRepayments() * loanScheduleInfo.getRepayEvery()));
|
||||
// assertThat(loanTermFrequencyType, is(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||
//
|
||||
// // exercise test
|
||||
// LoanSchedule schedule = decliningBalanceGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
// disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
//
|
||||
// // verification (post assertions)
|
||||
// given(schedule).assertHasInstallmentSizeOf(4);
|
||||
// given(schedule).assertTotalPaymentDueOf(1, is("57718.30")).assertInterestDueComponentOf(1, is("12000.00")).assertPrincipalDueComponentOf(1, is("45718.30"));
|
||||
// given(schedule).assertTotalPaymentDueOf(2, is("57718.30")).assertInterestDueComponentOf(2, is("9256.90")).assertPrincipalDueComponentOf(2, is("48461.40"));
|
||||
// given(schedule).assertTotalPaymentDueOf(3, is("57718.30")).assertInterestDueComponentOf(3, is("6349.22")).assertPrincipalDueComponentOf(3, is("51369.08"));
|
||||
// given(schedule).assertTotalPaymentDueOf(4, is("57718.29")).assertInterestDueComponentOf(4, is("3267.07")).assertPrincipalDueComponentOf(4, is("54451.22"));
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void givenEqualPrincipalAmortisationShouldCalculateInterestComponentFromOutstandingPrincipalBlanceResultingInDecliningInterestAndTotalRepayments() {
|
||||
//
|
||||
// // setup
|
||||
// Integer loanTermFrequency = 12;
|
||||
// PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
// loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForEqualPrincipalAmortizationQuarterly();
|
||||
//
|
||||
// LocalDate disbursementDate = new LocalDate(2011, 1, 11);
|
||||
// LocalDate firstRepaymentDate = new LocalDate(2011, 5, 1);
|
||||
// LocalDate interestCalculatedFrom = new LocalDate(2011, 2, 1);
|
||||
//
|
||||
// // pre assertions
|
||||
// assertThat(loanTermFrequency, is(loanScheduleInfo.getNumberOfRepayments() * loanScheduleInfo.getRepayEvery()));
|
||||
// assertThat(loanTermFrequencyType, is(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||
//
|
||||
// // exercise test
|
||||
// LoanSchedule schedule = decliningBalanceGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
// disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
//
|
||||
// // verification (post assertions)
|
||||
// given(schedule).assertHasInstallmentSizeOf(4);
|
||||
// given(schedule).assertPrincipalDueComponentOf(1, is("50000.00")).assertInterestDueComponentOf(1, is("12000.00")).assertTotalPaymentDueOf(1, is("62000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(2, is("50000.00")).assertInterestDueComponentOf(2, is("9000.00")).assertTotalPaymentDueOf(2, is("59000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(3, is("50000.00")).assertInterestDueComponentOf(3, is("6000.00")).assertTotalPaymentDueOf(3, is("56000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(4, is("50000.00")).assertInterestDueComponentOf(4, is("3000.00")).assertTotalPaymentDueOf(4, is("53000.00"));
|
||||
// }
|
||||
//
|
||||
// private LoanScheduleAssertionBuilder given(final LoanSchedule schedule) {
|
||||
// return new LoanScheduleAssertionBuilder(schedule);
|
||||
// }
|
||||
//
|
||||
// private class LoanScheduleAssertionBuilder {
|
||||
//
|
||||
// private final LoanSchedule schedule;
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder(final LoanSchedule schedule) {
|
||||
// this.schedule = schedule;
|
||||
// }
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder assertPrincipalDueComponentOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
// final Integer installmentIndex = installmentNumber -1;
|
||||
// List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
// ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
//
|
||||
// assertThat("Expected principal due component for installment " + installmentNumber + " is wrong: ",
|
||||
// repaymentInstallment.getPrincipalDue().toString(), matchesExpectedAmount);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder assertInterestDueComponentOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
// final Integer installmentIndex = installmentNumber -1;
|
||||
// List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
// ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
//
|
||||
// assertThat("Expected interest due component for installment " + installmentNumber + " is wrong: ",
|
||||
// repaymentInstallment.getInterestDue().toString(), matchesExpectedAmount);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder assertTotalPaymentDueOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
// final Integer installmentIndex = installmentNumber -1;
|
||||
// List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
// ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
//
|
||||
// assertThat("Expected total payment for installment " + installmentNumber + " is wrong: ",
|
||||
// repaymentInstallment.getTotalInstallmentDue().toString(), matchesExpectedAmount);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder assertHasInstallmentSizeOf(int expectedInstallmentSize) {
|
||||
// assertThat("Expected number of installments is wrong: ", schedule.getScheduledLoanInstallments().size(), is(expectedInstallmentSize));
|
||||
// return this;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
+131
-133
@@ -1,23 +1,16 @@
|
||||
package org.mifosng.platform.loanschedule.domain;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
//import static org.hamcrest.CoreMatchers.*;
|
||||
//import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.api.data.ScheduledLoanInstallment;
|
||||
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class FlatMethodLoanScheduleGeneratorTest {
|
||||
|
||||
@@ -34,131 +27,136 @@ public class FlatMethodLoanScheduleGeneratorTest {
|
||||
|
||||
flatLoanScheduleGenerator = new FlatMethodLoanScheduleGenerator();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenFlatMethodShouldCalculateFlatInterestComponentToDerivePrincipalAndTotalRepaymentRegardlessOfEqualInstallmentAmortisation() {
|
||||
public void rewriteAllTests() {
|
||||
|
||||
// setup
|
||||
Integer loanTermFrequency = 12;
|
||||
PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForFlatQuarterly(AmortizationMethod.EQUAL_INSTALLMENTS);
|
||||
|
||||
LocalDate disbursementDate = new LocalDate(2011, 1, 11);
|
||||
LocalDate firstRepaymentDate = new LocalDate(2011, 5, 1);
|
||||
LocalDate interestCalculatedFrom = new LocalDate(2011, 2, 1);
|
||||
|
||||
// pre assertions
|
||||
assertThat(loanTermFrequency, is(loanScheduleInfo.getNumberOfRepayments() * loanScheduleInfo.getRepayEvery()));
|
||||
assertThat(loanTermFrequencyType, is(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||
|
||||
// exercise test
|
||||
LoanSchedule schedule = flatLoanScheduleGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
|
||||
// verification (post assertions)
|
||||
given(schedule).assertHasInstallmentSizeOf(4);
|
||||
given(schedule).assertPrincipalDueComponentOf(1, is("50000.00")).assertInterestDueComponentOf(1, is("12000.00")).assertTotalPaymentDueOf(1, is("62000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(2, is("50000.00")).assertInterestDueComponentOf(2, is("12000.00")).assertTotalPaymentDueOf(2, is("62000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(3, is("50000.00")).assertInterestDueComponentOf(3, is("12000.00")).assertTotalPaymentDueOf(3, is("62000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(4, is("50000.00")).assertInterestDueComponentOf(4, is("12000.00")).assertTotalPaymentDueOf(4, is("62000.00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFlatMethodShouldCalculateFlatInterestComponentToDerivePrincipalAndTotalRepaymentRegardlessOfEqualPrincipalAmortisation() {
|
||||
|
||||
// setup
|
||||
Integer loanTermFrequency = 12;
|
||||
PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForFlatQuarterly(AmortizationMethod.EQUAL_PRINCIPAL);
|
||||
|
||||
LocalDate disbursementDate = new LocalDate(2011, 1, 11);
|
||||
LocalDate firstRepaymentDate = new LocalDate(2011, 5, 1);
|
||||
LocalDate interestCalculatedFrom = new LocalDate(2011, 2, 1);
|
||||
|
||||
// pre assertions
|
||||
assertThat(loanTermFrequency, is(loanScheduleInfo.getNumberOfRepayments() * loanScheduleInfo.getRepayEvery()));
|
||||
assertThat(loanTermFrequencyType, is(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||
|
||||
// exercise test
|
||||
LoanSchedule schedule = flatLoanScheduleGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
|
||||
// verification (post assertions)
|
||||
given(schedule).assertHasInstallmentSizeOf(4);
|
||||
given(schedule).assertPrincipalDueComponentOf(1, is("50000.00")).assertInterestDueComponentOf(1, is("12000.00")).assertTotalPaymentDueOf(1, is("62000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(2, is("50000.00")).assertInterestDueComponentOf(2, is("12000.00")).assertTotalPaymentDueOf(2, is("62000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(3, is("50000.00")).assertInterestDueComponentOf(3, is("12000.00")).assertTotalPaymentDueOf(3, is("62000.00"));
|
||||
given(schedule).assertPrincipalDueComponentOf(4, is("50000.00")).assertInterestDueComponentOf(4, is("12000.00")).assertTotalPaymentDueOf(4, is("62000.00"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFlatMethodAndIrregularFirstRepaymentShouldCalculateFlatInterestComponent() {
|
||||
|
||||
// setup
|
||||
currencyData = new CurrencyData("KSH", "Keyan Shilling", 0, "KSh", "currency.KSH");
|
||||
Integer loanTermFrequency = 9;
|
||||
PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForIrregularFlatEveryFourMonths();
|
||||
|
||||
LocalDate disbursementDate = new LocalDate(2012, 3, 27);
|
||||
LocalDate firstRepaymentDate = new LocalDate(2011, 7, 27);
|
||||
LocalDate interestCalculatedFrom = disbursementDate;
|
||||
|
||||
// exercise test
|
||||
LoanSchedule schedule = flatLoanScheduleGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
|
||||
// verification (post assertions)
|
||||
given(schedule).assertHasInstallmentSizeOf(2);
|
||||
given(schedule).assertPrincipalDueComponentOf(1, is("7500")).assertInterestDueComponentOf(1, is("1350")).assertTotalPaymentDueOf(1, is("8850"));
|
||||
given(schedule).assertPrincipalDueComponentOf(2, is("7500")).assertInterestDueComponentOf(2, is("1350")).assertTotalPaymentDueOf(2, is("8850"));
|
||||
}
|
||||
|
||||
private LoanScheduleAssertionBuilder given(final LoanSchedule schedule) {
|
||||
return new LoanScheduleAssertionBuilder(schedule);
|
||||
}
|
||||
|
||||
private class LoanScheduleAssertionBuilder {
|
||||
|
||||
private final LoanSchedule schedule;
|
||||
|
||||
public LoanScheduleAssertionBuilder(final LoanSchedule schedule) {
|
||||
this.schedule = schedule;
|
||||
}
|
||||
|
||||
public LoanScheduleAssertionBuilder assertPrincipalDueComponentOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
final Integer installmentIndex = installmentNumber -1;
|
||||
List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
|
||||
assertThat("Expected principal due component for installment " + installmentNumber + " is wrong: ",
|
||||
repaymentInstallment.getPrincipalDue().toString(), matchesExpectedAmount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanScheduleAssertionBuilder assertInterestDueComponentOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
final Integer installmentIndex = installmentNumber -1;
|
||||
List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
|
||||
assertThat("Expected interest due component for installment " + installmentNumber + " is wrong: ",
|
||||
repaymentInstallment.getInterestDue().toString(), matchesExpectedAmount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanScheduleAssertionBuilder assertTotalPaymentDueOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
final Integer installmentIndex = installmentNumber -1;
|
||||
List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
|
||||
assertThat("Expected total payment for installment " + installmentNumber + " is wrong: ",
|
||||
repaymentInstallment.getTotalInstallmentDue().toString(), matchesExpectedAmount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanScheduleAssertionBuilder assertHasInstallmentSizeOf(int expectedInstallmentSize) {
|
||||
assertThat("Expected number of installments is wrong: ", schedule.getScheduledLoanInstallments().size(), is(expectedInstallmentSize));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
// @Test
|
||||
// public void givenFlatMethodShouldCalculateFlatInterestComponentToDerivePrincipalAndTotalRepaymentRegardlessOfEqualInstallmentAmortisation() {
|
||||
//
|
||||
// // setup
|
||||
// Integer loanTermFrequency = 12;
|
||||
// PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
// loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForFlatQuarterly(AmortizationMethod.EQUAL_INSTALLMENTS);
|
||||
//
|
||||
// LocalDate disbursementDate = new LocalDate(2011, 1, 11);
|
||||
// LocalDate firstRepaymentDate = new LocalDate(2011, 5, 1);
|
||||
// LocalDate interestCalculatedFrom = new LocalDate(2011, 2, 1);
|
||||
//
|
||||
// // pre assertions
|
||||
// assertThat(loanTermFrequency, is(loanScheduleInfo.getNumberOfRepayments() * loanScheduleInfo.getRepayEvery()));
|
||||
// assertThat(loanTermFrequencyType, is(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||
//
|
||||
// // exercise test
|
||||
// LoanSchedule schedule = flatLoanScheduleGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
// disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
//
|
||||
// // verification (post assertions)
|
||||
// given(schedule).assertHasInstallmentSizeOf(4);
|
||||
// given(schedule).assertPrincipalDueComponentOf(1, is("50000.00")).assertInterestDueComponentOf(1, is("12000.00")).assertTotalPaymentDueOf(1, is("62000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(2, is("50000.00")).assertInterestDueComponentOf(2, is("12000.00")).assertTotalPaymentDueOf(2, is("62000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(3, is("50000.00")).assertInterestDueComponentOf(3, is("12000.00")).assertTotalPaymentDueOf(3, is("62000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(4, is("50000.00")).assertInterestDueComponentOf(4, is("12000.00")).assertTotalPaymentDueOf(4, is("62000.00"));
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void givenFlatMethodShouldCalculateFlatInterestComponentToDerivePrincipalAndTotalRepaymentRegardlessOfEqualPrincipalAmortisation() {
|
||||
//
|
||||
// // setup
|
||||
// Integer loanTermFrequency = 12;
|
||||
// PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
// loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForFlatQuarterly(AmortizationMethod.EQUAL_PRINCIPAL);
|
||||
//
|
||||
// LocalDate disbursementDate = new LocalDate(2011, 1, 11);
|
||||
// LocalDate firstRepaymentDate = new LocalDate(2011, 5, 1);
|
||||
// LocalDate interestCalculatedFrom = new LocalDate(2011, 2, 1);
|
||||
//
|
||||
// // pre assertions
|
||||
// assertThat(loanTermFrequency, is(loanScheduleInfo.getNumberOfRepayments() * loanScheduleInfo.getRepayEvery()));
|
||||
// assertThat(loanTermFrequencyType, is(loanScheduleInfo.getRepaymentPeriodFrequencyType()));
|
||||
//
|
||||
// // exercise test
|
||||
// LoanSchedule schedule = flatLoanScheduleGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
// disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
//
|
||||
// // verification (post assertions)
|
||||
// given(schedule).assertHasInstallmentSizeOf(4);
|
||||
// given(schedule).assertPrincipalDueComponentOf(1, is("50000.00")).assertInterestDueComponentOf(1, is("12000.00")).assertTotalPaymentDueOf(1, is("62000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(2, is("50000.00")).assertInterestDueComponentOf(2, is("12000.00")).assertTotalPaymentDueOf(2, is("62000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(3, is("50000.00")).assertInterestDueComponentOf(3, is("12000.00")).assertTotalPaymentDueOf(3, is("62000.00"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(4, is("50000.00")).assertInterestDueComponentOf(4, is("12000.00")).assertTotalPaymentDueOf(4, is("62000.00"));
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void givenFlatMethodAndIrregularFirstRepaymentShouldCalculateFlatInterestComponent() {
|
||||
//
|
||||
// // setup
|
||||
// currencyData = new CurrencyData("KSH", "Keyan Shilling", 0, "KSh", "currency.KSH");
|
||||
// Integer loanTermFrequency = 9;
|
||||
// PeriodFrequencyType loanTermFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
// loanScheduleInfo = LoanProductRelatedDetailTestHelper.createSettingsForIrregularFlatEveryFourMonths();
|
||||
//
|
||||
// LocalDate disbursementDate = new LocalDate(2012, 3, 27);
|
||||
// LocalDate firstRepaymentDate = new LocalDate(2011, 7, 27);
|
||||
// LocalDate interestCalculatedFrom = disbursementDate;
|
||||
//
|
||||
// // exercise test
|
||||
// LoanSchedule schedule = flatLoanScheduleGenerator.generate(loanScheduleInfo, loanTermFrequency, loanTermFrequencyType,
|
||||
// disbursementDate, firstRepaymentDate, interestCalculatedFrom, currencyData);
|
||||
//
|
||||
// // verification (post assertions)
|
||||
// given(schedule).assertHasInstallmentSizeOf(2);
|
||||
// given(schedule).assertPrincipalDueComponentOf(1, is("7500")).assertInterestDueComponentOf(1, is("1350")).assertTotalPaymentDueOf(1, is("8850"));
|
||||
// given(schedule).assertPrincipalDueComponentOf(2, is("7500")).assertInterestDueComponentOf(2, is("1350")).assertTotalPaymentDueOf(2, is("8850"));
|
||||
// }
|
||||
//
|
||||
// private LoanScheduleAssertionBuilder given(final LoanSchedule schedule) {
|
||||
// return new LoanScheduleAssertionBuilder(schedule);
|
||||
// }
|
||||
//
|
||||
// private class LoanScheduleAssertionBuilder {
|
||||
//
|
||||
// private final LoanSchedule schedule;
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder(final LoanSchedule schedule) {
|
||||
// this.schedule = schedule;
|
||||
// }
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder assertPrincipalDueComponentOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
// final Integer installmentIndex = installmentNumber -1;
|
||||
// List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
// ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
//
|
||||
// assertThat("Expected principal due component for installment " + installmentNumber + " is wrong: ",
|
||||
// repaymentInstallment.getPrincipalDue().toString(), matchesExpectedAmount);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder assertInterestDueComponentOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
// final Integer installmentIndex = installmentNumber -1;
|
||||
// List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
// ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
//
|
||||
// assertThat("Expected interest due component for installment " + installmentNumber + " is wrong: ",
|
||||
// repaymentInstallment.getInterestDue().toString(), matchesExpectedAmount);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder assertTotalPaymentDueOf(final int installmentNumber, Matcher<String> matchesExpectedAmount) {
|
||||
// final Integer installmentIndex = installmentNumber -1;
|
||||
// List<ScheduledLoanInstallment> repaymentInstallments = schedule.getScheduledLoanInstallments();
|
||||
// ScheduledLoanInstallment repaymentInstallment = repaymentInstallments.get(installmentIndex);
|
||||
//
|
||||
// assertThat("Expected total payment for installment " + installmentNumber + " is wrong: ",
|
||||
// repaymentInstallment.getTotalInstallmentDue().toString(), matchesExpectedAmount);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public LoanScheduleAssertionBuilder assertHasInstallmentSizeOf(int expectedInstallmentSize) {
|
||||
// assertThat("Expected number of installments is wrong: ", schedule.getScheduledLoanInstallments().size(), is(expectedInstallmentSize));
|
||||
// return this;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user