diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/LoanDTO.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/LoanDTO.java index 6345d14c5..421066a9b 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/LoanDTO.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/LoanDTO.java @@ -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 newLoanTransactions; - public LoanDTO(final Long loanId, final Long loanProductId, final Long officeId, final BigDecimal calculatedInterest, - final boolean cashBasedAccountingEnabled, final boolean accrualBasedAccountingEnabled, - final List newLoanTransactions) { + public LoanDTO(final Long loanId, final Long loanProductId, final Long officeId, final boolean cashBasedAccountingEnabled, + final boolean accrualBasedAccountingEnabled, final List 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; - } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java index dcbca5553..92aeb228b 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java @@ -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 newLoanTransactions = new ArrayList(); @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); } /** diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java index 9dcd35fc2..084d661f0 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java @@ -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
+ * 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); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanTransactionEnumData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanTransactionEnumData.java index 95e6c20d5..f11e63f18 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanTransactionEnumData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanTransactionEnumData.java @@ -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; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 7a17fe539..127cdf2ac 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -1215,6 +1215,11 @@ public class Loan extends AbstractPersistable { 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 { } 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; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java index f02c6819b..c828e8c7e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java @@ -86,6 +86,10 @@ public final class LoanTransaction extends AbstractPersistable { 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, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransactionType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransactionType.java index 1343fa6f7..5d2f6f2d0 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransactionType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransactionType.java @@ -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; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java index 2215708c5..fccf55e52 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java @@ -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; }