FINERACT-2330: Buy-Down fees Accounting for non merchant product

This commit is contained in:
Jose Alberto Hernandez
2025-08-15 22:54:36 +02:00
committed by Arnold Gálovics
parent 125c8b4db2
commit 6bbc4bd3f3
32 changed files with 233 additions and 65 deletions
@@ -271,7 +271,7 @@ public class LoanBuyDownFeeTest extends BaseLoanIntegrationTest {
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue()).loanScheduleType("PROGRESSIVE")
.loanScheduleProcessingType("HORIZONTAL").enableBuyDownFee(true)
.loanScheduleProcessingType("HORIZONTAL").enableBuyDownFee(true).merchantBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE).locale("en").dateFormat("dd MMMM yyyy");
@@ -496,7 +496,7 @@ public class LoanBuyDownFeeTest extends BaseLoanIntegrationTest {
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
@@ -865,4 +865,44 @@ public class LoanBuyDownFeeTest extends BaseLoanIntegrationTest {
});
}
@Test
public void testBuyDownFeeForNonMerchant() {
runAt("10 September 2024", () -> {
deleteAllExternalEvents();
// Add initial buy down fee
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
.createLoanProduct(createProgressiveLoanProductWithBuyDownFee().merchantBuyDownFee(false));
// Apply for the loan with proper progressive loan settings
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applyLP2ProgressiveLoanRequest(clientId,
loanProductsResponse.getResourceId(), "01 September 2024", 1000.0, 10.0, 12, null));
loanId = postLoansResponse.getLoanId();
loanTransactionHelper.approveLoan(loanId, approveLoanRequest(1000.0, "01 September 2024"));
disburseLoan(loanId, BigDecimal.valueOf(1000.0), "01 September 2024");
final Long buyDownFeeTransactionId = addBuyDownFeeForLoan(loanId, 400.0, "10 September 2024");
assertNotNull(buyDownFeeTransactionId);
verifyTransactions(loanId, //
transaction(1000.0, "Disbursement", "01 September 2024"), //
transaction(400.0, "Buy Down Fee", "10 September 2024"));
// Verify initial buy down fee (non merchant) accounting entries
verifyTRJournalEntries(buyDownFeeTransactionId, debit(fundSource, 400.0), credit(deferredIncomeLiabilityAccount, 400.0));
// Reverse Buy Down Fee (non merchant)
PostLoansLoanIdTransactionsResponse transactionsResponse = loanTransactionHelper.reverseLoanTransaction(loanId,
buyDownFeeTransactionId, new PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat(DATETIME_PATTERN)
.transactionDate("10 September 2024").note("Buy Down Fee reversed").transactionAmount(0.0).locale("en"));
Assertions.assertNotNull(transactionsResponse);
Assertions.assertNotNull(transactionsResponse.getResourceId());
Assertions.assertEquals(transactionsResponse.getResourceId(), buyDownFeeTransactionId);
// Verify initial buy down fee (non merchant) reversed accounting entries
verifyTRJournalEntries(buyDownFeeTransactionId, debit(fundSource, 400.0), credit(deferredIncomeLiabilityAccount, 400.0),
credit(fundSource, 400.0), debit(deferredIncomeLiabilityAccount, 400.0));
});
}
}
@@ -259,7 +259,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
@@ -339,7 +339,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
@@ -404,7 +404,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@@ -414,7 +414,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@@ -424,7 +424,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@@ -434,7 +434,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@@ -444,7 +444,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE).merchantBuyDownFee(true)
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@@ -454,7 +454,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE).merchantBuyDownFee(true)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())));
}
}
@@ -206,7 +206,7 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
.enableBuyDownFee(true).buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)//
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)//
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.INTEREST)//
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.INTEREST).merchantBuyDownFee(true)//
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue()) //
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue()) //
.capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE) //
@@ -167,6 +167,7 @@ public class LoanProductTestBuilder {
private String chargeOffBehaviour;
private boolean interestRecognitionOnDisbursementDate = false;
private Boolean enableBuyDownFee = false;
private Boolean merchantBuyDownFee = false;
private String buyDownFeeCalculationType;
public String build() {
@@ -347,8 +348,8 @@ public class LoanProductTestBuilder {
map.put("enableBuyDownFee", this.enableBuyDownFee);
}
if (this.buyDownFeeCalculationType != null) {
map.put("buyDownFeeCalculationType", this.buyDownFeeCalculationType);
if (this.merchantBuyDownFee != null) {
map.put("merchantBuyDownFee", this.merchantBuyDownFee);
}
return map;
@@ -921,6 +922,11 @@ public class LoanProductTestBuilder {
return this;
}
public LoanProductTestBuilder withMerchantBuyDownFee(final Boolean merchantBuyDownFee) {
this.merchantBuyDownFee = merchantBuyDownFee;
return this;
}
public LoanProductTestBuilder withBuyDownFeeCalculationType(final String buyDownFeeCalculationType) {
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
return this;