FINERACT-2080: Extract calculations from loan entity

This commit is contained in:
Oleksii Novikov
2025-05-22 13:58:44 +02:00
committed by Adam Saghy
parent 18a55874ba
commit 47d5330802
53 changed files with 1403 additions and 1128 deletions
@@ -90,7 +90,10 @@ import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.Abs
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.MoneyHolder;
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.TransactionCtx;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeValidator;
import org.apache.fineract.portfolio.loanaccount.service.InterestRefundService;
import org.apache.fineract.portfolio.loanaccount.service.LoanBalanceService;
import org.apache.fineract.portfolio.loanaccount.service.LoanTransactionService;
import org.apache.fineract.portfolio.loanaccount.service.schedule.LoanScheduleComponent;
import org.apache.fineract.portfolio.loanproduct.calc.EMICalculator;
import org.apache.fineract.portfolio.loanproduct.calc.data.PeriodDueDetails;
@@ -118,13 +121,17 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
private final LoanRepositoryWrapper loanRepositoryWrapper;
private final InterestRefundService interestRefundService;
private final LoanScheduleComponent loanSchedule;
private final LoanTransactionService loanTransactionService;
public AdvancedPaymentScheduleTransactionProcessor(EMICalculator emiCalculator, LoanRepositoryWrapper loanRepositoryWrapper,
InterestRefundService interestRefundService, ExternalIdFactory externalIdFactory, LoanScheduleComponent loanSchedule) {
super(externalIdFactory);
public AdvancedPaymentScheduleTransactionProcessor(final EMICalculator emiCalculator, final LoanRepositoryWrapper loanRepositoryWrapper,
final InterestRefundService interestRefundService, final ExternalIdFactory externalIdFactory,
final LoanScheduleComponent loanSchedule, final LoanTransactionService loanTransactionRepository,
final LoanChargeValidator loanChargeValidator, final LoanBalanceService loanBalanceService) {
super(externalIdFactory, loanChargeValidator, loanBalanceService);
this.emiCalculator = emiCalculator;
this.loanRepositoryWrapper = loanRepositoryWrapper;
this.interestRefundService = interestRefundService;
this.loanTransactionService = loanTransactionRepository;
this.loanSchedule = loanSchedule;
}
@@ -269,7 +276,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
public ProgressiveLoanInterestScheduleModel calculateInterestScheduleModel(@NotNull Long loanId, LocalDate targetDate) {
Loan loan = loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
List<LoanTransaction> transactions = loan.retrieveListOfTransactionsForReprocessing();
final List<LoanTransaction> transactions = loanTransactionService.retrieveListOfTransactionsForReprocessing(loan);
MonetaryCurrency currency = loan.getLoanRepaymentScheduleDetail().getCurrency();
List<LoanRepaymentScheduleInstallment> installments = loan.getRepaymentScheduleInstallments();
Set<LoanCharge> charges = loan.getActiveCharges();
@@ -1514,7 +1521,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
newTransaction.updateLoan(loan);
loan.getLoanTransactions().add(newTransaction);
}
loan.updateLoanSummaryDerivedFields();
loanBalanceService.updateLoanSummaryDerivedFields(loan);
}
}
}
@@ -62,6 +62,7 @@ public class InternalProgressiveLoanApiResource implements InitializingBean {
private final AdvancedPaymentScheduleTransactionProcessor advancedPaymentScheduleTransactionProcessor;
private final ProgressiveLoanInterestScheduleModelParserService progressiveLoanInterestScheduleModelParserService;
private final InterestScheduleModelRepositoryWrapper writePlatformService;
private final LoanTransactionService loanTransactionService;
@Override
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
@@ -94,7 +95,7 @@ public class InternalProgressiveLoanApiResource implements InitializingBean {
}
private ProgressiveLoanInterestScheduleModel reprocessTransactionsAndGetModel(final Loan loan) {
final List<LoanTransaction> transactionsToReprocess = loan.retrieveListOfTransactionsForReprocessing();
final List<LoanTransaction> transactionsToReprocess = loanTransactionService.retrieveListOfTransactionsForReprocessing(loan);
final LocalDate businessDate = ThreadLocalContextUtil.getBusinessDate();
final Pair<ChangedTransactionDetail, ProgressiveLoanInterestScheduleModel> changedTransactionDetailProgressiveLoanInterestScheduleModelPair = advancedPaymentScheduleTransactionProcessor
.reprocessProgressiveLoanTransactionsTransactional(loan.getDisbursementDate(), businessDate, transactionsToReprocess,
@@ -49,6 +49,7 @@ import java.util.Set;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.domain.ActionContext;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
@@ -69,6 +70,10 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.MoneyHolder;
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.TransactionCtx;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeValidator;
import org.apache.fineract.portfolio.loanaccount.service.InterestRefundService;
import org.apache.fineract.portfolio.loanaccount.service.LoanBalanceService;
import org.apache.fineract.portfolio.loanaccount.service.LoanTransactionService;
import org.apache.fineract.portfolio.loanaccount.service.schedule.LoanScheduleComponent;
import org.apache.fineract.portfolio.loanproduct.calc.EMICalculator;
import org.apache.fineract.portfolio.loanproduct.calc.data.ProgressiveLoanInterestScheduleModel;
@@ -98,8 +103,6 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
private static final MockedStatic<MoneyHelper> MONEY_HELPER = mockStatic(MoneyHelper.class);
private AdvancedPaymentScheduleTransactionProcessor underTest;
private static final EMICalculator emiCalculator = Mockito.mock(EMICalculator.class);
private static final LoanRepositoryWrapper loanRepositoryWrapper = Mockito.mock(LoanRepositoryWrapper.class);
private static final LoanScheduleComponent loanSchedule = Mockito.mock(LoanScheduleComponent.class);
@BeforeAll
public static void init() {
@@ -114,7 +117,10 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
@BeforeEach
public void setUp() {
underTest = new AdvancedPaymentScheduleTransactionProcessor(emiCalculator, loanRepositoryWrapper, null, null, loanSchedule);
underTest = new AdvancedPaymentScheduleTransactionProcessor(emiCalculator, Mockito.mock(LoanRepositoryWrapper.class),
Mockito.mock(InterestRefundService.class), Mockito.mock(ExternalIdFactory.class), Mockito.mock(LoanScheduleComponent.class),
Mockito.mock(LoanTransactionService.class), Mockito.mock(LoanChargeValidator.class),
Mockito.mock(LoanBalanceService.class));
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);