FINERACT-2225: Save journal entries for accrual transaction created by charge adjustment

This commit is contained in:
Oleksii Novikov
2025-04-01 14:23:55 +02:00
committed by Adam Saghy
parent 510b4853e7
commit f3606bb2d1
4 changed files with 44 additions and 5 deletions
@@ -19,6 +19,7 @@
package org.apache.fineract.portfolio.loanaccount.service;
import jakarta.annotation.PostConstruct;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
@@ -27,6 +28,7 @@ import org.apache.fineract.infrastructure.event.business.domain.loan.LoanCloseBu
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRelationTypeEnum;
@Slf4j
@RequiredArgsConstructor
@@ -50,7 +52,7 @@ public class LoanAccrualEventService {
LoanStatus status = loan.getStatus();
if (status.isClosedObligationsMet() || status.isOverpaid()) {
log.debug("Loan closure on accrual for loan {}", loan.getId());
loanAccrualsProcessingService.processAccrualsOnLoanClosure(loan);
loanAccrualsProcessingService.processAccrualsOnLoanClosure(loan, false);
loanAccrualActivityProcessingService.processAccrualActivityForLoanClosure(loan);
}
}
@@ -64,9 +66,19 @@ public class LoanAccrualEventService {
LoanStatus status = loan.getStatus();
if (status.isClosedObligationsMet() || status.isOverpaid()) {
log.debug("Loan balance change on accrual for loan {}", loan.getId());
loanAccrualsProcessingService.processAccrualsOnLoanClosure(loan);
final boolean hasChargeAdjustment = hasChargeAdjustment(loan);
loanAccrualsProcessingService.processAccrualsOnLoanClosure(loan, hasChargeAdjustment);
loanAccrualActivityProcessingService.processAccrualActivityForLoanClosure(loan);
}
}
private boolean hasChargeAdjustment(final Loan loan) {
return loan.getLoanTransactions().stream()
.filter(transaction -> transaction.isChargeAdjustment() && transaction.isNotReversed())
.anyMatch(chargeAdjustment -> chargeAdjustment.getLoanTransactionRelations().stream()
.anyMatch(relation -> relation.getRelationType() == LoanTransactionRelationTypeEnum.CHARGE_ADJUSTMENT
&& relation.getFromTransaction() != null
&& Objects.equals(relation.getFromTransaction().getId(), chargeAdjustment.getId())));
}
}
}
@@ -83,6 +83,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanSchedul
import org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.lang.NonNull;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -284,9 +285,9 @@ public class LoanAccrualsProcessingServiceImpl implements LoanAccrualsProcessing
* method calculates accruals for loan on loan closure
*/
@Override
public void processAccrualsOnLoanClosure(@NotNull Loan loan) {
public void processAccrualsOnLoanClosure(@NonNull final Loan loan, final boolean addJournal) {
// check and process accruals for loan WITHOUT interest recalculation details and compounding posted as income
addAccruals(loan, loan.getLastLoanRepaymentScheduleInstallment().getDueDate(), false, true, false);
addAccruals(loan, loan.getLastLoanRepaymentScheduleInstallment().getDueDate(), false, true, addJournal);
if (isProgressiveAccrual(loan)) {
return;
}