adding Lifecycle event called Interest Applied

This commit is contained in:
Vishwas Babu AJ
2013-03-24 19:05:32 +05:30
parent 29c071d763
commit 28d66e39ec
8 changed files with 69 additions and 26 deletions
@@ -5,7 +5,6 @@
*/
package org.mifosplatform.accounting.journalentry.data;
import java.math.BigDecimal;
import java.util.List;
public class LoanDTO {
@@ -13,18 +12,15 @@ public class LoanDTO {
private Long loanId;
private Long loanProductId;
private Long officeId;
private BigDecimal calculatedInterest;
private boolean cashBasedAccountingEnabled;
private boolean accrualBasedAccountingEnabled;
private List<LoanTransactionDTO> newLoanTransactions;
public LoanDTO(final Long loanId, final Long loanProductId, final Long officeId, final BigDecimal calculatedInterest,
final boolean cashBasedAccountingEnabled, final boolean accrualBasedAccountingEnabled,
final List<LoanTransactionDTO> newLoanTransactions) {
public LoanDTO(final Long loanId, final Long loanProductId, final Long officeId, final boolean cashBasedAccountingEnabled,
final boolean accrualBasedAccountingEnabled, final List<LoanTransactionDTO> newLoanTransactions) {
this.loanId = loanId;
this.loanProductId = loanProductId;
this.officeId = officeId;
this.calculatedInterest = calculatedInterest;
this.cashBasedAccountingEnabled = cashBasedAccountingEnabled;
this.accrualBasedAccountingEnabled = accrualBasedAccountingEnabled;
this.newLoanTransactions = newLoanTransactions;
@@ -78,11 +74,4 @@ public class LoanDTO {
this.newLoanTransactions = newLoanTransactions;
}
public BigDecimal getCalculatedInterest() {
return this.calculatedInterest;
}
public void setCalculatedInterest(BigDecimal calculatedInterest) {
this.calculatedInterest = calculatedInterest;
}
}
@@ -56,8 +56,6 @@ public class AccountingProcessorHelper {
final Long loanId = (Long) accountingBridgeData.get("loanId");
final Long loanProductId = (Long) accountingBridgeData.get("loanProductId");
final Long officeId = (Long) accountingBridgeData.get("officeId");
final BigDecimal calculatedInterest = (BigDecimal) accountingBridgeData.get("calculatedInterest");
final List<LoanTransactionDTO> newLoanTransactions = new ArrayList<LoanTransactionDTO>();
@SuppressWarnings("unchecked")
@@ -81,8 +79,7 @@ public class AccountingProcessorHelper {
}
return new LoanDTO(loanId, loanProductId, officeId, calculatedInterest, cashBasedAccountingEnabled, accrualBasedAccountingEnabled,
newLoanTransactions);
return new LoanDTO(loanId, loanProductId, officeId, cashBasedAccountingEnabled, accrualBasedAccountingEnabled, newLoanTransactions);
}
/**
@@ -34,6 +34,11 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
createJournalEntriesForDisbursements(loanDTO, loanTransactionDTO, office);
}
/*** Handle Interest Postings ***/
if (loanTransactionDTO.getTransactionType().isApplyInterest()) {
createJournalEntriesForInterestPostings(loanDTO, loanTransactionDTO, office);
}
/*** Handle Apply charges ***/
else if (loanTransactionDTO.getTransactionType().isApplyCharges()) {
createJournalEntriesForApplyCharges(loanDTO, loanTransactionDTO, office);
@@ -58,9 +63,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
}
/**
* Debit loan Portfolio and credit Fund source for Disbursement. Also
* recognise the receivable interest (Debit "Interest Receivable" and credit
* "Income from Interest")
* Debit loan Portfolio and credit Fund source for Disbursement.
*
* @param loanDTO
* @param loanTransactionDTO
@@ -77,7 +80,6 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
final String transactionId = loanTransactionDTO.getTransactionId();
final Date transactionDate = loanTransactionDTO.getTransactionDate();
final BigDecimal disbursalAmount = loanTransactionDTO.getAmount();
final BigDecimal interestAmount = loanDTO.getCalculatedInterest();
final boolean isReversed = loanTransactionDTO.isReversed();
// create journal entries for the disbursement (or disbursement
@@ -85,12 +87,33 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, ACCRUAL_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO,
ACCRUAL_ACCOUNTS_FOR_LOAN.FUND_SOURCE, loanProductId, loanId, transactionId, transactionDate, disbursalAmount, isReversed);
}
/**
* Recognise the receivable interest <br/>
* Debit "Interest Receivable" and Credit "Income from Interest"
*
* @param loanDTO
* @param loanTransactionDTO
* @param office
*/
private void createJournalEntriesForInterestPostings(final LoanDTO loanDTO, final LoanTransactionDTO loanTransactionDTO,
final Office office) {
// loan properties
final Long loanProductId = loanDTO.getLoanProductId();
final Long loanId = loanDTO.getLoanId();
// transaction properties
final String transactionId = loanTransactionDTO.getTransactionId();
final Date transactionDate = loanTransactionDTO.getTransactionDate();
final BigDecimal amount = loanTransactionDTO.getAmount();
final boolean isReversed = loanTransactionDTO.isReversed();
// create journal entries for recognising interest (or reversal)
BigDecimal interestApplied = loanDTO.getCalculatedInterest();
if (interestApplied != null && !(interestApplied.compareTo(BigDecimal.ZERO) == 0)) {
if (amount != null && !(amount.compareTo(BigDecimal.ZERO) == 0)) {
helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_RECEIVABLE,
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS, loanProductId, loanId, transactionId, transactionDate, interestAmount,
isReversed);
ACCRUAL_ACCOUNTS_FOR_LOAN.INTEREST_ON_LOANS, loanProductId, loanId, transactionId, transactionDate, amount, isReversed);
}
}
@@ -19,6 +19,7 @@ public class LoanTransactionEnumData {
private final boolean repaymentAtDisbursement;
private final boolean repayment;
private final boolean contra;
private final boolean applyInterest;
private final boolean waiveInterest;
private final boolean waiveCharges;
private final boolean applyCharges;
@@ -36,6 +37,7 @@ public class LoanTransactionEnumData {
this.waiveInterest = Long.valueOf(4).equals(this.id);
this.waiveCharges = Long.valueOf(9).equals(this.id);
this.applyCharges = Long.valueOf(10).equals(this.id);
this.applyInterest = Long.valueOf(11).equals(this.id);
this.writeOff = Long.valueOf(6).equals(this.id);
this.recoveryRepayment = Long.valueOf(8).equals(this.id);
}
@@ -76,4 +78,8 @@ public class LoanTransactionEnumData {
return this.applyCharges;
}
public boolean isApplyInterest() {
return this.applyInterest;
}
}
@@ -1215,6 +1215,11 @@ public class Loan extends AbstractPersistable<Long> {
private void disburse(final LocalDate expectedDisbursedOnLocalDate) {
this.actualDisbursementDate = expectedDisbursedOnLocalDate.toDate();
updateLoanScheduleDependentDerivedFields();
/****
* Vishwas TODO: Refactor to skip unnecessary creation of Disbursement
* and fees applied transactions (though they are not persisted) on
* modifications to loan application modification
*****/
handleDisbursementTransaction(expectedDisbursedOnLocalDate);
}
@@ -1275,6 +1280,17 @@ public class Loan extends AbstractPersistable<Long> {
} else {
updateLoanSummaryDerivedFields();
}
/***
* Adding a temporary Interest applied transaction (applying the
* full Interest as soon as the loan is disbursed), will have to
* re-look into this logic once loans with Interest calculation need
* to be created or more advances accrual accounting support has to
* be provided
***/
Money interestApplied = Money.of(this.getCurrency(), this.summary.getTotalInterestCharged());
final LoanTransaction interestAppliedTransaction = LoanTransaction.applyInterest(this, interestApplied, actualDisbursementDate);
this.loanTransactions.add(interestAppliedTransaction);
}
return actualChanges;
@@ -86,6 +86,10 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
return new LoanTransaction(loan, LoanTransactionType.WAIVE_INTEREST, waived.getAmount(), waiveDate);
}
public static LoanTransaction applyInterest(final Loan loan, final Money amount, final LocalDate interestAppliedDate) {
return new LoanTransaction(loan, LoanTransactionType.APPLY_INTEREST, amount.getAmount(), interestAppliedDate);
}
public static LoanTransaction copyTransactionProperties(LoanTransaction loanTransaction) {
return new LoanTransaction(loanTransaction.loan, loanTransaction.typeOf, loanTransaction.dateOf, loanTransaction.amount,
loanTransaction.principalPortion, loanTransaction.interestPortion, loanTransaction.feeChargesPortion,
@@ -21,7 +21,8 @@ public enum LoanTransactionType {
*/
RECOVERY_REPAYMENT(8, "loanTransactionType.recoveryRepayment"), //
WAIVE_CHARGES(9, "loanTransactionType.waiveCharges"), //
APPLY_CHARGES(10, "loanTransactionType.applyCharges");
APPLY_CHARGES(10, "loanTransactionType.applyCharges"), //
APPLY_INTEREST(11, "loanTransactionType.applyInterest");
private final Integer value;
private final String code;
@@ -75,6 +76,9 @@ public enum LoanTransactionType {
case 10:
loanTransactionType = LoanTransactionType.APPLY_CHARGES;
break;
case 11:
loanTransactionType = LoanTransactionType.APPLY_INTEREST;
break;
default:
loanTransactionType = LoanTransactionType.INVALID;
break;
@@ -248,6 +248,10 @@ public class LoanEnumerations {
optionData = new LoanTransactionEnumData(LoanTransactionType.APPLY_CHARGES.getValue().longValue(),
LoanTransactionType.APPLY_CHARGES.getCode(), "Apply Charge");
break;
case APPLY_INTEREST:
optionData = new LoanTransactionEnumData(LoanTransactionType.APPLY_INTEREST.getValue().longValue(),
LoanTransactionType.APPLY_INTEREST.getCode(), "Apply Interest");
break;
}
return optionData;
}