mifosx-58: restructure loan schedule to contain summary plus detail of schedule. As part of this work I removed the use of MoneyData in data objects and instead return currency and decimal for each monetary amount aligning with rest of application.
This commit is contained in:
@@ -32,14 +32,14 @@ import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
import org.mifosng.platform.api.data.EnumOptionData;
|
||||
import org.mifosng.platform.api.data.FundData;
|
||||
import org.mifosng.platform.api.data.LoanAccountData;
|
||||
import org.mifosng.platform.api.data.LoanAccountSummaryData;
|
||||
import org.mifosng.platform.api.data.LoanBasicDetailsData;
|
||||
import org.mifosng.platform.api.data.LoanPermissionData;
|
||||
import org.mifosng.platform.api.data.LoanProductLookup;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentPeriodData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentTransactionData;
|
||||
import org.mifosng.platform.api.data.LoanSchedule;
|
||||
import org.mifosng.platform.api.data.LoanScheduleData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
import org.mifosng.platform.api.data.StaffData;
|
||||
import org.mifosng.platform.api.data.TransactionProcessingStrategyData;
|
||||
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
|
||||
@@ -159,7 +159,7 @@ public class LoansApiResource {
|
||||
// populate loan officers if query param is passed in
|
||||
Collection<StaffData> allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.getClientOfficeId());
|
||||
|
||||
final LoanAccountData newLoanAccount = new LoanAccountData(loanBasicDetails, convenienceDataRequired, null, null, null, null, charges,
|
||||
final LoanAccountData newLoanAccount = new LoanAccountData(loanBasicDetails, convenienceDataRequired, null, null, null, charges,
|
||||
productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions,
|
||||
amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers);
|
||||
@@ -196,16 +196,15 @@ public class LoansApiResource {
|
||||
|
||||
int loanRepaymentsCount = 0;
|
||||
Collection<LoanRepaymentTransactionData> loanRepayments = null;
|
||||
Collection<LoanRepaymentPeriodData> repaymentSchedule = null;
|
||||
LoanAccountSummaryData summary = null;
|
||||
LoanScheduleData repaymentSchedule = null;
|
||||
LoanPermissionData permissions = null;
|
||||
Collection<ChargeData> charges = null;
|
||||
|
||||
boolean convenienceDataRequired = false;
|
||||
Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
if (!associationParameters.isEmpty()) {
|
||||
if (associationParameters.contains("all")) {
|
||||
responseParameters.addAll(Arrays.asList("summary", "repaymentSchedule", "loanRepayments", "permissions", "convenienceData", "charges"));
|
||||
responseParameters.addAll(Arrays.asList("repaymentSchedule", "loanRepayments", "permissions", "convenienceData", "charges"));
|
||||
} else {
|
||||
responseParameters.addAll(associationParameters);
|
||||
}
|
||||
@@ -215,11 +214,12 @@ public class LoansApiResource {
|
||||
loanRepayments = currentLoanRepayments;
|
||||
loanRepaymentsCount = loanRepayments.size();
|
||||
}
|
||||
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId);
|
||||
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, loanBasicDetails.getCurrency(), loanRepayments);
|
||||
|
||||
summary = this.loanReadPlatformService.retrieveSummary(loanBasicDetails.getCurrency(), repaymentSchedule, loanRepayments);
|
||||
|
||||
boolean isWaiveAllowed = summary.isWaiveAllowed(loanBasicDetails.getCurrency(), loanBasicDetails.getInArrearsTolerance());
|
||||
MoneyData tolerance = MoneyData.of(loanBasicDetails.getCurrency(), loanBasicDetails.getInArrearsTolerance());
|
||||
MoneyData totalOutstandingMoney = MoneyData.of(loanBasicDetails.getCurrency(), repaymentSchedule.totalOutstanding());
|
||||
boolean isWaiveAllowed = totalOutstandingMoney.isGreaterThanZero() && (tolerance.isGreaterThan(totalOutstandingMoney) || tolerance.isEqualTo(totalOutstandingMoney));
|
||||
|
||||
permissions = this.loanReadPlatformService.retrieveLoanPermissions(loanBasicDetails, isWaiveAllowed, loanRepaymentsCount);
|
||||
convenienceDataRequired = true;
|
||||
|
||||
@@ -270,7 +270,8 @@ public class LoansApiResource {
|
||||
chargeTemplate = this.chargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||
}
|
||||
|
||||
final LoanAccountData loanAccount = new LoanAccountData(loanBasicDetails, convenienceDataRequired, summary, repaymentSchedule, loanRepayments, permissions, charges,
|
||||
final LoanAccountData loanAccount = new LoanAccountData(loanBasicDetails, convenienceDataRequired,
|
||||
repaymentSchedule, loanRepayments, permissions, charges,
|
||||
productOptions, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions,
|
||||
amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers);
|
||||
|
||||
@@ -8,8 +8,10 @@ import org.joda.time.LocalDate;
|
||||
/**
|
||||
* Immutable data object representing loan account data.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class LoanAccountData {
|
||||
|
||||
// basic loan details
|
||||
private final Long id;
|
||||
private final String externalId;
|
||||
private final Long clientId;
|
||||
@@ -50,15 +52,13 @@ public class LoanAccountData {
|
||||
private final LocalDate lifeCycleStatusDate;
|
||||
|
||||
// associations
|
||||
private final LoanAccountSummaryData summary;
|
||||
private final Collection<LoanRepaymentPeriodData> repaymentSchedule;
|
||||
private final LoanScheduleData repaymentSchedule;
|
||||
private final Collection<LoanRepaymentTransactionData> loanRepayments;
|
||||
private final Collection<ChargeData> charges;
|
||||
private final LoanPermissionData permissions;
|
||||
private final LoanConvenienceData convenienceData;
|
||||
|
||||
// template
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<StaffData> loanOfficerOptions;
|
||||
private final Collection<LoanProductLookup> productOptions;
|
||||
private final Collection<EnumOptionData> termFrequencyTypeOptions;
|
||||
@@ -70,14 +70,12 @@ public class LoanAccountData {
|
||||
private final Collection<EnumOptionData> interestCalculationPeriodTypeOptions;
|
||||
private final Collection<FundData> fundOptions;
|
||||
private final Collection<ChargeData> chargeOptions;
|
||||
@SuppressWarnings("unused")
|
||||
private final ChargeData chargeTemplate;
|
||||
|
||||
public LoanAccountData(
|
||||
final LoanBasicDetailsData basicDetails,
|
||||
final boolean convenienceDataRequired,
|
||||
final LoanAccountSummaryData summary,
|
||||
final Collection<LoanRepaymentPeriodData> repaymentSchedule,
|
||||
final LoanScheduleData repaymentSchedule,
|
||||
final Collection<LoanRepaymentTransactionData> loanRepayments,
|
||||
final LoanPermissionData permissions,
|
||||
final Collection<ChargeData> charges,
|
||||
@@ -93,7 +91,6 @@ public class LoanAccountData {
|
||||
final Collection<ChargeData> chargeOptions,
|
||||
final ChargeData chargeTemplate,
|
||||
final Collection<StaffData> loanOfficerOptions) {
|
||||
this.summary = summary;
|
||||
this.repaymentSchedule = repaymentSchedule;
|
||||
this.loanRepayments = loanRepayments;
|
||||
this.permissions = permissions;
|
||||
@@ -177,212 +174,4 @@ public class LoanAccountData {
|
||||
this.status = basicDetails.getStatus();
|
||||
this.lifeCycleStatusDate = basicDetails.getLifeCycleStatusDate();
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
public Long getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return clientName;
|
||||
}
|
||||
|
||||
public Long getLoanProductId() {
|
||||
return loanProductId;
|
||||
}
|
||||
|
||||
public String getLoanProductName() {
|
||||
return loanProductName;
|
||||
}
|
||||
|
||||
public String getLoanProductDescription() {
|
||||
return loanProductDescription;
|
||||
}
|
||||
|
||||
public EnumOptionData getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Long getFundId() {
|
||||
return fundId;
|
||||
}
|
||||
|
||||
public String getFundName() {
|
||||
return fundName;
|
||||
}
|
||||
|
||||
public LocalDate getSubmittedOnDate() {
|
||||
return submittedOnDate;
|
||||
}
|
||||
|
||||
public LocalDate getApprovedOnDate() {
|
||||
return approvedOnDate;
|
||||
}
|
||||
|
||||
public LocalDate getExpectedDisbursementDate() {
|
||||
return expectedDisbursementDate;
|
||||
}
|
||||
|
||||
public LocalDate getActualDisbursementDate() {
|
||||
return actualDisbursementDate;
|
||||
}
|
||||
|
||||
public LocalDate getRepaymentsStartingFromDate() {
|
||||
return repaymentsStartingFromDate;
|
||||
}
|
||||
|
||||
public LocalDate getInterestChargedFromDate() {
|
||||
return interestChargedFromDate;
|
||||
}
|
||||
|
||||
public LocalDate getClosedOnDate() {
|
||||
return closedOnDate;
|
||||
}
|
||||
|
||||
public LocalDate getExpectedMaturityDate() {
|
||||
return expectedMaturityDate;
|
||||
}
|
||||
|
||||
public CurrencyData getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipal() {
|
||||
return this.principal;
|
||||
}
|
||||
|
||||
public BigDecimal getInArrearsTolerance() {
|
||||
return this.inArrearsTolerance;
|
||||
}
|
||||
|
||||
public Integer getTermFrequency() {
|
||||
return termFrequency;
|
||||
}
|
||||
|
||||
public EnumOptionData getTermPeriodFrequencyType() {
|
||||
return termPeriodFrequencyType;
|
||||
}
|
||||
|
||||
public Integer getNumberOfRepayments() {
|
||||
return numberOfRepayments;
|
||||
}
|
||||
|
||||
public Integer getRepaymentEvery() {
|
||||
return repaymentEvery;
|
||||
}
|
||||
|
||||
public Integer getTransactionStrategyId() {
|
||||
return transactionStrategyId;
|
||||
}
|
||||
|
||||
public BigDecimal getInterestRatePerPeriod() {
|
||||
return interestRatePerPeriod;
|
||||
}
|
||||
|
||||
public BigDecimal getAnnualInterestRate() {
|
||||
return annualInterestRate;
|
||||
}
|
||||
|
||||
public EnumOptionData getRepaymentFrequencyType() {
|
||||
return repaymentFrequencyType;
|
||||
}
|
||||
|
||||
public EnumOptionData getInterestRateFrequencyType() {
|
||||
return interestRateFrequencyType;
|
||||
}
|
||||
|
||||
public EnumOptionData getAmortizationType() {
|
||||
return amortizationType;
|
||||
}
|
||||
|
||||
public EnumOptionData getInterestType() {
|
||||
return interestType;
|
||||
}
|
||||
|
||||
public EnumOptionData getInterestCalculationPeriodType() {
|
||||
return interestCalculationPeriodType;
|
||||
}
|
||||
|
||||
public LocalDate getLifeCycleStatusDate() {
|
||||
return lifeCycleStatusDate;
|
||||
}
|
||||
|
||||
public LoanAccountSummaryData getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
public Collection<LoanRepaymentPeriodData> getRepaymentSchedule() {
|
||||
return repaymentSchedule;
|
||||
}
|
||||
|
||||
public Collection<LoanRepaymentTransactionData> getLoanRepayments() {
|
||||
return loanRepayments;
|
||||
}
|
||||
|
||||
public LoanPermissionData getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public LoanConvenienceData getConvenienceData() {
|
||||
return convenienceData;
|
||||
}
|
||||
|
||||
public Collection<ChargeData> getCharges() {
|
||||
return this.charges;
|
||||
}
|
||||
|
||||
public Collection<LoanProductLookup> getProductOptions() {
|
||||
return productOptions;
|
||||
}
|
||||
|
||||
public Collection<EnumOptionData> getTermFrequencyTypeOptions() {
|
||||
return termFrequencyTypeOptions;
|
||||
}
|
||||
|
||||
public Collection<EnumOptionData> getRepaymentFrequencyTypeOptions() {
|
||||
return repaymentFrequencyTypeOptions;
|
||||
}
|
||||
|
||||
public Collection<TransactionProcessingStrategyData> getRepaymentStrategyOptions() {
|
||||
return repaymentStrategyOptions;
|
||||
}
|
||||
|
||||
public Collection<EnumOptionData> getInterestRateFrequencyTypeOptions() {
|
||||
return interestRateFrequencyTypeOptions;
|
||||
}
|
||||
|
||||
public Collection<EnumOptionData> getAmortizationTypeOptions() {
|
||||
return amortizationTypeOptions;
|
||||
}
|
||||
|
||||
public Collection<EnumOptionData> getInterestTypeOptions() {
|
||||
return interestTypeOptions;
|
||||
}
|
||||
|
||||
public Collection<EnumOptionData> getInterestCalculationPeriodTypeOptions() {
|
||||
return interestCalculationPeriodTypeOptions;
|
||||
}
|
||||
|
||||
public Collection<FundData> getFundOptions() {
|
||||
return fundOptions;
|
||||
}
|
||||
|
||||
public Collection<ChargeData> getChargeOptions() {
|
||||
return chargeOptions;
|
||||
}
|
||||
|
||||
public Long getLoanOfficerId() {
|
||||
return loanOfficerId;
|
||||
}
|
||||
|
||||
public String getLoanOfficerName() {
|
||||
return loanOfficerName;
|
||||
}
|
||||
}
|
||||
+37
-127
@@ -2,38 +2,45 @@ package org.mifosng.platform.api.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Immutable data object representing summary information of loan.
|
||||
*
|
||||
* <code>currency</code> is provided in summary even though its also passed with basic loan information so its possible to just request summary only.
|
||||
*
|
||||
* Note: getter/setter not added on purpose - google-gson only requires fields to generate json.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class LoanAccountSummaryData {
|
||||
|
||||
private MoneyData originalPrincipal;
|
||||
private MoneyData originalInterest;
|
||||
private MoneyData originalTotal;
|
||||
private MoneyData principalPaid;
|
||||
private MoneyData principalOutstanding;
|
||||
private MoneyData interestPaid;
|
||||
private MoneyData interestWaived;
|
||||
private MoneyData interestOutstanding;
|
||||
private MoneyData totalPaid;
|
||||
private MoneyData totalWaived;
|
||||
private MoneyData totalOutstanding;
|
||||
private MoneyData totalInArrears;
|
||||
|
||||
protected LoanAccountSummaryData() {
|
||||
//
|
||||
}
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal originalPrincipal;
|
||||
private final BigDecimal originalInterest;
|
||||
private final BigDecimal originalTotal;
|
||||
private final BigDecimal principalPaid;
|
||||
private final BigDecimal principalOutstanding;
|
||||
private final BigDecimal interestPaid;
|
||||
private final BigDecimal interestWaived;
|
||||
private final BigDecimal interestOutstanding;
|
||||
private final BigDecimal totalPaid;
|
||||
private final BigDecimal totalWaived;
|
||||
private final BigDecimal totalOutstanding;
|
||||
private final BigDecimal totalInArrears;
|
||||
|
||||
public LoanAccountSummaryData(
|
||||
MoneyData originalPrincipal,
|
||||
MoneyData principalPaid,
|
||||
MoneyData principalOutstanding,
|
||||
MoneyData originalInterest,
|
||||
MoneyData interestPaid,
|
||||
MoneyData interestWaived,
|
||||
MoneyData interestOutstanding,
|
||||
MoneyData originalTotal,
|
||||
MoneyData totalPaid,
|
||||
MoneyData totalWaived,
|
||||
MoneyData totalOutstanding,
|
||||
MoneyData totalInArrears) {
|
||||
final CurrencyData currency,
|
||||
final BigDecimal originalPrincipal,
|
||||
final BigDecimal principalPaid,
|
||||
final BigDecimal principalOutstanding,
|
||||
final BigDecimal originalInterest,
|
||||
final BigDecimal interestPaid,
|
||||
final BigDecimal interestWaived,
|
||||
final BigDecimal interestOutstanding,
|
||||
final BigDecimal originalTotal,
|
||||
final BigDecimal totalPaid,
|
||||
final BigDecimal totalWaived,
|
||||
final BigDecimal totalOutstanding,
|
||||
final BigDecimal totalInArrears) {
|
||||
this.currency = currency;
|
||||
this.originalPrincipal = originalPrincipal;
|
||||
this.principalPaid = principalPaid;
|
||||
this.principalOutstanding = principalOutstanding;
|
||||
@@ -48,104 +55,7 @@ public class LoanAccountSummaryData {
|
||||
this.totalInArrears = totalInArrears;
|
||||
}
|
||||
|
||||
public boolean isWaiveAllowed(final CurrencyData currency, final BigDecimal toleranceAmount) {
|
||||
MoneyData tolerance = MoneyData.of(currency, toleranceAmount);
|
||||
return this.totalOutstanding.isGreaterThanZero() && (tolerance.isGreaterThan(this.totalOutstanding) || tolerance.isEqualTo(this.totalOutstanding));
|
||||
}
|
||||
|
||||
public MoneyData getOriginalPrincipal() {
|
||||
return originalPrincipal;
|
||||
}
|
||||
|
||||
public void setOriginalPrincipal(MoneyData originalPrincipal) {
|
||||
this.originalPrincipal = originalPrincipal;
|
||||
}
|
||||
|
||||
public MoneyData getOriginalInterest() {
|
||||
return originalInterest;
|
||||
}
|
||||
|
||||
public void setOriginalInterest(MoneyData originalInterest) {
|
||||
this.originalInterest = originalInterest;
|
||||
}
|
||||
|
||||
public MoneyData getOriginalTotal() {
|
||||
return originalTotal;
|
||||
}
|
||||
|
||||
public void setOriginalTotal(MoneyData originalTotal) {
|
||||
this.originalTotal = originalTotal;
|
||||
}
|
||||
|
||||
public MoneyData getPrincipalPaid() {
|
||||
return principalPaid;
|
||||
}
|
||||
|
||||
public void setPrincipalPaid(MoneyData principalPaid) {
|
||||
this.principalPaid = principalPaid;
|
||||
}
|
||||
|
||||
public MoneyData getPrincipalOutstanding() {
|
||||
return principalOutstanding;
|
||||
}
|
||||
|
||||
public void setPrincipalOutstanding(MoneyData principalOutstanding) {
|
||||
this.principalOutstanding = principalOutstanding;
|
||||
}
|
||||
|
||||
public MoneyData getInterestPaid() {
|
||||
return interestPaid;
|
||||
}
|
||||
|
||||
public void setInterestPaid(MoneyData interestPaid) {
|
||||
this.interestPaid = interestPaid;
|
||||
}
|
||||
|
||||
public MoneyData getInterestWaived() {
|
||||
return interestWaived;
|
||||
}
|
||||
|
||||
public void setInterestWaived(MoneyData interestWaived) {
|
||||
this.interestWaived = interestWaived;
|
||||
}
|
||||
|
||||
public MoneyData getInterestOutstanding() {
|
||||
return interestOutstanding;
|
||||
}
|
||||
|
||||
public void setInterestOutstanding(MoneyData interestOutstanding) {
|
||||
this.interestOutstanding = interestOutstanding;
|
||||
}
|
||||
|
||||
public MoneyData getTotalPaid() {
|
||||
return totalPaid;
|
||||
}
|
||||
|
||||
public void setTotalPaid(MoneyData totalPaid) {
|
||||
this.totalPaid = totalPaid;
|
||||
}
|
||||
|
||||
public MoneyData getTotalWaived() {
|
||||
return totalWaived;
|
||||
}
|
||||
|
||||
public void setTotalWaived(MoneyData totalWaived) {
|
||||
this.totalWaived = totalWaived;
|
||||
}
|
||||
|
||||
public MoneyData getTotalOutstanding() {
|
||||
return totalOutstanding;
|
||||
}
|
||||
|
||||
public void setTotalOutstanding(MoneyData totalOutstanding) {
|
||||
this.totalOutstanding = totalOutstanding;
|
||||
}
|
||||
|
||||
public MoneyData getTotalInArrears() {
|
||||
return totalInArrears;
|
||||
}
|
||||
|
||||
public void setTotalInArrears(MoneyData totalInArrears) {
|
||||
this.totalInArrears = totalInArrears;
|
||||
public BigDecimal totalOutstanding() {
|
||||
return this.totalOutstanding;
|
||||
}
|
||||
}
|
||||
+37
-99
@@ -1,33 +1,36 @@
|
||||
package org.mifosng.platform.api.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Immutable data object representing a repayment period of a loan schedule.
|
||||
*/
|
||||
public class LoanRepaymentPeriodData {
|
||||
|
||||
private Long loanId;
|
||||
private Integer period;
|
||||
private LocalDate date;
|
||||
private MoneyData principal;
|
||||
private MoneyData principalPaid;
|
||||
private MoneyData principalOutstanding;
|
||||
private MoneyData interest;
|
||||
private MoneyData interestPaid;
|
||||
private MoneyData interestWaived;
|
||||
private MoneyData interestOutstanding;
|
||||
private MoneyData total;
|
||||
private MoneyData totalPaid;
|
||||
private MoneyData totalWaived;
|
||||
private MoneyData totalOutstanding;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long loanId;
|
||||
@SuppressWarnings("unused")
|
||||
private final Integer period;
|
||||
private final LocalDate date;
|
||||
private final BigDecimal principal;
|
||||
private final BigDecimal principalPaid;
|
||||
private final BigDecimal principalOutstanding;
|
||||
private final BigDecimal interest;
|
||||
private final BigDecimal interestPaid;
|
||||
private final BigDecimal interestWaived;
|
||||
private final BigDecimal interestOutstanding;
|
||||
private final BigDecimal total;
|
||||
private final BigDecimal totalPaid;
|
||||
private final BigDecimal totalWaived;
|
||||
private final BigDecimal totalOutstanding;
|
||||
|
||||
public LoanRepaymentPeriodData() {
|
||||
//
|
||||
}
|
||||
|
||||
public LoanRepaymentPeriodData(Long loanId, Integer period,
|
||||
LocalDate date, MoneyData principal, MoneyData principalPaid,
|
||||
MoneyData principalOutstanding, MoneyData interest,
|
||||
MoneyData interestPaid, MoneyData interestWaived, MoneyData interestOutstanding,
|
||||
MoneyData total, MoneyData totalPaid, MoneyData totalWaived, MoneyData totalOutstanding) {
|
||||
public LoanRepaymentPeriodData(final Long loanId, final Integer period,
|
||||
final LocalDate date, final BigDecimal principal, final BigDecimal principalPaid,
|
||||
final BigDecimal principalOutstanding, final BigDecimal interest,
|
||||
final BigDecimal interestPaid, final BigDecimal interestWaived, final BigDecimal interestOutstanding,
|
||||
final BigDecimal total, final BigDecimal totalPaid, final BigDecimal totalWaived, final BigDecimal totalOutstanding) {
|
||||
this.loanId = loanId;
|
||||
this.period = period;
|
||||
this.date = date;
|
||||
@@ -44,116 +47,51 @@ public class LoanRepaymentPeriodData {
|
||||
this.totalOutstanding = totalOutstanding;
|
||||
}
|
||||
|
||||
public Long getLoanId() {
|
||||
return loanId;
|
||||
}
|
||||
|
||||
public void setLoanId(Long loanId) {
|
||||
this.loanId = loanId;
|
||||
}
|
||||
|
||||
public Integer getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
public void setPeriod(Integer period) {
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public MoneyData getPrincipal() {
|
||||
public BigDecimal getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public void setPrincipal(MoneyData principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public MoneyData getPrincipalPaid() {
|
||||
public BigDecimal getPrincipalPaid() {
|
||||
return principalPaid;
|
||||
}
|
||||
|
||||
public void setPrincipalPaid(MoneyData principalPaid) {
|
||||
this.principalPaid = principalPaid;
|
||||
}
|
||||
|
||||
public MoneyData getPrincipalOutstanding() {
|
||||
public BigDecimal getPrincipalOutstanding() {
|
||||
return principalOutstanding;
|
||||
}
|
||||
|
||||
public void setPrincipalOutstanding(MoneyData principalOutstanding) {
|
||||
this.principalOutstanding = principalOutstanding;
|
||||
}
|
||||
|
||||
public MoneyData getInterest() {
|
||||
public BigDecimal getInterest() {
|
||||
return interest;
|
||||
}
|
||||
|
||||
public void setInterest(MoneyData interest) {
|
||||
this.interest = interest;
|
||||
}
|
||||
|
||||
public MoneyData getInterestPaid() {
|
||||
public BigDecimal getInterestPaid() {
|
||||
return interestPaid;
|
||||
}
|
||||
|
||||
public void setInterestPaid(MoneyData interestPaid) {
|
||||
this.interestPaid = interestPaid;
|
||||
}
|
||||
|
||||
public MoneyData getInterestWaived() {
|
||||
public BigDecimal getInterestWaived() {
|
||||
return interestWaived;
|
||||
}
|
||||
|
||||
public void setInterestWaived(MoneyData interestWaived) {
|
||||
this.interestWaived = interestWaived;
|
||||
}
|
||||
|
||||
public MoneyData getInterestOutstanding() {
|
||||
public BigDecimal getInterestOutstanding() {
|
||||
return interestOutstanding;
|
||||
}
|
||||
|
||||
public void setInterestOutstanding(MoneyData interestOutstanding) {
|
||||
this.interestOutstanding = interestOutstanding;
|
||||
}
|
||||
|
||||
public MoneyData getTotal() {
|
||||
public BigDecimal getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(MoneyData total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public MoneyData getTotalPaid() {
|
||||
public BigDecimal getTotalPaid() {
|
||||
return totalPaid;
|
||||
}
|
||||
|
||||
public void setTotalPaid(MoneyData totalPaid) {
|
||||
this.totalPaid = totalPaid;
|
||||
}
|
||||
|
||||
public MoneyData getTotalWaived() {
|
||||
public BigDecimal getTotalWaived() {
|
||||
return totalWaived;
|
||||
}
|
||||
|
||||
public void setTotalWaived(MoneyData totalWaived) {
|
||||
this.totalWaived = totalWaived;
|
||||
}
|
||||
|
||||
public MoneyData getTotalOutstanding() {
|
||||
public BigDecimal getTotalOutstanding() {
|
||||
return totalOutstanding;
|
||||
}
|
||||
|
||||
public void setTotalOutstanding(MoneyData totalOutstanding) {
|
||||
this.totalOutstanding = totalOutstanding;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.mifosng.platform.api.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Immutable data object representing the expected disbursement and repayment schedule for the loan.
|
||||
*/
|
||||
public class LoanScheduleData {
|
||||
|
||||
private final LoanAccountSummaryData summary;
|
||||
@SuppressWarnings("unused")
|
||||
private final CurrencyData currency;
|
||||
@SuppressWarnings("unused")
|
||||
private final Collection<LoanRepaymentPeriodData> repaymentPeriods;
|
||||
|
||||
public LoanScheduleData(final CurrencyData currency, final Collection<LoanRepaymentPeriodData> repaymentPeriods, final Collection<LoanRepaymentTransactionData> loanRepayments) {
|
||||
this.summary = derivedSummaryFrom(currency, repaymentPeriods, loanRepayments);
|
||||
this.currency = currency;
|
||||
this.repaymentPeriods = repaymentPeriods;
|
||||
}
|
||||
|
||||
private LoanAccountSummaryData derivedSummaryFrom(
|
||||
final CurrencyData currency,
|
||||
final Collection<LoanRepaymentPeriodData> repaymentSchedule,
|
||||
final Collection<LoanRepaymentTransactionData> loanRepayments) {
|
||||
|
||||
BigDecimal originalPrincipal = BigDecimal.ZERO;
|
||||
BigDecimal principalPaid = BigDecimal.ZERO;
|
||||
BigDecimal principalOutstanding = BigDecimal.ZERO;
|
||||
BigDecimal originalInterest = BigDecimal.ZERO;
|
||||
BigDecimal interestPaid = BigDecimal.ZERO;
|
||||
BigDecimal interestWaived = BigDecimal.ZERO;
|
||||
BigDecimal interestOutstanding = BigDecimal.ZERO;
|
||||
BigDecimal originalTotal = BigDecimal.ZERO;
|
||||
BigDecimal totalPaid = BigDecimal.ZERO;
|
||||
BigDecimal totalWaived = BigDecimal.ZERO;
|
||||
BigDecimal totalOutstanding = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal totalInArrears = BigDecimal.ZERO;
|
||||
|
||||
for (LoanRepaymentPeriodData installment : repaymentSchedule) {
|
||||
originalPrincipal = originalPrincipal.add(installment.getPrincipal());
|
||||
principalPaid = principalPaid.add(installment.getPrincipalPaid());
|
||||
principalOutstanding = principalOutstanding.add(installment.getPrincipalOutstanding());
|
||||
|
||||
originalInterest = originalInterest.add(installment.getInterest());
|
||||
interestPaid = interestPaid.add(installment.getInterestPaid());
|
||||
interestWaived = interestWaived.add(installment.getInterestWaived());
|
||||
interestOutstanding = interestOutstanding.add(installment.getInterestOutstanding());
|
||||
|
||||
originalTotal = originalTotal.add(installment.getTotal());
|
||||
totalPaid = totalPaid.add(installment.getTotalPaid());
|
||||
totalWaived = totalWaived.add(installment.getTotalWaived());
|
||||
totalOutstanding = totalOutstanding.add(installment.getTotalOutstanding());
|
||||
|
||||
if (installment.getDate().isBefore(new LocalDate())) {
|
||||
totalInArrears = totalInArrears.add(installment.getTotalOutstanding());
|
||||
}
|
||||
}
|
||||
|
||||
// sum up all repayment transactions
|
||||
Long waiverType = (long) 4;
|
||||
MoneyData totalRepaymentAmount = MoneyData.of(currency,BigDecimal.ZERO);
|
||||
if (loanRepayments != null) {
|
||||
for (LoanRepaymentTransactionData loanRepayment : loanRepayments) {
|
||||
Long transactionType = loanRepayment.getTransactionType().getId();
|
||||
if (transactionType.equals(waiverType)) {
|
||||
// skip
|
||||
} else {
|
||||
totalRepaymentAmount = totalRepaymentAmount.plus(loanRepayment.getTotal());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// detect if loan is in overpaid state
|
||||
if (totalRepaymentAmount.isGreaterThan(MoneyData.of(currency, totalPaid))) {
|
||||
BigDecimal difference = totalRepaymentAmount.getAmount().subtract(totalPaid);
|
||||
totalOutstanding = totalOutstanding.subtract(difference);
|
||||
}
|
||||
|
||||
return new LoanAccountSummaryData(currency, originalPrincipal,
|
||||
principalPaid, principalOutstanding, originalInterest,
|
||||
interestPaid, interestWaived, interestOutstanding,
|
||||
originalTotal, totalPaid, totalWaived, totalOutstanding,
|
||||
totalInArrears);
|
||||
}
|
||||
|
||||
public BigDecimal totalOutstanding() {
|
||||
return this.summary.totalOutstanding();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -147,7 +147,7 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
|
||||
"expectedFirstRepaymentOnDate", "interestChargedFromDate",
|
||||
"closedOnDate", "expectedMaturityDate",
|
||||
"status",
|
||||
"lifeCycleStatusDate", "summary", "repaymentSchedule",
|
||||
"lifeCycleStatusDate", "repaymentSchedule",
|
||||
"loanRepayments", "permissions", "convenienceData", "charges",
|
||||
"productOptions", "amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions",
|
||||
"repaymentFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions",
|
||||
|
||||
+2
-7
@@ -3,25 +3,20 @@ package org.mifosng.platform.loan.service;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.LoanAccountSummaryData;
|
||||
import org.mifosng.platform.api.data.LoanBasicDetailsData;
|
||||
import org.mifosng.platform.api.data.LoanPermissionData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentPeriodData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentTransactionData;
|
||||
import org.mifosng.platform.api.data.LoanScheduleData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
|
||||
public interface LoanReadPlatformService {
|
||||
|
||||
LoanBasicDetailsData retrieveLoanAccountDetails(Long loanId);
|
||||
|
||||
Collection<LoanRepaymentPeriodData> retrieveRepaymentSchedule(Long loanId);
|
||||
LoanScheduleData retrieveRepaymentSchedule(Long loanId, CurrencyData currencyData, Collection<LoanRepaymentTransactionData> loanRepayments);
|
||||
|
||||
Collection<LoanRepaymentTransactionData> retrieveLoanPayments(Long loanId);
|
||||
|
||||
LoanAccountSummaryData retrieveSummary(CurrencyData currency,
|
||||
Collection<LoanRepaymentPeriodData> repaymentSchedule,
|
||||
Collection<LoanRepaymentTransactionData> loanRepayments);
|
||||
|
||||
LoanPermissionData retrieveLoanPermissions(
|
||||
LoanBasicDetailsData loanBasicDetails, boolean isWaiverAllowed,
|
||||
int repaymentAndWaiveCount);
|
||||
|
||||
+21
-103
@@ -10,12 +10,12 @@ import org.mifosng.platform.api.data.ChargeData;
|
||||
import org.mifosng.platform.api.data.ClientData;
|
||||
import org.mifosng.platform.api.data.CurrencyData;
|
||||
import org.mifosng.platform.api.data.EnumOptionData;
|
||||
import org.mifosng.platform.api.data.LoanAccountSummaryData;
|
||||
import org.mifosng.platform.api.data.LoanBasicDetailsData;
|
||||
import org.mifosng.platform.api.data.LoanPermissionData;
|
||||
import org.mifosng.platform.api.data.LoanProductData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentPeriodData;
|
||||
import org.mifosng.platform.api.data.LoanRepaymentTransactionData;
|
||||
import org.mifosng.platform.api.data.LoanScheduleData;
|
||||
import org.mifosng.platform.api.data.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.MoneyData;
|
||||
import org.mifosng.platform.client.service.ClientReadPlatformService;
|
||||
@@ -89,8 +89,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<LoanRepaymentPeriodData> retrieveRepaymentSchedule(
|
||||
Long loanId) {
|
||||
public LoanScheduleData retrieveRepaymentSchedule(final Long loanId, final CurrencyData currency, final Collection<LoanRepaymentTransactionData> loanRepayments) {
|
||||
|
||||
try {
|
||||
context.authenticatedUser();
|
||||
@@ -98,88 +97,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
LoanScheduleMapper rm = new LoanScheduleMapper();
|
||||
String sql = "select " + rm.loanScheduleSchema()
|
||||
+ " where l.id = ? order by ls.loan_id, ls.installment";
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { loanId });
|
||||
|
||||
Collection<LoanRepaymentPeriodData> repaymentSchedulePeriods = this.jdbcTemplate.query(sql, rm, new Object[] { loanId });
|
||||
|
||||
return new LoanScheduleData(currency, repaymentSchedulePeriods, loanRepayments);
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new LoanNotFoundException(loanId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanAccountSummaryData retrieveSummary(
|
||||
final CurrencyData currencyData,
|
||||
final Collection<LoanRepaymentPeriodData> repaymentSchedule,
|
||||
final Collection<LoanRepaymentTransactionData> loanRepayments) {
|
||||
|
||||
BigDecimal originalPrincipal = BigDecimal.ZERO;
|
||||
BigDecimal principalPaid = BigDecimal.ZERO;
|
||||
BigDecimal principalOutstanding = BigDecimal.ZERO;
|
||||
BigDecimal originalInterest = BigDecimal.ZERO;
|
||||
BigDecimal interestPaid = BigDecimal.ZERO;
|
||||
BigDecimal interestWaived = BigDecimal.ZERO;
|
||||
BigDecimal interestOutstanding = BigDecimal.ZERO;
|
||||
BigDecimal originalTotal = BigDecimal.ZERO;
|
||||
BigDecimal totalPaid = BigDecimal.ZERO;
|
||||
BigDecimal totalWaived = BigDecimal.ZERO;
|
||||
BigDecimal totalOutstanding = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal totalInArrears = BigDecimal.ZERO;
|
||||
|
||||
for (LoanRepaymentPeriodData installment : repaymentSchedule) {
|
||||
originalPrincipal = originalPrincipal.add(installment.getPrincipal().getAmount());
|
||||
principalPaid = principalPaid.add(installment.getPrincipalPaid().getAmount());
|
||||
principalOutstanding = principalOutstanding.add(installment.getPrincipalOutstanding().getAmount());
|
||||
|
||||
originalInterest = originalInterest.add(installment.getInterest().getAmount());
|
||||
interestPaid = interestPaid.add(installment.getInterestPaid().getAmount());
|
||||
interestWaived = interestWaived.add(installment.getInterestWaived().getAmount());
|
||||
interestOutstanding = interestOutstanding.add(installment.getInterestOutstanding().getAmount());
|
||||
|
||||
originalTotal = originalTotal.add(installment.getTotal().getAmount());
|
||||
totalPaid = totalPaid.add(installment.getTotalPaid().getAmount());
|
||||
totalWaived = totalWaived.add(installment.getTotalWaived().getAmount());
|
||||
totalOutstanding = totalOutstanding.add(installment.getTotalOutstanding().getAmount());
|
||||
|
||||
if (installment.getDate().isBefore(new LocalDate())) {
|
||||
totalInArrears = totalInArrears.add(installment.getTotalOutstanding().getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
// sum up all repayment transactions
|
||||
Long waiverType = (long) 4;
|
||||
MoneyData totalRepaymentAmount = MoneyData.of(currencyData, BigDecimal.ZERO);
|
||||
if (loanRepayments != null) {
|
||||
for (LoanRepaymentTransactionData loanRepayment : loanRepayments) {
|
||||
Long transactionType = loanRepayment.getTransactionType().getId();
|
||||
if (transactionType.equals(waiverType)) {
|
||||
// skip
|
||||
} else {
|
||||
totalRepaymentAmount = totalRepaymentAmount.plus(loanRepayment.getTotal());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// detect if loan is in overpaid state
|
||||
if (totalRepaymentAmount.isGreaterThan(MoneyData.of(currencyData, totalPaid))) {
|
||||
BigDecimal difference = totalRepaymentAmount.getAmount().subtract(totalPaid);
|
||||
totalOutstanding = totalOutstanding.subtract(difference);
|
||||
}
|
||||
|
||||
return new LoanAccountSummaryData(
|
||||
MoneyData.of(currencyData,originalPrincipal),
|
||||
MoneyData.of(currencyData, principalPaid),
|
||||
MoneyData.of(currencyData, principalOutstanding),
|
||||
MoneyData.of(currencyData, originalInterest),
|
||||
MoneyData.of(currencyData, interestPaid),
|
||||
MoneyData.of(currencyData, interestWaived),
|
||||
MoneyData.of(currencyData, interestOutstanding),
|
||||
MoneyData.of(currencyData, originalTotal),
|
||||
MoneyData.of(currencyData, totalPaid),
|
||||
MoneyData.of(currencyData, totalWaived),
|
||||
MoneyData.of(currencyData, totalOutstanding),
|
||||
MoneyData.of(currencyData, totalInArrears));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<LoanRepaymentTransactionData> retrieveLoanPayments(Long loanId) {
|
||||
try {
|
||||
@@ -516,13 +441,12 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
public LoanRepaymentPeriodData mapRow(final ResultSet rs,
|
||||
final int rowNum) throws SQLException {
|
||||
|
||||
// FIXME - kw - currency not need per installment period any longer, just at loan schedule level.
|
||||
String currencyCode = rs.getString("currencyCode");
|
||||
String currencyName = rs.getString("currencyName");
|
||||
String currencyNameCode = rs.getString("currencyNameCode");
|
||||
String currencyDisplaySymbol = rs
|
||||
.getString("currencyDisplaySymbol");
|
||||
Integer currencyDigits = JdbcSupport.getInteger(rs,
|
||||
"currencyDigits");
|
||||
String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
Integer currencyDigits = JdbcSupport.getInteger(rs,"currencyDigits");
|
||||
CurrencyData currencyData = new CurrencyData(currencyCode,
|
||||
currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
@@ -531,28 +455,22 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
Integer period = JdbcSupport.getInteger(rs, "period");
|
||||
LocalDate date = JdbcSupport.getLocalDate(rs, "date");
|
||||
|
||||
BigDecimal principalBD = rs.getBigDecimal("principal");
|
||||
MoneyData principal = MoneyData.of(currencyData, principalBD);
|
||||
BigDecimal principalPaidBD = rs.getBigDecimal("principalPaid");
|
||||
MoneyData principalPaid = MoneyData.of(currencyData, principalPaidBD);
|
||||
MoneyData principalOutstanding = MoneyData.of(currencyData,principalBD.subtract(principalPaidBD));
|
||||
BigDecimal principal = rs.getBigDecimal("principal");
|
||||
BigDecimal principalPaid = rs.getBigDecimal("principalPaid");
|
||||
BigDecimal principalOutstanding = principal.subtract(principalPaid);
|
||||
|
||||
BigDecimal interestBD = rs.getBigDecimal("interest");
|
||||
MoneyData interest = MoneyData.of(currencyData, interestBD);
|
||||
BigDecimal interestPaidBD = rs.getBigDecimal("interestPaid");
|
||||
MoneyData interestPaid = MoneyData.of(currencyData, interestPaidBD);
|
||||
|
||||
BigDecimal interestWaivedBD = rs.getBigDecimal("interestWaived");
|
||||
if (interestWaivedBD == null) {
|
||||
interestWaivedBD = BigDecimal.ZERO;
|
||||
BigDecimal interest = rs.getBigDecimal("interest");
|
||||
BigDecimal interestPaid = rs.getBigDecimal("interestPaid");
|
||||
BigDecimal interestWaived = rs.getBigDecimal("interestWaived");
|
||||
if (interestWaived == null) {
|
||||
interestWaived = BigDecimal.ZERO;
|
||||
}
|
||||
MoneyData interestWaived = MoneyData.of(currencyData, interestWaivedBD);
|
||||
MoneyData interestOutstanding = MoneyData.of(currencyData, interestBD.subtract(interestPaidBD).subtract(interestWaivedBD));
|
||||
BigDecimal interestOutstanding = interest.subtract(interestPaid).subtract(interestWaived);
|
||||
|
||||
MoneyData total = MoneyData.of(currencyData,principalBD.add(interestBD));
|
||||
MoneyData totalPaid = principalPaid.plus(interestPaid);
|
||||
MoneyData totalWaived = interestWaived;
|
||||
MoneyData totalOutstanding = principalOutstanding.plus(interestOutstanding);
|
||||
BigDecimal total = principal.add(interest);
|
||||
BigDecimal totalPaid = principalPaid.add(interestPaid);
|
||||
BigDecimal totalWaived = interestWaived;
|
||||
BigDecimal totalOutstanding = principalOutstanding.add(interestOutstanding);
|
||||
|
||||
return new LoanRepaymentPeriodData(loanId, period, date,
|
||||
principal, principalPaid, principalOutstanding, interest,
|
||||
|
||||
Reference in New Issue
Block a user