Merge remote-tracking branch 'vishwas/mifosx-255'

This commit is contained in:
Keith Woodlock
2013-03-21 12:29:47 +00:00
5 changed files with 91 additions and 25 deletions
@@ -60,18 +60,27 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
handleTransaction(loanTransaction, currency, installments, charges);
} else {
/**
* reverse existing transactions and create new transactions
* in their Lieu
* For existing transactions, check if the re-payment
* breakup (principal, interest, fees, penalties) has
* changed.<br>
**/
LoanTransaction newLoanTransaction = LoanTransaction.copyTransactionProperties(loanTransaction);
// Reverse the original loan transaction
loanTransaction.reverse();
changedTransactionDetail.getReversedTransactions().add(loanTransaction);
// Reset derived component of new loan transaction
// Reset derived component of new loan transaction and
// re-process transaction
newLoanTransaction.resetDerivedComponents();
changedTransactionDetail.getNewTransactions().add(newLoanTransaction);
handleTransaction(newLoanTransaction, currency, installments, charges);
/**
* Check if the transaction amounts have changed. If so,
* reverse the original transaction and update
* changedTransactionDetail accordingly
**/
if (!LoanTransaction.transactionAmountsMatch(currency, loanTransaction, newLoanTransaction)) {
loanTransaction.reverse();
changedTransactionDetail.getReversedTransactions().add(loanTransaction);
changedTransactionDetail.getNewTransactions().add(newLoanTransaction);
}
}
} else if (loanTransaction.isWriteOff()) {
@@ -3,6 +3,12 @@ package org.mifosplatform.portfolio.loanaccount.domain;
import java.util.ArrayList;
import java.util.List;
/**
* Stores details of {@link LoanTransaction}'s that were reversed or newly
* created
*
*
*/
public class ChangedTransactionDetail {
private List<LoanTransaction> newTransactions = new ArrayList<LoanTransaction>();
@@ -520,6 +520,14 @@ public class Loan extends AbstractPersistable<Long> {
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
.determineProcessor(this.transactionProcessingStrategy);
if (!loanCharge.isDueAtDisbursement() && loanCharge.isPaidOrPartiallyPaid(loanCurrency())) {
/****
* TODO Vishwas Currently we do not allow removing a loan charge
* after a loan is approved (hence there is no need to adjust any
* loan transactions).
*
* Consider removing this block of code or logically completing it
* for the future by getting the list of affected Transactions
***/
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement,
getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges());
@@ -570,6 +578,14 @@ public class Loan extends AbstractPersistable<Long> {
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
.determineProcessor(this.transactionProcessingStrategy);
if (!loanCharge.isDueAtDisbursement()) {
/****
* TODO Vishwas Currently we do not allow waiving updating loan
* charge after a loan is approved (hence there is no need to adjust
* any loan transactions).
*
* Consider removing this block of code or logically completing it
* for the future by getting the list of affected Transactions
***/
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement,
getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges());
@@ -619,7 +635,7 @@ public class Loan extends AbstractPersistable<Long> {
.determineProcessor(this.transactionProcessingStrategy);
if (!loanCharge.isDueAtDisbursement() && loanCharge.isPaidOrPartiallyPaid(loanCurrency())) {
/****
* TODO vishwas Currently we do not allow waiving fully paid loan
* TODO Vishwas Currently we do not allow waiving fully paid loan
* charge and waiving partially paid loan charges only waives the
* remaining amount.
*
@@ -717,6 +733,15 @@ public class Loan extends AbstractPersistable<Long> {
// if the loan application/contract is modified when repayments are
// already against it - then need to re-process it
/****
* TODO Vishwas Currently we do not allow modifying a Loan contract once
* the loan is approved (hence there is no need to adjust any loan
* transactions).
*
* Consider removing this block of code or logically completing it for
* the future by getting the list of affected Transactions
***/
final List<LoanTransaction> repaymentsOrWaivers = retreiveListOfTransactionsPostDisbursement();
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
@@ -1390,21 +1415,17 @@ public class Loan extends AbstractPersistable<Long> {
updateLoanSummaryDerivedFields();
}
public LoanTransaction waiveInterest(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine,
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds) {
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
final Money amountToWaive = Money.of(loanCurrency(), transactionAmount);
final LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(this, amountToWaive, transactionDate);
public ChangedTransactionDetail waiveInterest(final LoanTransaction waiveInterestTransaction,
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
final List<Long> existingReversedTransactionIds) {
existingTransactionIds.addAll(findExistingTransactionIds());
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
handleRepaymentOrWaiverTransaction(waiveInterestTransaction, loanLifecycleStateMachine, null);
ChangedTransactionDetail changedTransactionDetail = handleRepaymentOrWaiverTransaction(waiveInterestTransaction,
loanLifecycleStateMachine, null);
return waiveInterestTransaction;
return changedTransactionDetail;
}
public ChangedTransactionDetail makeRepayment(final LoanTransaction repaymentTransaction,
@@ -100,6 +100,16 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
return applyCharge;
}
public static boolean transactionAmountsMatch(MonetaryCurrency currency, LoanTransaction loanTransaction,
LoanTransaction newLoanTransaction) {
if (loanTransaction.getAmount(currency).isEqualTo(newLoanTransaction.getAmount(currency))
&& (loanTransaction.getPrincipalPortion(currency).isEqualTo(newLoanTransaction.getPrincipalPortion(currency)))
&& (loanTransaction.getInterestPortion(currency).isEqualTo(newLoanTransaction.getInterestPortion(currency)))
&& (loanTransaction.getFeeChargesPortion(currency).isEqualTo(newLoanTransaction.getFeeChargesPortion(currency)))
&& (loanTransaction.getPenaltyChargesPortion(currency).isEqualTo(newLoanTransaction.getPenaltyChargesPortion(currency)))) { return true; }
return false;
}
private LoanTransaction(Loan loan, Integer typeOf, Date dateOf, BigDecimal amount, BigDecimal principalPortion,
BigDecimal interestPortion, BigDecimal feeChargesPortion, BigDecimal penaltyChargesPortion, boolean reversed) {
super();
@@ -292,8 +292,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
* TODO Vishwas Batch save is giving me a
* HibernateOptimisticLockingFailureException, looping and saving for
* the time being, not a major issue for now as this loop is entered
* only in edge cases (when a payment is made before the latest payment
* recorded against the loan)
* only in edge cases (when a adjustment is made before the latest
* payment recorded against the loan)
***/
if (changedTransactionDetail != null) {
for (LoanTransaction loanTransaction : changedTransactionDetail.getNewTransactions()) {
@@ -336,21 +336,41 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
changes.put("transactionAmount", command.stringValueOfParameterNamed("transactionAmount"));
changes.put("locale", command.locale());
changes.put("dateFormat", command.dateFormat());
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
final Loan loan = retrieveLoanBy(loanId);
final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
final LoanTransaction waiveTransaction = loan.waiveInterest(command, defaultLoanLifecycleStateMachine(), existingTransactionIds,
existingReversedTransactionIds);
this.loanTransactionRepository.save(waiveTransaction);
final Money transactionAmountAsMoney = Money.of(loan.getCurrency(), transactionAmount);
LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(loan, transactionAmountAsMoney, transactionDate);
final ChangedTransactionDetail changedTransactionDetail = loan.waiveInterest(waiveInterestTransaction,
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds);
this.loanTransactionRepository.save(waiveInterestTransaction);
/***
* TODO Vishwas Batch save is giving me a
* HibernateOptimisticLockingFailureException, looping and saving for
* the time being, not a major issue for now as this loop is entered
* only in edge cases (when a waiver is made before the latest payment
* recorded against the loan)
***/
if (changedTransactionDetail != null) {
for (LoanTransaction loanTransaction : changedTransactionDetail.getNewTransactions()) {
this.loanTransactionRepository.save(loanTransaction);
}
}
this.loanRepository.save(loan);
final String noteText = command.stringValueOfParameterNamed("note");
if (StringUtils.isNotBlank(noteText)) {
changes.put("note", noteText);
final Note note = Note.loanTransactionNote(loan, waiveTransaction, noteText);
final Note note = Note.loanTransactionNote(loan, waiveInterestTransaction, noteText);
this.noteRepository.save(note);
}
@@ -358,7 +378,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(waiveTransaction.getId()) //
.withEntityId(waiveInterestTransaction.getId()) //
.withOfficeId(loan.getOfficeId()) //
.withClientId(loan.getClientId()) //
.withGroupId(loan.getGroupId()) //