From 066adccc44d24d7cd09845f04e6173772b9988ee Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Thu, 6 Jun 2013 14:49:36 +0100 Subject: [PATCH] MIFOSX-376: support ability to track advance and late paid amounts in repayment period. --- ...vance-and-late-payments-on-installment.sql | 3 ++ .../LoanRepaymentScheduleInstallment.java | 49 ++++++++++++++++--- .../data/LoanSchedulePeriodData.java | 21 ++++++-- .../service/LoanReadPlatformServiceImpl.java | 12 +++-- 4 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 mifosng-db/migrations/core_db/V53__track-advance-and-late-payments-on-installment.sql diff --git a/mifosng-db/migrations/core_db/V53__track-advance-and-late-payments-on-installment.sql b/mifosng-db/migrations/core_db/V53__track-advance-and-late-payments-on-installment.sql new file mode 100644 index 000000000..f7858d098 --- /dev/null +++ b/mifosng-db/migrations/core_db/V53__track-advance-and-late-payments-on-installment.sql @@ -0,0 +1,3 @@ +ALTER TABLE `m_loan_repayment_schedule` +ADD COLUMN `total_paid_in_advance_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `penalty_charges_waived_derived`, +ADD COLUMN `total_paid_late_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `total_paid_in_advance_derived`; \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java index 504afc65f..05ff88a47 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java @@ -86,6 +86,12 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus @Column(name = "penalty_charges_waived_derived", scale = 6, precision = 19, nullable = true) private BigDecimal penaltyChargesWaived; + @Column(name = "total_paid_in_advance_derived", scale = 6, precision = 19, nullable = true) + private BigDecimal totalPaidInAdvance; + + @Column(name = "total_paid_late_derived", scale = 6, precision = 19, nullable = true) + private BigDecimal totalPaidLate; + @Column(name = "completed_derived", nullable = false) private boolean obligationsMet; @@ -272,6 +278,8 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus this.penaltyChargesPaid = null; this.penaltyChargesWaived = null; this.penaltyChargesWrittenOff = null; + this.totalPaidInAdvance = null; + this.totalPaidLate = null; this.obligationsMet = false; this.obligationsMetOnDate = null; @@ -316,6 +324,8 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency); + trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, feePortionOfTransaction); + return feePortionOfTransaction; } @@ -337,6 +347,8 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency); + trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, interestPortionOfTransaction); + return interestPortionOfTransaction; } @@ -358,14 +370,9 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency); - return principalPortionOfTransaction; - } + trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, principalPortionOfTransaction); - private void checkIfRepaymentPeriodObligationsAreMet(final LocalDate transactionDate, final MonetaryCurrency currency) { - this.obligationsMet = getTotalOutstanding(currency).isZero(); - if (this.obligationsMet) { - this.obligationsMetOnDate = transactionDate.toDate(); - } + return principalPortionOfTransaction; } public Money waiveInterestComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) { @@ -486,4 +493,32 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus this.obligationsMetOnDate = actualDisbursementDate.toDate(); } } + + private void trackAdvanceAndLateTotalsForRepaymentPeriod(final LocalDate transactionDate, final MonetaryCurrency currency, + final Money amountPaidInRepaymentPeriod) { + if (isInAdvance(transactionDate)) { + this.totalPaidInAdvance = asMoney(this.totalPaidInAdvance, currency).plus(amountPaidInRepaymentPeriod).getAmount(); + } else if (isLatePayment(transactionDate)) { + this.totalPaidLate = asMoney(this.totalPaidLate, currency).plus(amountPaidInRepaymentPeriod).getAmount(); + } + } + + private Money asMoney(final BigDecimal decimal, final MonetaryCurrency currency) { + return Money.of(currency, decimal); + } + + private boolean isInAdvance(final LocalDate transactionDate) { + return transactionDate.isBefore(getDueDate()); + } + + private boolean isLatePayment(final LocalDate transactionDate) { + return transactionDate.isAfter(getDueDate()); + } + + private void checkIfRepaymentPeriodObligationsAreMet(final LocalDate transactionDate, final MonetaryCurrency currency) { + this.obligationsMet = getTotalOutstanding(currency).isZero(); + if (this.obligationsMet) { + this.obligationsMetOnDate = transactionDate.toDate(); + } + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java index 8659c33ee..0c7ba56cf 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java @@ -58,6 +58,10 @@ public class LoanSchedulePeriodData { @SuppressWarnings("unused") private final BigDecimal totalPaidForPeriod; @SuppressWarnings("unused") + private final BigDecimal totalPaidInAdvanceForPeriod; + @SuppressWarnings("unused") + private final BigDecimal totalPaidLateForPeriod; + @SuppressWarnings("unused") private final BigDecimal totalWaivedForPeriod; @SuppressWarnings("unused") private final BigDecimal totalWrittenOffForPeriod; @@ -92,15 +96,17 @@ public class LoanSchedulePeriodData { final BigDecimal feeChargesWaived, final BigDecimal feeChargesWrittenOff, final BigDecimal feeChargesOutstanding, final BigDecimal penaltyChargesDue, final BigDecimal penaltyChargesPaid, final BigDecimal penaltyChargesWaived, final BigDecimal penaltyChargesWrittenOff, final BigDecimal penaltyChargesOutstanding, final BigDecimal totalDueForPeriod, - final BigDecimal totalPaid, final BigDecimal totalWaived, final BigDecimal totalWrittenOff, final BigDecimal totalOutstanding, + final BigDecimal totalPaid, final BigDecimal totalPaidInAdvanceForPeriod, final BigDecimal totalPaidLateForPeriod, + final BigDecimal totalWaived, final BigDecimal totalWrittenOff, final BigDecimal totalOutstanding, final BigDecimal totalActualCostOfLoanForPeriod) { return new LoanSchedulePeriodData(periodNumber, fromDate, dueDate, obligationsMetOnDate, complete, principalOriginalDue, principalPaid, principalWrittenOff, principalOutstanding, outstandingPrincipalBalanceOfLoan, interestDueOnPrincipalOutstanding, interestPaid, interestWaived, interestWrittenOff, interestOutstanding, feeChargesDue, feeChargesPaid, feeChargesWaived, feeChargesWrittenOff, feeChargesOutstanding, penaltyChargesDue, penaltyChargesPaid, - penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding, totalDueForPeriod, totalPaid, totalWaived, - totalWrittenOff, totalOutstanding, totalActualCostOfLoanForPeriod); + penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding, totalDueForPeriod, totalPaid, + totalPaidInAdvanceForPeriod, totalPaidLateForPeriod, totalWaived, totalWrittenOff, totalOutstanding, + totalActualCostOfLoanForPeriod); } /* @@ -156,6 +162,8 @@ public class LoanSchedulePeriodData { this.totalOriginalDueForPeriod = chargesDueAtTimeOfDisbursement; this.totalDueForPeriod = chargesDueAtTimeOfDisbursement; this.totalPaidForPeriod = this.feeChargesPaid; + this.totalPaidInAdvanceForPeriod = null; + this.totalPaidLateForPeriod = null; this.totalWaivedForPeriod = null; this.totalWrittenOffForPeriod = null; this.totalOutstandingForPeriod = this.feeChargesOutstanding; @@ -215,6 +223,8 @@ public class LoanSchedulePeriodData { this.totalOriginalDueForPeriod = totalDueForPeriod; this.totalDueForPeriod = totalDueForPeriod; this.totalPaidForPeriod = BigDecimal.ZERO; + this.totalPaidInAdvanceForPeriod = null; + this.totalPaidLateForPeriod = null; this.totalWaivedForPeriod = null; this.totalWrittenOffForPeriod = null; this.totalOutstandingForPeriod = totalDueForPeriod; @@ -240,7 +250,8 @@ public class LoanSchedulePeriodData { final BigDecimal feeChargesWaived, final BigDecimal feeChargesWrittenOff, final BigDecimal feeChargesOutstanding, final BigDecimal penaltyChargesDue, final BigDecimal penaltyChargesPaid, final BigDecimal penaltyChargesWaived, final BigDecimal penaltyChargesWrittenOff, final BigDecimal penaltyChargesOutstanding, final BigDecimal totalDueForPeriod, - final BigDecimal totalPaid, final BigDecimal totalWaived, final BigDecimal totalWrittenOff, final BigDecimal totalOutstanding, + final BigDecimal totalPaid, final BigDecimal totalPaidInAdvanceForPeriod, final BigDecimal totalPaidLateForPeriod, + final BigDecimal totalWaived, final BigDecimal totalWrittenOff, final BigDecimal totalOutstanding, final BigDecimal totalActualCostOfLoanForPeriod) { this.period = periodNumber; this.fromDate = fromDate; @@ -282,6 +293,8 @@ public class LoanSchedulePeriodData { this.totalOriginalDueForPeriod = totalDueForPeriod; this.totalDueForPeriod = totalDueForPeriod; this.totalPaidForPeriod = totalPaid; + this.totalPaidInAdvanceForPeriod = totalPaidInAdvanceForPeriod; + this.totalPaidLateForPeriod = totalPaidLateForPeriod; this.totalWaivedForPeriod = totalWaived; this.totalWrittenOffForPeriod = totalWrittenOff; this.totalOutstandingForPeriod = totalOutstanding; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 97902cb18..1678499a8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -676,7 +676,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " ls.principal_amount as principalDue, ls.principal_completed_derived as principalPaid, ls.principal_writtenoff_derived as principalWrittenOff, " + " ls.interest_amount as interestDue, ls.interest_completed_derived as interestPaid, ls.interest_waived_derived as interestWaived, ls.interest_writtenoff_derived as interestWrittenOff, " + " ls.fee_charges_amount as feeChargesDue, ls.fee_charges_completed_derived as feeChargesPaid, ls.fee_charges_waived_derived as feeChargesWaived, ls.fee_charges_writtenoff_derived as feeChargesWrittenOff, " - + " ls.penalty_charges_amount as penaltyChargesDue, ls.penalty_charges_completed_derived as penaltyChargesPaid, ls.penalty_charges_waived_derived as penaltyChargesWaived, ls.penalty_charges_writtenoff_derived as penaltyChargesWrittenOff " + + " ls.penalty_charges_amount as penaltyChargesDue, ls.penalty_charges_completed_derived as penaltyChargesPaid, ls.penalty_charges_waived_derived as penaltyChargesWaived, ls.penalty_charges_writtenoff_derived as penaltyChargesWrittenOff, " + + " ls.total_paid_in_advance_derived as totalPaidInAdvanceForPeriod, ls.total_paid_late_derived as totalPaidLateForPeriod " + " from m_loan_repayment_schedule ls "; } @@ -757,6 +758,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final BigDecimal penaltyChargesWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penaltyChargesWaived"); final BigDecimal penaltyChargesWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penaltyChargesWrittenOff"); + final BigDecimal totalPaidInAdvanceForPeriod = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, + "totalPaidInAdvanceForPeriod"); + final BigDecimal totalPaidLateForPeriod = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "totalPaidLateForPeriod"); + final BigDecimal penaltyChargesActualDue = penaltyChargesExpectedDue.subtract(penaltyChargesWaived).subtract( penaltyChargesWrittenOff); final BigDecimal penaltyChargesOutstanding = penaltyChargesActualDue.subtract(penaltyChargesPaid); @@ -794,8 +799,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { outstandingPrincipalBalanceOfLoan, interestExpectedDue, interestPaid, interestWaived, interestWrittenOff, interestOutstanding, feeChargesExpectedDue, feeChargesPaid, feeChargesWaived, feeChargesWrittenOff, feeChargesOutstanding, penaltyChargesExpectedDue, penaltyChargesPaid, penaltyChargesWaived, - penaltyChargesWrittenOff, penaltyChargesOutstanding, totalDueForPeriod, totalPaidForPeriod, totalWaivedForPeriod, - totalWrittenOffForPeriod, totalOutstandingForPeriod, totalActualCostOfLoanForPeriod); + penaltyChargesWrittenOff, penaltyChargesOutstanding, totalDueForPeriod, totalPaidForPeriod, + totalPaidInAdvanceForPeriod, totalPaidLateForPeriod, totalWaivedForPeriod, totalWrittenOffForPeriod, + totalOutstandingForPeriod, totalActualCostOfLoanForPeriod); periods.add(periodData); }