FINERACT-2181: Move the remaining transactions reprocessing logic out of the loan entity to ReprocessLoanTransactionsService.
This commit is contained in:
committed by
Adam Saghy
parent
f3bb66f209
commit
2d2cbb46b5
+1
-50
@@ -713,28 +713,6 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
|||||||
loanLifecycleStateMachine.transition(LoanEvent.LOAN_CHARGE_ADDED, this);
|
loanLifecycleStateMachine.transition(LoanEvent.LOAN_CHARGE_ADDED, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail reprocessTransactions() {
|
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = getTransactionProcessor();
|
|
||||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retrieveListOfTransactionsForReprocessing();
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.reprocessLoanTransactions(
|
|
||||||
getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(),
|
|
||||||
getActiveCharges());
|
|
||||||
for (TransactionChangeData change : changedTransactionDetail.getTransactionChanges()) {
|
|
||||||
change.getNewTransaction().updateLoan(this);
|
|
||||||
}
|
|
||||||
final List<LoanTransaction> newTransactions = changedTransactionDetail.getTransactionChanges().stream()
|
|
||||||
.map(TransactionChangeData::getNewTransaction).toList();
|
|
||||||
this.loanTransactions.addAll(newTransactions);
|
|
||||||
updateLoanSummaryDerivedFields();
|
|
||||||
return changedTransactionDetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChangedTransactionDetail reprocessTransactionsWithPostTransactionChecks(LocalDate transactionDate) {
|
|
||||||
ChangedTransactionDetail changedDetail = reprocessTransactions();
|
|
||||||
doPostLoanTransactionChecks(transactionDate, loanLifecycleStateMachine);
|
|
||||||
return changedDetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a loanTransaction for "Apply Charge Event" with transaction date set to "suppliedTransactionDate". The
|
* Creates a loanTransaction for "Apply Charge Event" with transaction date set to "suppliedTransactionDate". The
|
||||||
* newly created transaction is also added to the Loan on which this method is called.
|
* newly created transaction is also added to the Loan on which this method is called.
|
||||||
@@ -832,34 +810,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
|||||||
return lastRepaymentDate;
|
return lastRepaymentDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<ChangedTransactionDetail> removeLoanCharge(final LoanCharge loanCharge) {
|
public void removeOrModifyTransactionAssociatedWithLoanChargeIfDueAtDisbursement(final LoanCharge loanCharge) {
|
||||||
final boolean removed = loanCharge.isActive();
|
|
||||||
if (removed) {
|
|
||||||
loanCharge.setActive(false);
|
|
||||||
final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper();
|
|
||||||
wrapper.reprocess(getCurrency(), getDisbursementDate(), getRepaymentScheduleInstallments(), getActiveCharges());
|
|
||||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
|
||||||
}
|
|
||||||
|
|
||||||
removeOrModifyTransactionAssociatedWithLoanChargeIfDueAtDisbursement(loanCharge);
|
|
||||||
|
|
||||||
if (!loanCharge.isDueAtDisbursement() && loanCharge.isPaidOrPartiallyPaid(getCurrency())) {
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
return Optional.ofNullable(reprocessTransactions());
|
|
||||||
}
|
|
||||||
this.charges.remove(loanCharge);
|
|
||||||
updateLoanSummaryDerivedFields();
|
|
||||||
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeOrModifyTransactionAssociatedWithLoanChargeIfDueAtDisbursement(final LoanCharge loanCharge) {
|
|
||||||
if (loanCharge.isDueAtDisbursement()) {
|
if (loanCharge.isDueAtDisbursement()) {
|
||||||
LoanTransaction transactionToRemove = null;
|
LoanTransaction transactionToRemove = null;
|
||||||
List<LoanTransaction> transactions = getLoanTransactions();
|
List<LoanTransaction> transactions = getLoanTransactions();
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ public interface ReprocessLoanTransactionsService {
|
|||||||
|
|
||||||
void reprocessTransactions(Loan loan);
|
void reprocessTransactions(Loan loan);
|
||||||
|
|
||||||
void reprocessTransactions(Loan loan, List<LoanTransaction> loanTransactions);
|
void reprocessParticularTransactions(Loan loan, List<LoanTransaction> loanTransactions);
|
||||||
|
|
||||||
void reprocessTransactionsWithPostTransactionChecks(Loan loan, LocalDate transactionDate);
|
void reprocessTransactionsWithPostTransactionChecks(Loan loan, LocalDate transactionDate);
|
||||||
|
|
||||||
|
|||||||
+51
-21
@@ -27,6 +27,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail
|
|||||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountService;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountService;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleProcessingWrapper;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.MoneyHolder;
|
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.MoneyHolder;
|
||||||
@@ -43,34 +44,24 @@ public class ReprocessLoanTransactionsServiceImpl implements ReprocessLoanTransa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reprocessTransactions(final Loan loan) {
|
public void reprocessTransactions(final Loan loan) {
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactions();
|
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = loan.retrieveListOfTransactionsForReprocessing();
|
||||||
if (changedTransactionDetail != null) {
|
final ChangedTransactionDetail changedTransactionDetail = reprocessTransactionsAndFetchChangedTransactions(loan,
|
||||||
handleChangedDetail(changedTransactionDetail);
|
allNonContraTransactionsPostDisbursement);
|
||||||
}
|
handleChangedDetail(changedTransactionDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reprocessTransactions(final Loan loan, final List<LoanTransaction> loanTransactions) {
|
public void reprocessParticularTransactions(final Loan loan, final List<LoanTransaction> loanTransactions) {
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = loan.getTransactionProcessor();
|
final ChangedTransactionDetail changedTransactionDetail = reprocessTransactionsAndFetchChangedTransactions(loan, loanTransactions);
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.reprocessLoanTransactions(
|
|
||||||
loan.getDisbursementDate(), loanTransactions, loan.getCurrency(), loan.getRepaymentScheduleInstallments(),
|
|
||||||
loan.getActiveCharges());
|
|
||||||
for (TransactionChangeData change : changedTransactionDetail.getTransactionChanges()) {
|
|
||||||
change.getNewTransaction().updateLoan(loan);
|
|
||||||
}
|
|
||||||
final List<LoanTransaction> newTransactions = changedTransactionDetail.getTransactionChanges().stream()
|
|
||||||
.map(TransactionChangeData::getNewTransaction).toList();
|
|
||||||
loan.getLoanTransactions().addAll(newTransactions);
|
|
||||||
loan.updateLoanSummaryDerivedFields();
|
|
||||||
handleChangedDetail(changedTransactionDetail);
|
handleChangedDetail(changedTransactionDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reprocessTransactionsWithPostTransactionChecks(final Loan loan, final LocalDate transactionDate) {
|
public void reprocessTransactionsWithPostTransactionChecks(final Loan loan, final LocalDate transactionDate) {
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactionsWithPostTransactionChecks(transactionDate);
|
final ChangedTransactionDetail changedTransactionDetail = reprocessTransactionsAndFetchChangedTransactions(loan,
|
||||||
if (changedTransactionDetail != null) {
|
loan.retrieveListOfTransactionsForReprocessing());
|
||||||
handleChangedDetail(changedTransactionDetail);
|
loan.doPostLoanTransactionChecks(transactionDate, loan.getLoanLifecycleStateMachine());
|
||||||
}
|
handleChangedDetail(changedTransactionDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,7 +71,30 @@ public class ReprocessLoanTransactionsServiceImpl implements ReprocessLoanTransa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeLoanCharge(final Loan loan, final LoanCharge loanCharge) {
|
public void removeLoanCharge(final Loan loan, final LoanCharge loanCharge) {
|
||||||
loan.removeLoanCharge(loanCharge).ifPresent(this::handleChangedDetail);
|
final boolean removed = loanCharge.isActive();
|
||||||
|
if (removed) {
|
||||||
|
loanCharge.setActive(false);
|
||||||
|
final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper();
|
||||||
|
wrapper.reprocess(loan.getCurrency(), loan.getDisbursementDate(), loan.getRepaymentScheduleInstallments(),
|
||||||
|
loan.getActiveCharges());
|
||||||
|
loan.updateSummaryWithTotalFeeChargesDueAtDisbursement(loan.deriveSumTotalOfChargesDueAtDisbursement());
|
||||||
|
}
|
||||||
|
|
||||||
|
loan.removeOrModifyTransactionAssociatedWithLoanChargeIfDueAtDisbursement(loanCharge);
|
||||||
|
|
||||||
|
if (!loanCharge.isDueAtDisbursement() && loanCharge.isPaidOrPartiallyPaid(loan.getCurrency())) {
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
reprocessTransactions(loan);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loan.getLoanCharges().remove(loanCharge);
|
||||||
|
loan.updateLoanSummaryDerivedFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -109,4 +123,20 @@ public class ReprocessLoanTransactionsServiceImpl implements ReprocessLoanTransa
|
|||||||
}
|
}
|
||||||
replayedTransactionBusinessEventService.raiseTransactionReplayedEvents(changedTransactionDetail);
|
replayedTransactionBusinessEventService.raiseTransactionReplayedEvents(changedTransactionDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ChangedTransactionDetail reprocessTransactionsAndFetchChangedTransactions(final Loan loan,
|
||||||
|
final List<LoanTransaction> loanTransactions) {
|
||||||
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = loan.getTransactionProcessor();
|
||||||
|
final ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.reprocessLoanTransactions(
|
||||||
|
loan.getDisbursementDate(), loanTransactions, loan.getCurrency(), loan.getRepaymentScheduleInstallments(),
|
||||||
|
loan.getActiveCharges());
|
||||||
|
for (TransactionChangeData change : changedTransactionDetail.getTransactionChanges()) {
|
||||||
|
change.getNewTransaction().updateLoan(loan);
|
||||||
|
}
|
||||||
|
final List<LoanTransaction> newTransactions = changedTransactionDetail.getTransactionChanges().stream()
|
||||||
|
.map(TransactionChangeData::getNewTransaction).toList();
|
||||||
|
loan.getLoanTransactions().addAll(newTransactions);
|
||||||
|
loan.updateLoanSummaryDerivedFields();
|
||||||
|
return changedTransactionDetail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2918,7 +2918,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
final List<LoanTransaction> loanTransactions = loan.retrieveListOfTransactionsForReprocessing();
|
final List<LoanTransaction> loanTransactions = loan.retrieveListOfTransactionsForReprocessing();
|
||||||
loanTransactions.add(chargeOffTransaction);
|
loanTransactions.add(chargeOffTransaction);
|
||||||
reprocessLoanTransactionsService.reprocessTransactions(loan, loanTransactions);
|
reprocessLoanTransactionsService.reprocessParticularTransactions(loan, loanTransactions);
|
||||||
loan.addLoanTransaction(chargeOffTransaction);
|
loan.addLoanTransaction(chargeOffTransaction);
|
||||||
} else {
|
} else {
|
||||||
reprocessLoanTransactionsService.processLatestTransaction(chargeOffTransaction, loan);
|
reprocessLoanTransactionsService.processLatestTransaction(chargeOffTransaction, loan);
|
||||||
|
|||||||
+3
-3
@@ -130,11 +130,11 @@ public class LoanReAmortizationServiceImpl {
|
|||||||
private void reverseReAmortizeTransaction(LoanTransaction reAmortizeTransaction, JsonCommand command) {
|
private void reverseReAmortizeTransaction(LoanTransaction reAmortizeTransaction, JsonCommand command) {
|
||||||
ExternalId reversalExternalId = externalIdFactory.createFromCommand(command,
|
ExternalId reversalExternalId = externalIdFactory.createFromCommand(command,
|
||||||
LoanReAmortizationApiConstants.externalIdParameterName);
|
LoanReAmortizationApiConstants.externalIdParameterName);
|
||||||
loanChargeValidator.validateRepaymentTypeTransactionNotBeforeAChargeRefund(reAmortizeTransaction.getLoan(), reAmortizeTransaction,
|
final Loan loan = reAmortizeTransaction.getLoan();
|
||||||
"reversed");
|
loanChargeValidator.validateRepaymentTypeTransactionNotBeforeAChargeRefund(loan, reAmortizeTransaction, "reversed");
|
||||||
reAmortizeTransaction.reverse(reversalExternalId);
|
reAmortizeTransaction.reverse(reversalExternalId);
|
||||||
reAmortizeTransaction.manuallyAdjustedOrReversed();
|
reAmortizeTransaction.manuallyAdjustedOrReversed();
|
||||||
reprocessLoanTransactionsService.reprocessTransactions(reAmortizeTransaction.getLoan());
|
reprocessLoanTransactionsService.reprocessTransactions(loan);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanTransaction findLatestNonReversedReAmortizeTransaction(Loan loan) {
|
private LoanTransaction findLatestNonReversedReAmortizeTransaction(Loan loan) {
|
||||||
|
|||||||
Reference in New Issue
Block a user