From 58b3a2cc3ec2401c383e5cbab43c751868550c50 Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Sat, 28 Jul 2012 01:47:08 +0100 Subject: [PATCH] fix some issues with late payments and checks for isFullyRepaid or overpaid. --- .../api/data/LoanAccountSummaryData.java | 2 +- .../DefaultLoanLifecycleStateMachine.java | 2 +- ...RepaymentScheduleTransactionProcessor.java | 8 +++++--- .../mifosng/platform/loan/domain/Loan.java | 19 ++++++++++++------- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanAccountSummaryData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanAccountSummaryData.java index 8a867f9c6..13bb8ff0b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanAccountSummaryData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanAccountSummaryData.java @@ -47,7 +47,7 @@ public class LoanAccountSummaryData { } public boolean isWaiveAllowed(MoneyData tolerance) { - return tolerance.isGreaterThan(this.totalOutstanding) || tolerance.isEqualTo(this.totalOutstanding); + return this.totalOutstanding.isGreaterThanZero() && (tolerance.isGreaterThan(this.totalOutstanding) || tolerance.isEqualTo(this.totalOutstanding)); } public MoneyData getOriginalPrincipal() { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/DefaultLoanLifecycleStateMachine.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/DefaultLoanLifecycleStateMachine.java index 17b2ee623..ccc771dbe 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/DefaultLoanLifecycleStateMachine.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/DefaultLoanLifecycleStateMachine.java @@ -54,7 +54,7 @@ public class DefaultLoanLifecycleStateMachine implements } break; case LOAN_REPAYMENT: - if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE, LoanStatus.OVERPAID)) { + if (this.anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE, LoanStatus.CLOSED, LoanStatus.OVERPAID)) { newState = stateOf(LoanStatus.ACTIVE, allowedLoanStatuses); } else { newState = from; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/DefaultLoanRepaymentScheduleTransactionProcessor.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/DefaultLoanRepaymentScheduleTransactionProcessor.java index e493bc10b..586632c05 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/DefaultLoanRepaymentScheduleTransactionProcessor.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/DefaultLoanRepaymentScheduleTransactionProcessor.java @@ -46,7 +46,7 @@ public class DefaultLoanRepaymentScheduleTransactionProcessor implements LoanRep transactionProcessed = true; } else if (isTransactionLate(installmentIndex, installments, loanTransaction.getTransactionDate())) { // does this result in a late payment of existing installment? - handleLateTransaction(installments, loanTransaction, currency); + handleLateTransaction(currentInstallment, installments, loanTransaction, currency); transactionProcessed = true; } else { // standard transaction @@ -65,14 +65,16 @@ public class DefaultLoanRepaymentScheduleTransactionProcessor implements LoanRep /** * Dont do anything special for late payments e.g. no fees, charges or penalties are applied + * @param currentInstallment2 */ protected void handleLateTransaction( + final LoanRepaymentScheduleInstallment currentInstallment, final List installments, final LoanTransaction loanTransaction, final MonetaryCurrency currency) { - final Money lateRepayment = loanTransaction.getAmount(currency); - Money loanOverPaymentAmount = handleOverpaymentTransaction(installments, loanTransaction, currency, lateRepayment); + Money installmentOverPaymentAmount = handleOnTimeTransaction(currentInstallment, loanTransaction, currency); + Money loanOverPaymentAmount = handleOverpaymentTransaction(installments, loanTransaction, currency, installmentOverPaymentAmount); if (loanOverPaymentAmount.isGreaterThanZero()) { onLoanOverpayment(loanTransaction, currency, loanOverPaymentAmount); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java index bfe003382..1b3f4348d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java @@ -455,9 +455,7 @@ public class Loan extends AbstractAuditableCustom { if (this.isOverPaid()) { handleLoanOverpayment(loanTransaction, loanLifecycleStateMachine); - } - - if (this.isRepaidInFull()) { + } else if (this.isRepaidInFull()) { handleLoanRepaymentInFull(loanTransaction, loanLifecycleStateMachine); } } @@ -567,18 +565,25 @@ public class Loan extends AbstractAuditableCustom { private boolean isRepaidInFull() { MonetaryCurrency currency = loanCurrency(); - - Money cumulativeOriginalExpectedTotal = Money.zero(currency); + + Money cumulativeOriginalPrincipalExpected = Money.zero(currency); + Money cumulativeOriginalInterestExpected = Money.zero(currency); + Money cumulativeOriginalTotalExpected = Money.zero(currency); + Money cumulativeTotalPaid = Money.zero(currency); Money cumulativeTotalWaived = Money.zero(currency); for (LoanRepaymentScheduleInstallment scheduledRepayment : this.repaymentScheduleInstallments) { - cumulativeOriginalExpectedTotal = cumulativeOriginalExpectedTotal.plus(scheduledRepayment.getPrincipal(currency)); + cumulativeOriginalPrincipalExpected = cumulativeOriginalPrincipalExpected.plus(scheduledRepayment.getPrincipal(currency)); + cumulativeOriginalInterestExpected = cumulativeOriginalInterestExpected.plus(scheduledRepayment.getInterest(currency)); + cumulativeTotalPaid = cumulativeTotalPaid.plus(scheduledRepayment.getPrincipalCompleted(currency).plus(scheduledRepayment.getInterestCompleted(currency))); cumulativeTotalWaived = cumulativeTotalWaived.plus(scheduledRepayment.getInterestWaived(currency)); } - Money totalOutstanding = cumulativeOriginalExpectedTotal.minus(cumulativeTotalPaid.plus(cumulativeTotalWaived)); + cumulativeOriginalTotalExpected = cumulativeOriginalPrincipalExpected.plus(cumulativeOriginalInterestExpected); + + Money totalOutstanding = cumulativeOriginalTotalExpected.minus(cumulativeTotalPaid.plus(cumulativeTotalWaived)); boolean isRepaidInFull = totalOutstanding.isZero(); return isRepaidInFull;