tidy up calculate loan schedule validation.
This commit is contained in:
+91
-84
@@ -10,23 +10,23 @@ import org.joda.time.LocalDate;
|
||||
public class CalculateLoanScheduleCommand {
|
||||
|
||||
private String currencyCode;
|
||||
private Integer digitsAfterDecimal;
|
||||
private BigDecimal principal;
|
||||
private BigDecimal inArrearsToleranceAmount;
|
||||
private Integer digitsAfterDecimalValue;
|
||||
private BigDecimal principalValue;
|
||||
private BigDecimal inArrearsToleranceValue;
|
||||
|
||||
private Integer repaymentEvery;
|
||||
private Integer repaymentFrequency;
|
||||
private Integer numberOfRepayments;
|
||||
private Integer repaymentEveryValue;
|
||||
private Integer repaymentFrequencyType;
|
||||
private Integer numberOfRepaymentsValue;
|
||||
|
||||
private BigDecimal interestRatePerPeriod;
|
||||
private Integer interestRateFrequencyMethod;
|
||||
private Integer amortizationMethod;
|
||||
private Integer interestMethod;
|
||||
private Integer interestCalculationPeriodMethod;
|
||||
private BigDecimal interestRatePerPeriodValue;
|
||||
private Integer interestRateFrequencyType;
|
||||
private Integer amortizationType;
|
||||
private Integer interestType;
|
||||
private Integer interestCalculationPeriodType;
|
||||
|
||||
private LocalDate expectedDisbursementDate;
|
||||
private LocalDate repaymentsStartingFromDate;
|
||||
private LocalDate interestCalculatedFromDate;
|
||||
private LocalDate expectedDisbursementLocalDate;
|
||||
private LocalDate repaymentsStartingFromLocalDate;
|
||||
private LocalDate interestChargedFromLocalDate;
|
||||
|
||||
protected CalculateLoanScheduleCommand() {
|
||||
//
|
||||
@@ -40,20 +40,24 @@ public class CalculateLoanScheduleCommand {
|
||||
final LocalDate repaymentsStartingFromDate, final LocalDate interestCalculatedFromDate) {
|
||||
|
||||
this.currencyCode = currencyCode;
|
||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
||||
this.principal = BigDecimal.valueOf(principal.doubleValue());
|
||||
this.interestRatePerPeriod = BigDecimal.valueOf(interestRatePerPeriod.doubleValue());
|
||||
this.interestRateFrequencyMethod = interestRateFrequencyMethod;
|
||||
this.interestMethod = interestMethod;
|
||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
||||
this.repaymentEvery = repaymentEvery;
|
||||
this.repaymentFrequency = repaymentFrequency;
|
||||
this.numberOfRepayments = numberOfRepayments;
|
||||
this.amortizationMethod = amortizationMethod;
|
||||
this.digitsAfterDecimalValue = digitsAfterDecimal;
|
||||
if (principal != null) {
|
||||
this.principalValue = BigDecimal.valueOf(principal.doubleValue());
|
||||
}
|
||||
if (interestRatePerPeriod != null) {
|
||||
this.interestRatePerPeriodValue = BigDecimal.valueOf(interestRatePerPeriod.doubleValue());
|
||||
}
|
||||
this.interestRateFrequencyType = interestRateFrequencyMethod;
|
||||
this.interestType = interestMethod;
|
||||
this.interestCalculationPeriodType = interestCalculationPeriodMethod;
|
||||
this.repaymentEveryValue = repaymentEvery;
|
||||
this.repaymentFrequencyType = repaymentFrequency;
|
||||
this.numberOfRepaymentsValue = numberOfRepayments;
|
||||
this.amortizationType = amortizationMethod;
|
||||
|
||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
||||
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
|
||||
this.interestCalculatedFromDate = interestCalculatedFromDate;
|
||||
this.expectedDisbursementLocalDate = expectedDisbursementDate;
|
||||
this.repaymentsStartingFromLocalDate = repaymentsStartingFromDate;
|
||||
this.interestChargedFromLocalDate= interestCalculatedFromDate;
|
||||
}
|
||||
|
||||
public String getCurrencyCode() {
|
||||
@@ -64,116 +68,119 @@ public class CalculateLoanScheduleCommand {
|
||||
this.currencyCode = currencyCode;
|
||||
}
|
||||
|
||||
public Integer getDigitsAfterDecimal() {
|
||||
return digitsAfterDecimal;
|
||||
public Integer getDigitsAfterDecimalValue() {
|
||||
return digitsAfterDecimalValue;
|
||||
}
|
||||
|
||||
public void setDigitsAfterDecimal(Integer digitsAfterDecimal) {
|
||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
||||
public void setDigitsAfterDecimalValue(Integer digitsAfterDecimalValue) {
|
||||
this.digitsAfterDecimalValue = digitsAfterDecimalValue;
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipal() {
|
||||
return principal;
|
||||
public BigDecimal getPrincipalValue() {
|
||||
return principalValue;
|
||||
}
|
||||
|
||||
public void setPrincipal(BigDecimal principal) {
|
||||
this.principal = principal;
|
||||
public void setPrincipalValue(BigDecimal principalValue) {
|
||||
this.principalValue = principalValue;
|
||||
}
|
||||
|
||||
public BigDecimal getInArrearsToleranceAmount() {
|
||||
return inArrearsToleranceAmount;
|
||||
public BigDecimal getInArrearsToleranceValue() {
|
||||
return inArrearsToleranceValue;
|
||||
}
|
||||
|
||||
public void setInArrearsToleranceAmount(BigDecimal inArrearsToleranceAmount) {
|
||||
this.inArrearsToleranceAmount = inArrearsToleranceAmount;
|
||||
public void setInArrearsToleranceValue(BigDecimal inArrearsToleranceValue) {
|
||||
this.inArrearsToleranceValue = inArrearsToleranceValue;
|
||||
}
|
||||
|
||||
public Integer getRepaymentEvery() {
|
||||
return repaymentEvery;
|
||||
public Integer getRepaymentEveryValue() {
|
||||
return repaymentEveryValue;
|
||||
}
|
||||
|
||||
public void setRepaymentEvery(Integer repaymentEvery) {
|
||||
this.repaymentEvery = repaymentEvery;
|
||||
public void setRepaymentEveryValue(Integer repaymentEveryValue) {
|
||||
this.repaymentEveryValue = repaymentEveryValue;
|
||||
}
|
||||
|
||||
public Integer getRepaymentFrequency() {
|
||||
return repaymentFrequency;
|
||||
public Integer getRepaymentFrequencyType() {
|
||||
return repaymentFrequencyType;
|
||||
}
|
||||
|
||||
public void setRepaymentFrequency(Integer repaymentFrequency) {
|
||||
this.repaymentFrequency = repaymentFrequency;
|
||||
public void setRepaymentFrequencyType(Integer repaymentFrequencyType) {
|
||||
this.repaymentFrequencyType = repaymentFrequencyType;
|
||||
}
|
||||
|
||||
public Integer getNumberOfRepayments() {
|
||||
return numberOfRepayments;
|
||||
public Integer getNumberOfRepaymentsValue() {
|
||||
return numberOfRepaymentsValue;
|
||||
}
|
||||
|
||||
public void setNumberOfRepayments(Integer numberOfRepayments) {
|
||||
this.numberOfRepayments = numberOfRepayments;
|
||||
public void setNumberOfRepaymentsValue(Integer numberOfRepaymentsValue) {
|
||||
this.numberOfRepaymentsValue = numberOfRepaymentsValue;
|
||||
}
|
||||
|
||||
public BigDecimal getInterestRatePerPeriod() {
|
||||
return interestRatePerPeriod;
|
||||
public BigDecimal getInterestRatePerPeriodValue() {
|
||||
return interestRatePerPeriodValue;
|
||||
}
|
||||
|
||||
public void setInterestRatePerPeriod(BigDecimal interestRatePerPeriod) {
|
||||
this.interestRatePerPeriod = interestRatePerPeriod;
|
||||
public void setInterestRatePerPeriodValue(BigDecimal interestRatePerPeriodValue) {
|
||||
this.interestRatePerPeriodValue = interestRatePerPeriodValue;
|
||||
}
|
||||
|
||||
public Integer getInterestRateFrequencyMethod() {
|
||||
return interestRateFrequencyMethod;
|
||||
public Integer getInterestRateFrequencyType() {
|
||||
return interestRateFrequencyType;
|
||||
}
|
||||
|
||||
public void setInterestRateFrequencyMethod(Integer interestRateFrequencyMethod) {
|
||||
this.interestRateFrequencyMethod = interestRateFrequencyMethod;
|
||||
public void setInterestRateFrequencyType(Integer interestRateFrequencyType) {
|
||||
this.interestRateFrequencyType = interestRateFrequencyType;
|
||||
}
|
||||
|
||||
public Integer getAmortizationMethod() {
|
||||
return amortizationMethod;
|
||||
public Integer getAmortizationType() {
|
||||
return amortizationType;
|
||||
}
|
||||
|
||||
public void setAmortizationMethod(Integer amortizationMethod) {
|
||||
this.amortizationMethod = amortizationMethod;
|
||||
public void setAmortizationType(Integer amortizationType) {
|
||||
this.amortizationType = amortizationType;
|
||||
}
|
||||
|
||||
public Integer getInterestMethod() {
|
||||
return interestMethod;
|
||||
public Integer getInterestType() {
|
||||
return interestType;
|
||||
}
|
||||
|
||||
public void setInterestMethod(Integer interestMethod) {
|
||||
this.interestMethod = interestMethod;
|
||||
public void setInterestType(Integer interestType) {
|
||||
this.interestType = interestType;
|
||||
}
|
||||
|
||||
public Integer getInterestCalculationPeriodMethod() {
|
||||
return interestCalculationPeriodMethod;
|
||||
public Integer getInterestCalculationPeriodType() {
|
||||
return interestCalculationPeriodType;
|
||||
}
|
||||
|
||||
public void setInterestCalculationPeriodMethod(
|
||||
Integer interestCalculationPeriodMethod) {
|
||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
||||
public void setInterestCalculationPeriodType(
|
||||
Integer interestCalculationPeriodType) {
|
||||
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
||||
}
|
||||
|
||||
public LocalDate getExpectedDisbursementDate() {
|
||||
return expectedDisbursementDate;
|
||||
public LocalDate getExpectedDisbursementLocalDate() {
|
||||
return expectedDisbursementLocalDate;
|
||||
}
|
||||
|
||||
public void setExpectedDisbursementDate(LocalDate expectedDisbursementDate) {
|
||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
||||
public void setExpectedDisbursementLocalDate(
|
||||
LocalDate expectedDisbursementLocalDate) {
|
||||
this.expectedDisbursementLocalDate = expectedDisbursementLocalDate;
|
||||
}
|
||||
|
||||
public LocalDate getRepaymentsStartingFromDate() {
|
||||
return repaymentsStartingFromDate;
|
||||
public LocalDate getRepaymentsStartingFromLocalDate() {
|
||||
return repaymentsStartingFromLocalDate;
|
||||
}
|
||||
|
||||
public void setRepaymentsStartingFromDate(LocalDate repaymentsStartingFromDate) {
|
||||
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
|
||||
public void setRepaymentsStartingFromLocalDate(
|
||||
LocalDate repaymentsStartingFromLocalDate) {
|
||||
this.repaymentsStartingFromLocalDate = repaymentsStartingFromLocalDate;
|
||||
}
|
||||
|
||||
public LocalDate getInterestCalculatedFromDate() {
|
||||
return interestCalculatedFromDate;
|
||||
public LocalDate getInterestChargedFromLocalDate() {
|
||||
return interestChargedFromLocalDate;
|
||||
}
|
||||
|
||||
public void setInterestCalculatedFromDate(LocalDate interestCalculatedFromDate) {
|
||||
this.interestCalculatedFromDate = interestCalculatedFromDate;
|
||||
public void setInterestChargedFromLocalDate(
|
||||
LocalDate interestChargedFromLocalDate) {
|
||||
this.interestChargedFromLocalDate = interestChargedFromLocalDate;
|
||||
}
|
||||
}
|
||||
+253
-218
@@ -10,38 +10,44 @@ import org.mifosng.data.LoanSchedule;
|
||||
@XmlRootElement
|
||||
public class SubmitLoanApplicationCommand {
|
||||
|
||||
private Long applicantId;
|
||||
private Long clientId;
|
||||
private Long productId;
|
||||
|
||||
// product
|
||||
private String locale;
|
||||
private String currencyCode;
|
||||
private Integer digitsAfterDecimal;
|
||||
private String principalFormatted;
|
||||
private BigDecimal principal;
|
||||
private String inArrearsToleranceAmountFormatted;
|
||||
private BigDecimal inArrearsToleranceAmount;
|
||||
private String digitsAfterDecimal;
|
||||
private Integer digitsAfterDecimalValue;
|
||||
private BigDecimal principalValue;
|
||||
private String principal;
|
||||
private BigDecimal inArrearsToleranceValue;
|
||||
private String inArrearsTolerance;
|
||||
|
||||
private Integer repaymentEvery;
|
||||
private Integer repaymentFrequency;
|
||||
private Integer numberOfRepayments;
|
||||
private String numberOfRepayments;
|
||||
private Integer numberOfRepaymentsValue;
|
||||
private String repaymentEvery;
|
||||
private Integer repaymentEveryValue;
|
||||
|
||||
private String interestRatePerPeriodFormatted;
|
||||
private BigDecimal interestRatePerPeriod;
|
||||
private Integer interestRateFrequencyMethod;
|
||||
private Integer amortizationMethod;
|
||||
private Integer interestMethod;
|
||||
private Integer interestCalculationPeriodMethod;
|
||||
private String interestRatePerPeriod;
|
||||
private BigDecimal interestRatePerPeriodValue;
|
||||
|
||||
private Integer repaymentFrequencyType;
|
||||
private Integer interestRateFrequencyType;
|
||||
private Integer amortizationType;
|
||||
private Integer interestType;
|
||||
private Integer interestCalculationPeriodType;
|
||||
// end of product related fields
|
||||
|
||||
private String expectedDisbursementDateFormatted;
|
||||
private String repaymentsStartingFromDateFormatted;
|
||||
private String interestCalculatedFromDateFormatted;
|
||||
private LocalDate expectedDisbursementDate;
|
||||
private LocalDate repaymentsStartingFromDate;
|
||||
private LocalDate interestCalculatedFromDate;
|
||||
private String expectedDisbursementDate;
|
||||
private String repaymentsStartingFromDate;
|
||||
private String interestChargedFromDate;
|
||||
private LocalDate expectedDisbursementLocalDate;
|
||||
private LocalDate repaymentsStartingFromLocalDate;
|
||||
private LocalDate interestChargedFromLocalDate;
|
||||
|
||||
private String dateFormat;
|
||||
private String submittedOnDateFormatted;
|
||||
private LocalDate submittedOnDate;
|
||||
private String submittedOnDate;
|
||||
private LocalDate submittedOnLocalDate;
|
||||
private String submittedOnNote;
|
||||
private String externalId;
|
||||
|
||||
@@ -51,49 +57,42 @@ public class SubmitLoanApplicationCommand {
|
||||
//
|
||||
}
|
||||
|
||||
public SubmitLoanApplicationCommand(final Long applicantId,
|
||||
public SubmitLoanApplicationCommand(final Long clientId,
|
||||
final Long productId, final LocalDate submittedOnDate,
|
||||
final String submittedOnNote,
|
||||
final LocalDate expectedDisbursementDate,
|
||||
final LocalDate repaymentsStartingFromDate,
|
||||
final LocalDate interestCalculatedFromDate,
|
||||
final LocalDate interestChargedFromLocalDate,
|
||||
final LoanSchedule loanSchedule, final String currencyCode,
|
||||
final Integer digitsAfterDecimal, final Number principal,
|
||||
final Number interestRatePerPeriod, Integer interestRateFrequencyMethod, final Integer interestMethod, final Integer interestCalculationPeriodMethod,
|
||||
final Integer repaymentEvery, final Integer repaymentFrequency, final Integer numberOfRepayments, Integer amortizationMethod, final Number toleranceAmount) {
|
||||
this.applicantId = applicantId;
|
||||
this.clientId = clientId;
|
||||
this.productId = productId;
|
||||
this.submittedOnDate = submittedOnDate;
|
||||
this.submittedOnLocalDate = submittedOnDate;
|
||||
this.submittedOnNote = submittedOnNote;
|
||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
||||
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
|
||||
this.interestCalculatedFromDate = interestCalculatedFromDate;
|
||||
this.expectedDisbursementLocalDate = expectedDisbursementDate;
|
||||
this.repaymentsStartingFromLocalDate = repaymentsStartingFromDate;
|
||||
this.interestChargedFromLocalDate = interestChargedFromLocalDate;
|
||||
this.loanSchedule = loanSchedule;
|
||||
this.inArrearsToleranceAmount = BigDecimal.valueOf(toleranceAmount.doubleValue());
|
||||
this.inArrearsToleranceValue = BigDecimal.valueOf(toleranceAmount.doubleValue());
|
||||
|
||||
this.currencyCode = currencyCode;
|
||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
||||
this.principal = BigDecimal.valueOf(principal.doubleValue());
|
||||
this.interestRatePerPeriod = BigDecimal.valueOf(interestRatePerPeriod.doubleValue());
|
||||
this.interestRateFrequencyMethod = interestRateFrequencyMethod;
|
||||
this.interestMethod = interestMethod;
|
||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
||||
this.repaymentEvery = repaymentEvery;
|
||||
this.repaymentFrequency = repaymentFrequency;
|
||||
this.numberOfRepayments = numberOfRepayments;
|
||||
this.amortizationMethod = amortizationMethod;
|
||||
this.digitsAfterDecimalValue = digitsAfterDecimal;
|
||||
this.principalValue = BigDecimal.valueOf(principal.doubleValue());
|
||||
this.interestRatePerPeriodValue = BigDecimal.valueOf(interestRatePerPeriod.doubleValue());
|
||||
this.interestRateFrequencyType = interestRateFrequencyMethod;
|
||||
this.interestType = interestMethod;
|
||||
this.interestCalculationPeriodType = interestCalculationPeriodMethod;
|
||||
this.repaymentEveryValue = repaymentEvery;
|
||||
this.repaymentFrequencyType = repaymentFrequency;
|
||||
this.numberOfRepaymentsValue = numberOfRepayments;
|
||||
this.amortizationType = amortizationMethod;
|
||||
}
|
||||
|
||||
public CalculateLoanScheduleCommand toCalculateLoanScheduleCommand() {
|
||||
return new CalculateLoanScheduleCommand(currencyCode, digitsAfterDecimal, principal, interestRatePerPeriod, interestRateFrequencyMethod, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentFrequency, numberOfRepayments, amortizationMethod, expectedDisbursementDate, repaymentsStartingFromDate, interestCalculatedFromDate);
|
||||
}
|
||||
|
||||
public Long getApplicantId() {
|
||||
return this.applicantId;
|
||||
}
|
||||
|
||||
public void setApplicantId(final Long applicantId) {
|
||||
this.applicantId = applicantId;
|
||||
return new CalculateLoanScheduleCommand(currencyCode, digitsAfterDecimalValue, principalValue, interestRatePerPeriodValue, interestRateFrequencyType, interestType, interestCalculationPeriodType, repaymentEveryValue, repaymentFrequencyType, numberOfRepaymentsValue, amortizationType,
|
||||
expectedDisbursementLocalDate, repaymentsStartingFromLocalDate, interestChargedFromLocalDate);
|
||||
}
|
||||
|
||||
public Long getProductId() {
|
||||
@@ -104,14 +103,6 @@ public class SubmitLoanApplicationCommand {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public LocalDate getSubmittedOnDate() {
|
||||
return this.submittedOnDate;
|
||||
}
|
||||
|
||||
public void setSubmittedOnDate(final LocalDate submittedOnDate) {
|
||||
this.submittedOnDate = submittedOnDate;
|
||||
}
|
||||
|
||||
public String getSubmittedOnNote() {
|
||||
return this.submittedOnNote;
|
||||
}
|
||||
@@ -120,24 +111,6 @@ public class SubmitLoanApplicationCommand {
|
||||
this.submittedOnNote = submittedOnNote;
|
||||
}
|
||||
|
||||
public LocalDate getExpectedDisbursementDate() {
|
||||
return this.expectedDisbursementDate;
|
||||
}
|
||||
|
||||
public void setExpectedDisbursementDate(
|
||||
final LocalDate expectedDisbursementDate) {
|
||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
||||
}
|
||||
|
||||
public LocalDate getRepaymentsStartingFromDate() {
|
||||
return this.repaymentsStartingFromDate;
|
||||
}
|
||||
|
||||
public void setRepaymentsStartingFromDate(
|
||||
final LocalDate repaymentsStartingFromDate) {
|
||||
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
|
||||
}
|
||||
|
||||
public LoanSchedule getLoanSchedule() {
|
||||
return this.loanSchedule;
|
||||
}
|
||||
@@ -162,130 +135,6 @@ public class SubmitLoanApplicationCommand {
|
||||
this.currencyCode = currencyCode;
|
||||
}
|
||||
|
||||
public Integer getDigitsAfterDecimal() {
|
||||
return digitsAfterDecimal;
|
||||
}
|
||||
|
||||
public void setDigitsAfterDecimal(Integer digitsAfterDecimal) {
|
||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public void setPrincipal(BigDecimal principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public BigDecimal getInArrearsToleranceAmount() {
|
||||
return inArrearsToleranceAmount;
|
||||
}
|
||||
|
||||
public void setInArrearsToleranceAmount(BigDecimal inArrearsToleranceAmount) {
|
||||
this.inArrearsToleranceAmount = inArrearsToleranceAmount;
|
||||
}
|
||||
|
||||
public Integer getRepaymentEvery() {
|
||||
return repaymentEvery;
|
||||
}
|
||||
|
||||
public void setRepaymentEvery(Integer repaymentEvery) {
|
||||
this.repaymentEvery = repaymentEvery;
|
||||
}
|
||||
|
||||
public Integer getRepaymentFrequency() {
|
||||
return repaymentFrequency;
|
||||
}
|
||||
|
||||
public void setRepaymentFrequency(Integer repaymentFrequency) {
|
||||
this.repaymentFrequency = repaymentFrequency;
|
||||
}
|
||||
|
||||
public Integer getNumberOfRepayments() {
|
||||
return numberOfRepayments;
|
||||
}
|
||||
|
||||
public void setNumberOfRepayments(Integer numberOfRepayments) {
|
||||
this.numberOfRepayments = numberOfRepayments;
|
||||
}
|
||||
|
||||
public BigDecimal getInterestRatePerPeriod() {
|
||||
return interestRatePerPeriod;
|
||||
}
|
||||
|
||||
public void setInterestRatePerPeriod(BigDecimal interestRatePerPeriod) {
|
||||
this.interestRatePerPeriod = interestRatePerPeriod;
|
||||
}
|
||||
|
||||
public Integer getInterestRateFrequencyMethod() {
|
||||
return interestRateFrequencyMethod;
|
||||
}
|
||||
|
||||
public void setInterestRateFrequencyMethod(Integer interestRateFrequencyMethod) {
|
||||
this.interestRateFrequencyMethod = interestRateFrequencyMethod;
|
||||
}
|
||||
|
||||
public Integer getAmortizationMethod() {
|
||||
return amortizationMethod;
|
||||
}
|
||||
|
||||
public void setAmortizationMethod(Integer amortizationMethod) {
|
||||
this.amortizationMethod = amortizationMethod;
|
||||
}
|
||||
|
||||
public Integer getInterestMethod() {
|
||||
return interestMethod;
|
||||
}
|
||||
|
||||
public void setInterestMethod(Integer interestMethod) {
|
||||
this.interestMethod = interestMethod;
|
||||
}
|
||||
|
||||
public Integer getInterestCalculationPeriodMethod() {
|
||||
return interestCalculationPeriodMethod;
|
||||
}
|
||||
|
||||
public void setInterestCalculationPeriodMethod(
|
||||
Integer interestCalculationPeriodMethod) {
|
||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
||||
}
|
||||
|
||||
public LocalDate getInterestCalculatedFromDate() {
|
||||
return interestCalculatedFromDate;
|
||||
}
|
||||
|
||||
public void setInterestCalculatedFromDate(LocalDate interestCalculatedFromDate) {
|
||||
this.interestCalculatedFromDate = interestCalculatedFromDate;
|
||||
}
|
||||
|
||||
public String getExpectedDisbursementDateFormatted() {
|
||||
return expectedDisbursementDateFormatted;
|
||||
}
|
||||
|
||||
public void setExpectedDisbursementDateFormatted(
|
||||
String expectedDisbursementDateFormatted) {
|
||||
this.expectedDisbursementDateFormatted = expectedDisbursementDateFormatted;
|
||||
}
|
||||
|
||||
public String getRepaymentsStartingFromDateFormatted() {
|
||||
return repaymentsStartingFromDateFormatted;
|
||||
}
|
||||
|
||||
public void setRepaymentsStartingFromDateFormatted(
|
||||
String repaymentsStartingFromDateFormatted) {
|
||||
this.repaymentsStartingFromDateFormatted = repaymentsStartingFromDateFormatted;
|
||||
}
|
||||
|
||||
public String getInterestCalculatedFromDateFormatted() {
|
||||
return interestCalculatedFromDateFormatted;
|
||||
}
|
||||
|
||||
public void setInterestCalculatedFromDateFormatted(
|
||||
String interestCalculatedFromDateFormatted) {
|
||||
this.interestCalculatedFromDateFormatted = interestCalculatedFromDateFormatted;
|
||||
}
|
||||
|
||||
public String getDateFormat() {
|
||||
return dateFormat;
|
||||
}
|
||||
@@ -294,37 +143,223 @@ public class SubmitLoanApplicationCommand {
|
||||
this.dateFormat = dateFormat;
|
||||
}
|
||||
|
||||
public String getSubmittedOnDateFormatted() {
|
||||
return submittedOnDateFormatted;
|
||||
public Long getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setSubmittedOnDateFormatted(String submittedOnDateFormatted) {
|
||||
this.submittedOnDateFormatted = submittedOnDateFormatted;
|
||||
public void setClientId(Long clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public String getPrincipalFormatted() {
|
||||
return principalFormatted;
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setPrincipalFormatted(String principalFormatted) {
|
||||
this.principalFormatted = principalFormatted;
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public String getInArrearsToleranceAmountFormatted() {
|
||||
return inArrearsToleranceAmountFormatted;
|
||||
public String getDigitsAfterDecimal() {
|
||||
return digitsAfterDecimal;
|
||||
}
|
||||
|
||||
public void setInArrearsToleranceAmountFormatted(
|
||||
String inArrearsToleranceAmountFormatted) {
|
||||
this.inArrearsToleranceAmountFormatted = inArrearsToleranceAmountFormatted;
|
||||
public void setDigitsAfterDecimal(String digitsAfterDecimal) {
|
||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
||||
}
|
||||
|
||||
public String getInterestRatePerPeriodFormatted() {
|
||||
return interestRatePerPeriodFormatted;
|
||||
public Integer getDigitsAfterDecimalValue() {
|
||||
return digitsAfterDecimalValue;
|
||||
}
|
||||
|
||||
public void setInterestRatePerPeriodFormatted(
|
||||
String interestRatePerPeriodFormatted) {
|
||||
this.interestRatePerPeriodFormatted = interestRatePerPeriodFormatted;
|
||||
public void setDigitsAfterDecimalValue(Integer digitsAfterDecimalValue) {
|
||||
this.digitsAfterDecimalValue = digitsAfterDecimalValue;
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipalValue() {
|
||||
return principalValue;
|
||||
}
|
||||
|
||||
public void setPrincipalValue(BigDecimal principalValue) {
|
||||
this.principalValue = principalValue;
|
||||
}
|
||||
|
||||
public String getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public void setPrincipal(String principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public BigDecimal getInArrearsToleranceValue() {
|
||||
return inArrearsToleranceValue;
|
||||
}
|
||||
|
||||
public void setInArrearsToleranceValue(BigDecimal inArrearsToleranceValue) {
|
||||
this.inArrearsToleranceValue = inArrearsToleranceValue;
|
||||
}
|
||||
|
||||
public String getInArrearsTolerance() {
|
||||
return inArrearsTolerance;
|
||||
}
|
||||
|
||||
public void setInArrearsTolerance(String inArrearsTolerance) {
|
||||
this.inArrearsTolerance = inArrearsTolerance;
|
||||
}
|
||||
|
||||
public String getNumberOfRepayments() {
|
||||
return numberOfRepayments;
|
||||
}
|
||||
|
||||
public void setNumberOfRepayments(String numberOfRepayments) {
|
||||
this.numberOfRepayments = numberOfRepayments;
|
||||
}
|
||||
|
||||
public Integer getNumberOfRepaymentsValue() {
|
||||
return numberOfRepaymentsValue;
|
||||
}
|
||||
|
||||
public void setNumberOfRepaymentsValue(Integer numberOfRepaymentsValue) {
|
||||
this.numberOfRepaymentsValue = numberOfRepaymentsValue;
|
||||
}
|
||||
|
||||
public String getRepaymentEvery() {
|
||||
return repaymentEvery;
|
||||
}
|
||||
|
||||
public void setRepaymentEvery(String repaymentEvery) {
|
||||
this.repaymentEvery = repaymentEvery;
|
||||
}
|
||||
|
||||
public Integer getRepaymentEveryValue() {
|
||||
return repaymentEveryValue;
|
||||
}
|
||||
|
||||
public void setRepaymentEveryValue(Integer repaymentEveryValue) {
|
||||
this.repaymentEveryValue = repaymentEveryValue;
|
||||
}
|
||||
|
||||
public String getInterestRatePerPeriod() {
|
||||
return interestRatePerPeriod;
|
||||
}
|
||||
|
||||
public void setInterestRatePerPeriod(String interestRatePerPeriod) {
|
||||
this.interestRatePerPeriod = interestRatePerPeriod;
|
||||
}
|
||||
|
||||
public BigDecimal getInterestRatePerPeriodValue() {
|
||||
return interestRatePerPeriodValue;
|
||||
}
|
||||
|
||||
public void setInterestRatePerPeriodValue(BigDecimal interestRatePerPeriodValue) {
|
||||
this.interestRatePerPeriodValue = interestRatePerPeriodValue;
|
||||
}
|
||||
|
||||
public Integer getRepaymentFrequencyType() {
|
||||
return repaymentFrequencyType;
|
||||
}
|
||||
|
||||
public void setRepaymentFrequencyType(Integer repaymentFrequencyType) {
|
||||
this.repaymentFrequencyType = repaymentFrequencyType;
|
||||
}
|
||||
|
||||
public Integer getInterestRateFrequencyType() {
|
||||
return interestRateFrequencyType;
|
||||
}
|
||||
|
||||
public void setInterestRateFrequencyType(Integer interestRateFrequencyType) {
|
||||
this.interestRateFrequencyType = interestRateFrequencyType;
|
||||
}
|
||||
|
||||
public Integer getAmortizationType() {
|
||||
return amortizationType;
|
||||
}
|
||||
|
||||
public void setAmortizationType(Integer amortizationType) {
|
||||
this.amortizationType = amortizationType;
|
||||
}
|
||||
|
||||
public Integer getInterestType() {
|
||||
return interestType;
|
||||
}
|
||||
|
||||
public void setInterestType(Integer interestType) {
|
||||
this.interestType = interestType;
|
||||
}
|
||||
|
||||
public Integer getInterestCalculationPeriodType() {
|
||||
return interestCalculationPeriodType;
|
||||
}
|
||||
|
||||
public void setInterestCalculationPeriodType(
|
||||
Integer interestCalculationPeriodType) {
|
||||
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
||||
}
|
||||
|
||||
public String getExpectedDisbursementDate() {
|
||||
return expectedDisbursementDate;
|
||||
}
|
||||
|
||||
public void setExpectedDisbursementDate(String expectedDisbursementDate) {
|
||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
||||
}
|
||||
|
||||
public String getRepaymentsStartingFromDate() {
|
||||
return repaymentsStartingFromDate;
|
||||
}
|
||||
|
||||
public void setRepaymentsStartingFromDate(String repaymentsStartingFromDate) {
|
||||
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
|
||||
}
|
||||
|
||||
public LocalDate getExpectedDisbursementLocalDate() {
|
||||
return expectedDisbursementLocalDate;
|
||||
}
|
||||
|
||||
public void setExpectedDisbursementLocalDate(
|
||||
LocalDate expectedDisbursementLocalDate) {
|
||||
this.expectedDisbursementLocalDate = expectedDisbursementLocalDate;
|
||||
}
|
||||
|
||||
public LocalDate getRepaymentsStartingFromLocalDate() {
|
||||
return repaymentsStartingFromLocalDate;
|
||||
}
|
||||
|
||||
public void setRepaymentsStartingFromLocalDate(
|
||||
LocalDate repaymentsStartingFromLocalDate) {
|
||||
this.repaymentsStartingFromLocalDate = repaymentsStartingFromLocalDate;
|
||||
}
|
||||
|
||||
public LocalDate getInterestChargedFromLocalDate() {
|
||||
return interestChargedFromLocalDate;
|
||||
}
|
||||
|
||||
public void setInterestChargedFromLocalDate(
|
||||
LocalDate interestChargedFromLocalDate) {
|
||||
this.interestChargedFromLocalDate = interestChargedFromLocalDate;
|
||||
}
|
||||
|
||||
public String getSubmittedOnDate() {
|
||||
return submittedOnDate;
|
||||
}
|
||||
|
||||
public void setSubmittedOnDate(String submittedOnDate) {
|
||||
this.submittedOnDate = submittedOnDate;
|
||||
}
|
||||
|
||||
public LocalDate getSubmittedOnLocalDate() {
|
||||
return submittedOnLocalDate;
|
||||
}
|
||||
|
||||
public void setSubmittedOnLocalDate(LocalDate submittedOnLocalDate) {
|
||||
this.submittedOnLocalDate = submittedOnLocalDate;
|
||||
}
|
||||
|
||||
public String getInterestChargedFromDate() {
|
||||
return interestChargedFromDate;
|
||||
}
|
||||
|
||||
public void setInterestChargedFromDate(String interestChargedFromDate) {
|
||||
this.interestChargedFromDate = interestChargedFromDate;
|
||||
}
|
||||
}
|
||||
+17
-6
@@ -109,10 +109,6 @@ validation.msg.loan.transaction.id.is.invalid=Loan transaction identifier is inv
|
||||
validation.msg.loan.state.transition.date.cannot.be.blank=A date must be provided when transitioning the loan into this state.
|
||||
validation.msg.note.exceeds.max.length=The content of the note exceeds max length of 1000 characters.
|
||||
|
||||
validation.msg.loan.repayment.date.cannot.be.blank=The repayment date cannot be blank.
|
||||
validation.msg.loan.repayment.must.be.greater.than.zero=The repayment amount must be a number greater than zero.
|
||||
validation.msg.loan.adjustment.must.be.zero.or.greater=The repayment amount must be a number greater than or equal to zero.
|
||||
|
||||
# loan event and transactions screens
|
||||
label.loan.on=On:
|
||||
label.loan.action.note=Note:
|
||||
@@ -128,7 +124,6 @@ dialog.title.waive.loan=Waive outstanding amount
|
||||
label.loan.transaction.on=Repayment on:
|
||||
label.loan.transaction.amount=Amount:
|
||||
|
||||
|
||||
tab.client.account.loan.details=Details
|
||||
tab.client.account.loan.schedule=Schedule
|
||||
tab.client.account.loan.repayments=Repayments
|
||||
@@ -211,7 +206,23 @@ form.label.loan.interest.charged.from=Interest charged from:
|
||||
form.label.loan.expected.disbursement.date.on=Expected disbursement on:
|
||||
form.label.loan.first.repayment.on=First repayment on:
|
||||
|
||||
validation.msg.loan.expectedDisbursementDate.method.cannot.be.blank=Expected disbursement on field cannot be blank.
|
||||
validation.msg.loan.digitsAfterDecimal.cannot.be.blank=You must enter a number to represent number of digits after decimal to be supported for product.
|
||||
validation.msg.loan.digitsAfterDecimal.is.not.within.expected.range=Decimal places must be a number between {1} and {2} inclusive.
|
||||
validation.msg.loan.repaymentEvery.cannot.be.blank=Repaid every cannot be blank.
|
||||
validation.msg.loan.repaymentEvery.not.greater.than.zero=Repaid every must be greater than 0.
|
||||
validation.msg.loan.numberOfRepayments.cannot.be.blank=# of repayments cannot be blank.
|
||||
validation.msg.loan.numberOfRepayments.not.greater.than.zero=# of repayments must be greater than 0.
|
||||
validation.msg.loan.principal.cannot.be.blank=Loan amount cannot be blank.
|
||||
validation.msg.loan.inArrearsTolerance.cannot.be.blank=Arrears tolerance cannot be blank.
|
||||
validation.msg.loan.interestRatePerPeriod.cannot.be.blank=Nominal interest rate % cannot be blank.
|
||||
validation.msg.loan.principal.not.greater.than.zero=Loan amount must be greater than zero.
|
||||
validation.msg.loan.inArrearsTolerance.not.zero.or.greater=Arrears tolerance must be greater than or equal to zero.
|
||||
validation.msg.loan.interest.rate.per.period.amount.cannot.be.negative=Nominal interest rate % cannot be negative.
|
||||
validation.msg.loan.repayment.date.cannot.be.blank=The repayment date cannot be blank.
|
||||
validation.msg.loan.repayment.must.be.greater.than.zero=The repayment amount must be a number greater than zero.
|
||||
validation.msg.loan.adjustment.must.be.zero.or.greater=The repayment amount must be a number greater than or equal to zero.
|
||||
|
||||
validation.msg.loan.expectedDisbursementDate.cannot.be.blank=Expected disbursement on field cannot be blank.
|
||||
validation.msg.loan.expectedDisbursementDate.cannot.be.after.first.repayment.date=Expected disbursement date cannot be after the first repayment date.
|
||||
validation.msg.loan.interestCalculatedFromDate.must.be.entered.when.using.repayments.startfrom.field=The date interest is to be calculated from cannot be left blank when a date is provided for when repayments start from.
|
||||
validation.msg.loan.submitted.on.date.cannot.be.blank=Submitted on date cannot be blank.
|
||||
|
||||
+33
-21
@@ -55,9 +55,28 @@ $(document).ready(function() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
globalDate: function(localDateAsISOString) {
|
||||
globalDate: function(dateParts) {
|
||||
try {
|
||||
if (localDateAsISOString === null) return "";
|
||||
|
||||
if (dateParts === null || dateParts === '') return "";
|
||||
|
||||
var year = dateParts[0];
|
||||
var month = parseInt(dateParts[1]) - 1; // month is zero indexed
|
||||
var day = dateParts[2];
|
||||
|
||||
var d = new Date();
|
||||
d.setFullYear(year,month,day);
|
||||
|
||||
return Globalize.format(d,"dd MMMM yyyy");
|
||||
} catch(e) {
|
||||
return "??";
|
||||
}
|
||||
},
|
||||
globalDateAsISOString: function(localDateAsISOString) {
|
||||
|
||||
try {
|
||||
if (localDateAsISOString === null || localDateAsISOString === '') return "";
|
||||
|
||||
var dateParts = localDateAsISOString.split("-")
|
||||
var year = dateParts[0];
|
||||
var month = parseInt(dateParts[1]) - 1; // month is zero indexed
|
||||
@@ -177,13 +196,13 @@ $(document).ready(function() {
|
||||
};
|
||||
|
||||
function calculateAnnualPercentageRate() {
|
||||
var periodInterestRate = parseFloat($('#interestRatePerPeriodFormatted').val());
|
||||
var periodInterestRate = parseFloat($('#interestRatePerPeriod').val());
|
||||
if (isNaN(periodInterestRate)) {
|
||||
periodInterestRate = 0;
|
||||
}
|
||||
|
||||
var periodsInYear = 12;
|
||||
var periodType = $('#interestRateFrequencyMethod').val();
|
||||
var periodType = $('#interestRateFrequencyType').val();
|
||||
if (periodType == 3) {
|
||||
periodsInYear = 1;
|
||||
} else if (periodType == 2) {
|
||||
@@ -207,7 +226,6 @@ $(document).ready(function() {
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
beforeSend: function(xhr) {
|
||||
console.log("base64: " + base64);
|
||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||
},
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
@@ -228,7 +246,7 @@ $(document).ready(function() {
|
||||
calculateLoanSchedule();
|
||||
|
||||
// change detection
|
||||
$('#principalFormatted').change(function() {
|
||||
$('#principal').change(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
@@ -236,7 +254,7 @@ $(document).ready(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#repaymentFrequency').change(function() {
|
||||
$('#repaymentFrequencyType').change(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
@@ -244,37 +262,37 @@ $(document).ready(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#expectedDisbursementDateFormatted').change(function() {
|
||||
$('#expectedDisbursementDate').change(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#repaymentsStartingFromDateFormatted').change(function() {
|
||||
$('#repaymentsStartingFromDate').change(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#interestRatePerPeriodFormatted').change(function() {
|
||||
$('#interestRatePerPeriod').change(function() {
|
||||
calculateAnnualPercentageRate();
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#interestRateFrequencyMethod').change(function() {
|
||||
$('#interestRateFrequencyType').change(function() {
|
||||
calculateAnnualPercentageRate();
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#amortizationMethod').change(function() {
|
||||
$('#amortizationType').change(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#interestMethod').change(function() {
|
||||
$('#interestType').change(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#interestCalculationPeriodMethod').change(function() {
|
||||
$('#interestCalculationPeriodType').change(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
$('#interestCalculatedFromDateFormatted').change(function() {
|
||||
$('#interestChargedFromDate').change(function() {
|
||||
calculateLoanSchedule();
|
||||
});
|
||||
|
||||
@@ -302,7 +320,6 @@ $(document).ready(function() {
|
||||
var calculateLoanScheduleurl = baseApiUrl + 'loans?command=calculateLoanSchedule';
|
||||
|
||||
var newFormData = JSON.stringify($('#entityform').serializeObject());
|
||||
console.log(newFormData);
|
||||
|
||||
var jqxhr2 = $.ajax({
|
||||
url: calculateLoanScheduleurl,
|
||||
@@ -312,7 +329,6 @@ $(document).ready(function() {
|
||||
data: newFormData,
|
||||
cache: false,
|
||||
beforeSend: function(xhr) {
|
||||
console.log("base64: " + base64);
|
||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||
},
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
@@ -332,7 +348,6 @@ $(document).ready(function() {
|
||||
var submitLoanApplicationUrl = baseApiUrl + 'loans';
|
||||
|
||||
var newFormData = JSON.stringify($('#entityform').serializeObject());
|
||||
console.log(newFormData);
|
||||
|
||||
var jqxhr2 = $.ajax({
|
||||
url: submitLoanApplicationUrl,
|
||||
@@ -342,11 +357,9 @@ $(document).ready(function() {
|
||||
data: newFormData,
|
||||
cache: false,
|
||||
beforeSend: function(xhr) {
|
||||
console.log("base64: " + base64);
|
||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||
},
|
||||
beforeSend: function(xhr) {
|
||||
console.log("base64: " + base64);
|
||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||
},
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
@@ -368,7 +381,6 @@ $(document).ready(function() {
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
beforeSend: function(xhr) {
|
||||
console.log("base64: " + base64);
|
||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||
},
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
{{#each scheduledLoanInstallments}}
|
||||
<tr>
|
||||
<td>{{=$ctx.number(installmentNumber)}}</td>
|
||||
<td>{{=$ctx.globalDate(periodEnd)}}</td>
|
||||
<td>{{=$ctx.globalDateAsISOString(periodEnd)}}</td>
|
||||
<td>{{=$ctx.money(principalDue)}}</td>
|
||||
<td>{{=$ctx.money(interestDue)}}</td>
|
||||
<td>{{=$ctx.money(totalInstallmentDue)}}</td>
|
||||
@@ -54,7 +54,7 @@
|
||||
<form id="entityform">
|
||||
<div id="formerrors"></div>
|
||||
|
||||
<input type="hidden" id="applicantId" name="applicantId" value="{{=clientId}}" />
|
||||
<input type="hidden" id="clientId" name="clientId" value="{{=clientId}}" />
|
||||
<input type="hidden" id="currencyCode" name="currencyCode" value="{{=selectedProduct.principalMoney.currencyCode}}" />
|
||||
<input type="hidden" id="digitsAfterDecimal" name="digitsAfterDecimal" value="{{=$ctx.number(selectedProduct.principalMoney.currencyDigitsAfterDecimal)}}" />
|
||||
|
||||
@@ -84,8 +84,8 @@
|
||||
<td style="text-align:right;vertical-align:bottom;width:50px;"> </td>
|
||||
<td valign="top">
|
||||
<input type="hidden" id="dateFormat" name="dateFormat" value="dd MMMM yyyy" />
|
||||
<label for="submittedOnDateFormatted"><spring:message code="form.label.loan.submitted.on"/></label>
|
||||
<input id="submittedOnDateFormatted" name="submittedOnDateFormatted" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(submittedOnDate)}}" />
|
||||
<label for="submittedOnDate"><spring:message code="form.label.loan.submitted.on"/></label>
|
||||
<input id="submittedOnDate" name="submittedOnDate" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(submittedOnDate)}}" />
|
||||
|
||||
<label for="submittedOnNote"><spring:message code="form.label.loan.submitted.on.note"/></label>
|
||||
<textarea id="submittedOnNote" name="submittedOnNote" rows="2" cols="50" draggable="false">{{=submittedOnNote}}</textarea>
|
||||
@@ -103,7 +103,7 @@
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.product.loan.amount"/></td>
|
||||
<td>
|
||||
<input id="principalFormatted" name="principalFormatted" title="" type="text" value="{{=$ctx.money(selectedProduct.principalMoney)}}" style="width: 125px;" />
|
||||
<input id="principal" name="principal" title="" type="text" value="{{=$ctx.money(selectedProduct.principalMoney)}}" style="width: 125px;" />
|
||||
<input id="principalCurrencyCode" name="principalCurrencyCode" title="" type="text" value="{{=selectedProduct.principalMoney.displaySymbol}}" style="width: 40px;" disabled="disabled" />
|
||||
</td>
|
||||
</tr>
|
||||
@@ -112,7 +112,7 @@
|
||||
<td>
|
||||
<input id="repaymentEvery" name="repaymentEvery" title="" type="text" value="{{=$ctx.number(selectedProduct.repaidEvery)}}" style="width: 50px;" />
|
||||
|
||||
<select name="repaymentFrequency" id="repaymentFrequency" title="" style="width: 121px;">
|
||||
<select name="repaymentFrequencyType" id="repaymentFrequencyType" title="" style="width: 121px;">
|
||||
{{#each selectedProduct.repaymentFrequencyOptions}}
|
||||
{{#if $ctx.number($parent.parent.data.selectedProduct.repaymentPeriodFrequency)===$ctx.number(id)}}
|
||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||
@@ -132,13 +132,13 @@
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.expected.disbursement.date.on"/></td>
|
||||
<td>
|
||||
<input id="expectedDisbursementDateFormatted" name="expectedDisbursementDateFormatted" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(expectedDisbursementDate)}}" style="width:172px;"/>
|
||||
<input id="expectedDisbursementDate" name="expectedDisbursementDate" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(expectedDisbursementDate)}}" style="width:172px;"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.first.repayment.on"/></td>
|
||||
<td>
|
||||
<input id="repaymentsStartingFromDateFormatted" name="repaymentsStartingFromDateFormatted" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(repaymentsStartingFromDate)}}" style="width:172px;"/>
|
||||
<input id="repaymentsStartingFromDate" name="repaymentsStartingFromDate" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(repaymentsStartingFromDate)}}" style="width:172px;"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -149,9 +149,9 @@
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.product.nominal.interestrate"/></td>
|
||||
<td>
|
||||
<input id="interestRatePerPeriodFormatted" name="interestRatePerPeriodFormatted" title="" type="text" value="{{=$ctx.decimal(selectedProduct.interestRatePerPeriod, 4)}}" style="width: 60px;" />
|
||||
<input id="interestRatePerPeriod" name="interestRatePerPeriod" title="" type="text" value="{{=$ctx.decimal(selectedProduct.interestRatePerPeriod, 4)}}" style="width: 60px;" />
|
||||
|
||||
<select name="interestRateFrequencyMethod" id="interestRateFrequencyMethod" title="" style="width: 115px;">
|
||||
<select name="interestRateFrequencyType" id="interestRateFrequencyType" title="" style="width: 115px;">
|
||||
{{#each selectedProduct.interestFrequencyOptions}}
|
||||
{{#if $ctx.number($parent.parent.data.selectedProduct.interestRatePeriod)===$ctx.number(id)}}
|
||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||
@@ -171,7 +171,7 @@
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.product.amortization"/></td>
|
||||
<td>
|
||||
<select name="amortizationMethod" id="amortizationMethod" title="" style="width: 178px;">
|
||||
<select name="amortizationType" id="amortizationType" title="" style="width: 178px;">
|
||||
{{#each selectedProduct.possibleAmortizationOptions}}
|
||||
{{#if $ctx.number($parent.parent.data.selectedProduct.amortizationMethod)===$ctx.number(id)}}
|
||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||
@@ -185,7 +185,7 @@
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.product.interest.method"/></td>
|
||||
<td>
|
||||
<select name="interestMethod" id="interestMethod" title="" style="width: 180px;">
|
||||
<select name="interestType" id="interestType" title="" style="width: 180px;">
|
||||
{{#each selectedProduct.possibleInterestOptions}}
|
||||
{{#if $ctx.number($parent.parent.data.selectedProduct.interestMethod)===$ctx.number(id)}}
|
||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||
@@ -199,7 +199,7 @@
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.product.interest.rate.calcutated.in.period"/></td>
|
||||
<td>
|
||||
<select id="interestCalculationPeriodMethod" name="interestCalculationPeriodMethod" title="" style="width: 220px;">
|
||||
<select id="interestCalculationPeriodType" name="interestCalculationPeriodType" title="" style="width: 220px;">
|
||||
{{#each selectedProduct.possibleInterestRateCalculatedInPeriodOptions}}
|
||||
{{#if $ctx.number($parent.parent.data.selectedProduct.interestRateCalculatedInPeriod)===$ctx.number(id)}}
|
||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||
@@ -213,13 +213,13 @@
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.interest.charged.from"/></td>
|
||||
<td>
|
||||
<input id="interestCalculatedFromDateFormatted" name="interestCalculatedFromDateFormatted" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(interestCalculatedFromDate)}}" style="width:172px;"/>
|
||||
<input id="interestChargedFromDate" name="interestChargedFromDate" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(interestCalculatedFromDate)}}" style="width:172px;"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><spring:message code="form.label.loan.product.arrears.tolerance"/></td>
|
||||
<td>
|
||||
<input id="inArrearsToleranceAmountFormatted" name="inArrearsToleranceAmountFormatted" title="" type="text" value="{{=$ctx.money(selectedProduct.inArrearsTolerance)}}" style="width: 125px;" />
|
||||
<input id="inArrearsTolerance" name="inArrearsTolerance" title="" type="text" value="{{=$ctx.money(selectedProduct.inArrearsTolerance)}}" style="width: 125px;" />
|
||||
<input id="inArrearsCurrencyCode" name="inArrearsCurrencyCode" title="" type="text" value="{{=selectedProduct.inArrearsTolerance.displaySymbol}}" style="width: 40px;" disabled="disabled" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -19,8 +19,6 @@ import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
import org.mifosng.data.LoanSchedule;
|
||||
import org.mifosng.data.MoneyData;
|
||||
import org.mifosng.data.ScheduledLoanInstallment;
|
||||
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
||||
import org.mifosng.data.command.ImportLoanCommand;
|
||||
import org.mifosng.data.command.ImportLoanRepaymentsCommand;
|
||||
@@ -32,25 +30,21 @@ import org.mifosng.platform.api.commands.ClientCommand;
|
||||
import org.mifosng.platform.api.commands.ImportClientCommand;
|
||||
import org.mifosng.platform.client.domain.Client;
|
||||
import org.mifosng.platform.client.domain.ClientRepository;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
import org.mifosng.platform.currency.domain.Money;
|
||||
import org.mifosng.platform.exceptions.UnAuthenticatedUserException;
|
||||
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
||||
import org.mifosng.platform.loan.domain.DefaultLoanLifecycleStateMachine;
|
||||
import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod;
|
||||
import org.mifosng.platform.loan.domain.InterestMethod;
|
||||
import org.mifosng.platform.loan.domain.Loan;
|
||||
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
||||
import org.mifosng.platform.loan.domain.LoanProduct;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosng.platform.loan.domain.LoanRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanStatus;
|
||||
import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanTransaction;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
import org.mifosng.platform.loan.service.CalculationPlatformService;
|
||||
import org.mifosng.platform.loan.service.LoanAssembler;
|
||||
import org.mifosng.platform.organisation.domain.Office;
|
||||
import org.mifosng.platform.organisation.domain.OfficeRepository;
|
||||
import org.mifosng.platform.organisation.domain.Organisation;
|
||||
@@ -75,11 +69,13 @@ public class ImportPlatformServiceImpl implements ImportPlatformService {
|
||||
private final CalculationPlatformService calculationPlatformService;
|
||||
private final LoanRepository loanRepository;
|
||||
private final LoanStatusRepository loanStatusRepository;
|
||||
private final LoanAssembler loanAssembler;
|
||||
|
||||
@Autowired
|
||||
public ImportPlatformServiceImpl(
|
||||
public ImportPlatformServiceImpl(final LoanAssembler loanAssembler,
|
||||
final OfficeRepository officeRepository, final ClientRepository clientRepository, final LoanProductRepository loanProductRepository,
|
||||
final CalculationPlatformService calculationPlatformService, final LoanRepository loanRepository, final LoanStatusRepository loanStatusRepository) {
|
||||
this.loanAssembler = loanAssembler;
|
||||
this.officeRepository = officeRepository;
|
||||
this.clientRepository = clientRepository;
|
||||
this.loanProductRepository = loanProductRepository;
|
||||
@@ -138,75 +134,10 @@ public class ImportPlatformServiceImpl implements ImportPlatformService {
|
||||
|
||||
SubmitLoanApplicationCommand command = combinedCommand.getSubmitLoanApplicationCommand();
|
||||
|
||||
// most of this code can be extracted out into an Assembler
|
||||
LoanProduct loanProduct = this.loanProductRepository.findOne(command
|
||||
.getProductId());
|
||||
Client client = this.clientRepository.findOne(command.getApplicantId());
|
||||
|
||||
MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal());
|
||||
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(command
|
||||
.getInterestRatePerPeriod().doubleValue());
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyMethod());
|
||||
|
||||
// apr calculator
|
||||
BigDecimal defaultAnnualNominalInterestRate = BigDecimal.ZERO;
|
||||
switch (interestPeriodFrequencyType) {
|
||||
case DAYS:
|
||||
break;
|
||||
case WEEKS:
|
||||
defaultAnnualNominalInterestRate = command.getInterestRatePerPeriod().multiply(BigDecimal.valueOf(52));
|
||||
break;
|
||||
case MONTHS:
|
||||
defaultAnnualNominalInterestRate = command.getInterestRatePerPeriod().multiply(BigDecimal.valueOf(12));
|
||||
break;
|
||||
case YEARS:
|
||||
defaultAnnualNominalInterestRate = command.getInterestRatePerPeriod();
|
||||
break;
|
||||
case INVALID:
|
||||
break;
|
||||
}
|
||||
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestMethod());
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodMethod());
|
||||
|
||||
final Integer repayEvery = command.getRepaymentEvery();
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType
|
||||
.fromInt(command.getRepaymentFrequency());
|
||||
final Integer defaultNumberOfInstallments = command.getNumberOfRepayments();
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationMethod());
|
||||
|
||||
LoanProductRelatedDetail loanRepaymentScheduleDetail = new LoanProductRelatedDetail(currency, command.getPrincipal(),
|
||||
defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod,
|
||||
repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, command.getInArrearsToleranceAmount());
|
||||
|
||||
LoanSchedule loanSchedule = command.getLoanSchedule();
|
||||
List<ScheduledLoanInstallment> loanRepaymentSchedule = loanSchedule
|
||||
.getScheduledLoanInstallments();
|
||||
|
||||
Loan loan = Loan.createNew(currentUser.getOrganisation(), loanProduct, client, loanRepaymentScheduleDetail);
|
||||
loan.setExternalId(command.getExternalId());
|
||||
|
||||
for (ScheduledLoanInstallment scheduledLoanInstallment : loanRepaymentSchedule) {
|
||||
|
||||
MoneyData readPrincipalDue = scheduledLoanInstallment
|
||||
.getPrincipalDue();
|
||||
|
||||
MoneyData readInterestDue = scheduledLoanInstallment
|
||||
.getInterestDue();
|
||||
|
||||
LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(
|
||||
loan, scheduledLoanInstallment.getInstallmentNumber(),
|
||||
scheduledLoanInstallment.getPeriodStart(),
|
||||
scheduledLoanInstallment.getPeriodEnd(), readPrincipalDue.getAmount(),
|
||||
readInterestDue.getAmount());
|
||||
loan.addRepaymentScheduleInstallment(installment);
|
||||
}
|
||||
Loan loan = loanAssembler.assembleFrom(command, currentUser.getOrganisation());
|
||||
|
||||
LoanLifecycleStateMachine loanLifecycleStateMachine = defaultLoanLifecycleStateMachine();
|
||||
|
||||
loan.submitApplication(command.getSubmittedOnDate(), command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate(), command.getInterestCalculatedFromDate(), loanLifecycleStateMachine);
|
||||
|
||||
LoanStateTransitionCommand approveLoanCommand = combinedCommand.getApproveLoanCommand();
|
||||
if (approveLoanCommand != null) {
|
||||
loan.approve(approveLoanCommand.getEventDate(), loanLifecycleStateMachine);
|
||||
|
||||
@@ -109,42 +109,42 @@ public class LoansApiResource {
|
||||
@QueryParam("command") final String commandParam,
|
||||
final SubmitLoanApplicationCommand command) {
|
||||
|
||||
LocalDate expectedDisbursementDate = apiDataConversionService
|
||||
.convertFrom(command.getExpectedDisbursementDateFormatted(),
|
||||
"expectedDisbursementDateFormatted",
|
||||
LocalDate expectedDisbursementLocalDate = apiDataConversionService
|
||||
.convertFrom(command.getExpectedDisbursementDate(),
|
||||
"expectedDisbursementDate",
|
||||
command.getDateFormat());
|
||||
LocalDate repaymentsStartingFromDate = apiDataConversionService
|
||||
.convertFrom(command.getRepaymentsStartingFromDateFormatted(),
|
||||
"repaymentsStartingFromDateFormatted",
|
||||
LocalDate repaymentsStartingFromLocalDate = apiDataConversionService
|
||||
.convertFrom(command.getRepaymentsStartingFromDate(),
|
||||
"repaymentsStartingFromDate",
|
||||
command.getDateFormat());
|
||||
LocalDate interestCalculatedFromDate = apiDataConversionService
|
||||
.convertFrom(command.getInterestCalculatedFromDateFormatted(),
|
||||
"interestCalculatedFromDateFormatted",
|
||||
LocalDate interestChargedFromLocalDate = apiDataConversionService
|
||||
.convertFrom(command.getInterestChargedFromDate(),
|
||||
"interestChargedFromDate",
|
||||
command.getDateFormat());
|
||||
LocalDate submittedOnDate = apiDataConversionService.convertFrom(
|
||||
command.getSubmittedOnDateFormatted(),
|
||||
"submittedOnDateFormatted", command.getDateFormat());
|
||||
command.setExpectedDisbursementDate(expectedDisbursementDate);
|
||||
command.setRepaymentsStartingFromDate(repaymentsStartingFromDate);
|
||||
command.setInterestCalculatedFromDate(interestCalculatedFromDate);
|
||||
command.setSubmittedOnDate(submittedOnDate);
|
||||
LocalDate submittedOnLocalDate = apiDataConversionService.convertFrom(
|
||||
command.getSubmittedOnDate(),
|
||||
"submittedOnDate", command.getDateFormat());
|
||||
|
||||
command.setExpectedDisbursementLocalDate(expectedDisbursementLocalDate);
|
||||
command.setRepaymentsStartingFromLocalDate(repaymentsStartingFromLocalDate);
|
||||
command.setInterestChargedFromLocalDate(interestChargedFromLocalDate);
|
||||
command.setSubmittedOnLocalDate(submittedOnLocalDate);
|
||||
|
||||
// FIXME - pass in locale through query string or in 'request body'
|
||||
Locale clientApplicationLocale = Locale.UK;
|
||||
BigDecimal principal = this.apiDataConversionService.convertFrom(
|
||||
command.getPrincipalFormatted(), "principalFormatted",
|
||||
clientApplicationLocale);
|
||||
BigDecimal interestRatePerPeriod = this.apiDataConversionService
|
||||
.convertFrom(command.getInterestRatePerPeriodFormatted(),
|
||||
"interestRatePerPeriodFormatted",
|
||||
clientApplicationLocale);
|
||||
BigDecimal inArrearsToleranceAmount = this.apiDataConversionService
|
||||
.convertFrom(command.getInArrearsToleranceAmountFormatted(),
|
||||
"inArrearsToleranceAmountFormatted",
|
||||
clientApplicationLocale);
|
||||
command.setPrincipal(principal);
|
||||
command.setInterestRatePerPeriod(interestRatePerPeriod);
|
||||
command.setInArrearsToleranceAmount(inArrearsToleranceAmount);
|
||||
Locale clientApplicationLocale = this.apiDataConversionService.localeFromString(command.getLocale());
|
||||
BigDecimal principalValue = this.apiDataConversionService.convertFrom(command.getPrincipal(), "principal", clientApplicationLocale);
|
||||
BigDecimal inArrearsToleranceValue = this.apiDataConversionService.convertFrom(command.getInArrearsTolerance(), "inArrearsTolerance", clientApplicationLocale);
|
||||
BigDecimal interestRatePerPeriodValue = this.apiDataConversionService.convertFrom(command.getInterestRatePerPeriod(),"interestRatePerPeriod", clientApplicationLocale);
|
||||
|
||||
Integer digitsAfterDecimalValue = this.apiDataConversionService.convertToInteger(command.getDigitsAfterDecimal(), "digitsAfterDecimal", clientApplicationLocale);
|
||||
Integer repaymentEveryValue = this.apiDataConversionService.convertToInteger(command.getRepaymentEvery(), "repaymentEvery", clientApplicationLocale);
|
||||
Integer numberOfRepaymentsValue = this.apiDataConversionService.convertToInteger(command.getNumberOfRepayments(), "numberOfRepayments", clientApplicationLocale);
|
||||
|
||||
command.setPrincipalValue(principalValue);
|
||||
command.setInArrearsToleranceValue(inArrearsToleranceValue);
|
||||
command.setInterestRatePerPeriodValue(interestRatePerPeriodValue);
|
||||
command.setDigitsAfterDecimalValue(digitsAfterDecimalValue);
|
||||
command.setRepaymentEveryValue(repaymentEveryValue);
|
||||
command.setNumberOfRepaymentsValue(numberOfRepaymentsValue);
|
||||
|
||||
CalculateLoanScheduleCommand calculateLoanScheduleCommand = command
|
||||
.toCalculateLoanScheduleCommand();
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableCustom<Ap
|
||||
Money interest = getInterest(totalAvailable.getCurrency());
|
||||
Money principal = getPrincipal(totalAvailable.getCurrency());
|
||||
|
||||
// TODO - configuration around order components of loan are paid off in.
|
||||
// TODO - NEWFEATURE - configuration around order components of loan are paid off in.
|
||||
// pay off interest
|
||||
if (remaining.isGreaterThanOrEqualTo(interest)) {
|
||||
this.interestCompleted = interest.getAmount();
|
||||
|
||||
+25
-174
@@ -3,13 +3,10 @@ package org.mifosng.platform.loan.service;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosng.data.ApiParameterError;
|
||||
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
||||
import org.mifosng.platform.DataValidatorBuilder;
|
||||
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
|
||||
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
||||
import org.mifosng.platform.loan.domain.InterestMethod;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
|
||||
public class CalculateLoanScheduleCommandValidator {
|
||||
|
||||
@@ -20,199 +17,53 @@ public class CalculateLoanScheduleCommandValidator {
|
||||
}
|
||||
|
||||
public void validate() {
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
if (StringUtils.isBlank(command.getCurrencyCode())) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.currency.cannot.be.empty", "The parameter currencyCode cannot be blank.", "currencyCode");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
|
||||
|
||||
if (command.getDigitsAfterDecimal() != null) {
|
||||
|
||||
if (command.getDigitsAfterDecimal() < 0 || command.getDigitsAfterDecimal() > 6) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.currency.digitsAfterDecimal.must.be.between.zero.and.six.inclusive", "The parameter digitsAfterDecimal must be a value between 1 and 6.", "digitsAfterDecimal", command.getDigitsAfterDecimal(), 1, 6);
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
} else {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.currency.digitsAfterDecimal.cannot.be.empty", "The parameter digitsAfterDecimal cannot be blank.", "digitsAfterDecimal");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank();
|
||||
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimalValue()).notNull().inMinMaxRange(0, 6);
|
||||
baseDataValidator.reset().parameter("principal").value(command.getPrincipalValue()).notNull().positiveAmount();
|
||||
baseDataValidator.reset().parameter("repaymentFrequencyType").value(command.getRepaymentFrequencyType()).notNull().inMinMaxRange(0, 3);
|
||||
baseDataValidator.reset().parameter("repaymentEvery").value(command.getRepaymentEveryValue()).notNull().greaterThanZero();
|
||||
baseDataValidator.reset().parameter("numberOfRepayments").value(command.getNumberOfRepaymentsValue()).notNull().greaterThanZero();
|
||||
baseDataValidator.reset().parameter("interestRatePerPeriod").value(command.getInterestRatePerPeriodValue()).notNull();
|
||||
baseDataValidator.reset().parameter("interestRateFrequencyType").value(command.getInterestRateFrequencyType()).notNull().inMinMaxRange(0, 3);
|
||||
baseDataValidator.reset().parameter("amortizationType").value(command.getAmortizationType()).notNull().inMinMaxRange(0, 1);
|
||||
baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).notNull().inMinMaxRange(0, 1);
|
||||
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(command.getInterestCalculationPeriodType()).notNull().inMinMaxRange(0, 1);
|
||||
|
||||
// FIXME - validate the number of digits before and after decimal provided (before is limited by database field, after is limited by number selected for product (and ultimately by the database field))
|
||||
if (command.getPrincipal() != null) {
|
||||
if (command.getPrincipal().doubleValue() <= Double.valueOf("0.0")) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.principal.amount.must.be.greater.than.zero", "The parameter principalMoney must be greater than zero.", "principalMoney");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
} else {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.principal.amount.cannot.be.empty", "The parameter principalMoney cannot be blank.", "principalMoney");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
baseDataValidator.reset().parameter("expectedDisbursementDate").value(command.getExpectedDisbursementLocalDate()).notNull();
|
||||
|
||||
if (command.getRepaymentFrequency() != null) {
|
||||
PeriodFrequencyType frequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequency());
|
||||
ApiParameterError error = null;
|
||||
switch (frequencyType) {
|
||||
case DAYS:
|
||||
error = validateNumberExistsAndInRange("validation.msg.product.repayment.repaidEvery", "repaidEvery", command.getRepaymentEvery(), 1, 365);
|
||||
break;
|
||||
case WEEKS:
|
||||
error = validateNumberExistsAndInRange("validation.msg.product.repayment.repaidEvery", "repaidEvery", command.getRepaymentEvery(), 1, 52);
|
||||
break;
|
||||
case MONTHS:
|
||||
error = validateNumberExistsAndInRange("validation.msg.product.repayment.repaidEvery", "repaidEvery", command.getRepaymentEvery(), 1, 12);
|
||||
break;
|
||||
case YEARS:
|
||||
error = validateNumberExistsAndInRange("validation.msg.product.repayment.repaidEvery", "repaidEvery", command.getRepaymentEvery(), 1, 2);
|
||||
break;
|
||||
default:
|
||||
error = ApiParameterError.parameterError("validation.msg.product.repayment.frequency.invalid", "The parameter repaymentFrequency is invalid.", "repaymentFrequency", command.getRepaymentFrequency());
|
||||
break;
|
||||
}
|
||||
if (error != null) {
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
} else {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.repayment.frequency.cannot.be.empty", "The parameter repaymentFrequency cannot be empty.", "repaymentFrequency");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (command.getNumberOfRepayments() != null) {
|
||||
if (command.getNumberOfRepayments() < 1 || command.getNumberOfRepayments() > 100) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.number.of.repayments.is.out.of.range", "The parameter numberOfRepayments must between {1} and {2}.", "numberOfRepayments", command.getNumberOfRepayments(), 1, 100);
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
} else {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.number.of.repayments.cannot.be.empty", "The parameter numberOfRepayments cannot be empty.", "numberOfRepayments");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (command.getAmortizationMethod() != null) {
|
||||
AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationMethod());
|
||||
ApiParameterError error = null;
|
||||
switch (amortizationMethod) {
|
||||
case EQUAL_PRINCIPAL:
|
||||
break;
|
||||
case EQUAL_INSTALLMENTS:
|
||||
break;
|
||||
default:
|
||||
error = ApiParameterError.parameterError("validation.msg.product.amortization.method.invalid", "The parameter amortizationMethod is invalid.", "amortizationMethod", command.getAmortizationMethod());
|
||||
dataValidationErrors.add(error);
|
||||
break;
|
||||
}
|
||||
if (error != null) {
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
} else {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.amortization.method.cannot.be.empty", "The parameter amortizationMethod cannot be empty.", "amortizationMethod");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (command.getExpectedDisbursementDate() == null) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.expectedDisbursementDate.method.cannot.be.blank", "The parameter expectedDisbursementDate cannot be empty.", "expectedDisbursementDate");
|
||||
dataValidationErrors.add(error);
|
||||
} else {
|
||||
if (command.getRepaymentsStartingFromDate() != null
|
||||
&& command.getExpectedDisbursementDate().isAfter(command.getRepaymentsStartingFromDate())) {
|
||||
if (command.getExpectedDisbursementLocalDate() != null) {
|
||||
if (command.getRepaymentsStartingFromLocalDate() != null
|
||||
&& command.getExpectedDisbursementLocalDate().isAfter(command.getRepaymentsStartingFromLocalDate())) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.expectedDisbursementDate.cannot.be.after.first.repayment.date",
|
||||
"The parameter expectedDisbursementDate has a date which falls after the given first repayment date.", "expectedDisbursementDate",
|
||||
command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate());
|
||||
command.getExpectedDisbursementLocalDate(), command.getRepaymentsStartingFromLocalDate());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (command.getRepaymentsStartingFromDate() != null && command.getInterestCalculatedFromDate() == null) {
|
||||
if (command.getRepaymentsStartingFromLocalDate() != null && command.getInterestChargedFromLocalDate() == null) {
|
||||
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.interestCalculatedFromDate.must.be.entered.when.using.repayments.startfrom.field",
|
||||
"The parameter interestCalculatedFromDate cannot be empty when first repayment date is provided.", "interestCalculatedFromDate", command.getRepaymentsStartingFromDate());
|
||||
"The parameter interestCalculatedFromDate cannot be empty when first repayment date is provided.", "interestCalculatedFromDate", command.getRepaymentsStartingFromLocalDate());
|
||||
dataValidationErrors.add(error);
|
||||
} else if (command.getRepaymentsStartingFromDate() == null && command.getInterestCalculatedFromDate() != null) {
|
||||
} else if (command.getRepaymentsStartingFromLocalDate() == null && command.getInterestChargedFromLocalDate() != null) {
|
||||
|
||||
// validate interestCalculatedFromDate is after or on repaymentsStartingFromDate
|
||||
if (command.getExpectedDisbursementDate().isAfter(command.getInterestCalculatedFromDate())) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.interestCalculatedFromDate.cannot.be.before.disbursement.date",
|
||||
"The parameter interestCalculatedFromDate cannot be before the date given for expected disbursement.", "interestCalculatedFromDate", command.getInterestCalculatedFromDate(), command.getExpectedDisbursementDate());
|
||||
if (command.getExpectedDisbursementLocalDate().isAfter(command.getInterestChargedFromLocalDate())) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.interestChargedFromDate.cannot.be.before.disbursement.date",
|
||||
"The parameter interestCalculatedFromDate cannot be before the date given for expected disbursement.", "interestChargedFromDate", command.getInterestChargedFromLocalDate(), command.getExpectedDisbursementLocalDate());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (command.getInterestRatePerPeriod()!= null) {
|
||||
if (command.getInterestRatePerPeriod().doubleValue() < Double.valueOf("0.0")) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.interest.rate.per.period.amount.cannot.be.negative",
|
||||
"The parameter interestRatePerPeriodFormatted cannot be less than zero.", "interestRatePerPeriodFormatted",
|
||||
command.getInterestRatePerPeriod());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
} else {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.interest.rate.per.period.amount.cannot.be.empty",
|
||||
"The parameter interestRatePerPeriodFormatted cannot be empty.", "interestRatePerPeriodFormatted",
|
||||
command.getInterestRatePerPeriod());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
// interest rate period type
|
||||
if (command.getInterestRateFrequencyMethod() != null) {
|
||||
PeriodFrequencyType frequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyMethod());
|
||||
ApiParameterError error = null;
|
||||
switch (frequencyType) {
|
||||
case DAYS:
|
||||
break;
|
||||
case WEEKS:
|
||||
break;
|
||||
case MONTHS:
|
||||
break;
|
||||
case YEARS:
|
||||
break;
|
||||
default:
|
||||
error = ApiParameterError.parameterError("validation.msg.product.interest.frequency.invalid",
|
||||
"The parameter interestRateFrequencyMethod cannot be empty.", "interestRateFrequencyMethod", command.getInterestRateFrequencyMethod());
|
||||
break;
|
||||
}
|
||||
if (error != null) {
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
} else {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.interest.frequency.cannot.be.empty",
|
||||
"The parameter interestRateFrequencyMethod cannot be empty.", "interestRateFrequencyMethod");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (command.getInterestMethod() != null) {
|
||||
InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestMethod());
|
||||
ApiParameterError error = null;
|
||||
switch (interestMethod) {
|
||||
case DECLINING_BALANCE:
|
||||
break;
|
||||
case FLAT:
|
||||
break;
|
||||
default:
|
||||
error = ApiParameterError.parameterError("validation.msg.product.interest.method.invalid",
|
||||
"The parameter interestMethod is invalid.", "interestMethod", command.getInterestMethod());
|
||||
break;
|
||||
}
|
||||
if (error != null) {
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
} else {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.interest.method.cannot.be.empty",
|
||||
"The parameter interestMethod cannot be empty.", "interestMethod");
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
private ApiParameterError validateNumberExistsAndInRange(String errorCodePreFix, String fieldName, Integer value, int min, int max) {
|
||||
ApiParameterError error = null;
|
||||
if (value == null) {
|
||||
error = ApiParameterError.parameterError(errorCodePreFix + ".cannot.be.empty", "The parameter " + fieldName + " cannot be blank.", fieldName);
|
||||
} else {
|
||||
if (value < min || value > max) {
|
||||
error = ApiParameterError.parameterError(errorCodePreFix + ".outside.allowed.range", "The parameter " + fieldName + " must be between {0} and {1} inclusive.", fieldName, min, max);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
+13
-14
@@ -51,20 +51,19 @@ public class CalculationPlatformServiceImpl implements
|
||||
CalculateLoanScheduleCommandValidator validator = new CalculateLoanScheduleCommandValidator(command);
|
||||
validator.validate();
|
||||
|
||||
// assemble 'loan data' into 'domain' object [LoanProductRelatedDetail]
|
||||
final BigDecimal principalAmount = BigDecimal.valueOf(command.getPrincipal().doubleValue());
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(command.getInterestRatePerPeriod().doubleValue());
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyMethod());
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestMethod());
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodMethod());
|
||||
final Integer repayEvery = command.getRepaymentEvery();
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequency());
|
||||
final Integer defaultNumberOfInstallments = command.getNumberOfRepayments();
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationMethod());
|
||||
final BigDecimal principalAmount = command.getPrincipalValue();
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = command.getInterestRatePerPeriodValue();
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyType());
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestType());
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodType());
|
||||
final Integer repayEvery = command.getRepaymentEveryValue();
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequencyType());
|
||||
final Integer defaultNumberOfInstallments = command.getNumberOfRepaymentsValue();
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationType());
|
||||
|
||||
final BigDecimal defaultAnnualNominalInterestRate = this.aprCalculator.calculateFrom(interestPeriodFrequencyType, defaultNominalInterestRatePerPeriod);
|
||||
|
||||
final MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal());
|
||||
final MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimalValue());
|
||||
|
||||
// in arrerars tolerance isnt relevant when auto-calculating a loan schedule
|
||||
final BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||
@@ -78,11 +77,11 @@ public class CalculationPlatformServiceImpl implements
|
||||
LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(interestMethod);
|
||||
|
||||
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(command.getCurrencyCode());
|
||||
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(), command.getDigitsAfterDecimal(),
|
||||
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(), command.getDigitsAfterDecimalValue(),
|
||||
applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
||||
|
||||
return loanScheduleGenerator.generate(loanScheduleInfo, command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate(),
|
||||
command.getInterestCalculatedFromDate(), currencyData);
|
||||
return loanScheduleGenerator.generate(loanScheduleInfo, command.getExpectedDisbursementLocalDate(), command.getRepaymentsStartingFromLocalDate(),
|
||||
command.getInterestChargedFromLocalDate(), currencyData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package org.mifosng.platform.loan.service;
|
||||
|
||||
import static org.mifosng.platform.Specifications.clientsThatMatch;
|
||||
import static org.mifosng.platform.Specifications.productThatMatches;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosng.data.LoanSchedule;
|
||||
import org.mifosng.data.MoneyData;
|
||||
import org.mifosng.data.ScheduledLoanInstallment;
|
||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||
import org.mifosng.platform.client.domain.Client;
|
||||
import org.mifosng.platform.client.domain.ClientRepository;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
import org.mifosng.platform.exceptions.ClientNotFoundException;
|
||||
import org.mifosng.platform.exceptions.LoanProductNotFoundException;
|
||||
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
||||
import org.mifosng.platform.loan.domain.DefaultLoanLifecycleStateMachine;
|
||||
import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod;
|
||||
import org.mifosng.platform.loan.domain.InterestMethod;
|
||||
import org.mifosng.platform.loan.domain.Loan;
|
||||
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
||||
import org.mifosng.platform.loan.domain.LoanProduct;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosng.platform.loan.domain.LoanStatus;
|
||||
import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
import org.mifosng.platform.loanschedule.domain.AprCalculator;
|
||||
import org.mifosng.platform.organisation.domain.Organisation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class LoanAssembler {
|
||||
|
||||
private final LoanStatusRepository loanStatusRepository;
|
||||
private final LoanProductRepository loanProductRepository;
|
||||
private final ClientRepository clientRepository;
|
||||
private final AprCalculator aprCalculator = new AprCalculator();
|
||||
|
||||
@Autowired
|
||||
public LoanAssembler(final LoanStatusRepository loanStatusRepository,
|
||||
final LoanProductRepository loanProductRepository,
|
||||
final ClientRepository clientRepository) {
|
||||
this.loanStatusRepository = loanStatusRepository;
|
||||
this.loanProductRepository = loanProductRepository;
|
||||
this.clientRepository = clientRepository;
|
||||
}
|
||||
|
||||
public Loan assembleFrom(SubmitLoanApplicationCommand command, Organisation organisation) {
|
||||
LoanProduct loanProduct = this.loanProductRepository.findOne(productThatMatches(organisation, command.getProductId()));
|
||||
if (loanProduct == null) {
|
||||
throw new LoanProductNotFoundException(command.getProductId());
|
||||
}
|
||||
Client client = this.clientRepository.findOne(clientsThatMatch(organisation, command.getClientId()));
|
||||
if (client == null) {
|
||||
throw new ClientNotFoundException(command.getClientId());
|
||||
}
|
||||
|
||||
// FIXME - should probably fetch applicationCurrency with currencycode to check its validity.
|
||||
MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimalValue());
|
||||
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = command.getInterestRatePerPeriodValue();
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyType());
|
||||
|
||||
BigDecimal defaultAnnualNominalInterestRate = aprCalculator.calculateFrom(interestPeriodFrequencyType, command.getInterestRatePerPeriodValue());
|
||||
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestType());
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodType());
|
||||
|
||||
final Integer repayEvery = command.getRepaymentEveryValue();
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequencyType());
|
||||
final Integer defaultNumberOfInstallments = command.getNumberOfRepaymentsValue();
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationType());
|
||||
|
||||
LoanProductRelatedDetail loanRepaymentScheduleDetail = new LoanProductRelatedDetail(currency,
|
||||
command.getPrincipalValue(), defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType, defaultAnnualNominalInterestRate,
|
||||
interestMethod, interestCalculationPeriodMethod,
|
||||
repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, command.getInArrearsToleranceValue());
|
||||
|
||||
LoanSchedule loanSchedule = command.getLoanSchedule();
|
||||
List<ScheduledLoanInstallment> loanRepaymentSchedule = loanSchedule.getScheduledLoanInstallments();
|
||||
|
||||
Loan loan = Loan.createNew(organisation, loanProduct, client, loanRepaymentScheduleDetail);
|
||||
loan.setExternalId(command.getExternalId());
|
||||
|
||||
for (ScheduledLoanInstallment scheduledLoanInstallment : loanRepaymentSchedule) {
|
||||
|
||||
MoneyData readPrincipalDue = scheduledLoanInstallment.getPrincipalDue();
|
||||
MoneyData readInterestDue = scheduledLoanInstallment.getInterestDue();
|
||||
|
||||
LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(
|
||||
loan, scheduledLoanInstallment.getInstallmentNumber(),
|
||||
scheduledLoanInstallment.getPeriodStart(),
|
||||
scheduledLoanInstallment.getPeriodEnd(), readPrincipalDue.getAmount(),
|
||||
readInterestDue.getAmount());
|
||||
loan.addRepaymentScheduleInstallment(installment);
|
||||
}
|
||||
|
||||
loan.submitApplication(command.getSubmittedOnLocalDate(), command.getExpectedDisbursementLocalDate(), command.getRepaymentsStartingFromLocalDate(), command.getInterestChargedFromLocalDate(), defaultLoanLifecycleStateMachine());
|
||||
|
||||
return loan;
|
||||
}
|
||||
|
||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||
List<LoanStatus> allowedLoanStatuses = this.loanStatusRepository.findAll();
|
||||
return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses);
|
||||
}
|
||||
}
|
||||
+2
@@ -37,7 +37,9 @@ public interface LoanWritePlatformService {
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_MAKE_LOAN_REPAYMENT_ROLE', 'CAN_MAKE_LOAN_REPAYMENT_IN_THE_PAST_ROLE')")
|
||||
public EntityIdentifier makeLoanRepayment(LoanTransactionCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE')")
|
||||
EntityIdentifier adjustLoanTransaction(AdjustLoanTransactionCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE')")
|
||||
EntityIdentifier waiveLoanAmount(LoanTransactionCommand command);
|
||||
}
|
||||
+7
-63
@@ -2,7 +2,6 @@ package org.mifosng.platform.loan.service;
|
||||
|
||||
import static org.mifosng.platform.Specifications.loansThatMatch;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -10,7 +9,6 @@ import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.data.EntityIdentifier;
|
||||
import org.mifosng.data.LoanSchedule;
|
||||
import org.mifosng.data.MoneyData;
|
||||
import org.mifosng.data.ScheduledLoanInstallment;
|
||||
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
||||
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
||||
@@ -18,8 +16,6 @@ import org.mifosng.data.command.LoanStateTransitionCommand;
|
||||
import org.mifosng.data.command.LoanTransactionCommand;
|
||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||
import org.mifosng.data.command.UndoStateTransitionCommand;
|
||||
import org.mifosng.platform.client.domain.Client;
|
||||
import org.mifosng.platform.client.domain.ClientRepository;
|
||||
import org.mifosng.platform.client.domain.Note;
|
||||
import org.mifosng.platform.client.domain.NoteRepository;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
@@ -27,15 +23,9 @@ import org.mifosng.platform.currency.domain.Money;
|
||||
import org.mifosng.platform.exceptions.LoanNotFoundException;
|
||||
import org.mifosng.platform.exceptions.NoAuthorizationException;
|
||||
import org.mifosng.platform.exceptions.PlatformDomainRuleException;
|
||||
import org.mifosng.platform.loan.domain.AmortizationMethod;
|
||||
import org.mifosng.platform.loan.domain.DefaultLoanLifecycleStateMachine;
|
||||
import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod;
|
||||
import org.mifosng.platform.loan.domain.InterestMethod;
|
||||
import org.mifosng.platform.loan.domain.Loan;
|
||||
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
||||
import org.mifosng.platform.loan.domain.LoanProduct;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
import org.mifosng.platform.loan.domain.LoanProductRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosng.platform.loan.domain.LoanRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanStatus;
|
||||
@@ -43,7 +33,6 @@ import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
||||
import org.mifosng.platform.loan.domain.LoanTransaction;
|
||||
import org.mifosng.platform.loan.domain.LoanTransactionRepository;
|
||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||
import org.mifosng.platform.loanschedule.domain.AprCalculator;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
import org.mifosng.platform.user.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -56,24 +45,21 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final LoanRepository loanRepository;
|
||||
private final LoanProductRepository loanProductRepository;
|
||||
private final LoanStatusRepository loanStatusRepository;
|
||||
private final ClientRepository clientRepository;
|
||||
private final NoteRepository noteRepository;
|
||||
private final CalculationPlatformService calculationPlatformService;
|
||||
private final AprCalculator aprCalculator = new AprCalculator();
|
||||
private final LoanTransactionRepository loanTransactionRepository;
|
||||
private final LoanAssembler loanAssembler;
|
||||
|
||||
@Autowired
|
||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final LoanAssembler loanAssembler,
|
||||
final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository,
|
||||
final LoanStatusRepository loanStatusRepository, final LoanProductRepository loanProductRepository,
|
||||
final ClientRepository clientRepository, final NoteRepository noteRepository, final CalculationPlatformService calculationPlatformService) {
|
||||
final LoanStatusRepository loanStatusRepository,
|
||||
final NoteRepository noteRepository, final CalculationPlatformService calculationPlatformService) {
|
||||
this.context = context;
|
||||
this.loanAssembler = loanAssembler;
|
||||
this.loanRepository = loanRepository;
|
||||
this.loanTransactionRepository = loanTransactionRepository;
|
||||
this.loanProductRepository = loanProductRepository;
|
||||
this.clientRepository = clientRepository;
|
||||
this.loanStatusRepository = loanStatusRepository;
|
||||
this.noteRepository = noteRepository;
|
||||
this.calculationPlatformService = calculationPlatformService;
|
||||
@@ -97,55 +83,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
SubmitLoanApplicationCommandValidator validator = new SubmitLoanApplicationCommandValidator(command);
|
||||
validator.validate();
|
||||
|
||||
LocalDate submittedOn = command.getSubmittedOnDate();
|
||||
LocalDate submittedOn = command.getSubmittedOnLocalDate();
|
||||
if (this.isBeforeToday(submittedOn) && currentUser.hasNotPermissionForAnyOf("CAN_SUBMIT_HISTORIC_LOAN_APPLICATION_ROLE", "PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE")) {
|
||||
throw new NoAuthorizationException("Cannot add backdated loan.");
|
||||
}
|
||||
|
||||
// FIXME - looks like assembly of LoanProductRelatedDetail is common with loan product and calculate loan schedule areas. remove duplication into an assembler.
|
||||
LoanProduct loanProduct = this.loanProductRepository.findOne(command.getProductId());
|
||||
Client client = this.clientRepository.findOne(command.getApplicantId());
|
||||
Loan loan = loanAssembler.assembleFrom(command, currentUser.getOrganisation());
|
||||
|
||||
MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal());
|
||||
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(command.getInterestRatePerPeriod().doubleValue());
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyMethod());
|
||||
|
||||
BigDecimal defaultAnnualNominalInterestRate = aprCalculator.calculateFrom(interestPeriodFrequencyType, command.getInterestRatePerPeriod());
|
||||
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestMethod());
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodMethod());
|
||||
|
||||
final Integer repayEvery = command.getRepaymentEvery();
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequency());
|
||||
final Integer defaultNumberOfInstallments = command.getNumberOfRepayments();
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationMethod());
|
||||
|
||||
LoanProductRelatedDetail loanRepaymentScheduleDetail = new LoanProductRelatedDetail(currency,
|
||||
command.getPrincipal(), defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType, defaultAnnualNominalInterestRate,
|
||||
interestMethod, interestCalculationPeriodMethod,
|
||||
repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, command.getInArrearsToleranceAmount());
|
||||
|
||||
LoanSchedule loanSchedule = command.getLoanSchedule();
|
||||
List<ScheduledLoanInstallment> loanRepaymentSchedule = loanSchedule.getScheduledLoanInstallments();
|
||||
|
||||
Loan loan = Loan.createNew(currentUser.getOrganisation(), loanProduct, client, loanRepaymentScheduleDetail);
|
||||
loan.setExternalId(command.getExternalId());
|
||||
|
||||
for (ScheduledLoanInstallment scheduledLoanInstallment : loanRepaymentSchedule) {
|
||||
|
||||
MoneyData readPrincipalDue = scheduledLoanInstallment.getPrincipalDue();
|
||||
MoneyData readInterestDue = scheduledLoanInstallment.getInterestDue();
|
||||
|
||||
LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(
|
||||
loan, scheduledLoanInstallment.getInstallmentNumber(),
|
||||
scheduledLoanInstallment.getPeriodStart(),
|
||||
scheduledLoanInstallment.getPeriodEnd(), readPrincipalDue.getAmount(),
|
||||
readInterestDue.getAmount());
|
||||
loan.addRepaymentScheduleInstallment(installment);
|
||||
}
|
||||
|
||||
loan.submitApplication(submittedOn, command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate(), command.getInterestCalculatedFromDate(), defaultLoanLifecycleStateMachine());
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
if (StringUtils.isNotBlank(command.getSubmittedOnNote())) {
|
||||
|
||||
+16
-16
@@ -25,15 +25,15 @@ public class SubmitLoanApplicationCommandValidator {
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (command.getSubmittedOnDate() == null) {
|
||||
if (command.getSubmittedOnLocalDate() == null) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.submitted.on.date.cannot.be.blank",
|
||||
"The parameter submittedOnDateFormatted cannot be empty.", "submittedOnDateFormatted");
|
||||
"The parameter submittedOnDate cannot be empty.", "submittedOnDateFormatted");
|
||||
dataValidationErrors.add(error);
|
||||
} else {
|
||||
if (command.getSubmittedOnDate().isAfter(command.getExpectedDisbursementDate())) {
|
||||
if (command.getSubmittedOnLocalDate().isAfter(command.getExpectedDisbursementLocalDate())) {
|
||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.submitted.on.date.cannot.be.after.expectedDisbursementDate",
|
||||
"The date of parameter submittedOnDateFormatted cannot fall after the date given for expectedDisbursementDateFormatted.", "submittedOnDateFormatted",
|
||||
command.getSubmittedOnDateFormatted(), command.getExpectedDisbursementDateFormatted());
|
||||
"The date of parameter submittedOnDate cannot fall after the date given for expectedDisbursementDate.", "submittedOnDate",
|
||||
command.getSubmittedOnDate(), command.getExpectedDisbursementDate());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
@@ -41,17 +41,17 @@ public class SubmitLoanApplicationCommandValidator {
|
||||
try {
|
||||
// reuse calculate loan schedule validator for now
|
||||
CalculateLoanScheduleCommand calculateLoanScheduleCommand = new CalculateLoanScheduleCommand(
|
||||
command.getCurrencyCode(), command.getDigitsAfterDecimal(),
|
||||
command.getPrincipal(), command.getInterestRatePerPeriod(),
|
||||
command.getInterestRateFrequencyMethod(),
|
||||
command.getInterestMethod(), command.getInterestCalculationPeriodMethod(),
|
||||
command.getRepaymentEvery(),
|
||||
command.getRepaymentFrequency(),
|
||||
command.getNumberOfRepayments(),
|
||||
command.getAmortizationMethod(),
|
||||
command.getExpectedDisbursementDate(),
|
||||
command.getRepaymentsStartingFromDate(),
|
||||
command.getInterestCalculatedFromDate());
|
||||
command.getCurrencyCode(), command.getDigitsAfterDecimalValue(),
|
||||
command.getPrincipalValue(), command.getInterestRatePerPeriodValue(),
|
||||
command.getInterestRateFrequencyType(),
|
||||
command.getInterestType(), command.getInterestCalculationPeriodType(),
|
||||
command.getRepaymentEveryValue(),
|
||||
command.getRepaymentFrequencyType(),
|
||||
command.getNumberOfRepaymentsValue(),
|
||||
command.getAmortizationType(),
|
||||
command.getExpectedDisbursementLocalDate(),
|
||||
command.getRepaymentsStartingFromLocalDate(),
|
||||
command.getInterestChargedFromLocalDate());
|
||||
|
||||
CalculateLoanScheduleCommandValidator validator = new CalculateLoanScheduleCommandValidator(
|
||||
calculateLoanScheduleCommand);
|
||||
|
||||
-2
@@ -9,7 +9,6 @@ import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
||||
public class PmtCalculator {
|
||||
|
||||
public Money calculatePaymentForOnePeriodFrom(LoanProductRelatedDetail loanScheduleInfo, BigDecimal periodInterestRateForRepaymentPeriod, MonetaryCurrency monetaryCurrency) {
|
||||
// TODO - check if going to doubles is a problem
|
||||
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
||||
|
||||
double futureValue = 0;
|
||||
@@ -24,7 +23,6 @@ public class PmtCalculator {
|
||||
}
|
||||
|
||||
public Money calculateTotalRepaymentFrom(LoanProductRelatedDetail loanScheduleInfo, BigDecimal periodInterestRateForRepaymentPeriod, MonetaryCurrency monetaryCurrency) {
|
||||
// TODO - check if going to doubles is a problem
|
||||
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
||||
|
||||
double futureValue = 0;
|
||||
|
||||
-1
@@ -44,7 +44,6 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
|
||||
return this.jdbcTemplate.query(sql, mapper, new Object[] {currentUser.getOrganisation().getId() });
|
||||
}
|
||||
|
||||
// FIXME - does it make sense to use JDBC over repository for this?
|
||||
@Override
|
||||
public RoleData retrieveRole(final Long id) {
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
Reference in New Issue
Block a user