continue loan term changes..

This commit is contained in:
Keith Woodlock
2012-08-07 14:38:27 +01:00
parent 20a8d08475
commit 41e57ba4bd
9 changed files with 92 additions and 31 deletions
@@ -12,6 +12,9 @@ public class CalculateLoanScheduleCommand {
private final Long productId;
private final BigDecimal principal;
private final Integer loanTermFrequency;
private final Integer loanTermFrequencyType;
private final Integer repaymentEvery;
private final Integer repaymentFrequencyType;
private final Integer numberOfRepayments;
@@ -31,6 +34,7 @@ public class CalculateLoanScheduleCommand {
final BigDecimal principal,
final BigDecimal interestRatePerPeriod, Integer interestRateFrequencyMethod, final Integer interestMethod, final Integer interestCalculationPeriodMethod,
final Integer repaymentEvery, final Integer repaymentFrequency, final Integer numberOfRepayments, Integer amortizationMethod,
final Integer loanTermFrequency, final Integer loanTermFrequencyType,
final LocalDate expectedDisbursementDate,
final LocalDate repaymentsStartingFromDate, final LocalDate interestCalculatedFromDate) {
@@ -44,6 +48,8 @@ public class CalculateLoanScheduleCommand {
this.repaymentFrequencyType = repaymentFrequency;
this.numberOfRepayments = numberOfRepayments;
this.amortizationType = amortizationMethod;
this.loanTermFrequency = loanTermFrequency;
this.loanTermFrequencyType = loanTermFrequencyType;
this.expectedDisbursementDate = expectedDisbursementDate;
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
@@ -57,6 +63,14 @@ public class CalculateLoanScheduleCommand {
public BigDecimal getPrincipal() {
return principal;
}
public Integer getLoanTermFrequency() {
return loanTermFrequency;
}
public Integer getLoanTermFrequencyType() {
return loanTermFrequencyType;
}
public Integer getRepaymentEvery() {
return repaymentEvery;
@@ -20,11 +20,13 @@ public class SubmitLoanApplicationCommand {
private final BigDecimal principal;
private final BigDecimal inArrearsTolerance;
private final Integer loanTermFrequency;
private final Integer loanTermFrequencyType;
private final Integer numberOfRepayments;
private final Integer repaymentEvery;
private final BigDecimal interestRatePerPeriod;
private final Integer repaymentFrequencyType;
private final Integer interestRateFrequencyType;
private final Integer amortizationType;
@@ -52,6 +54,7 @@ public class SubmitLoanApplicationCommand {
final Integer interestMethod,
final Integer interestCalculationPeriodMethod,
final Integer repaymentEvery, final Integer repaymentFrequency, final Integer numberOfRepayments, Integer amortizationMethod,
final Integer loanTermFrequency, final Integer loanTermFrequencyType,
final BigDecimal toleranceAmount) {
this.clientId = clientId;
this.productId = productId;
@@ -66,6 +69,8 @@ public class SubmitLoanApplicationCommand {
this.interestChargedFromDate = interestChargedFromLocalDate;
this.principal = principal;
this.loanTermFrequency = loanTermFrequency;
this.loanTermFrequencyType = loanTermFrequencyType;
this.inArrearsTolerance = toleranceAmount;
this.interestRatePerPeriod = interestRatePerPeriod;
@@ -80,7 +85,8 @@ public class SubmitLoanApplicationCommand {
public CalculateLoanScheduleCommand toCalculateLoanScheduleCommand() {
return new CalculateLoanScheduleCommand(productId,
principal, interestRatePerPeriod, interestRateFrequencyType, interestType, interestCalculationPeriodType, repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationType,
principal, interestRatePerPeriod, interestRateFrequencyType, interestType, interestCalculationPeriodType, repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationType,
this.loanTermFrequency, this.loanTermFrequencyType,
expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate);
}
@@ -127,6 +133,14 @@ public class SubmitLoanApplicationCommand {
public Integer getRepaymentEvery() {
return repaymentEvery;
}
public Integer getLoanTermFrequency() {
return loanTermFrequency;
}
public Integer getLoanTermFrequencyType() {
return loanTermFrequencyType;
}
public BigDecimal getInterestRatePerPeriod() {
return interestRatePerPeriod;
@@ -23,6 +23,7 @@ public class LoanProductData {
private MoneyData inArrearsTolerance;
private Integer numberOfRepayments;
private Integer loanTermFrequency;
private Integer repaymentEvery;
private BigDecimal interestRatePerPeriod = BigDecimal.ZERO;
private BigDecimal annualInterestRate = BigDecimal.ZERO;
@@ -54,6 +55,7 @@ public class LoanProductData {
public LoanProductData(DateTime createdOn, DateTime lastModifedOn, Long id,
String name, String description, MoneyData principal,
MoneyData tolerance, Integer numberOfRepayments,
Integer loanTermFrequency,
Integer repaymentEvery, BigDecimal interestRatePerPeriod,
BigDecimal annualInterestRate,
EnumOptionData loanTermFrequencyType,
@@ -70,6 +72,7 @@ public class LoanProductData {
this.principal = principal;
this.inArrearsTolerance = tolerance;
this.numberOfRepayments = numberOfRepayments;
this.loanTermFrequency = loanTermFrequency;
this.repaymentEvery = repaymentEvery;
this.interestRatePerPeriod = interestRatePerPeriod;
this.annualInterestRate = annualInterestRate;
@@ -165,6 +168,14 @@ public class LoanProductData {
public void setNumberOfRepayments(Integer numberOfRepayments) {
this.numberOfRepayments = numberOfRepayments;
}
public Integer getLoanTermFrequency() {
return loanTermFrequency;
}
public void setLoanTermFrequency(Integer loanTermFrequency) {
this.loanTermFrequency = loanTermFrequency;
}
public Integer getRepaymentEvery() {
return repaymentEvery;
@@ -933,6 +933,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("clientId", "productId", "externalId", "fundId", "transactionProcessingStrategyId",
"principal", "inArrearsTolerance", "interestRatePerPeriod", "repaymentEvery", "numberOfRepayments",
"loanTermFrequency", "loanTermFrequencyType",
"repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType",
"expectedDisbursementDate", "repaymentsStartingFromDate", "interestChargedFromDate", "submittedOnDate", "submittedOnNote",
"locale", "dateFormat")
@@ -956,6 +957,9 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Integer numberOfRepayments = extractIntegerParameter("numberOfRepayments", requestMap, modifiedParameters);
Integer repaymentFrequencyType = extractIntegerParameter("repaymentFrequencyType", requestMap, modifiedParameters);
Integer loanTermFrequency = extractIntegerParameter("loanTermFrequency", requestMap, modifiedParameters);
Integer loanTermFrequencyType = extractIntegerParameter("loanTermFrequencyType", requestMap, modifiedParameters);
Integer interestRateFrequencyTypeValue = extractIntegerParameter("interestRateFrequencyType", requestMap, modifiedParameters);
Integer amortizationTypeValue = extractIntegerParameter("amortizationType", requestMap, modifiedParameters);
Integer interestTypeValue = extractIntegerParameter("interestType", requestMap, modifiedParameters);
@@ -972,7 +976,9 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
submittedOnDate, submittedOnNote,
expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate,
principal, interestRatePerPeriod, interestRateFrequencyTypeValue, interestTypeValue, interestCalculationPeriodTypeValue,
repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationTypeValue, inArrearsToleranceValue);
repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationTypeValue,
loanTermFrequency, loanTermFrequencyType,
inArrearsToleranceValue);
}
@Override
@@ -270,7 +270,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
Integer repaidEvery = loan.getLoanRepaymentScheduleDetail().getRepayEvery();
Integer selectedRepaymentFrequency = loan.getLoanRepaymentScheduleDetail().getRepaymentPeriodFrequencyType().getValue();
Integer selectedRepaymentSchedule = loan.getLoanRepaymentScheduleDetail().getAmortizationMethod().getValue();
Integer selectedAmortizationMethod = loan.getLoanRepaymentScheduleDetail().getAmortizationMethod().getValue();
// FIXME - use values from loan table here instead of inferring.
Integer loanTermFrequency = repaidEvery * numberOfInstallments;
Integer loanTermFrequencyType = selectedRepaymentFrequency;
// use annual percentage rate to re-calculate loan schedule for late disbursement
BigDecimal interestRatePerPeriod = interestRatePerYear;
@@ -283,8 +287,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
loan.getLoanProduct().getId(),
principalAsDecimal,
interestRatePerPeriod, interestRateFrequencyMethod, interestMethod, interestCalculationInPeriod,
repaidEvery, selectedRepaymentFrequency, numberOfInstallments,
selectedRepaymentSchedule, actualDisbursementDate, repaymentsStartingFromDate, interestCalculatedFromDate);
repaidEvery, selectedRepaymentFrequency, numberOfInstallments, selectedAmortizationMethod,
loanTermFrequency, loanTermFrequencyType,
actualDisbursementDate, repaymentsStartingFromDate, interestCalculatedFromDate);
LoanSchedule loanSchedule = this.calculationPlatformService.calculateLoanSchedule(calculateCommand);
@@ -14,6 +14,8 @@ public interface LoanDropdownReadPlatformService {
List<EnumOptionData> retrieveLoanInterestRateCalculatedInPeriodOptions();
List<EnumOptionData> retrieveLoanTermFrequencyTypeOptions();
List<EnumOptionData> retrieveRepaymentFrequencyTypeOptions();
List<EnumOptionData> retrieveInterestRateFrequencyTypeOptions();
@@ -4,6 +4,7 @@ import static org.mifosng.platform.loanproduct.service.LoanEnumerations.amortiza
import static org.mifosng.platform.loanproduct.service.LoanEnumerations.interestCalculationPeriodType;
import static org.mifosng.platform.loanproduct.service.LoanEnumerations.interestRateFrequencyType;
import static org.mifosng.platform.loanproduct.service.LoanEnumerations.interestType;
import static org.mifosng.platform.loanproduct.service.LoanEnumerations.loanTermFrequencyType;
import static org.mifosng.platform.loanproduct.service.LoanEnumerations.repaymentFrequencyType;
import java.util.ArrayList;
@@ -60,6 +61,16 @@ public class LoanDropdownReadPlatformServiceImpl implements LoanDropdownReadPlat
return allowedOptions;
}
@Override
public List<EnumOptionData> retrieveLoanTermFrequencyTypeOptions() {
List<EnumOptionData> loanTermFrequencyOptions = Arrays.asList(
loanTermFrequencyType(PeriodFrequencyType.DAYS),
loanTermFrequencyType(PeriodFrequencyType.WEEKS),
loanTermFrequencyType(PeriodFrequencyType.MONTHS),
loanTermFrequencyType(PeriodFrequencyType.YEARS));
return loanTermFrequencyOptions;
}
@Override
public List<EnumOptionData> retrieveRepaymentFrequencyTypeOptions() {
@@ -105,13 +105,14 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
.amortizationType(AmortizationMethod.EQUAL_INSTALLMENTS));
productData.setInterestType(LoanEnumerations
.interestType(InterestMethod.DECLINING_BALANCE));
productData.setRepaymentFrequencyType(LoanEnumerations
.repaymentFrequencyType(PeriodFrequencyType.MONTHS));
productData.setInterestRateFrequencyType(LoanEnumerations
.interestRateFrequencyType(PeriodFrequencyType.MONTHS));
productData
.setInterestCalculationPeriodType(LoanEnumerations
.interestCalculationPeriodType(InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD));
productData.setLoanTermFrequencyType(LoanEnumerations.loanTermFrequencyType(PeriodFrequencyType.MONTHS));
productData.setRepaymentFrequencyType(LoanEnumerations.repaymentFrequencyType(PeriodFrequencyType.MONTHS));
productData.setInterestRateFrequencyType(LoanEnumerations.interestRateFrequencyType(PeriodFrequencyType.MONTHS));
productData.setInterestCalculationPeriodType(LoanEnumerations.interestCalculationPeriodType(InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD));
populateProductDataWithDropdownOptions(productData);
@@ -179,13 +180,11 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
MoneyData principalMoney = MoneyData.of(currencyData, principal);
MoneyData toleranceMoney = MoneyData.of(currencyData, tolerance);
Integer numberOfRepayments = JdbcSupport.getInteger(rs,
"numberOfRepayments");
Integer numberOfRepayments = JdbcSupport.getInteger(rs,"numberOfRepayments");
Integer repaymentEvery = JdbcSupport.getInteger(rs, "repaidEvery");
BigDecimal interestRatePerPeriod = rs
.getBigDecimal("interestRatePerPeriod");
BigDecimal annualInterestRate = rs
.getBigDecimal("annualInterestRate");
Integer loanTermFrequency = repaymentEvery * numberOfRepayments;
BigDecimal interestRatePerPeriod = rs.getBigDecimal("interestRatePerPeriod");
BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");
int repaymentFrequencyTypeId = JdbcSupport.getInteger(rs, "repaymentPeriodFrequency");
EnumOptionData repaymentFrequencyType = LoanEnumerations.repaymentFrequencyType(repaymentFrequencyTypeId);
@@ -213,7 +212,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
return new LoanProductData(createdOn, lastModifedOn, id, name,
description, principalMoney, toleranceMoney,
numberOfRepayments, repaymentEvery, interestRatePerPeriod,
numberOfRepayments, loanTermFrequency, repaymentEvery, interestRatePerPeriod,
annualInterestRate, loanTermFrequencyType, repaymentFrequencyType,
interestRateFrequencyType, amortizationType, interestType,
interestCalculationPeriodType, fundId, fundName, transactionStrategyId, transactionStrategyName);
@@ -246,6 +245,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
List<EnumOptionData> amortizationTypeOptions = dropdownReadPlatformService.retrieveLoanAmortizationTypeOptions();
List<EnumOptionData> interestTypeOptions = dropdownReadPlatformService.retrieveLoanInterestTypeOptions();
List<EnumOptionData> interestCalculationPeriodTypeOptions = dropdownReadPlatformService.retrieveLoanInterestRateCalculatedInPeriodOptions();
List<EnumOptionData> loanTermFrequencyTypeOptions = dropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions();
List<EnumOptionData> repaymentFrequencyTypeOptions = dropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions();
List<EnumOptionData> interestRateFrequencyTypeOptions = dropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions();
@@ -256,6 +256,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
productData.setAmortizationTypeOptions(amortizationTypeOptions);
productData.setInterestTypeOptions(interestTypeOptions);
productData.setInterestCalculationPeriodTypeOptions(interestCalculationPeriodTypeOptions);
productData.setLoanTermFrequencyTypeOptions(loanTermFrequencyTypeOptions);
productData.setRepaymentFrequencyTypeOptions(repaymentFrequencyTypeOptions);
productData.setInterestRateFrequencyTypeOptions(interestRateFrequencyTypeOptions);
productData.setFundOptions(fundOptions);
@@ -27,10 +27,12 @@ public class FlatLoanScheduleGenerator implements LoanScheduleGenerator {
List<ScheduledLoanInstallment> scheduledLoanInstallments = new ArrayList<ScheduledLoanInstallment>();
List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(
loanScheduleInfo, disbursementDate, firstRepaymentDate);
List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(loanScheduleInfo, disbursementDate, firstRepaymentDate);
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
// FIXME - use the expected loan term to work out interest due
// loan term = 9 months
Money principalPerInstallment = loanScheduleInfo.getPrincipal()
.dividedBy(loanScheduleInfo.getNumberOfRepayments(),
@@ -46,9 +48,7 @@ public class FlatLoanScheduleGenerator implements LoanScheduleGenerator {
.divide(BigDecimal.valueOf(Double.valueOf("100.0")), mc)
.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 totalPrincipal = Money.zero(outstandingBalance.getCurrency());
@@ -59,14 +59,11 @@ public class FlatLoanScheduleGenerator implements LoanScheduleGenerator {
totalPrincipal = totalPrincipal.plus(principalPerInstallment);
if (installmentNumber == loanScheduleInfo.getNumberOfRepayments()) {
Money difference = totalPrincipal.minus(loanScheduleInfo
.getPrincipal());
Money difference = totalPrincipal.minus(loanScheduleInfo.getPrincipal());
if (difference.isLessThanZero()) {
principalPerInstallment = principalPerInstallment
.plus(difference.abs());
principalPerInstallment = principalPerInstallment.plus(difference.abs());
} else if (difference.isGreaterThanZero()) {
principalPerInstallment = principalPerInstallment
.minus(difference.abs());
principalPerInstallment = principalPerInstallment.minus(difference.abs());
}
}