add mifos style repayment processor that pays off interest, then principal from most overdue installments first.

This commit is contained in:
Keith Woodlock
2012-08-01 23:11:53 +01:00
parent b4e9b5a566
commit bc747a91ed
3 changed files with 101 additions and 5 deletions
@@ -37,7 +37,8 @@ public class CreocoreLoanRepaymentScheduleTransactionProcessor extends
}
/**
* For early/'in advance' repayments, pays off principal component only.
* For early/'in advance' repayments, pay off in the same way as on-time payments,
* interest first then principal.
*/
@Override
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(
@@ -8,12 +8,12 @@ public class LoanRepaymentScheduleTransactionProcessorFactory {
public LoanRepaymentScheduleTransactionProcessor determineProcessor(final LoanTransactionProcessingStrategy transactionProcessingStrategy) {
LoanRepaymentScheduleTransactionProcessor processor = new HeavensFamilyLoanRepaymentScheduleTransactionProcessor();
LoanRepaymentScheduleTransactionProcessor processor = new MifosStyleLoanRepaymentScheduleTransactionProcessor();
if (transactionProcessingStrategy != null) {
if (transactionProcessingStrategy.isStandardMifosStrategy()) {
processor = new HeavensFamilyLoanRepaymentScheduleTransactionProcessor();
processor = new MifosStyleLoanRepaymentScheduleTransactionProcessor();
}
if (transactionProcessingStrategy.isHeavensfamilyStrategy()) {
@@ -31,5 +31,4 @@ public class LoanRepaymentScheduleTransactionProcessorFactory {
return processor;
}
}
}
@@ -0,0 +1,96 @@
package org.mifosng.platform.loan.domain;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosng.platform.currency.domain.Money;
/**
* Old Mifos style {@link LoanRepaymentScheduleTransactionProcessor}.
*
* For ALL types of transactions, pays off components in order of interest, then
* principal.
*
* Other formulas exist on mifos where you can choose 'Declining-Balance Interest Recalculation' which simply
* means, recalculate the interest component based on the how much principal is outstanding at a point in time;
* but this isnt trying to model that option only the basic one for now.
*/
public class MifosStyleLoanRepaymentScheduleTransactionProcessor extends
AbstractLoanRepaymentScheduleTransactionProcessor {
@Override
protected boolean isTransactionInAdvanceOfInstallment(
final int currentInstallmentIndex,
final List<LoanRepaymentScheduleInstallment> installments,
final LocalDate transactionDate, final Money transactionAmount) {
LoanRepaymentScheduleInstallment currentInstallment = installments.get(currentInstallmentIndex);
return transactionDate.isBefore(currentInstallment.getDueDate());
}
/**
* For early/'in advance' repayments, pay off in the same way as on-time payments,
* interest first then principal.
*/
@Override
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(
final LoanRepaymentScheduleInstallment currentInstallment,
final List<LoanRepaymentScheduleInstallment> installments,
final LoanTransaction loanTransaction,
final LocalDate transactionDate, final Money paymentInAdvance) {
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance);
}
/**
* For late repayments, pay off in the same way as on-time payments,
* interest first then principal.
*/
@Override
protected Money handleTransactionThatIsALateRepaymentOfInstallment(
final LoanRepaymentScheduleInstallment currentInstallment,
final List<LoanRepaymentScheduleInstallment> installments,
final LoanTransaction loanTransaction,
final Money transactionAmountUnprocessed) {
return handleTransactionThatIsOnTimePaymentOfInstallment(
currentInstallment, loanTransaction,
transactionAmountUnprocessed);
}
/**
* For normal on-time repayments, pays off interest first, then principal.
*/
@Override
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(
final LoanRepaymentScheduleInstallment currentInstallment,
final LoanTransaction loanTransaction,
final Money transactionAmountUnprocessed) {
Money transactionAmountRemaining = transactionAmountUnprocessed;
Money interestPortion = currentInstallment
.payInterestComponent(transactionAmountRemaining);
transactionAmountRemaining = transactionAmountRemaining
.minus(interestPortion);
Money principalPortion = currentInstallment
.payPrincipalComponent(transactionAmountRemaining);
transactionAmountRemaining = transactionAmountRemaining
.minus(principalPortion);
Money interestWaivedPortion = Money.zero(transactionAmountRemaining
.getCurrency());
loanTransaction.updateComponents(principalPortion, interestPortion,
interestWaivedPortion);
return transactionAmountRemaining;
}
@Override
protected void onLoanOverpayment(final LoanTransaction loanTransaction,
final Money loanOverPaymentAmount) {
// dont do anything for with loan over-payment
}
}