MIFOSX-297: track overpaid amount on loan table.

This commit is contained in:
Keith Woodlock
2013-06-10 14:16:16 +01:00
parent 989a869eb8
commit dd145c7fc1
6 changed files with 90 additions and 69 deletions
@@ -0,0 +1,2 @@
ALTER TABLE `m_loan`
ADD COLUMN `total_overpaid_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `total_outstanding_derived`;
@@ -86,12 +86,12 @@ public class LoansApiResource {
private final Set<String> LOAN_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "accountNo", "status", "externalId", private final Set<String> LOAN_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "accountNo", "status", "externalId",
"clientId", "group", "loanProductId", "loanProductName", "loanProductDescription", "fundId", "fundName", "loanPurposeId", "clientId", "group", "loanProductId", "loanProductName", "loanProductDescription", "fundId", "fundName", "loanPurposeId",
"loanPurposeName", "loanOfficerId", "loanOfficerName", "currency", "principal", "inArrearsTolerance", "termFrequency", "loanPurposeName", "loanOfficerId", "loanOfficerName", "currency", "principal", "totalOverpaid", "inArrearsTolerance",
"termPeriodFrequencyType", "numberOfRepayments", "repaymentEvery", "interestRatePerPeriod", "annualInterestRate", "termFrequency", "termPeriodFrequencyType", "numberOfRepayments", "repaymentEvery", "interestRatePerPeriod",
"repaymentFrequencyType", "transactionProcessingStrategyId", "interestRateFrequencyType", "amortizationType", "interestType", "annualInterestRate", "repaymentFrequencyType", "transactionProcessingStrategyId", "interestRateFrequencyType",
"interestCalculationPeriodType", "expectedFirstRepaymentOnDate", "graceOnPrincipalPayment", "graceOnInterestPayment", "amortizationType", "interestType", "interestCalculationPeriodType", "expectedFirstRepaymentOnDate", "graceOnPrincipalPayment",
"graceOnInterestCharged", "interestChargedFromDate", "timeline", "totalFeeChargesAtDisbursement", "summary", "graceOnInterestPayment", "graceOnInterestCharged", "interestChargedFromDate", "timeline", "totalFeeChargesAtDisbursement",
"repaymentSchedule", "transactions", "charges", "collateral", "guarantors", "meeting", "productOptions", "summary", "repaymentSchedule", "transactions", "charges", "collateral", "guarantors", "meeting", "productOptions",
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions", "amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions",
"termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions", "termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions",
"loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions", "chargeTemplate", "calendarOptions")); "loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions", "chargeTemplate", "calendarOptions"));
@@ -120,6 +120,7 @@ public class LoanAccountData {
@Transient @Transient
private final BigDecimal feeChargesAtDisbursementCharged; private final BigDecimal feeChargesAtDisbursementCharged;
private final BigDecimal totalOverpaid;
/** /**
* Used to produce a {@link LoanAccountData} with only collateral options * Used to produce a {@link LoanAccountData} with only collateral options
@@ -146,6 +147,7 @@ public class LoanAccountData {
final String loanOfficerName = null; final String loanOfficerName = null;
final CurrencyData currencyData = null; final CurrencyData currencyData = null;
final BigDecimal principal = null; final BigDecimal principal = null;
final BigDecimal totalOverpaid = null;
final BigDecimal inArrearsTolerance = null; final BigDecimal inArrearsTolerance = null;
final Integer termFrequency = null; final Integer termFrequency = null;
final EnumOptionData termPeriodFrequencyType = null; final EnumOptionData termPeriodFrequencyType = null;
@@ -191,8 +193,8 @@ public class LoanAccountData {
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, currencyData, principal, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments,
repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod, repaymentEvery, repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod,
interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate,
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary,
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
@@ -225,6 +227,7 @@ public class LoanAccountData {
final String loanOfficerName = null; final String loanOfficerName = null;
final CurrencyData currencyData = null; final CurrencyData currencyData = null;
final BigDecimal principal = null; final BigDecimal principal = null;
final BigDecimal totalOverpaid = null;
final BigDecimal inArrearsTolerance = null; final BigDecimal inArrearsTolerance = null;
final Integer termFrequency = null; final Integer termFrequency = null;
final EnumOptionData termPeriodFrequencyType = null; final EnumOptionData termPeriodFrequencyType = null;
@@ -271,8 +274,8 @@ public class LoanAccountData {
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, currencyData, principal, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments,
repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod, repaymentEvery, repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod,
interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate,
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary,
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
@@ -286,9 +289,9 @@ public class LoanAccountData {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, clientAcc.clientId, clientAcc.clientName, return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, clientAcc.clientId, clientAcc.clientName,
clientAcc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, clientAcc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription,
acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency,
acc.principal, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.principal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType,
acc.repaymentEvery, acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType, acc.transactionProcessingStrategyId,
acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment, acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, clientAcc.timeline, acc.summary, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, clientAcc.timeline, acc.summary,
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
@@ -323,6 +326,7 @@ public class LoanAccountData {
final String loanOfficerName = null; final String loanOfficerName = null;
final CurrencyData currencyData = null; final CurrencyData currencyData = null;
final BigDecimal principal = null; final BigDecimal principal = null;
final BigDecimal totalOverpaid = null;
final BigDecimal inArrearsTolerance = null; final BigDecimal inArrearsTolerance = null;
final Integer termFrequency = null; final Integer termFrequency = null;
final EnumOptionData termPeriodFrequencyType = null; final EnumOptionData termPeriodFrequencyType = null;
@@ -369,8 +373,8 @@ public class LoanAccountData {
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, currencyData, principal, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments,
repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod, repaymentEvery, repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod,
interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate,
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary,
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
@@ -384,16 +388,16 @@ public class LoanAccountData {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId, return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
groupAcc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName, groupAcc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName,
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal,
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments,
acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType, acc.interestRatePerPeriod, acc.repaymentEvery, acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType,
acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.interestCalculationPeriodType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
acc.interestChargedFromDate, groupAcc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, groupAcc.timeline, acc.summary,
acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions, acc.transactionProcessingStrategyOptions, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions, acc.interestTypeOptions, acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null, acc.loanOfficerOptions, acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions); acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions);
} }
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product, public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
@@ -422,6 +426,7 @@ public class LoanAccountData {
final String loanOfficerName = null; final String loanOfficerName = null;
final CurrencyData currencyData = null; final CurrencyData currencyData = null;
final BigDecimal principal = null; final BigDecimal principal = null;
final BigDecimal totalOverpaid = null;
final BigDecimal inArrearsTolerance = null; final BigDecimal inArrearsTolerance = null;
final Integer numberOfRepayments = null; final Integer numberOfRepayments = null;
final Integer repaymentEvery = null; final Integer repaymentEvery = null;
@@ -459,7 +464,7 @@ public class LoanAccountData {
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType,
product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(), loanPurposeId, product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(), loanPurposeId,
loanPurposeName, loanOfficerId, loanOfficerName, product.getCurrency(), product.getPrincipal(), loanPurposeName, loanOfficerId, loanOfficerName, product.getCurrency(), product.getPrincipal(), totalOverpaid,
product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType, product.getNumberOfRepayments(), product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType, product.getNumberOfRepayments(),
product.getRepaymentEvery(), product.getRepaymentFrequencyType(), product.getTransactionProcessingStrategyId(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(), product.getTransactionProcessingStrategyId(),
product.getAmortizationType(), product.getInterestRatePerPeriod(), product.getInterestRateFrequencyType(), product.getAmortizationType(), product.getInterestRatePerPeriod(), product.getInterestRateFrequencyType(),
@@ -506,8 +511,8 @@ public class LoanAccountData {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId, return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
acc.group, acc.loanType, product.getId(), product.getName(), product.getDescription(), product.getFundId(), acc.group, acc.loanType, product.getId(), product.getName(), product.getDescription(), product.getFundId(),
product.getFundName(), acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, product.getFundName(), acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName,
product.getCurrency(), product.getPrincipal(), product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType, product.getCurrency(), product.getPrincipal(), acc.totalOverpaid, product.getInArrearsTolerance(), termFrequency,
product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(), termPeriodFrequencyType, product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(),
product.getTransactionProcessingStrategyId(), product.getAmortizationType(), product.getInterestRatePerPeriod(), product.getTransactionProcessingStrategyId(), product.getAmortizationType(), product.getInterestRatePerPeriod(),
product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(), product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(),
product.getInterestCalculationPeriodType(), acc.expectedFirstRepaymentOnDate, product.getGraceOnPrincipalPayment(), product.getInterestCalculationPeriodType(), acc.expectedFirstRepaymentOnDate, product.getGraceOnPrincipalPayment(),
@@ -526,14 +531,15 @@ public class LoanAccountData {
final String externalId, final Long clientId, final String clientName, final Long clientOfficeId, final GroupGeneralData group, final String externalId, final Long clientId, final String clientName, final Long clientOfficeId, final GroupGeneralData group,
final EnumOptionData loanType, final Long loanProductId, final String loanProductName, final String loanProductDescription, final EnumOptionData loanType, final Long loanProductId, final String loanProductName, final String loanProductDescription,
final Long fundId, final String fundName, final Long loanPurposeId, final String loanPurposeName, final Long loanOfficerId, final Long fundId, final String fundName, final Long loanPurposeId, final String loanPurposeName, final Long loanOfficerId,
final String loanOfficerName, final CurrencyData currencyData, final BigDecimal principal, final BigDecimal inArrearsTolerance, final String loanOfficerName, final CurrencyData currencyData, final BigDecimal principal, final BigDecimal totalOverpaid,
final Integer termFrequency, final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments, final BigDecimal inArrearsTolerance, final Integer termFrequency, final EnumOptionData termPeriodFrequencyType,
final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType, final Long transactionStrategyId, final Integer numberOfRepayments, final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType,
final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod, final EnumOptionData interestRateFrequencyType, final Long transactionStrategyId, final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod,
final BigDecimal annualInterestRate, final EnumOptionData interestType, final EnumOptionData interestCalculationPeriodType, final EnumOptionData interestRateFrequencyType, final BigDecimal annualInterestRate, final EnumOptionData interestType,
final LocalDate expectedFirstRepaymentOnDate, final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final EnumOptionData interestCalculationPeriodType, final LocalDate expectedFirstRepaymentOnDate,
final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
final LoanSummaryData loanSummary, final BigDecimal feeChargesDueAtDisbursementCharged) { final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary,
final BigDecimal feeChargesDueAtDisbursementCharged) {
final LoanScheduleData repaymentSchedule = null; final LoanScheduleData repaymentSchedule = null;
final Collection<LoanTransactionData> transactions = null; final Collection<LoanTransactionData> transactions = null;
@@ -559,10 +565,10 @@ public class LoanAccountData {
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanType, loanProductId,
loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, currencyData, principal, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments,
repaymentFrequencyType, transactionStrategyId, amortizationType, interestRatePerPeriod, interestRateFrequencyType, repaymentEvery, repaymentFrequencyType, transactionStrategyId, amortizationType, interestRatePerPeriod,
annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate,
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary,
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions,
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
@@ -587,15 +593,15 @@ public class LoanAccountData {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId, return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName,
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal,
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments,
acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType, acc.interestRatePerPeriod, acc.repaymentEvery, acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType,
acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.interestCalculationPeriodType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
acc.interestChargedFromDate, acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, acc.timeline, acc.summary,
transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions, interestRateFrequencyTypeOptions, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions,
amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions); fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions);
} }
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions, public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
@@ -611,16 +617,16 @@ public class LoanAccountData {
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId, return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName, group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName,
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal,
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments,
acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType, acc.interestRatePerPeriod, acc.repaymentEvery, acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType,
acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.interestCalculationPeriodType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
acc.interestChargedFromDate, acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, acc.timeline, acc.summary,
acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions, acc.transactionProcessingStrategyOptions, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions, acc.interestTypeOptions, acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null, acc.loanOfficerOptions, acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions); acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions);
} }
private LoanAccountData( private LoanAccountData(
@@ -644,6 +650,7 @@ public class LoanAccountData {
final String loanOfficerName, // final String loanOfficerName, //
final CurrencyData currency, final CurrencyData currency,
final BigDecimal principal, final BigDecimal principal,
final BigDecimal totalOverpaid,
final BigDecimal inArrearsTolerance, // final BigDecimal inArrearsTolerance, //
final Integer termFrequency, final Integer termFrequency,
final EnumOptionData termPeriodFrequencyType, // final EnumOptionData termPeriodFrequencyType, //
@@ -686,6 +693,7 @@ public class LoanAccountData {
this.loanOfficerName = loanOfficerName; this.loanOfficerName = loanOfficerName;
this.currency = currency; this.currency = currency;
this.principal = principal; this.principal = principal;
this.totalOverpaid = totalOverpaid;
this.inArrearsTolerance = inArrearsTolerance; this.inArrearsTolerance = inArrearsTolerance;
this.termFrequency = termFrequency; this.termFrequency = termFrequency;
this.termPeriodFrequencyType = termPeriodFrequencyType; this.termPeriodFrequencyType = termPeriodFrequencyType;
@@ -224,6 +224,10 @@ public class Loan extends AbstractPersistable<Long> {
@Column(name = "interest_calculated_from_date") @Column(name = "interest_calculated_from_date")
private Date interestChargedFromDate; private Date interestChargedFromDate;
@SuppressWarnings("unused")
@Column(name = "total_overpaid_derived", scale = 6, precision = 19)
private BigDecimal totalOverpaid;
@LazyCollection(LazyCollectionOption.FALSE) @LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
private Set<LoanCharge> charges = new HashSet<LoanCharge>(); private Set<LoanCharge> charges = new HashSet<LoanCharge>();
@@ -766,7 +770,11 @@ public class Loan extends AbstractPersistable<Long> {
if (isNotDisbursed()) { if (isNotDisbursed()) {
this.summary.zeroFields(); this.summary.zeroFields();
this.summaryArrearsAging = null; this.summaryArrearsAging = null;
this.totalOverpaid = null;
} else { } else {
final Money overpaidBy = calculateTotalOverpayment();
this.totalOverpaid = overpaidBy.getAmountDefaultedToNullIfZero();
final Money principal = this.loanRepaymentScheduleDetail.getPrincipal(); final Money principal = this.loanRepaymentScheduleDetail.getPrincipal();
this.summary.updateSummary(loanCurrency(), principal, this.repaymentScheduleInstallments, this.loanSummaryWrapper, this.summary.updateSummary(loanCurrency(), principal, this.repaymentScheduleInstallments, this.loanSummaryWrapper,
isDisbursed()); isDisbursed());
@@ -1558,12 +1566,9 @@ public class Loan extends AbstractPersistable<Long> {
private void doPostLoanTransactionChecks(final LocalDate transactionDate, final LoanLifecycleStateMachine loanLifecycleStateMachine) { private void doPostLoanTransactionChecks(final LocalDate transactionDate, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
if (this.isOverPaid()) { if (this.isOverPaid()) {
// FIXME - kw - update account balance to negative amount.
handleLoanOverpayment(loanLifecycleStateMachine); handleLoanOverpayment(loanLifecycleStateMachine);
} else if (this.summary.isRepaidInFull(loanCurrency())) { } else if (this.summary.isRepaidInFull(loanCurrency())) {
// TODO - KW - probably should not close the loan automatically but
// let user decide if loan is closed or not and provide closing
// date.
// - need to dig into loan closure scenarios with MFIs
handleLoanRepaymentInFull(transactionDate, loanLifecycleStateMachine); handleLoanRepaymentInFull(transactionDate, loanLifecycleStateMachine);
} }
} }
@@ -13,9 +13,13 @@ import javax.persistence.Embeddable;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.scheduledjobs.UpdateLoanSummariesScheduledJob;
/** /**
* LoanSummary encapsulates all the summary details of a {@link Loan}. * Encapsulates all the summary details of a {@link Loan}.
*
* {@link LoanSummary} fields are updated through a scheduled job. see -
* {@link UpdateLoanSummariesScheduledJob}.
*/ */
@Embeddable @Embeddable
public final class LoanSummary { public final class LoanSummary {
@@ -436,6 +436,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
+ " l.total_waived_derived as totalWaived," + " l.total_waived_derived as totalWaived,"
+ " l.total_writtenoff_derived as totalWrittenOff," + " l.total_writtenoff_derived as totalWrittenOff,"
+ " l.total_outstanding_derived as totalOutstanding," + " l.total_outstanding_derived as totalOutstanding,"
+ " l.total_overpaid_derived as totalOverpaid,"
+ " la.principal_overdue_derived as principalOverdue," + " la.principal_overdue_derived as principalOverdue,"
+ " la.interest_overdue_derived as interestOverdue," + " la.interest_overdue_derived as interestOverdue,"
+ " la.fee_charges_overdue_derived as feeChargesOverdue," + " la.fee_charges_overdue_derived as feeChargesOverdue,"
@@ -543,6 +544,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
expectedMaturityDate); expectedMaturityDate);
final BigDecimal principal = rs.getBigDecimal("principal"); final BigDecimal principal = rs.getBigDecimal("principal");
final BigDecimal totalOverpaid = rs.getBigDecimal("totalOverpaid");
final BigDecimal inArrearsTolerance = rs.getBigDecimal("inArrearsTolerance"); final BigDecimal inArrearsTolerance = rs.getBigDecimal("inArrearsTolerance");
final Integer numberOfRepayments = JdbcSupport.getInteger(rs, "numberOfRepayments"); final Integer numberOfRepayments = JdbcSupport.getInteger(rs, "numberOfRepayments");
@@ -646,11 +648,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, groupData, return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, groupData,
loanType, loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanType, loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName,
loanOfficerId, loanOfficerName, currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, loanOfficerId, loanOfficerName, currencyData, principal, totalOverpaid, inArrearsTolerance, termFrequency,
numberOfRepayments, repaymentEvery, repaymentFrequencyType, transactionStrategyId, amortizationType, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, transactionStrategyId,
interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType,
expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestCalculationPeriodType, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment,
interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged); graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged);
} }
} }