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 {
|
public class CalculateLoanScheduleCommand {
|
||||||
|
|
||||||
private String currencyCode;
|
private String currencyCode;
|
||||||
private Integer digitsAfterDecimal;
|
private Integer digitsAfterDecimalValue;
|
||||||
private BigDecimal principal;
|
private BigDecimal principalValue;
|
||||||
private BigDecimal inArrearsToleranceAmount;
|
private BigDecimal inArrearsToleranceValue;
|
||||||
|
|
||||||
private Integer repaymentEvery;
|
private Integer repaymentEveryValue;
|
||||||
private Integer repaymentFrequency;
|
private Integer repaymentFrequencyType;
|
||||||
private Integer numberOfRepayments;
|
private Integer numberOfRepaymentsValue;
|
||||||
|
|
||||||
private BigDecimal interestRatePerPeriod;
|
private BigDecimal interestRatePerPeriodValue;
|
||||||
private Integer interestRateFrequencyMethod;
|
private Integer interestRateFrequencyType;
|
||||||
private Integer amortizationMethod;
|
private Integer amortizationType;
|
||||||
private Integer interestMethod;
|
private Integer interestType;
|
||||||
private Integer interestCalculationPeriodMethod;
|
private Integer interestCalculationPeriodType;
|
||||||
|
|
||||||
private LocalDate expectedDisbursementDate;
|
private LocalDate expectedDisbursementLocalDate;
|
||||||
private LocalDate repaymentsStartingFromDate;
|
private LocalDate repaymentsStartingFromLocalDate;
|
||||||
private LocalDate interestCalculatedFromDate;
|
private LocalDate interestChargedFromLocalDate;
|
||||||
|
|
||||||
protected CalculateLoanScheduleCommand() {
|
protected CalculateLoanScheduleCommand() {
|
||||||
//
|
//
|
||||||
@@ -40,20 +40,24 @@ public class CalculateLoanScheduleCommand {
|
|||||||
final LocalDate repaymentsStartingFromDate, final LocalDate interestCalculatedFromDate) {
|
final LocalDate repaymentsStartingFromDate, final LocalDate interestCalculatedFromDate) {
|
||||||
|
|
||||||
this.currencyCode = currencyCode;
|
this.currencyCode = currencyCode;
|
||||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
this.digitsAfterDecimalValue = digitsAfterDecimal;
|
||||||
this.principal = BigDecimal.valueOf(principal.doubleValue());
|
if (principal != null) {
|
||||||
this.interestRatePerPeriod = BigDecimal.valueOf(interestRatePerPeriod.doubleValue());
|
this.principalValue = BigDecimal.valueOf(principal.doubleValue());
|
||||||
this.interestRateFrequencyMethod = interestRateFrequencyMethod;
|
}
|
||||||
this.interestMethod = interestMethod;
|
if (interestRatePerPeriod != null) {
|
||||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
this.interestRatePerPeriodValue = BigDecimal.valueOf(interestRatePerPeriod.doubleValue());
|
||||||
this.repaymentEvery = repaymentEvery;
|
}
|
||||||
this.repaymentFrequency = repaymentFrequency;
|
this.interestRateFrequencyType = interestRateFrequencyMethod;
|
||||||
this.numberOfRepayments = numberOfRepayments;
|
this.interestType = interestMethod;
|
||||||
this.amortizationMethod = amortizationMethod;
|
this.interestCalculationPeriodType = interestCalculationPeriodMethod;
|
||||||
|
this.repaymentEveryValue = repaymentEvery;
|
||||||
|
this.repaymentFrequencyType = repaymentFrequency;
|
||||||
|
this.numberOfRepaymentsValue = numberOfRepayments;
|
||||||
|
this.amortizationType = amortizationMethod;
|
||||||
|
|
||||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
this.expectedDisbursementLocalDate = expectedDisbursementDate;
|
||||||
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
|
this.repaymentsStartingFromLocalDate = repaymentsStartingFromDate;
|
||||||
this.interestCalculatedFromDate = interestCalculatedFromDate;
|
this.interestChargedFromLocalDate= interestCalculatedFromDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCurrencyCode() {
|
public String getCurrencyCode() {
|
||||||
@@ -64,116 +68,119 @@ public class CalculateLoanScheduleCommand {
|
|||||||
this.currencyCode = currencyCode;
|
this.currencyCode = currencyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getDigitsAfterDecimal() {
|
public Integer getDigitsAfterDecimalValue() {
|
||||||
return digitsAfterDecimal;
|
return digitsAfterDecimalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDigitsAfterDecimal(Integer digitsAfterDecimal) {
|
public void setDigitsAfterDecimalValue(Integer digitsAfterDecimalValue) {
|
||||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
this.digitsAfterDecimalValue = digitsAfterDecimalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getPrincipal() {
|
public BigDecimal getPrincipalValue() {
|
||||||
return principal;
|
return principalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrincipal(BigDecimal principal) {
|
public void setPrincipalValue(BigDecimal principalValue) {
|
||||||
this.principal = principal;
|
this.principalValue = principalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getInArrearsToleranceAmount() {
|
public BigDecimal getInArrearsToleranceValue() {
|
||||||
return inArrearsToleranceAmount;
|
return inArrearsToleranceValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInArrearsToleranceAmount(BigDecimal inArrearsToleranceAmount) {
|
public void setInArrearsToleranceValue(BigDecimal inArrearsToleranceValue) {
|
||||||
this.inArrearsToleranceAmount = inArrearsToleranceAmount;
|
this.inArrearsToleranceValue = inArrearsToleranceValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getRepaymentEvery() {
|
public Integer getRepaymentEveryValue() {
|
||||||
return repaymentEvery;
|
return repaymentEveryValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRepaymentEvery(Integer repaymentEvery) {
|
public void setRepaymentEveryValue(Integer repaymentEveryValue) {
|
||||||
this.repaymentEvery = repaymentEvery;
|
this.repaymentEveryValue = repaymentEveryValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getRepaymentFrequency() {
|
public Integer getRepaymentFrequencyType() {
|
||||||
return repaymentFrequency;
|
return repaymentFrequencyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRepaymentFrequency(Integer repaymentFrequency) {
|
public void setRepaymentFrequencyType(Integer repaymentFrequencyType) {
|
||||||
this.repaymentFrequency = repaymentFrequency;
|
this.repaymentFrequencyType = repaymentFrequencyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getNumberOfRepayments() {
|
public Integer getNumberOfRepaymentsValue() {
|
||||||
return numberOfRepayments;
|
return numberOfRepaymentsValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNumberOfRepayments(Integer numberOfRepayments) {
|
public void setNumberOfRepaymentsValue(Integer numberOfRepaymentsValue) {
|
||||||
this.numberOfRepayments = numberOfRepayments;
|
this.numberOfRepaymentsValue = numberOfRepaymentsValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getInterestRatePerPeriod() {
|
public BigDecimal getInterestRatePerPeriodValue() {
|
||||||
return interestRatePerPeriod;
|
return interestRatePerPeriodValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterestRatePerPeriod(BigDecimal interestRatePerPeriod) {
|
public void setInterestRatePerPeriodValue(BigDecimal interestRatePerPeriodValue) {
|
||||||
this.interestRatePerPeriod = interestRatePerPeriod;
|
this.interestRatePerPeriodValue = interestRatePerPeriodValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getInterestRateFrequencyMethod() {
|
public Integer getInterestRateFrequencyType() {
|
||||||
return interestRateFrequencyMethod;
|
return interestRateFrequencyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterestRateFrequencyMethod(Integer interestRateFrequencyMethod) {
|
public void setInterestRateFrequencyType(Integer interestRateFrequencyType) {
|
||||||
this.interestRateFrequencyMethod = interestRateFrequencyMethod;
|
this.interestRateFrequencyType = interestRateFrequencyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getAmortizationMethod() {
|
public Integer getAmortizationType() {
|
||||||
return amortizationMethod;
|
return amortizationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmortizationMethod(Integer amortizationMethod) {
|
public void setAmortizationType(Integer amortizationType) {
|
||||||
this.amortizationMethod = amortizationMethod;
|
this.amortizationType = amortizationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getInterestMethod() {
|
public Integer getInterestType() {
|
||||||
return interestMethod;
|
return interestType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterestMethod(Integer interestMethod) {
|
public void setInterestType(Integer interestType) {
|
||||||
this.interestMethod = interestMethod;
|
this.interestType = interestType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getInterestCalculationPeriodMethod() {
|
public Integer getInterestCalculationPeriodType() {
|
||||||
return interestCalculationPeriodMethod;
|
return interestCalculationPeriodType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterestCalculationPeriodMethod(
|
public void setInterestCalculationPeriodType(
|
||||||
Integer interestCalculationPeriodMethod) {
|
Integer interestCalculationPeriodType) {
|
||||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getExpectedDisbursementDate() {
|
public LocalDate getExpectedDisbursementLocalDate() {
|
||||||
return expectedDisbursementDate;
|
return expectedDisbursementLocalDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExpectedDisbursementDate(LocalDate expectedDisbursementDate) {
|
public void setExpectedDisbursementLocalDate(
|
||||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
LocalDate expectedDisbursementLocalDate) {
|
||||||
|
this.expectedDisbursementLocalDate = expectedDisbursementLocalDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getRepaymentsStartingFromDate() {
|
public LocalDate getRepaymentsStartingFromLocalDate() {
|
||||||
return repaymentsStartingFromDate;
|
return repaymentsStartingFromLocalDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRepaymentsStartingFromDate(LocalDate repaymentsStartingFromDate) {
|
public void setRepaymentsStartingFromLocalDate(
|
||||||
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
|
LocalDate repaymentsStartingFromLocalDate) {
|
||||||
|
this.repaymentsStartingFromLocalDate = repaymentsStartingFromLocalDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getInterestCalculatedFromDate() {
|
public LocalDate getInterestChargedFromLocalDate() {
|
||||||
return interestCalculatedFromDate;
|
return interestChargedFromLocalDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterestCalculatedFromDate(LocalDate interestCalculatedFromDate) {
|
public void setInterestChargedFromLocalDate(
|
||||||
this.interestCalculatedFromDate = interestCalculatedFromDate;
|
LocalDate interestChargedFromLocalDate) {
|
||||||
|
this.interestChargedFromLocalDate = interestChargedFromLocalDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+253
-218
@@ -10,38 +10,44 @@ import org.mifosng.data.LoanSchedule;
|
|||||||
@XmlRootElement
|
@XmlRootElement
|
||||||
public class SubmitLoanApplicationCommand {
|
public class SubmitLoanApplicationCommand {
|
||||||
|
|
||||||
private Long applicantId;
|
private Long clientId;
|
||||||
private Long productId;
|
private Long productId;
|
||||||
|
|
||||||
// product
|
// product
|
||||||
|
private String locale;
|
||||||
private String currencyCode;
|
private String currencyCode;
|
||||||
private Integer digitsAfterDecimal;
|
private String digitsAfterDecimal;
|
||||||
private String principalFormatted;
|
private Integer digitsAfterDecimalValue;
|
||||||
private BigDecimal principal;
|
private BigDecimal principalValue;
|
||||||
private String inArrearsToleranceAmountFormatted;
|
private String principal;
|
||||||
private BigDecimal inArrearsToleranceAmount;
|
private BigDecimal inArrearsToleranceValue;
|
||||||
|
private String inArrearsTolerance;
|
||||||
|
|
||||||
private Integer repaymentEvery;
|
private String numberOfRepayments;
|
||||||
private Integer repaymentFrequency;
|
private Integer numberOfRepaymentsValue;
|
||||||
private Integer numberOfRepayments;
|
private String repaymentEvery;
|
||||||
|
private Integer repaymentEveryValue;
|
||||||
|
|
||||||
private String interestRatePerPeriodFormatted;
|
private String interestRatePerPeriod;
|
||||||
private BigDecimal interestRatePerPeriod;
|
private BigDecimal interestRatePerPeriodValue;
|
||||||
private Integer interestRateFrequencyMethod;
|
|
||||||
private Integer amortizationMethod;
|
|
||||||
private Integer interestMethod;
|
|
||||||
private Integer interestCalculationPeriodMethod;
|
|
||||||
|
|
||||||
private String expectedDisbursementDateFormatted;
|
private Integer repaymentFrequencyType;
|
||||||
private String repaymentsStartingFromDateFormatted;
|
private Integer interestRateFrequencyType;
|
||||||
private String interestCalculatedFromDateFormatted;
|
private Integer amortizationType;
|
||||||
private LocalDate expectedDisbursementDate;
|
private Integer interestType;
|
||||||
private LocalDate repaymentsStartingFromDate;
|
private Integer interestCalculationPeriodType;
|
||||||
private LocalDate interestCalculatedFromDate;
|
// end of product related fields
|
||||||
|
|
||||||
|
private String expectedDisbursementDate;
|
||||||
|
private String repaymentsStartingFromDate;
|
||||||
|
private String interestChargedFromDate;
|
||||||
|
private LocalDate expectedDisbursementLocalDate;
|
||||||
|
private LocalDate repaymentsStartingFromLocalDate;
|
||||||
|
private LocalDate interestChargedFromLocalDate;
|
||||||
|
|
||||||
private String dateFormat;
|
private String dateFormat;
|
||||||
private String submittedOnDateFormatted;
|
private String submittedOnDate;
|
||||||
private LocalDate submittedOnDate;
|
private LocalDate submittedOnLocalDate;
|
||||||
private String submittedOnNote;
|
private String submittedOnNote;
|
||||||
private String externalId;
|
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 Long productId, final LocalDate submittedOnDate,
|
||||||
final String submittedOnNote,
|
final String submittedOnNote,
|
||||||
final LocalDate expectedDisbursementDate,
|
final LocalDate expectedDisbursementDate,
|
||||||
final LocalDate repaymentsStartingFromDate,
|
final LocalDate repaymentsStartingFromDate,
|
||||||
final LocalDate interestCalculatedFromDate,
|
final LocalDate interestChargedFromLocalDate,
|
||||||
final LoanSchedule loanSchedule, final String currencyCode,
|
final LoanSchedule loanSchedule, final String currencyCode,
|
||||||
final Integer digitsAfterDecimal, final Number principal,
|
final Integer digitsAfterDecimal, final Number principal,
|
||||||
final Number interestRatePerPeriod, Integer interestRateFrequencyMethod, final Integer interestMethod, final Integer interestCalculationPeriodMethod,
|
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) {
|
final Integer repaymentEvery, final Integer repaymentFrequency, final Integer numberOfRepayments, Integer amortizationMethod, final Number toleranceAmount) {
|
||||||
this.applicantId = applicantId;
|
this.clientId = clientId;
|
||||||
this.productId = productId;
|
this.productId = productId;
|
||||||
this.submittedOnDate = submittedOnDate;
|
this.submittedOnLocalDate = submittedOnDate;
|
||||||
this.submittedOnNote = submittedOnNote;
|
this.submittedOnNote = submittedOnNote;
|
||||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
this.expectedDisbursementLocalDate = expectedDisbursementDate;
|
||||||
this.repaymentsStartingFromDate = repaymentsStartingFromDate;
|
this.repaymentsStartingFromLocalDate = repaymentsStartingFromDate;
|
||||||
this.interestCalculatedFromDate = interestCalculatedFromDate;
|
this.interestChargedFromLocalDate = interestChargedFromLocalDate;
|
||||||
this.loanSchedule = loanSchedule;
|
this.loanSchedule = loanSchedule;
|
||||||
this.inArrearsToleranceAmount = BigDecimal.valueOf(toleranceAmount.doubleValue());
|
this.inArrearsToleranceValue = BigDecimal.valueOf(toleranceAmount.doubleValue());
|
||||||
|
|
||||||
this.currencyCode = currencyCode;
|
this.currencyCode = currencyCode;
|
||||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
this.digitsAfterDecimalValue = digitsAfterDecimal;
|
||||||
this.principal = BigDecimal.valueOf(principal.doubleValue());
|
this.principalValue = BigDecimal.valueOf(principal.doubleValue());
|
||||||
this.interestRatePerPeriod = BigDecimal.valueOf(interestRatePerPeriod.doubleValue());
|
this.interestRatePerPeriodValue = BigDecimal.valueOf(interestRatePerPeriod.doubleValue());
|
||||||
this.interestRateFrequencyMethod = interestRateFrequencyMethod;
|
this.interestRateFrequencyType = interestRateFrequencyMethod;
|
||||||
this.interestMethod = interestMethod;
|
this.interestType = interestMethod;
|
||||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
this.interestCalculationPeriodType = interestCalculationPeriodMethod;
|
||||||
this.repaymentEvery = repaymentEvery;
|
this.repaymentEveryValue = repaymentEvery;
|
||||||
this.repaymentFrequency = repaymentFrequency;
|
this.repaymentFrequencyType = repaymentFrequency;
|
||||||
this.numberOfRepayments = numberOfRepayments;
|
this.numberOfRepaymentsValue = numberOfRepayments;
|
||||||
this.amortizationMethod = amortizationMethod;
|
this.amortizationType = amortizationMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CalculateLoanScheduleCommand toCalculateLoanScheduleCommand() {
|
public CalculateLoanScheduleCommand toCalculateLoanScheduleCommand() {
|
||||||
return new CalculateLoanScheduleCommand(currencyCode, digitsAfterDecimal, principal, interestRatePerPeriod, interestRateFrequencyMethod, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentFrequency, numberOfRepayments, amortizationMethod, expectedDisbursementDate, repaymentsStartingFromDate, interestCalculatedFromDate);
|
return new CalculateLoanScheduleCommand(currencyCode, digitsAfterDecimalValue, principalValue, interestRatePerPeriodValue, interestRateFrequencyType, interestType, interestCalculationPeriodType, repaymentEveryValue, repaymentFrequencyType, numberOfRepaymentsValue, amortizationType,
|
||||||
}
|
expectedDisbursementLocalDate, repaymentsStartingFromLocalDate, interestChargedFromLocalDate);
|
||||||
|
|
||||||
public Long getApplicantId() {
|
|
||||||
return this.applicantId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApplicantId(final Long applicantId) {
|
|
||||||
this.applicantId = applicantId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getProductId() {
|
public Long getProductId() {
|
||||||
@@ -104,14 +103,6 @@ public class SubmitLoanApplicationCommand {
|
|||||||
this.productId = productId;
|
this.productId = productId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getSubmittedOnDate() {
|
|
||||||
return this.submittedOnDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubmittedOnDate(final LocalDate submittedOnDate) {
|
|
||||||
this.submittedOnDate = submittedOnDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSubmittedOnNote() {
|
public String getSubmittedOnNote() {
|
||||||
return this.submittedOnNote;
|
return this.submittedOnNote;
|
||||||
}
|
}
|
||||||
@@ -120,24 +111,6 @@ public class SubmitLoanApplicationCommand {
|
|||||||
this.submittedOnNote = submittedOnNote;
|
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() {
|
public LoanSchedule getLoanSchedule() {
|
||||||
return this.loanSchedule;
|
return this.loanSchedule;
|
||||||
}
|
}
|
||||||
@@ -162,130 +135,6 @@ public class SubmitLoanApplicationCommand {
|
|||||||
this.currencyCode = currencyCode;
|
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() {
|
public String getDateFormat() {
|
||||||
return dateFormat;
|
return dateFormat;
|
||||||
}
|
}
|
||||||
@@ -294,37 +143,223 @@ public class SubmitLoanApplicationCommand {
|
|||||||
this.dateFormat = dateFormat;
|
this.dateFormat = dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSubmittedOnDateFormatted() {
|
public Long getClientId() {
|
||||||
return submittedOnDateFormatted;
|
return clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubmittedOnDateFormatted(String submittedOnDateFormatted) {
|
public void setClientId(Long clientId) {
|
||||||
this.submittedOnDateFormatted = submittedOnDateFormatted;
|
this.clientId = clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPrincipalFormatted() {
|
public String getLocale() {
|
||||||
return principalFormatted;
|
return locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrincipalFormatted(String principalFormatted) {
|
public void setLocale(String locale) {
|
||||||
this.principalFormatted = principalFormatted;
|
this.locale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getInArrearsToleranceAmountFormatted() {
|
public String getDigitsAfterDecimal() {
|
||||||
return inArrearsToleranceAmountFormatted;
|
return digitsAfterDecimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInArrearsToleranceAmountFormatted(
|
public void setDigitsAfterDecimal(String digitsAfterDecimal) {
|
||||||
String inArrearsToleranceAmountFormatted) {
|
this.digitsAfterDecimal = digitsAfterDecimal;
|
||||||
this.inArrearsToleranceAmountFormatted = inArrearsToleranceAmountFormatted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getInterestRatePerPeriodFormatted() {
|
public Integer getDigitsAfterDecimalValue() {
|
||||||
return interestRatePerPeriodFormatted;
|
return digitsAfterDecimalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterestRatePerPeriodFormatted(
|
public void setDigitsAfterDecimalValue(Integer digitsAfterDecimalValue) {
|
||||||
String interestRatePerPeriodFormatted) {
|
this.digitsAfterDecimalValue = digitsAfterDecimalValue;
|
||||||
this.interestRatePerPeriodFormatted = interestRatePerPeriodFormatted;
|
}
|
||||||
|
|
||||||
|
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.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.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
|
# loan event and transactions screens
|
||||||
label.loan.on=On:
|
label.loan.on=On:
|
||||||
label.loan.action.note=Note:
|
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.on=Repayment on:
|
||||||
label.loan.transaction.amount=Amount:
|
label.loan.transaction.amount=Amount:
|
||||||
|
|
||||||
|
|
||||||
tab.client.account.loan.details=Details
|
tab.client.account.loan.details=Details
|
||||||
tab.client.account.loan.schedule=Schedule
|
tab.client.account.loan.schedule=Schedule
|
||||||
tab.client.account.loan.repayments=Repayments
|
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.expected.disbursement.date.on=Expected disbursement on:
|
||||||
form.label.loan.first.repayment.on=First repayment 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.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.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.
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
globalDate: function(localDateAsISOString) {
|
globalDate: function(dateParts) {
|
||||||
try {
|
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 dateParts = localDateAsISOString.split("-")
|
||||||
var year = dateParts[0];
|
var year = dateParts[0];
|
||||||
var month = parseInt(dateParts[1]) - 1; // month is zero indexed
|
var month = parseInt(dateParts[1]) - 1; // month is zero indexed
|
||||||
@@ -177,13 +196,13 @@ $(document).ready(function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function calculateAnnualPercentageRate() {
|
function calculateAnnualPercentageRate() {
|
||||||
var periodInterestRate = parseFloat($('#interestRatePerPeriodFormatted').val());
|
var periodInterestRate = parseFloat($('#interestRatePerPeriod').val());
|
||||||
if (isNaN(periodInterestRate)) {
|
if (isNaN(periodInterestRate)) {
|
||||||
periodInterestRate = 0;
|
periodInterestRate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var periodsInYear = 12;
|
var periodsInYear = 12;
|
||||||
var periodType = $('#interestRateFrequencyMethod').val();
|
var periodType = $('#interestRateFrequencyType').val();
|
||||||
if (periodType == 3) {
|
if (periodType == 3) {
|
||||||
periodsInYear = 1;
|
periodsInYear = 1;
|
||||||
} else if (periodType == 2) {
|
} else if (periodType == 2) {
|
||||||
@@ -207,7 +226,6 @@ $(document).ready(function() {
|
|||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
cache: false,
|
cache: false,
|
||||||
beforeSend: function(xhr) {
|
beforeSend: function(xhr) {
|
||||||
console.log("base64: " + base64);
|
|
||||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||||
},
|
},
|
||||||
success: function(data, textStatus, jqXHR) {
|
success: function(data, textStatus, jqXHR) {
|
||||||
@@ -228,7 +246,7 @@ $(document).ready(function() {
|
|||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
|
|
||||||
// change detection
|
// change detection
|
||||||
$('#principalFormatted').change(function() {
|
$('#principal').change(function() {
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -236,7 +254,7 @@ $(document).ready(function() {
|
|||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#repaymentFrequency').change(function() {
|
$('#repaymentFrequencyType').change(function() {
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -244,37 +262,37 @@ $(document).ready(function() {
|
|||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#expectedDisbursementDateFormatted').change(function() {
|
$('#expectedDisbursementDate').change(function() {
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#repaymentsStartingFromDateFormatted').change(function() {
|
$('#repaymentsStartingFromDate').change(function() {
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#interestRatePerPeriodFormatted').change(function() {
|
$('#interestRatePerPeriod').change(function() {
|
||||||
calculateAnnualPercentageRate();
|
calculateAnnualPercentageRate();
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#interestRateFrequencyMethod').change(function() {
|
$('#interestRateFrequencyType').change(function() {
|
||||||
calculateAnnualPercentageRate();
|
calculateAnnualPercentageRate();
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#amortizationMethod').change(function() {
|
$('#amortizationType').change(function() {
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#interestMethod').change(function() {
|
$('#interestType').change(function() {
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#interestCalculationPeriodMethod').change(function() {
|
$('#interestCalculationPeriodType').change(function() {
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#interestCalculatedFromDateFormatted').change(function() {
|
$('#interestChargedFromDate').change(function() {
|
||||||
calculateLoanSchedule();
|
calculateLoanSchedule();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -302,7 +320,6 @@ $(document).ready(function() {
|
|||||||
var calculateLoanScheduleurl = baseApiUrl + 'loans?command=calculateLoanSchedule';
|
var calculateLoanScheduleurl = baseApiUrl + 'loans?command=calculateLoanSchedule';
|
||||||
|
|
||||||
var newFormData = JSON.stringify($('#entityform').serializeObject());
|
var newFormData = JSON.stringify($('#entityform').serializeObject());
|
||||||
console.log(newFormData);
|
|
||||||
|
|
||||||
var jqxhr2 = $.ajax({
|
var jqxhr2 = $.ajax({
|
||||||
url: calculateLoanScheduleurl,
|
url: calculateLoanScheduleurl,
|
||||||
@@ -312,7 +329,6 @@ $(document).ready(function() {
|
|||||||
data: newFormData,
|
data: newFormData,
|
||||||
cache: false,
|
cache: false,
|
||||||
beforeSend: function(xhr) {
|
beforeSend: function(xhr) {
|
||||||
console.log("base64: " + base64);
|
|
||||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||||
},
|
},
|
||||||
success: function(data, textStatus, jqXHR) {
|
success: function(data, textStatus, jqXHR) {
|
||||||
@@ -332,7 +348,6 @@ $(document).ready(function() {
|
|||||||
var submitLoanApplicationUrl = baseApiUrl + 'loans';
|
var submitLoanApplicationUrl = baseApiUrl + 'loans';
|
||||||
|
|
||||||
var newFormData = JSON.stringify($('#entityform').serializeObject());
|
var newFormData = JSON.stringify($('#entityform').serializeObject());
|
||||||
console.log(newFormData);
|
|
||||||
|
|
||||||
var jqxhr2 = $.ajax({
|
var jqxhr2 = $.ajax({
|
||||||
url: submitLoanApplicationUrl,
|
url: submitLoanApplicationUrl,
|
||||||
@@ -342,11 +357,9 @@ $(document).ready(function() {
|
|||||||
data: newFormData,
|
data: newFormData,
|
||||||
cache: false,
|
cache: false,
|
||||||
beforeSend: function(xhr) {
|
beforeSend: function(xhr) {
|
||||||
console.log("base64: " + base64);
|
|
||||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||||
},
|
},
|
||||||
beforeSend: function(xhr) {
|
beforeSend: function(xhr) {
|
||||||
console.log("base64: " + base64);
|
|
||||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||||
},
|
},
|
||||||
success: function(data, textStatus, jqXHR) {
|
success: function(data, textStatus, jqXHR) {
|
||||||
@@ -368,7 +381,6 @@ $(document).ready(function() {
|
|||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
cache: false,
|
cache: false,
|
||||||
beforeSend: function(xhr) {
|
beforeSend: function(xhr) {
|
||||||
console.log("base64: " + base64);
|
|
||||||
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
xhr.setRequestHeader("Authorization", "Basic " + base64);
|
||||||
},
|
},
|
||||||
success: function(data, textStatus, jqXHR) {
|
success: function(data, textStatus, jqXHR) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
{{#each scheduledLoanInstallments}}
|
{{#each scheduledLoanInstallments}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{=$ctx.number(installmentNumber)}}</td>
|
<td>{{=$ctx.number(installmentNumber)}}</td>
|
||||||
<td>{{=$ctx.globalDate(periodEnd)}}</td>
|
<td>{{=$ctx.globalDateAsISOString(periodEnd)}}</td>
|
||||||
<td>{{=$ctx.money(principalDue)}}</td>
|
<td>{{=$ctx.money(principalDue)}}</td>
|
||||||
<td>{{=$ctx.money(interestDue)}}</td>
|
<td>{{=$ctx.money(interestDue)}}</td>
|
||||||
<td>{{=$ctx.money(totalInstallmentDue)}}</td>
|
<td>{{=$ctx.money(totalInstallmentDue)}}</td>
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
<form id="entityform">
|
<form id="entityform">
|
||||||
<div id="formerrors"></div>
|
<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="currencyCode" name="currencyCode" value="{{=selectedProduct.principalMoney.currencyCode}}" />
|
||||||
<input type="hidden" id="digitsAfterDecimal" name="digitsAfterDecimal" value="{{=$ctx.number(selectedProduct.principalMoney.currencyDigitsAfterDecimal)}}" />
|
<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 style="text-align:right;vertical-align:bottom;width:50px;"> </td>
|
||||||
<td valign="top">
|
<td valign="top">
|
||||||
<input type="hidden" id="dateFormat" name="dateFormat" value="dd MMMM yyyy" />
|
<input type="hidden" id="dateFormat" name="dateFormat" value="dd MMMM yyyy" />
|
||||||
<label for="submittedOnDateFormatted"><spring:message code="form.label.loan.submitted.on"/></label>
|
<label for="submittedOnDate"><spring:message code="form.label.loan.submitted.on"/></label>
|
||||||
<input id="submittedOnDateFormatted" name="submittedOnDateFormatted" title="" type="text" class="datepickerfield" value="{{=$ctx.globalDate(submittedOnDate)}}" />
|
<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>
|
<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>
|
<textarea id="submittedOnNote" name="submittedOnNote" rows="2" cols="50" draggable="false">{{=submittedOnNote}}</textarea>
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.product.loan.amount"/></td>
|
<td><spring:message code="form.label.loan.product.loan.amount"/></td>
|
||||||
<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" />
|
<input id="principalCurrencyCode" name="principalCurrencyCode" title="" type="text" value="{{=selectedProduct.principalMoney.displaySymbol}}" style="width: 40px;" disabled="disabled" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<input id="repaymentEvery" name="repaymentEvery" title="" type="text" value="{{=$ctx.number(selectedProduct.repaidEvery)}}" style="width: 50px;" />
|
<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}}
|
{{#each selectedProduct.repaymentFrequencyOptions}}
|
||||||
{{#if $ctx.number($parent.parent.data.selectedProduct.repaymentPeriodFrequency)===$ctx.number(id)}}
|
{{#if $ctx.number($parent.parent.data.selectedProduct.repaymentPeriodFrequency)===$ctx.number(id)}}
|
||||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||||
@@ -132,13 +132,13 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.expected.disbursement.date.on"/></td>
|
<td><spring:message code="form.label.loan.expected.disbursement.date.on"/></td>
|
||||||
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.first.repayment.on"/></td>
|
<td><spring:message code="form.label.loan.first.repayment.on"/></td>
|
||||||
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -149,9 +149,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.product.nominal.interestrate"/></td>
|
<td><spring:message code="form.label.loan.product.nominal.interestrate"/></td>
|
||||||
<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}}
|
{{#each selectedProduct.interestFrequencyOptions}}
|
||||||
{{#if $ctx.number($parent.parent.data.selectedProduct.interestRatePeriod)===$ctx.number(id)}}
|
{{#if $ctx.number($parent.parent.data.selectedProduct.interestRatePeriod)===$ctx.number(id)}}
|
||||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||||
@@ -171,7 +171,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.product.amortization"/></td>
|
<td><spring:message code="form.label.loan.product.amortization"/></td>
|
||||||
<td>
|
<td>
|
||||||
<select name="amortizationMethod" id="amortizationMethod" title="" style="width: 178px;">
|
<select name="amortizationType" id="amortizationType" title="" style="width: 178px;">
|
||||||
{{#each selectedProduct.possibleAmortizationOptions}}
|
{{#each selectedProduct.possibleAmortizationOptions}}
|
||||||
{{#if $ctx.number($parent.parent.data.selectedProduct.amortizationMethod)===$ctx.number(id)}}
|
{{#if $ctx.number($parent.parent.data.selectedProduct.amortizationMethod)===$ctx.number(id)}}
|
||||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||||
@@ -185,7 +185,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.product.interest.method"/></td>
|
<td><spring:message code="form.label.loan.product.interest.method"/></td>
|
||||||
<td>
|
<td>
|
||||||
<select name="interestMethod" id="interestMethod" title="" style="width: 180px;">
|
<select name="interestType" id="interestType" title="" style="width: 180px;">
|
||||||
{{#each selectedProduct.possibleInterestOptions}}
|
{{#each selectedProduct.possibleInterestOptions}}
|
||||||
{{#if $ctx.number($parent.parent.data.selectedProduct.interestMethod)===$ctx.number(id)}}
|
{{#if $ctx.number($parent.parent.data.selectedProduct.interestMethod)===$ctx.number(id)}}
|
||||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||||
@@ -199,7 +199,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.product.interest.rate.calcutated.in.period"/></td>
|
<td><spring:message code="form.label.loan.product.interest.rate.calcutated.in.period"/></td>
|
||||||
<td>
|
<td>
|
||||||
<select id="interestCalculationPeriodMethod" name="interestCalculationPeriodMethod" title="" style="width: 220px;">
|
<select id="interestCalculationPeriodType" name="interestCalculationPeriodType" title="" style="width: 220px;">
|
||||||
{{#each selectedProduct.possibleInterestRateCalculatedInPeriodOptions}}
|
{{#each selectedProduct.possibleInterestRateCalculatedInPeriodOptions}}
|
||||||
{{#if $ctx.number($parent.parent.data.selectedProduct.interestRateCalculatedInPeriod)===$ctx.number(id)}}
|
{{#if $ctx.number($parent.parent.data.selectedProduct.interestRateCalculatedInPeriod)===$ctx.number(id)}}
|
||||||
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
<option value="{{=$ctx.number(id)}}" selected="selected">{{=value}}</option>
|
||||||
@@ -213,13 +213,13 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.interest.charged.from"/></td>
|
<td><spring:message code="form.label.loan.interest.charged.from"/></td>
|
||||||
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><spring:message code="form.label.loan.product.arrears.tolerance"/></td>
|
<td><spring:message code="form.label.loan.product.arrears.tolerance"/></td>
|
||||||
<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" />
|
<input id="inArrearsCurrencyCode" name="inArrearsCurrencyCode" title="" type="text" value="{{=selectedProduct.inArrearsTolerance.displaySymbol}}" style="width: 40px;" disabled="disabled" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ import org.joda.time.LocalDate;
|
|||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.joda.time.format.ISODateTimeFormat;
|
import org.joda.time.format.ISODateTimeFormat;
|
||||||
import org.mifosng.data.LoanSchedule;
|
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.CalculateLoanScheduleCommand;
|
||||||
import org.mifosng.data.command.ImportLoanCommand;
|
import org.mifosng.data.command.ImportLoanCommand;
|
||||||
import org.mifosng.data.command.ImportLoanRepaymentsCommand;
|
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.api.commands.ImportClientCommand;
|
||||||
import org.mifosng.platform.client.domain.Client;
|
import org.mifosng.platform.client.domain.Client;
|
||||||
import org.mifosng.platform.client.domain.ClientRepository;
|
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.currency.domain.Money;
|
||||||
import org.mifosng.platform.exceptions.UnAuthenticatedUserException;
|
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.DefaultLoanLifecycleStateMachine;
|
||||||
import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod;
|
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.Loan;
|
||||||
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
||||||
import org.mifosng.platform.loan.domain.LoanProduct;
|
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.LoanProductRepository;
|
||||||
import org.mifosng.platform.loan.domain.LoanRepaymentScheduleInstallment;
|
|
||||||
import org.mifosng.platform.loan.domain.LoanRepository;
|
import org.mifosng.platform.loan.domain.LoanRepository;
|
||||||
import org.mifosng.platform.loan.domain.LoanStatus;
|
import org.mifosng.platform.loan.domain.LoanStatus;
|
||||||
import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
||||||
import org.mifosng.platform.loan.domain.LoanTransaction;
|
import org.mifosng.platform.loan.domain.LoanTransaction;
|
||||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||||
import org.mifosng.platform.loan.service.CalculationPlatformService;
|
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.Office;
|
||||||
import org.mifosng.platform.organisation.domain.OfficeRepository;
|
import org.mifosng.platform.organisation.domain.OfficeRepository;
|
||||||
import org.mifosng.platform.organisation.domain.Organisation;
|
import org.mifosng.platform.organisation.domain.Organisation;
|
||||||
@@ -75,11 +69,13 @@ public class ImportPlatformServiceImpl implements ImportPlatformService {
|
|||||||
private final CalculationPlatformService calculationPlatformService;
|
private final CalculationPlatformService calculationPlatformService;
|
||||||
private final LoanRepository loanRepository;
|
private final LoanRepository loanRepository;
|
||||||
private final LoanStatusRepository loanStatusRepository;
|
private final LoanStatusRepository loanStatusRepository;
|
||||||
|
private final LoanAssembler loanAssembler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ImportPlatformServiceImpl(
|
public ImportPlatformServiceImpl(final LoanAssembler loanAssembler,
|
||||||
final OfficeRepository officeRepository, final ClientRepository clientRepository, final LoanProductRepository loanProductRepository,
|
final OfficeRepository officeRepository, final ClientRepository clientRepository, final LoanProductRepository loanProductRepository,
|
||||||
final CalculationPlatformService calculationPlatformService, final LoanRepository loanRepository, final LoanStatusRepository loanStatusRepository) {
|
final CalculationPlatformService calculationPlatformService, final LoanRepository loanRepository, final LoanStatusRepository loanStatusRepository) {
|
||||||
|
this.loanAssembler = loanAssembler;
|
||||||
this.officeRepository = officeRepository;
|
this.officeRepository = officeRepository;
|
||||||
this.clientRepository = clientRepository;
|
this.clientRepository = clientRepository;
|
||||||
this.loanProductRepository = loanProductRepository;
|
this.loanProductRepository = loanProductRepository;
|
||||||
@@ -138,75 +134,10 @@ public class ImportPlatformServiceImpl implements ImportPlatformService {
|
|||||||
|
|
||||||
SubmitLoanApplicationCommand command = combinedCommand.getSubmitLoanApplicationCommand();
|
SubmitLoanApplicationCommand command = combinedCommand.getSubmitLoanApplicationCommand();
|
||||||
|
|
||||||
// most of this code can be extracted out into an Assembler
|
Loan loan = loanAssembler.assembleFrom(command, currentUser.getOrganisation());
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
LoanLifecycleStateMachine loanLifecycleStateMachine = defaultLoanLifecycleStateMachine();
|
LoanLifecycleStateMachine loanLifecycleStateMachine = defaultLoanLifecycleStateMachine();
|
||||||
|
|
||||||
loan.submitApplication(command.getSubmittedOnDate(), command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate(), command.getInterestCalculatedFromDate(), loanLifecycleStateMachine);
|
|
||||||
|
|
||||||
LoanStateTransitionCommand approveLoanCommand = combinedCommand.getApproveLoanCommand();
|
LoanStateTransitionCommand approveLoanCommand = combinedCommand.getApproveLoanCommand();
|
||||||
if (approveLoanCommand != null) {
|
if (approveLoanCommand != null) {
|
||||||
loan.approve(approveLoanCommand.getEventDate(), loanLifecycleStateMachine);
|
loan.approve(approveLoanCommand.getEventDate(), loanLifecycleStateMachine);
|
||||||
|
|||||||
@@ -109,42 +109,42 @@ public class LoansApiResource {
|
|||||||
@QueryParam("command") final String commandParam,
|
@QueryParam("command") final String commandParam,
|
||||||
final SubmitLoanApplicationCommand command) {
|
final SubmitLoanApplicationCommand command) {
|
||||||
|
|
||||||
LocalDate expectedDisbursementDate = apiDataConversionService
|
LocalDate expectedDisbursementLocalDate = apiDataConversionService
|
||||||
.convertFrom(command.getExpectedDisbursementDateFormatted(),
|
.convertFrom(command.getExpectedDisbursementDate(),
|
||||||
"expectedDisbursementDateFormatted",
|
"expectedDisbursementDate",
|
||||||
command.getDateFormat());
|
command.getDateFormat());
|
||||||
LocalDate repaymentsStartingFromDate = apiDataConversionService
|
LocalDate repaymentsStartingFromLocalDate = apiDataConversionService
|
||||||
.convertFrom(command.getRepaymentsStartingFromDateFormatted(),
|
.convertFrom(command.getRepaymentsStartingFromDate(),
|
||||||
"repaymentsStartingFromDateFormatted",
|
"repaymentsStartingFromDate",
|
||||||
command.getDateFormat());
|
command.getDateFormat());
|
||||||
LocalDate interestCalculatedFromDate = apiDataConversionService
|
LocalDate interestChargedFromLocalDate = apiDataConversionService
|
||||||
.convertFrom(command.getInterestCalculatedFromDateFormatted(),
|
.convertFrom(command.getInterestChargedFromDate(),
|
||||||
"interestCalculatedFromDateFormatted",
|
"interestChargedFromDate",
|
||||||
command.getDateFormat());
|
command.getDateFormat());
|
||||||
LocalDate submittedOnDate = apiDataConversionService.convertFrom(
|
LocalDate submittedOnLocalDate = apiDataConversionService.convertFrom(
|
||||||
command.getSubmittedOnDateFormatted(),
|
command.getSubmittedOnDate(),
|
||||||
"submittedOnDateFormatted", command.getDateFormat());
|
"submittedOnDate", command.getDateFormat());
|
||||||
command.setExpectedDisbursementDate(expectedDisbursementDate);
|
|
||||||
command.setRepaymentsStartingFromDate(repaymentsStartingFromDate);
|
|
||||||
command.setInterestCalculatedFromDate(interestCalculatedFromDate);
|
|
||||||
command.setSubmittedOnDate(submittedOnDate);
|
|
||||||
|
|
||||||
// FIXME - pass in locale through query string or in 'request body'
|
command.setExpectedDisbursementLocalDate(expectedDisbursementLocalDate);
|
||||||
Locale clientApplicationLocale = Locale.UK;
|
command.setRepaymentsStartingFromLocalDate(repaymentsStartingFromLocalDate);
|
||||||
BigDecimal principal = this.apiDataConversionService.convertFrom(
|
command.setInterestChargedFromLocalDate(interestChargedFromLocalDate);
|
||||||
command.getPrincipalFormatted(), "principalFormatted",
|
command.setSubmittedOnLocalDate(submittedOnLocalDate);
|
||||||
clientApplicationLocale);
|
|
||||||
BigDecimal interestRatePerPeriod = this.apiDataConversionService
|
Locale clientApplicationLocale = this.apiDataConversionService.localeFromString(command.getLocale());
|
||||||
.convertFrom(command.getInterestRatePerPeriodFormatted(),
|
BigDecimal principalValue = this.apiDataConversionService.convertFrom(command.getPrincipal(), "principal", clientApplicationLocale);
|
||||||
"interestRatePerPeriodFormatted",
|
BigDecimal inArrearsToleranceValue = this.apiDataConversionService.convertFrom(command.getInArrearsTolerance(), "inArrearsTolerance", clientApplicationLocale);
|
||||||
clientApplicationLocale);
|
BigDecimal interestRatePerPeriodValue = this.apiDataConversionService.convertFrom(command.getInterestRatePerPeriod(),"interestRatePerPeriod", clientApplicationLocale);
|
||||||
BigDecimal inArrearsToleranceAmount = this.apiDataConversionService
|
|
||||||
.convertFrom(command.getInArrearsToleranceAmountFormatted(),
|
Integer digitsAfterDecimalValue = this.apiDataConversionService.convertToInteger(command.getDigitsAfterDecimal(), "digitsAfterDecimal", clientApplicationLocale);
|
||||||
"inArrearsToleranceAmountFormatted",
|
Integer repaymentEveryValue = this.apiDataConversionService.convertToInteger(command.getRepaymentEvery(), "repaymentEvery", clientApplicationLocale);
|
||||||
clientApplicationLocale);
|
Integer numberOfRepaymentsValue = this.apiDataConversionService.convertToInteger(command.getNumberOfRepayments(), "numberOfRepayments", clientApplicationLocale);
|
||||||
command.setPrincipal(principal);
|
|
||||||
command.setInterestRatePerPeriod(interestRatePerPeriod);
|
command.setPrincipalValue(principalValue);
|
||||||
command.setInArrearsToleranceAmount(inArrearsToleranceAmount);
|
command.setInArrearsToleranceValue(inArrearsToleranceValue);
|
||||||
|
command.setInterestRatePerPeriodValue(interestRatePerPeriodValue);
|
||||||
|
command.setDigitsAfterDecimalValue(digitsAfterDecimalValue);
|
||||||
|
command.setRepaymentEveryValue(repaymentEveryValue);
|
||||||
|
command.setNumberOfRepaymentsValue(numberOfRepaymentsValue);
|
||||||
|
|
||||||
CalculateLoanScheduleCommand calculateLoanScheduleCommand = command
|
CalculateLoanScheduleCommand calculateLoanScheduleCommand = command
|
||||||
.toCalculateLoanScheduleCommand();
|
.toCalculateLoanScheduleCommand();
|
||||||
|
|||||||
+1
-1
@@ -99,7 +99,7 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableCustom<Ap
|
|||||||
Money interest = getInterest(totalAvailable.getCurrency());
|
Money interest = getInterest(totalAvailable.getCurrency());
|
||||||
Money principal = getPrincipal(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
|
// pay off interest
|
||||||
if (remaining.isGreaterThanOrEqualTo(interest)) {
|
if (remaining.isGreaterThanOrEqualTo(interest)) {
|
||||||
this.interestCompleted = interest.getAmount();
|
this.interestCompleted = interest.getAmount();
|
||||||
|
|||||||
+25
-174
@@ -3,13 +3,10 @@ package org.mifosng.platform.loan.service;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.mifosng.data.ApiParameterError;
|
import org.mifosng.data.ApiParameterError;
|
||||||
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
||||||
|
import org.mifosng.platform.DataValidatorBuilder;
|
||||||
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
|
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 {
|
public class CalculateLoanScheduleCommandValidator {
|
||||||
|
|
||||||
@@ -20,199 +17,53 @@ public class CalculateLoanScheduleCommandValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void validate() {
|
public void validate() {
|
||||||
|
|
||||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
|
||||||
if (StringUtils.isBlank(command.getCurrencyCode())) {
|
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
|
||||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.product.currency.cannot.be.empty", "The parameter currencyCode cannot be blank.", "currencyCode");
|
|
||||||
dataValidationErrors.add(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.getDigitsAfterDecimal() != null) {
|
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);
|
||||||
|
|
||||||
if (command.getDigitsAfterDecimal() < 0 || command.getDigitsAfterDecimal() > 6) {
|
baseDataValidator.reset().parameter("expectedDisbursementDate").value(command.getExpectedDisbursementLocalDate()).notNull();
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.getExpectedDisbursementLocalDate() != null) {
|
||||||
if (command.getPrincipal() != null) {
|
if (command.getRepaymentsStartingFromLocalDate() != null
|
||||||
if (command.getPrincipal().doubleValue() <= Double.valueOf("0.0")) {
|
&& command.getExpectedDisbursementLocalDate().isAfter(command.getRepaymentsStartingFromLocalDate())) {
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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())) {
|
|
||||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.expectedDisbursementDate.cannot.be.after.first.repayment.date",
|
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",
|
"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);
|
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",
|
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);
|
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
|
// validate interestCalculatedFromDate is after or on repaymentsStartingFromDate
|
||||||
if (command.getExpectedDisbursementDate().isAfter(command.getInterestCalculatedFromDate())) {
|
if (command.getExpectedDisbursementLocalDate().isAfter(command.getInterestChargedFromLocalDate())) {
|
||||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.interestCalculatedFromDate.cannot.be.before.disbursement.date",
|
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.", "interestCalculatedFromDate", command.getInterestCalculatedFromDate(), command.getExpectedDisbursementDate());
|
"The parameter interestCalculatedFromDate cannot be before the date given for expected disbursement.", "interestChargedFromDate", command.getInterestChargedFromLocalDate(), command.getExpectedDisbursementLocalDate());
|
||||||
dataValidationErrors.add(error);
|
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()) {
|
if (!dataValidationErrors.isEmpty()) {
|
||||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
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);
|
CalculateLoanScheduleCommandValidator validator = new CalculateLoanScheduleCommandValidator(command);
|
||||||
validator.validate();
|
validator.validate();
|
||||||
|
|
||||||
// assemble 'loan data' into 'domain' object [LoanProductRelatedDetail]
|
final BigDecimal principalAmount = command.getPrincipalValue();
|
||||||
final BigDecimal principalAmount = BigDecimal.valueOf(command.getPrincipal().doubleValue());
|
final BigDecimal defaultNominalInterestRatePerPeriod = command.getInterestRatePerPeriodValue();
|
||||||
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(command.getInterestRatePerPeriod().doubleValue());
|
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyType());
|
||||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.fromInt(command.getInterestRateFrequencyMethod());
|
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestType());
|
||||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.getInterestMethod());
|
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodType());
|
||||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command.getInterestCalculationPeriodMethod());
|
final Integer repayEvery = command.getRepaymentEveryValue();
|
||||||
final Integer repayEvery = command.getRepaymentEvery();
|
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequencyType());
|
||||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command.getRepaymentFrequency());
|
final Integer defaultNumberOfInstallments = command.getNumberOfRepaymentsValue();
|
||||||
final Integer defaultNumberOfInstallments = command.getNumberOfRepayments();
|
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationType());
|
||||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.getAmortizationMethod());
|
|
||||||
|
|
||||||
final BigDecimal defaultAnnualNominalInterestRate = this.aprCalculator.calculateFrom(interestPeriodFrequencyType, defaultNominalInterestRatePerPeriod);
|
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
|
// in arrerars tolerance isnt relevant when auto-calculating a loan schedule
|
||||||
final BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
final BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||||
@@ -78,11 +77,11 @@ public class CalculationPlatformServiceImpl implements
|
|||||||
LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(interestMethod);
|
LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(interestMethod);
|
||||||
|
|
||||||
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(command.getCurrencyCode());
|
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());
|
applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
||||||
|
|
||||||
return loanScheduleGenerator.generate(loanScheduleInfo, command.getExpectedDisbursementDate(), command.getRepaymentsStartingFromDate(),
|
return loanScheduleGenerator.generate(loanScheduleInfo, command.getExpectedDisbursementLocalDate(), command.getRepaymentsStartingFromLocalDate(),
|
||||||
command.getInterestCalculatedFromDate(), currencyData);
|
command.getInterestChargedFromLocalDate(), currencyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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')")
|
@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);
|
public EntityIdentifier makeLoanRepayment(LoanTransactionCommand command);
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE')")
|
||||||
EntityIdentifier adjustLoanTransaction(AdjustLoanTransactionCommand command);
|
EntityIdentifier adjustLoanTransaction(AdjustLoanTransactionCommand command);
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE')")
|
||||||
EntityIdentifier waiveLoanAmount(LoanTransactionCommand command);
|
EntityIdentifier waiveLoanAmount(LoanTransactionCommand command);
|
||||||
}
|
}
|
||||||
+7
-63
@@ -2,7 +2,6 @@ package org.mifosng.platform.loan.service;
|
|||||||
|
|
||||||
import static org.mifosng.platform.Specifications.loansThatMatch;
|
import static org.mifosng.platform.Specifications.loansThatMatch;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -10,7 +9,6 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosng.data.EntityIdentifier;
|
import org.mifosng.data.EntityIdentifier;
|
||||||
import org.mifosng.data.LoanSchedule;
|
import org.mifosng.data.LoanSchedule;
|
||||||
import org.mifosng.data.MoneyData;
|
|
||||||
import org.mifosng.data.ScheduledLoanInstallment;
|
import org.mifosng.data.ScheduledLoanInstallment;
|
||||||
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
||||||
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
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.LoanTransactionCommand;
|
||||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||||
import org.mifosng.data.command.UndoStateTransitionCommand;
|
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.Note;
|
||||||
import org.mifosng.platform.client.domain.NoteRepository;
|
import org.mifosng.platform.client.domain.NoteRepository;
|
||||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
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.LoanNotFoundException;
|
||||||
import org.mifosng.platform.exceptions.NoAuthorizationException;
|
import org.mifosng.platform.exceptions.NoAuthorizationException;
|
||||||
import org.mifosng.platform.exceptions.PlatformDomainRuleException;
|
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.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.Loan;
|
||||||
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
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.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosng.platform.loan.domain.LoanRepository;
|
import org.mifosng.platform.loan.domain.LoanRepository;
|
||||||
import org.mifosng.platform.loan.domain.LoanStatus;
|
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.LoanTransaction;
|
||||||
import org.mifosng.platform.loan.domain.LoanTransactionRepository;
|
import org.mifosng.platform.loan.domain.LoanTransactionRepository;
|
||||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
||||||
import org.mifosng.platform.loanschedule.domain.AprCalculator;
|
|
||||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||||
import org.mifosng.platform.user.domain.AppUser;
|
import org.mifosng.platform.user.domain.AppUser;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -56,24 +45,21 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final LoanRepository loanRepository;
|
private final LoanRepository loanRepository;
|
||||||
private final LoanProductRepository loanProductRepository;
|
|
||||||
private final LoanStatusRepository loanStatusRepository;
|
private final LoanStatusRepository loanStatusRepository;
|
||||||
private final ClientRepository clientRepository;
|
|
||||||
private final NoteRepository noteRepository;
|
private final NoteRepository noteRepository;
|
||||||
private final CalculationPlatformService calculationPlatformService;
|
private final CalculationPlatformService calculationPlatformService;
|
||||||
private final AprCalculator aprCalculator = new AprCalculator();
|
|
||||||
private final LoanTransactionRepository loanTransactionRepository;
|
private final LoanTransactionRepository loanTransactionRepository;
|
||||||
|
private final LoanAssembler loanAssembler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final LoanAssembler loanAssembler,
|
||||||
final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository,
|
final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository,
|
||||||
final LoanStatusRepository loanStatusRepository, final LoanProductRepository loanProductRepository,
|
final LoanStatusRepository loanStatusRepository,
|
||||||
final ClientRepository clientRepository, final NoteRepository noteRepository, final CalculationPlatformService calculationPlatformService) {
|
final NoteRepository noteRepository, final CalculationPlatformService calculationPlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.loanAssembler = loanAssembler;
|
||||||
this.loanRepository = loanRepository;
|
this.loanRepository = loanRepository;
|
||||||
this.loanTransactionRepository = loanTransactionRepository;
|
this.loanTransactionRepository = loanTransactionRepository;
|
||||||
this.loanProductRepository = loanProductRepository;
|
|
||||||
this.clientRepository = clientRepository;
|
|
||||||
this.loanStatusRepository = loanStatusRepository;
|
this.loanStatusRepository = loanStatusRepository;
|
||||||
this.noteRepository = noteRepository;
|
this.noteRepository = noteRepository;
|
||||||
this.calculationPlatformService = calculationPlatformService;
|
this.calculationPlatformService = calculationPlatformService;
|
||||||
@@ -97,55 +83,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
SubmitLoanApplicationCommandValidator validator = new SubmitLoanApplicationCommandValidator(command);
|
SubmitLoanApplicationCommandValidator validator = new SubmitLoanApplicationCommandValidator(command);
|
||||||
validator.validate();
|
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")) {
|
if (this.isBeforeToday(submittedOn) && currentUser.hasNotPermissionForAnyOf("CAN_SUBMIT_HISTORIC_LOAN_APPLICATION_ROLE", "PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE")) {
|
||||||
throw new NoAuthorizationException("Cannot add backdated loan.");
|
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.
|
Loan loan = loanAssembler.assembleFrom(command, currentUser.getOrganisation());
|
||||||
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());
|
|
||||||
|
|
||||||
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);
|
this.loanRepository.save(loan);
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(command.getSubmittedOnNote())) {
|
if (StringUtils.isNotBlank(command.getSubmittedOnNote())) {
|
||||||
|
|||||||
+16
-16
@@ -25,15 +25,15 @@ public class SubmitLoanApplicationCommandValidator {
|
|||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.getSubmittedOnDate() == null) {
|
if (command.getSubmittedOnLocalDate() == null) {
|
||||||
ApiParameterError error = ApiParameterError.parameterError("validation.msg.loan.submitted.on.date.cannot.be.blank",
|
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);
|
dataValidationErrors.add(error);
|
||||||
} else {
|
} 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",
|
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",
|
"The date of parameter submittedOnDate cannot fall after the date given for expectedDisbursementDate.", "submittedOnDate",
|
||||||
command.getSubmittedOnDateFormatted(), command.getExpectedDisbursementDateFormatted());
|
command.getSubmittedOnDate(), command.getExpectedDisbursementDate());
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,17 +41,17 @@ public class SubmitLoanApplicationCommandValidator {
|
|||||||
try {
|
try {
|
||||||
// reuse calculate loan schedule validator for now
|
// reuse calculate loan schedule validator for now
|
||||||
CalculateLoanScheduleCommand calculateLoanScheduleCommand = new CalculateLoanScheduleCommand(
|
CalculateLoanScheduleCommand calculateLoanScheduleCommand = new CalculateLoanScheduleCommand(
|
||||||
command.getCurrencyCode(), command.getDigitsAfterDecimal(),
|
command.getCurrencyCode(), command.getDigitsAfterDecimalValue(),
|
||||||
command.getPrincipal(), command.getInterestRatePerPeriod(),
|
command.getPrincipalValue(), command.getInterestRatePerPeriodValue(),
|
||||||
command.getInterestRateFrequencyMethod(),
|
command.getInterestRateFrequencyType(),
|
||||||
command.getInterestMethod(), command.getInterestCalculationPeriodMethod(),
|
command.getInterestType(), command.getInterestCalculationPeriodType(),
|
||||||
command.getRepaymentEvery(),
|
command.getRepaymentEveryValue(),
|
||||||
command.getRepaymentFrequency(),
|
command.getRepaymentFrequencyType(),
|
||||||
command.getNumberOfRepayments(),
|
command.getNumberOfRepaymentsValue(),
|
||||||
command.getAmortizationMethod(),
|
command.getAmortizationType(),
|
||||||
command.getExpectedDisbursementDate(),
|
command.getExpectedDisbursementLocalDate(),
|
||||||
command.getRepaymentsStartingFromDate(),
|
command.getRepaymentsStartingFromLocalDate(),
|
||||||
command.getInterestCalculatedFromDate());
|
command.getInterestChargedFromLocalDate());
|
||||||
|
|
||||||
CalculateLoanScheduleCommandValidator validator = new CalculateLoanScheduleCommandValidator(
|
CalculateLoanScheduleCommandValidator validator = new CalculateLoanScheduleCommandValidator(
|
||||||
calculateLoanScheduleCommand);
|
calculateLoanScheduleCommand);
|
||||||
|
|||||||
-2
@@ -9,7 +9,6 @@ import org.mifosng.platform.loan.domain.LoanProductRelatedDetail;
|
|||||||
public class PmtCalculator {
|
public class PmtCalculator {
|
||||||
|
|
||||||
public Money calculatePaymentForOnePeriodFrom(LoanProductRelatedDetail loanScheduleInfo, BigDecimal periodInterestRateForRepaymentPeriod, MonetaryCurrency monetaryCurrency) {
|
public Money calculatePaymentForOnePeriodFrom(LoanProductRelatedDetail loanScheduleInfo, BigDecimal periodInterestRateForRepaymentPeriod, MonetaryCurrency monetaryCurrency) {
|
||||||
// TODO - check if going to doubles is a problem
|
|
||||||
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
||||||
|
|
||||||
double futureValue = 0;
|
double futureValue = 0;
|
||||||
@@ -24,7 +23,6 @@ public class PmtCalculator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Money calculateTotalRepaymentFrom(LoanProductRelatedDetail loanScheduleInfo, BigDecimal periodInterestRateForRepaymentPeriod, MonetaryCurrency monetaryCurrency) {
|
public Money calculateTotalRepaymentFrom(LoanProductRelatedDetail loanScheduleInfo, BigDecimal periodInterestRateForRepaymentPeriod, MonetaryCurrency monetaryCurrency) {
|
||||||
// TODO - check if going to doubles is a problem
|
|
||||||
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
||||||
|
|
||||||
double futureValue = 0;
|
double futureValue = 0;
|
||||||
|
|||||||
-1
@@ -44,7 +44,6 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
|
|||||||
return this.jdbcTemplate.query(sql, mapper, new Object[] {currentUser.getOrganisation().getId() });
|
return this.jdbcTemplate.query(sql, mapper, new Object[] {currentUser.getOrganisation().getId() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - does it make sense to use JDBC over repository for this?
|
|
||||||
@Override
|
@Override
|
||||||
public RoleData retrieveRole(final Long id) {
|
public RoleData retrieveRole(final Long id) {
|
||||||
AppUser currentUser = context.authenticatedUser();
|
AppUser currentUser = context.authenticatedUser();
|
||||||
|
|||||||
Reference in New Issue
Block a user