From 8a5300ef23ccad6e38846783bef5a64a0303d81a Mon Sep 17 00:00:00 2001 From: Jose Alberto Hernandez Date: Thu, 3 Jul 2025 07:37:21 -0500 Subject: [PATCH] FINERACT-2311: Buy Down fee adjustment - Template API --- ...a => LoanBuyDownFeeBalanceRepository.java} | 24 +++++------ .../BuyDownFeeWritePlatformServiceImpl.java | 10 ++--- ...ogressiveLoanTransactionValidatorImpl.java | 4 +- .../ProgressiveLoanAccountConfiguration.java | 6 +-- .../api/LoanTransactionsApiResource.java | 3 ++ .../service/LoanReadPlatformServiceImpl.java | 13 ++++++ .../starter/LoanAccountConfiguration.java | 11 ++--- .../integrationtests/LoanTransactionTest.java | 42 +++++++++++++++++++ 8 files changed, 86 insertions(+), 27 deletions(-) rename fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/repository/{LoanBuyDownFeesBalanceRepository.java => LoanBuyDownFeeBalanceRepository.java} (52%) diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/repository/LoanBuyDownFeesBalanceRepository.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/repository/LoanBuyDownFeeBalanceRepository.java similarity index 52% rename from fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/repository/LoanBuyDownFeesBalanceRepository.java rename to fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/repository/LoanBuyDownFeeBalanceRepository.java index 88dceec5d..519e50fbc 100644 --- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/repository/LoanBuyDownFeesBalanceRepository.java +++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/repository/LoanBuyDownFeeBalanceRepository.java @@ -21,29 +21,29 @@ package org.apache.fineract.portfolio.loanaccount.repository; import java.math.BigDecimal; import java.util.List; import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeBalance; -import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepaymentPeriodData; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; -public interface LoanBuyDownFeesBalanceRepository +@Repository +public interface LoanBuyDownFeeBalanceRepository extends JpaRepository, JpaSpecificationExecutor { - String FIND_BALANCE_REPAYMENT_SCHEDULE_DATA = "SELECT new org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepaymentPeriodData(lbfb.loanTransaction.id, lbfb.loan.id, lbfb.loanTransaction.dateOf, lbfb.loanTransaction.reversed, lbfb.amount, lbfb.unrecognizedAmount, lbfb.loanTransaction.feeChargesPortion) FROM LoanBuyDownFeeBalance lbfb "; - List findAllByLoanId(Long loanId); LoanBuyDownFeeBalance findByLoanIdAndLoanTransactionId(Long loanId, Long transactionId); - @Query(FIND_BALANCE_REPAYMENT_SCHEDULE_DATA + " WHERE lbfb.loan.id = :loanId") - List findRepaymentPeriodDataByLoanId(Long loanId); + @Query("SELECT lbfb FROM LoanBuyDownFeeBalance lbfb WHERE lbfb.loan.id = :loanId ORDER BY lbfb.date ASC") + List findRepaymentPeriodDataByLoanId(@Param("loanId") Long loanId); - @Query("SELECT SUM(lbfb.amount) FROM LoanBuyDownFeeBalance lbfb WHERE lbfb.loan.id = :loanId") - BigDecimal calculateBuydownFeeAmount(Long loanId); + @Query("SELECT COALESCE(SUM(lbfb.amount), 0) FROM LoanBuyDownFeeBalance lbfb WHERE lbfb.loan.id = :loanId") + BigDecimal calculateBuyDownFee(@Param("loanId") Long loanId); - @Query("SELECT SUM(lbfb.amountAdjustment) FROM LoanBuyDownFeeBalance lbfb WHERE lbfb.loan.id = :loanId") - BigDecimal calculateBuydownFeeAdjustment(Long loanId); + @Query("SELECT COALESCE(SUM(lbfb.amountAdjustment), 0) FROM LoanBuyDownFeeBalance lbfb WHERE lbfb.loan.id = :loanId") + BigDecimal calculateBuyDownFeeAdjustment(@Param("loanId") Long loanId); - @Query("SELECT lbfb FROM LoanBuyDownFeeBalance lbfb, LoanTransaction lt, LoanTransactionRelation ltr WHERE lt.loan.id = lbfb.loan.id AND ltr.fromTransaction.id =:transactionId AND ltr.toTransaction.id=lt.id AND lbfb.loanTransaction.id = lt.id") - LoanBuyDownFeeBalance findBalanceForAdjustment(Long transactionId); + @Query("SELECT lbfb FROM LoanBuyDownFeeBalance lbfb WHERE lbfb.loan.id = :loanId AND lbfb.amountAdjustment IS NULL ORDER BY lbfb.date DESC") + List findBalanceForAdjustment(@Param("loanId") Long loanId); } diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/BuyDownFeeWritePlatformServiceImpl.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/BuyDownFeeWritePlatformServiceImpl.java index 902b0a46d..e02b18ae9 100644 --- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/BuyDownFeeWritePlatformServiceImpl.java +++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/BuyDownFeeWritePlatformServiceImpl.java @@ -51,7 +51,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRelation; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRelationTypeEnum; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository; -import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeesBalanceRepository; +import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeeBalanceRepository; import org.apache.fineract.portfolio.note.service.NoteWritePlatformService; import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService; @@ -68,7 +68,7 @@ public class BuyDownFeeWritePlatformServiceImpl implements BuyDownFeePlatformSer private final LoanJournalEntryPoster loanJournalEntryPoster; private final NoteWritePlatformService noteWritePlatformService; private final ExternalIdFactory externalIdFactory; - private final LoanBuyDownFeesBalanceRepository loanBuyDownFeesBalanceRepository; + private final LoanBuyDownFeeBalanceRepository loanBuyDownFeeBalanceRepository; private final ReprocessLoanTransactionsService reprocessLoanTransactionsService; private final LoanBalanceService loanBalanceService; private final LoanLifecycleStateMachine loanLifecycleStateMachine; @@ -177,13 +177,13 @@ public class BuyDownFeeWritePlatformServiceImpl implements BuyDownFeePlatformSer LoanTransaction savedBuyDownFeeAdjustment = loanTransactionRepository.saveAndFlush(buyDownFeeAdjustment); // Update buy down fee balance - LoanBuyDownFeeBalance buydownFeeBalance = loanBuyDownFeesBalanceRepository.findByLoanIdAndLoanTransactionId(loanId, + LoanBuyDownFeeBalance buydownFeeBalance = loanBuyDownFeeBalanceRepository.findByLoanIdAndLoanTransactionId(loanId, buyDownFeeTransactionId); if (buydownFeeBalance != null) { buydownFeeBalance.setAmountAdjustment(MathUtil.nullToZero(buydownFeeBalance.getAmountAdjustment()).add(transactionAmount)); buydownFeeBalance .setUnrecognizedAmount(MathUtil.negativeToZero(buydownFeeBalance.getUnrecognizedAmount().subtract(transactionAmount))); - loanBuyDownFeesBalanceRepository.save(buydownFeeBalance); + loanBuyDownFeeBalanceRepository.save(buydownFeeBalance); } // Update outstanding loan balances @@ -236,6 +236,6 @@ public class BuyDownFeeWritePlatformServiceImpl implements BuyDownFeePlatformSer buyDownFeeBalance.setDate(buyDownFeeTransaction.getTransactionDate()); buyDownFeeBalance.setAmount(buyDownFeeTransaction.getAmount()); buyDownFeeBalance.setUnrecognizedAmount(buyDownFeeTransaction.getAmount()); - loanBuyDownFeesBalanceRepository.saveAndFlush(buyDownFeeBalance); + loanBuyDownFeeBalanceRepository.saveAndFlush(buyDownFeeBalance); } } diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanTransactionValidatorImpl.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanTransactionValidatorImpl.java index 46bf83fdd..a1a0155af 100644 --- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanTransactionValidatorImpl.java +++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanTransactionValidatorImpl.java @@ -58,7 +58,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; import org.apache.fineract.portfolio.loanaccount.exception.LoanTransactionProcessingException; -import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeesBalanceRepository; +import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeeBalanceRepository; import org.apache.fineract.portfolio.loanaccount.repository.LoanCapitalizedIncomeBalanceRepository; import org.apache.fineract.portfolio.loanaccount.serialization.LoanTransactionValidator; import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; @@ -71,7 +71,7 @@ public class ProgressiveLoanTransactionValidatorImpl implements ProgressiveLoanT private final LoanTransactionValidator loanTransactionValidator; private final LoanRepositoryWrapper loanRepositoryWrapper; private final LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository; - private final LoanBuyDownFeesBalanceRepository loanBuydownFeeBalanceRepository; + private final LoanBuyDownFeeBalanceRepository loanBuydownFeeBalanceRepository; private final LoanTransactionRepository loanTransactionRepository; @Override diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/ProgressiveLoanAccountConfiguration.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/ProgressiveLoanAccountConfiguration.java index 6e6665ed6..e0e44f49b 100644 --- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/ProgressiveLoanAccountConfiguration.java +++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/ProgressiveLoanAccountConfiguration.java @@ -24,7 +24,7 @@ import org.apache.fineract.infrastructure.event.business.service.BusinessEventNo import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository; -import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeesBalanceRepository; +import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeeBalanceRepository; import org.apache.fineract.portfolio.loanaccount.repository.LoanCapitalizedIncomeBalanceRepository; import org.apache.fineract.portfolio.loanaccount.serialization.LoanTransactionValidator; import org.apache.fineract.portfolio.loanaccount.service.CapitalizedIncomeBalanceService; @@ -66,9 +66,9 @@ public class ProgressiveLoanAccountConfiguration { public ProgressiveLoanTransactionValidator progressiveLoanTransactionValidator(FromJsonHelper fromApiJsonHelper, LoanTransactionValidator loanTransactionValidator, LoanRepositoryWrapper loanRepositoryWrapper, LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository, - LoanBuyDownFeesBalanceRepository loanBuydownFeesBalanceRepository, LoanTransactionRepository loanTransactionRepository) { + LoanBuyDownFeeBalanceRepository loanBuydownFeeBalanceRepository, LoanTransactionRepository loanTransactionRepository) { return new ProgressiveLoanTransactionValidatorImpl(fromApiJsonHelper, loanTransactionValidator, loanRepositoryWrapper, - loanCapitalizedIncomeBalanceRepository, loanBuydownFeesBalanceRepository, loanTransactionRepository); + loanCapitalizedIncomeBalanceRepository, loanBuydownFeeBalanceRepository, loanTransactionRepository); } @Bean diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java index e5f503de9..039f7a70e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java @@ -688,6 +688,9 @@ public class LoanTransactionsApiResource { LoanTransactionType.CAPITALIZED_INCOME_ADJUSTMENT, transactionId); } else if (CommandParameterUtil.is(commandParam, LoanApiConstants.BUY_DOWN_FEE_COMMAND)) { transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(resolvedLoanId); + } else if (CommandParameterUtil.is(commandParam, LoanApiConstants.BUY_DOWN_FEE_ADJUSTMENT_COMMAND)) { + transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(resolvedLoanId, + LoanTransactionType.BUY_DOWN_FEE_ADJUSTMENT, transactionId); } else { throw new UnrecognizedQueryParamException("command", commandParam); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 3bff93be0..a409e0991 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -109,6 +109,7 @@ import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData; import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData; import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO; import org.apache.fineract.portfolio.loanaccount.domain.Loan; +import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeBalance; import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType; import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType; import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy; @@ -133,6 +134,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.OverdueLoanSc import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType; import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType; import org.apache.fineract.portfolio.loanaccount.mapper.LoanTransactionMapper; +import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeeBalanceRepository; import org.apache.fineract.portfolio.loanaccount.repository.LoanCapitalizedIncomeBalanceRepository; import org.apache.fineract.portfolio.loanaccount.serialization.LoanForeclosureValidator; import org.apache.fineract.portfolio.loanproduct.data.LoanProductData; @@ -189,6 +191,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa private final LoanTransactionProcessingService loadTransactionProcessingService; private final LoanBalanceService loanBalanceService; private final LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository; + private final LoanBuyDownFeeBalanceRepository loanBuyDownFeeBalanceRepository; @Override public LoanAccountData retrieveOne(final Long loanId) { @@ -503,6 +506,16 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa LoanEnumerations.transactionType(transactionType), DateUtils.getBusinessLocalDate(), transactionAmount, paymentOptions, retriveLoanCurrencyData(loanId)); break; + case BUY_DOWN_FEE_ADJUSTMENT: + final LoanBuyDownFeeBalance loanBuyDownFeeBalance = loanBuyDownFeeBalanceRepository.findByLoanIdAndLoanTransactionId(loanId, + transactionId); + + transactionAmount = (loanBuyDownFeeBalance == null) ? BigDecimal.ZERO + : loanBuyDownFeeBalance.getAmount().subtract(MathUtil.nullToZero(loanBuyDownFeeBalance.getAmountAdjustment())); + loanTransactionData = LoanTransactionData.loanTransactionDataForCreditTemplate( + LoanEnumerations.transactionType(transactionType), DateUtils.getBusinessLocalDate(), transactionAmount, + paymentOptions, retriveLoanCurrencyData(loanId)); + break; default: loanTransactionData = LoanTransactionData.templateOnTop(retrieveLoanTransactionTemplate(loanId), LoanEnumerations.transactionType(transactionType)); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java index 1f94fa781..00609a999 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java @@ -88,7 +88,7 @@ import org.apache.fineract.portfolio.loanaccount.mapper.LoanChargeMapper; import org.apache.fineract.portfolio.loanaccount.mapper.LoanCollateralManagementMapper; import org.apache.fineract.portfolio.loanaccount.mapper.LoanMapper; import org.apache.fineract.portfolio.loanaccount.mapper.LoanTransactionMapper; -import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeesBalanceRepository; +import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeeBalanceRepository; import org.apache.fineract.portfolio.loanaccount.repository.LoanCapitalizedIncomeBalanceRepository; import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanTermVariationsRepository; import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionValidator; @@ -339,7 +339,8 @@ public class LoanAccountConfiguration { LoanChargePaidByReadService loanChargePaidByReadService, LoanTransactionRelationReadService loanTransactionRelationReadService, LoanForeclosureValidator loanForeclosureValidator, LoanTransactionMapper loanTransactionMapper, LoanTransactionProcessingService loanTransactionProcessingService, LoanBalanceService loanBalanceService, - LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository) { + LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository, + LoanBuyDownFeeBalanceRepository loanBuyDownFeeBalanceRepository) { return new LoanReadPlatformServiceImpl(jdbcTemplate, context, loanRepositoryWrapper, applicationCurrencyRepository, loanProductReadPlatformService, clientReadPlatformService, groupReadPlatformService, loanDropdownReadPlatformService, fundReadPlatformService, chargeReadPlatformService, codeValueReadPlatformService, calendarReadPlatformService, @@ -347,7 +348,7 @@ public class LoanAccountConfiguration { loanUtilService, configurationDomainService, accountDetailsReadPlatformService, columnValidator, sqlGenerator, delinquencyReadPlatformService, loanTransactionRepository, loanChargePaidByReadService, loanTransactionRelationReadService, loanForeclosureValidator, loanTransactionMapper, loanTransactionProcessingService, loanBalanceService, - loanCapitalizedIncomeBalanceRepository); + loanCapitalizedIncomeBalanceRepository, loanBuyDownFeeBalanceRepository); } @Bean @@ -383,12 +384,12 @@ public class LoanAccountConfiguration { LoanAssembler loanAssembler, LoanTransactionRepository loanTransactionRepository, PaymentDetailWritePlatformService paymentDetailWritePlatformService, LoanJournalEntryPoster loanJournalEntryPoster, NoteWritePlatformService noteWritePlatformService, ExternalIdFactory externalIdFactory, - LoanBuyDownFeesBalanceRepository loanBuyDownFeesBalanceRepository, + LoanBuyDownFeeBalanceRepository loanBuyDownFeeBalanceRepository, ReprocessLoanTransactionsService reprocessLoanTransactionsService, LoanBalanceService loanBalanceService, LoanLifecycleStateMachine loanLifecycleStateMachine, BusinessEventNotifierService businessEventNotifierService) { return new BuyDownFeeWritePlatformServiceImpl(loanTransactionValidator, loanAssembler, loanTransactionRepository, paymentDetailWritePlatformService, loanJournalEntryPoster, noteWritePlatformService, externalIdFactory, - loanBuyDownFeesBalanceRepository, reprocessLoanTransactionsService, loanBalanceService, loanLifecycleStateMachine, + loanBuyDownFeeBalanceRepository, reprocessLoanTransactionsService, loanBalanceService, loanLifecycleStateMachine, businessEventNotifierService); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionTest.java index 838ad1180..16db6e0e9 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionTest.java @@ -43,6 +43,8 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest { private final String capitalizedIncomeCommand = "capitalizedIncome"; private final String capitalizedIncomeAdjustmentCommand = "capitalizedIncomeAdjustment"; + private final String buyDownFeeCommand = "buyDownFee"; + private final String buyDownFeeAdjustmentCommand = "buyDownFeeAdjustment"; @Test public void testGetLoanTransactionsFiltering() { @@ -166,4 +168,44 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest { }); } + @Test + public void testGetLoanTransactionTemplateForBuyDownFeeAdjustment() { + final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()); + + final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive() + .enableBuyDownFee(true).buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)// + .buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)// + .buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.INTEREST)// + .deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue()) // + .incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue()) // + .capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE) // + .buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())// + .incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())); + + final String loanExternalIdStr = UUID.randomUUID().toString(); + + runAt("20 December 2024", () -> { + final Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), + "20 December 2024", 430.0, 7.0, 6, (request) -> request.externalId(loanExternalIdStr)); + + disburseLoan(loanId, BigDecimal.valueOf(230), "20 December 2024"); + + PostLoansLoanIdTransactionsResponse loanTransactionResponse = loanTransactionHelper.executeLoanTransaction(loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat(DATETIME_PATTERN).transactionDate("20 December 2024").locale("en") + .transactionAmount(150.0), + buyDownFeeCommand); + assertNotNull(loanTransactionResponse); + final Long transactionId = loanTransactionResponse.getResourceId(); + assertNotNull(transactionId); + log.info("Loan Id {} with transaction id {}", loanId, transactionId); + + final GetLoansLoanIdTransactionsTemplateResponse transactionTemplate = loanTransactionHelper.retrieveTransactionTemplate(loanId, + buyDownFeeAdjustmentCommand, null, null, null, transactionId); + + assertNotNull(transactionTemplate); + assertEquals("loanTransactionType." + buyDownFeeAdjustmentCommand, transactionTemplate.getType().getCode()); + assertEquals(transactionTemplate.getAmount(), 150); + }); + } + }