FINERACT-2181: Rework "createMissingAccrualTransactionDuringChargeOffIfNeeded" to avoid flushing and triggering business event as part of Transaction processor
This commit is contained in:
committed by
Adam Saghy
parent
166c1981fb
commit
22282ded00
+36
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.data;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||
|
||||
/**
|
||||
* Represents a transaction change, storing both the old reversed transaction (if any) and the new transaction.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
public class TransactionChangeData {
|
||||
|
||||
private LoanTransaction oldTransaction;
|
||||
private LoanTransaction newTransaction;
|
||||
}
|
||||
+40
-4
@@ -18,9 +18,12 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.domain;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import lombok.Getter;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.TransactionChangeData;
|
||||
|
||||
/**
|
||||
* Stores details of {@link LoanTransaction}'s that were reversed or newly created
|
||||
@@ -28,8 +31,41 @@ import lombok.Getter;
|
||||
@Getter
|
||||
public class ChangedTransactionDetail {
|
||||
|
||||
private final Map<Long, LoanTransaction> newTransactionMappings = new LinkedHashMap<>();
|
||||
private final List<TransactionChangeData> transactionChanges = new ArrayList<>();
|
||||
|
||||
private final Map<LoanTransaction, Long> currentTransactionToOldId = new LinkedHashMap<>();
|
||||
public void addTransactionChange(final TransactionChangeData transactionChangeData) {
|
||||
for (TransactionChangeData change : transactionChanges) {
|
||||
if (transactionChangeData.getOldTransaction() != null && change.getOldTransaction() != null
|
||||
&& Objects.equals(change.getOldTransaction().getId(), transactionChangeData.getOldTransaction().getId())) {
|
||||
change.setOldTransaction(transactionChangeData.getOldTransaction());
|
||||
change.setNewTransaction(transactionChangeData.getNewTransaction());
|
||||
return;
|
||||
} else if (transactionChangeData.getOldTransaction() == null && change.getOldTransaction() == null
|
||||
&& change.getNewTransaction() != null
|
||||
&& Objects.equals(change.getNewTransaction().getId(), transactionChangeData.getNewTransaction().getId())) {
|
||||
change.setNewTransaction(transactionChangeData.getNewTransaction());
|
||||
return;
|
||||
}
|
||||
}
|
||||
transactionChanges.add(transactionChangeData);
|
||||
}
|
||||
|
||||
public void addNewTransactionChangeBeforeExistingOne(final TransactionChangeData newTransactionChange,
|
||||
final LoanTransaction existingLoanTransaction) {
|
||||
if (existingLoanTransaction != null) {
|
||||
final Optional<TransactionChangeData> existingChange = transactionChanges.stream().filter(
|
||||
change -> change.getNewTransaction() != null && Objects.equals(change.getNewTransaction(), existingLoanTransaction))
|
||||
.findFirst();
|
||||
|
||||
if (existingChange.isPresent()) {
|
||||
transactionChanges.add(transactionChanges.indexOf(existingChange.get()), newTransactionChange);
|
||||
return;
|
||||
}
|
||||
}
|
||||
transactionChanges.add(newTransactionChange);
|
||||
}
|
||||
|
||||
public void removeTransactionChange(final LoanTransaction newTransaction) {
|
||||
transactionChanges.removeIf(change -> change.getNewTransaction().equals(newTransaction));
|
||||
}
|
||||
}
|
||||
|
||||
+11
-6
@@ -107,6 +107,7 @@ import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.OutstandingAmountsDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.TransactionChangeData;
|
||||
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.TransactionCtx;
|
||||
@@ -719,10 +720,12 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.reprocessLoanTransactions(
|
||||
getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(),
|
||||
getActiveCharges());
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
mapEntry.getValue().updateLoan(this);
|
||||
for (TransactionChangeData change : changedTransactionDetail.getTransactionChanges()) {
|
||||
change.getNewTransaction().updateLoan(this);
|
||||
}
|
||||
this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values());
|
||||
final List<LoanTransaction> newTransactions = changedTransactionDetail.getTransactionChanges().stream()
|
||||
.map(TransactionChangeData::getNewTransaction).toList();
|
||||
this.loanTransactions.addAll(newTransactions);
|
||||
updateLoanSummaryDerivedFields();
|
||||
return changedTransactionDetail;
|
||||
}
|
||||
@@ -2656,14 +2659,16 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.reprocessLoanTransactions(
|
||||
getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(),
|
||||
getActiveCharges());
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
mapEntry.getValue().updateLoan(this);
|
||||
for (TransactionChangeData change : changedTransactionDetail.getTransactionChanges()) {
|
||||
change.getNewTransaction().updateLoan(this);
|
||||
}
|
||||
/*
|
||||
* Commented since throwing exception if external id present for one of the transactions. for this need to save
|
||||
* the reversed transactions first and then new transactions.
|
||||
*/
|
||||
this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values());
|
||||
final List<LoanTransaction> newTransactions = changedTransactionDetail.getTransactionChanges().stream()
|
||||
.map(TransactionChangeData::getNewTransaction).toList();
|
||||
this.loanTransactions.addAll(newTransactions);
|
||||
updateLoanSummaryDerivedFields();
|
||||
|
||||
return changedTransactionDetail;
|
||||
|
||||
+16
-11
@@ -25,7 +25,6 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -34,6 +33,7 @@ import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanChargePaidDetail;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.TransactionChangeData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
|
||||
@@ -187,7 +187,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
**/
|
||||
if (newLoanTransaction.isReversed()) {
|
||||
loanTransaction.reverse();
|
||||
changedTransactionDetail.getNewTransactionMappings().put(loanTransaction.getId(), loanTransaction);
|
||||
changedTransactionDetail.addTransactionChange(new TransactionChangeData(loanTransaction, loanTransaction));
|
||||
} else if (LoanTransaction.transactionAmountsMatch(currency, loanTransaction, newLoanTransaction)) {
|
||||
loanTransaction.updateLoanTransactionToRepaymentScheduleMappings(
|
||||
newLoanTransaction.getLoanTransactionToRepaymentScheduleMappings());
|
||||
@@ -264,7 +264,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processLatestTransaction(final LoanTransaction loanTransaction, final TransactionCtx ctx) {
|
||||
public ChangedTransactionDetail processLatestTransaction(final LoanTransaction loanTransaction, final TransactionCtx ctx) {
|
||||
switch (loanTransaction.getTypeOf()) {
|
||||
case WRITEOFF -> handleWriteOff(loanTransaction, ctx.getCurrency(), ctx.getInstallments());
|
||||
case REFUND_FOR_ACTIVE_LOAN -> handleRefund(loanTransaction, ctx.getCurrency(), ctx.getInstallments(), ctx.getCharges());
|
||||
@@ -288,6 +288,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctx.getChangedTransactionDetail();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -421,10 +422,12 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
|
||||
private void reprocessChargebackTransactionRelation(ChangedTransactionDetail changedTransactionDetail,
|
||||
List<LoanTransaction> transactionsToBeProcessed) {
|
||||
|
||||
List<LoanTransaction> mergedTransactionList = getMergedTransactionList(transactionsToBeProcessed, changedTransactionDetail);
|
||||
for (Map.Entry<Long, LoanTransaction> entry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
if (entry.getValue().isChargeback()) {
|
||||
for (TransactionChangeData change : changedTransactionDetail.getTransactionChanges()) {
|
||||
LoanTransaction newTransaction = change.getNewTransaction();
|
||||
LoanTransaction oldTransaction = change.getOldTransaction();
|
||||
|
||||
if (newTransaction.isChargeback()) {
|
||||
for (LoanTransaction loanTransaction : mergedTransactionList) {
|
||||
if (loanTransaction.isReversed()) {
|
||||
continue;
|
||||
@@ -433,8 +436,9 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
LoanTransactionRelation oldLoanTransactionRelation = null;
|
||||
for (LoanTransactionRelation transactionRelation : loanTransaction.getLoanTransactionRelations()) {
|
||||
if (LoanTransactionRelationTypeEnum.CHARGEBACK.equals(transactionRelation.getRelationType())
|
||||
&& entry.getKey().equals(transactionRelation.getToTransaction().getId())) {
|
||||
newLoanTransactionRelation = LoanTransactionRelation.linkToTransaction(loanTransaction, entry.getValue(),
|
||||
&& oldTransaction != null && oldTransaction.getId() != null
|
||||
&& oldTransaction.getId().equals(transactionRelation.getToTransaction().getId())) {
|
||||
newLoanTransactionRelation = LoanTransactionRelation.linkToTransaction(loanTransaction, newTransaction,
|
||||
LoanTransactionRelationTypeEnum.CHARGEBACK);
|
||||
oldLoanTransactionRelation = transactionRelation;
|
||||
break;
|
||||
@@ -511,8 +515,9 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
|
||||
private List<LoanTransaction> getMergedTransactionList(List<LoanTransaction> transactionList,
|
||||
ChangedTransactionDetail changedTransactionDetail) {
|
||||
List<LoanTransaction> mergedList = new ArrayList<>(changedTransactionDetail.getNewTransactionMappings().values());
|
||||
mergedList.addAll(new ArrayList<>(transactionList));
|
||||
List<LoanTransaction> mergedList = new ArrayList<>(
|
||||
changedTransactionDetail.getTransactionChanges().stream().map(TransactionChangeData::getNewTransaction).toList());
|
||||
mergedList.addAll(transactionList);
|
||||
return mergedList;
|
||||
}
|
||||
|
||||
@@ -525,7 +530,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
// Adding Replayed relation from newly created transaction to reversed transaction
|
||||
newLoanTransaction.getLoanTransactionRelations().add(
|
||||
LoanTransactionRelation.linkToTransaction(newLoanTransaction, loanTransaction, LoanTransactionRelationTypeEnum.REPLAYED));
|
||||
changedTransactionDetail.getNewTransactionMappings().put(loanTransaction.getId(), newLoanTransaction);
|
||||
changedTransactionDetail.addTransactionChange(new TransactionChangeData(loanTransaction, newLoanTransaction));
|
||||
}
|
||||
|
||||
protected void processCreditTransaction(LoanTransaction loanTransaction, MoneyHolder overpaymentHolder, MonetaryCurrency currency,
|
||||
|
||||
+3
-1
@@ -39,8 +39,10 @@ public interface LoanRepaymentScheduleTransactionProcessor {
|
||||
/**
|
||||
* Provides support for processing the latest transaction (which should be the latest transaction) against the loan
|
||||
* schedule.
|
||||
*
|
||||
* @return ChangedTransactionDetail
|
||||
*/
|
||||
void processLatestTransaction(LoanTransaction loanTransaction, TransactionCtx ctx);
|
||||
ChangedTransactionDetail processLatestTransaction(LoanTransaction loanTransaction, TransactionCtx ctx);
|
||||
|
||||
/**
|
||||
* Provides support for passing all {@link LoanTransaction}'s so it will completely re-process the entire loan
|
||||
|
||||
+22
-9
@@ -18,14 +18,15 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanAdjustTransactionBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanAccrualAdjustmentTransactionBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanAccrualTransactionCreatedBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.TransactionChangeData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanTransactionNotFoundException;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ReplayedTransactionBusinessEventServiceImpl implements ReplayedTransactionBusinessEventService {
|
||||
@@ -35,18 +36,30 @@ public class ReplayedTransactionBusinessEventServiceImpl implements ReplayedTran
|
||||
|
||||
@Override
|
||||
public void raiseTransactionReplayedEvents(final ChangedTransactionDetail changedTransactionDetail) {
|
||||
if (changedTransactionDetail == null || changedTransactionDetail.getNewTransactionMappings().isEmpty()) {
|
||||
if (changedTransactionDetail == null || changedTransactionDetail.getTransactionChanges().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// Extra safety net to avoid event leaking
|
||||
try {
|
||||
businessEventNotifierService.startExternalEventRecording();
|
||||
for (Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
LoanTransaction oldTransaction = loanTransactionRepository.findById(mapEntry.getKey())
|
||||
.orElseThrow(() -> new LoanTransactionNotFoundException(mapEntry.getKey()));
|
||||
LoanAdjustTransactionBusinessEvent.Data data = new LoanAdjustTransactionBusinessEvent.Data(oldTransaction);
|
||||
data.setNewTransactionDetail(mapEntry.getValue());
|
||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanAdjustTransactionBusinessEvent(data));
|
||||
|
||||
for (TransactionChangeData change : changedTransactionDetail.getTransactionChanges()) {
|
||||
final LoanTransaction newTransaction = change.getNewTransaction();
|
||||
final LoanTransaction oldTransaction = change.getOldTransaction();
|
||||
|
||||
if (oldTransaction != null) {
|
||||
final LoanAdjustTransactionBusinessEvent.Data data = new LoanAdjustTransactionBusinessEvent.Data(oldTransaction);
|
||||
data.setNewTransactionDetail(newTransaction);
|
||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanAdjustTransactionBusinessEvent(data));
|
||||
} else {
|
||||
if (newTransaction.isAccrual()) {
|
||||
businessEventNotifierService
|
||||
.notifyPostBusinessEvent(new LoanAccrualTransactionCreatedBusinessEvent(newTransaction));
|
||||
} else {
|
||||
businessEventNotifierService
|
||||
.notifyPostBusinessEvent(new LoanAccrualAdjustmentTransactionBusinessEvent(newTransaction));
|
||||
}
|
||||
}
|
||||
}
|
||||
businessEventNotifierService.stopExternalEventRecording();
|
||||
} catch (Exception e) {
|
||||
|
||||
+6
@@ -19,17 +19,23 @@
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||
|
||||
public interface ReprocessLoanTransactionsService {
|
||||
|
||||
void reprocessTransactions(Loan loan);
|
||||
|
||||
void reprocessTransactions(Loan loan, List<LoanTransaction> loanTransactions);
|
||||
|
||||
void reprocessTransactionsWithPostTransactionChecks(Loan loan, LocalDate transactionDate);
|
||||
|
||||
void processPostDisbursementTransactions(Loan loan);
|
||||
|
||||
void removeLoanCharge(Loan loan, LoanCharge loanCharge);
|
||||
|
||||
void processLatestTransaction(LoanTransaction loanTransaction, Loan loan);
|
||||
|
||||
}
|
||||
|
||||
+43
-5
@@ -19,14 +19,18 @@
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.portfolio.interestpauses.service.LoanAccountTransfersService;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.TransactionChangeData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountService;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
|
||||
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.MoneyHolder;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.TransactionCtx;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@@ -45,6 +49,22 @@ public class ReprocessLoanTransactionsServiceImpl implements ReprocessLoanTransa
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reprocessTransactions(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();
|
||||
handleChangedDetail(changedTransactionDetail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reprocessTransactionsWithPostTransactionChecks(final Loan loan, final LocalDate transactionDate) {
|
||||
final ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactionsWithPostTransactionChecks(transactionDate);
|
||||
@@ -63,12 +83,30 @@ public class ReprocessLoanTransactionsServiceImpl implements ReprocessLoanTransa
|
||||
loan.removeLoanCharge(loanCharge).ifPresent(this::handleChangedDetail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processLatestTransaction(final LoanTransaction loanTransaction, final Loan loan) {
|
||||
final ChangedTransactionDetail changedTransactionDetail = loan.getTransactionProcessor().processLatestTransaction(loanTransaction,
|
||||
new TransactionCtx(loan.getCurrency(), loan.getRepaymentScheduleInstallments(), loan.getActiveCharges(),
|
||||
new MoneyHolder(loan.getTotalOverpaidAsMoney()), new ChangedTransactionDetail()));
|
||||
final List<LoanTransaction> newTransactions = changedTransactionDetail.getTransactionChanges().stream()
|
||||
.map(TransactionChangeData::getNewTransaction).peek(transaction -> transaction.updateLoan(loan)).toList();
|
||||
loan.getLoanTransactions().addAll(newTransactions);
|
||||
|
||||
loan.updateLoanSummaryDerivedFields();
|
||||
handleChangedDetail(changedTransactionDetail);
|
||||
}
|
||||
|
||||
private void handleChangedDetail(final ChangedTransactionDetail changedTransactionDetail) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
loanAccountService.saveLoanTransactionWithDataIntegrityViolationChecks(mapEntry.getValue());
|
||||
loanAccountTransfersService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
|
||||
for (TransactionChangeData change : changedTransactionDetail.getTransactionChanges()) {
|
||||
final LoanTransaction newTransaction = change.getNewTransaction();
|
||||
final LoanTransaction oldTransaction = change.getOldTransaction();
|
||||
|
||||
loanAccountService.saveLoanTransactionWithDataIntegrityViolationChecks(newTransaction);
|
||||
|
||||
if (oldTransaction != null) {
|
||||
loanAccountTransfersService.updateLoanTransaction(oldTransaction.getId(), newTransaction);
|
||||
}
|
||||
}
|
||||
replayedTransactionBusinessEventService.raiseTransactionReplayedEvents(changedTransactionDetail);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user