FINERACT-2311: Buy Down fees - Reversal of existing transaction

This commit is contained in:
Jose Alberto Hernandez
2025-07-30 18:43:55 +02:00
committed by Adam Saghy
parent 0581c09273
commit e46a98065e
8 changed files with 422 additions and 6 deletions
@@ -18,8 +18,10 @@
*/
package org.apache.fineract.portfolio.loanaccount.service;
import java.util.Optional;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.springframework.transaction.annotation.Transactional;
public interface BuyDownFeePlatformService {
@@ -29,4 +31,7 @@ public interface BuyDownFeePlatformService {
@Transactional
CommandProcessingResult buyDownFeeAdjustment(Long loanId, Long buyDownFeeTransactionId, JsonCommand command);
@Transactional
Optional<LoanTransaction> reverseBuyDownFee(LoanTransaction buyDownFeeTransaction);
}
@@ -32,6 +32,7 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
import org.apache.fineract.infrastructure.core.service.MathUtil;
@@ -49,6 +50,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeBalance;
import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRelation;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRelationRepository;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRelationTypeEnum;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeeBalanceRepository;
@@ -73,6 +75,7 @@ public class BuyDownFeeWritePlatformServiceImpl implements BuyDownFeePlatformSer
private final LoanBalanceService loanBalanceService;
private final LoanLifecycleStateMachine loanLifecycleStateMachine;
private final BusinessEventNotifierService businessEventNotifierService;
private final LoanTransactionRelationRepository loanTransactionRelationRepository;
@Transactional
@Override
@@ -210,6 +213,37 @@ public class BuyDownFeeWritePlatformServiceImpl implements BuyDownFeePlatformSer
.withClientId(loan.getClientId()).withLoanId(loan.getId()).build();
}
@Override
@Transactional
public Optional<LoanTransaction> reverseBuyDownFee(LoanTransaction buyDownFeeTransaction) {
LoanTransaction amortizationTransaction = null;
Loan loan = buyDownFeeTransaction.getLoan();
BigDecimal totalAmortizationAmount = BigDecimal.ZERO;
if (loanTransactionRelationRepository.hasLoanTransactionRelationsWithType(buyDownFeeTransaction,
LoanTransactionRelationTypeEnum.ADJUSTMENT)) {
throw new GeneralPlatformDomainRuleException(
"error.msg.loan.transaction.with.not.reversed.transaction.related", "Undo Loan Transaction: "
+ buyDownFeeTransaction.getId() + " is not allowed. Loan transaction has not reversed transaction related",
buyDownFeeTransaction.getId());
}
LoanBuyDownFeeBalance buydownFeeBalance = loanBuyDownFeeBalanceRepository
.findByLoanIdAndLoanTransactionId(buyDownFeeTransaction.getLoan().getId(), buyDownFeeTransaction.getId());
if (buydownFeeBalance != null) {
totalAmortizationAmount = buydownFeeBalance.getAmount().subtract(MathUtil.nullToZero(buydownFeeBalance.getAmountAdjustment())
.add(MathUtil.nullToZero(buydownFeeBalance.getUnrecognizedAmount())));
loanBuyDownFeeBalanceRepository.delete(buydownFeeBalance);
}
if (MathUtil.isGreaterThanZero(totalAmortizationAmount)) {
amortizationTransaction = LoanTransaction.buyDownFeeAmortizationAdjustment(loan,
Money.of(loan.getCurrency(), totalAmortizationAmount), DateUtils.getBusinessLocalDate(), externalIdFactory.create());
}
return (amortizationTransaction == null) ? Optional.empty() : Optional.of(amortizationTransaction);
}
private void recalculateLoanTransactions(Loan loan, LocalDate transactionDate, LoanTransaction transaction) {
if (loan.isInterestBearingAndInterestRecalculationEnabled() || DateUtils.isBeforeBusinessDate(transactionDate)) {
reprocessLoanTransactionsService.reprocessTransactions(loan);