added undo writeoff transaction

This commit is contained in:
Pramod Nuthakki
2013-12-02 17:58:40 +05:30
parent 40ec10ef11
commit eb75708b66
10 changed files with 105 additions and 6 deletions
@@ -0,0 +1 @@
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('transaction_loan', 'UNDOWRITEOFF_LOAN', 'LOAN', 'UNDOWRITEOFF', 0);
@@ -65,11 +65,11 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
* and fee write off need not be considered). Debit losses written
* off and credit Loan Portfolio
**/
else if (loanTransactionDTO.getTransactionType().isWriteOff() && !loanTransactionDTO.isReversed()) {
else if (loanTransactionDTO.getTransactionType().isWriteOff()) {
final BigDecimal principalAmount = loanTransactionDTO.getPrincipal();
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CASH_ACCOUNTS_FOR_LOAN.LOSSES_WRITTEN_OFF, CASH_ACCOUNTS_FOR_LOAN.LOAN_PORTFOLIO, loanProductId, paymentTypeId,
loanId, transactionId, transactionDate, principalAmount, false);
loanId, transactionId, transactionDate, principalAmount, loanTransactionDTO.isReversed());
} else if (loanTransactionDTO.getTransactionType().isInitiateTransfer()
|| loanTransactionDTO.getTransactionType().isApproveTransfer()
|| loanTransactionDTO.getTransactionType().isWithdrawTransfer()) {
@@ -377,6 +377,10 @@ public class CommandWrapper {
public boolean isLoanWriteOff() {
return this.actionName.equalsIgnoreCase("WRITEOFF") && this.entityName.equalsIgnoreCase("LOAN");
}
public boolean isUndoLoanWriteOff() {
return this.actionName.equalsIgnoreCase("UNDOWRITEOFF") && this.entityName.equalsIgnoreCase("LOAN");
}
public boolean isCloseLoanAsObligationsMet() {
return this.actionName.equalsIgnoreCase("CLOSE") && this.entityName.equalsIgnoreCase("LOAN");
@@ -573,6 +573,16 @@ public class CommandWrapperBuilder {
this.href = "/loans/" + loanId + "/transactions/template?command=writeoff";
return this;
}
public CommandWrapperBuilder undoWriteOffLoanTransaction(final Long loanId) {
this.actionName = "UNDOWRITEOFF";
this.entityName = "LOAN";
this.entityId = null;
this.loanId = loanId;
this.href = "/loans/" + loanId + "/transactions/template?command=undowriteoff";
return this;
}
public CommandWrapperBuilder closeLoanAsRescheduledTransaction(final Long loanId) {
this.actionName = "CLOSEASRESCHEDULED";
@@ -346,7 +346,9 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
handler = this.applicationContext.getBean("loanApplicationModificationCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = this.applicationContext.getBean("loanApplicationDeletionCommandHandler", NewCommandSourceHandler.class);
} else {
} else if (wrapper.isUndoLoanWriteOff()) {
handler = this.applicationContext.getBean("undoWriteOffLoanCommandHandler", NewCommandSourceHandler.class);
}else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isLoanChargeResource()) {
@@ -149,7 +149,10 @@ public class LoanTransactionsApiResource {
} else if (is(commandParam, "close")) {
final CommandWrapper commandRequest = builder.closeLoanTransaction(loanId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
}else if (is(commandParam, "undowriteoff")) {
final CommandWrapper commandRequest = builder.undoWriteOffLoanTransaction(loanId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam); }
@@ -2097,6 +2097,21 @@ public class Loan extends AbstractPersistable<Long> {
return changedTransactionDetail;
}
public ChangedTransactionDetail undoWrittenOff(final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds){
existingTransactionIds.addAll(findExistingTransactionIds());
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
final LoanTransaction writeOffTransaction = findWriteOffTransaction();
writeOffTransaction.reverse();
this.loanStatus = LoanStatus.ACTIVE.getValue();
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
.determineProcessor(this.transactionProcessingStrategy);
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges());
updateLoanSummaryDerivedFields();
return changedTransactionDetail;
}
private LoanTransaction findWriteOffTransaction() {
@@ -2350,7 +2365,7 @@ public class Loan extends AbstractPersistable<Long> {
return status().isClosedObligationsMet();
}
private boolean isClosedWrittenOff() {
public boolean isClosedWrittenOff() {
return status().isClosedWrittenOff();
}
@@ -0,0 +1,32 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UndoWriteOffLoanCommandHandler implements NewCommandSourceHandler {
private final LoanWritePlatformService writePlatformService;
@Autowired
public UndoWriteOffLoanCommandHandler(final LoanWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.undoWriteOff(command.getLoanId());
}
}
@@ -74,6 +74,6 @@ public interface LoanWritePlatformService {
void applyChargeForOverdueLoans() throws JobExecutionException;
CommandProcessingResult undoWriteOff(Long loanId);
}
@@ -546,6 +546,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.LOAN)) { throw new PlatformServiceUnavailableException(
"error.msg.loan.transfer.transaction.update.not.allowed", "Loan transaction:" + transactionId
+ " update not allowed as it involves in account transfer", transactionId); }
if(loan.isClosedWrittenOff()){ throw new PlatformServiceUnavailableException(
"error.msg.loan.written.off.update.not.allowed", "Loan transaction:" + transactionId
+ " update not allowed as loan status is written off", transactionId); }
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
@@ -1692,4 +1695,33 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
}
}
@Override
public CommandProcessingResult undoWriteOff(Long loanId) {
final Loan loan = this.loanAssembler.assembleFrom(loanId);
checkClientOrGroupActive(loan);
final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
if(!loan.isClosedWrittenOff()){
throw new PlatformServiceUnavailableException(
"error.msg.loan.status.not.written.off.update.not.allowed", "Loan :" + loanId
+ " update not allowed as loan status is not written off", loanId);
}
ChangedTransactionDetail changedTransactionDetail =loan.undoWrittenOff(existingTransactionIds,existingReversedTransactionIds);
if (changedTransactionDetail != null) {
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
this.loanTransactionRepository.save(mapEntry.getValue());
this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
}
}
this.loanRepository.save(loan);
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
return new CommandProcessingResultBuilder() //
.withOfficeId(loan.getOfficeId()) //
.withClientId(loan.getClientId()) //
.withGroupId(loan.getGroupId()) //
.withLoanId(loanId) //
.build();
}
}