FINERACT-2311: Loan product - Buy down fees accounting configuration

This commit is contained in:
adam.magyari
2025-06-26 10:02:49 +02:00
committed by Adam Saghy
parent bb46397daa
commit d88f6a2f22
9 changed files with 118 additions and 16 deletions
@@ -102,6 +102,8 @@ public class ProductToGLAccountMappingHelper {
optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditPenaltyAccountId");
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue());
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue());
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue());
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue());
if (optionalProductToGLAccountMappingEntries.contains(paramName)) {
saveProductToAccountMapping(element, paramName, productId, accountTypeId, expectedAccountType, portfolioProductType);
@@ -171,6 +171,10 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
accountMappingDetails.put(LoanProductAccountingDataParams.DEFERRED_INCOME_LIABILITY.getValue(), gLAccountData);
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION)) {
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_CAPITALIZATION.getValue(), gLAccountData);
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.BUY_DOWN_EXPENSE)) {
accountMappingDetails.put(LoanProductAccountingDataParams.BUY_DOWN_EXPENSE.getValue(), gLAccountData);
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN)) {
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_BUY_DOWN.getValue(), gLAccountData);
}
}
@@ -111,7 +111,10 @@ public final class AccountingConstants {
INCOME_FROM_GOODWILL_CREDIT_FEES(20), //
INCOME_FROM_GOODWILL_CREDIT_PENALTY(21), //
INCOME_FROM_CAPITALIZATION(22), //
DEFERRED_INCOME_LIABILITY(23); //
DEFERRED_INCOME_LIABILITY(23), //
BUY_DOWN_EXPENSE(24), //
INCOME_FROM_BUY_DOWN(25), //
;
private final Integer value;
@@ -179,7 +182,10 @@ public final class AccountingConstants {
EXPENSE_GL_ACCOUNT_ID("expenseAccountId"), //
CHARGE_OFF_REASON_CODE_VALUE_ID("chargeOffReasonCodeValueId"), //
DEFERRED_INCOME_LIABILITY("deferredIncomeLiabilityAccountId"), //
INCOME_FROM_CAPITALIZATION("incomeFromCapitalizationAccountId"); //
INCOME_FROM_CAPITALIZATION("incomeFromCapitalizationAccountId"), //
BUY_DOWN_EXPENSE("buyDownExpenseAccountId"), //
INCOME_FROM_BUY_DOWN("incomeFromBuyDownAccountId"), //
;
private final String value;
@@ -223,7 +229,10 @@ public final class AccountingConstants {
INCOME_FROM_GOODWILL_CREDIT_FEES("incomeFromGoodwillCreditFeesAccount"), //
INCOME_FROM_GOODWILL_CREDIT_PENALTY("incomeFromGoodwillCreditPenaltyAccount"), //
DEFERRED_INCOME_LIABILITY("deferredIncomeLiabilityAccount"), //
INCOME_FROM_CAPITALIZATION("incomeFromCapitalizationAccount"); //
INCOME_FROM_CAPITALIZATION("incomeFromCapitalizationAccount"), //
BUY_DOWN_EXPENSE("buyDownExpenseAccount"), //
INCOME_FROM_BUY_DOWN("incomeFromBuyDownAccount"), //
;
private final String value;
@@ -363,6 +363,9 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(),
loanProductId, AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.getValue(),
AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.toString(), changes);
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(), loanProductId,
AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN.getValue(), AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN.toString(),
changes);
// expenses
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
@@ -376,6 +379,8 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.CHARGE_OFF_FRAUD_EXPENSE.getValue(),
loanProductId, AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(),
AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.toString(), changes);
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), loanProductId,
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue(), AccrualAccountsForLoan.BUY_DOWN_EXPENSE.toString(), changes);
// liabilities
mergeLoanToLiabilityAccountMappingChanges(element, LoanProductAccountingParams.OVERPAYMENT.getValue(), loanProductId,
@@ -289,6 +289,10 @@ public final class LoanProductsApiResourceSwagger {
public Long deferredIncomeLiabilityAccountId;
@Schema(example = "37")
public Long incomeFromCapitalizationAccountId;
@Schema(example = "27")
public Long buyDownExpenseAccountId;
@Schema(example = "38")
public Long incomeFromBuyDownAccountId;
public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
public List<LoanProductChargeToGLAccountMapper> feeToIncomeAccountMappings;
public List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings;
@@ -1268,6 +1272,8 @@ public final class LoanProductsApiResourceSwagger {
public GetGlAccountMapping overpaymentLiabilityAccount;
public GetGlAccountMapping deferredIncomeLiabilityAccount;
public GetGlAccountMapping incomeFromCapitalizationAccount;
public GetGlAccountMapping buyDownExpenseAccount;
public GetGlAccountMapping incomeFromBuyDownAccount;
}
static final class GetLoanPaymentChannelToFundSourceMappings {
@@ -1723,6 +1729,10 @@ public final class LoanProductsApiResourceSwagger {
public Long deferredIncomeLiabilityAccountId;
@Schema(example = "37")
public Long incomeFromCapitalizationAccountId;
@Schema(example = "27")
public Long buyDownExpenseAccountId;
@Schema(example = "38")
public Long incomeFromBuyDownAccountId;
public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
public List<LoanProductChargeToGLAccountMapper> feeToIncomeAccountMappings;
public List<PostLoanProductsRequest.PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings;
@@ -190,6 +190,9 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
this.loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(), loanProductId,
AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.getValue());
this.loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(), loanProductId,
AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN.getValue());
// expenses
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
@@ -204,6 +207,9 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
LoanProductAccountingParams.CHARGE_OFF_FRAUD_EXPENSE.getValue(), loanProductId,
AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue());
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), loanProductId,
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue());
// liabilities
this.loanProductToGLAccountMappingHelper.saveLoanToLiabilityAccountMapping(element,
@@ -154,7 +154,8 @@ public final class LoanProductDataValidator {
LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue(),
LoanProductAccountingParams.CHARGE_OFF_REASON_CODE_VALUE_ID.getValue(),
LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(),
LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue(), LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME,
LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue(), LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(),
LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(), LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME,
LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME,
LoanProductConstants.INTEREST_RATE_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME,
LoanProductConstants.NUMBER_OF_REPAYMENT_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, LoanProductConstants.SHORT_NAME,
@@ -892,7 +893,7 @@ public final class LoanProductDataValidator {
validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
validateBuyDownFee(transactionProcessingStrategyCode, element, baseDataValidator);
validateBuyDownFee(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -1942,7 +1943,7 @@ public final class LoanProductDataValidator {
validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
validateBuyDownFee(transactionProcessingStrategyCode, element, baseDataValidator);
validateBuyDownFee(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -2754,7 +2755,8 @@ public final class LoanProductDataValidator {
}
}
private void validateBuyDownFee(String transactionProcessingStrategyCode, JsonElement element, DataValidatorBuilder baseDataValidator) {
private void validateBuyDownFee(String transactionProcessingStrategyCode, JsonElement element, DataValidatorBuilder baseDataValidator,
Integer accountingRuleType) {
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME, element)) {
final String buyDownFeeCalculationType = this.fromApiJsonHelper
.extractStringNamed(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME, element);
@@ -2798,6 +2800,21 @@ public final class LoanProductDataValidator {
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME).value(buyDownFeeIncomeType)
.isOneOfEnumValues(LoanBuyDownFeeIncomeType.class)
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true);
// Accounting
if (AccountingValidations.isAccrualBasedAccounting(accountingRuleType)) {
final Long deferredIncomeLiabilityAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue())
.value(deferredIncomeLiabilityAccountId).notNull()
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true)
.integerGreaterThanZero();
final Long incomeFromDeferredIncomeAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue())
.value(incomeFromDeferredIncomeAccountId).notNull()
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true)
.integerGreaterThanZero();
}
}
} else if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, element)) {
Boolean enableBuyDownFee = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME,
@@ -162,6 +162,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
protected final Account goodwillExpenseAccount = accountHelper.createExpenseAccount("goodwillExpenseAccount");
protected final Account goodwillIncomeAccount = accountHelper.createIncomeAccount("goodwillIncomeAccount");
protected final Account deferredIncomeLiabilityAccount = accountHelper.createLiabilityAccount("deferredIncomeLiabilityAccount");
protected final Account buyDownExpenseAccount = accountHelper.createExpenseAccount("buyDownExpenseAccount");
protected final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
protected JournalEntryHelper journalEntryHelper = new JournalEntryHelper(requestSpec, responseSpec);
protected ClientHelper clientHelper = new ClientHelper(requestSpec, responseSpec);
@@ -251,7 +251,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId());
@@ -290,7 +292,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
.enableBuyDownFee(false).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId());
@@ -327,7 +331,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId());
@@ -342,8 +348,16 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(),
loanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(), new PutLoanProductsProductIdRequest()
.enableBuyDownFee(false).buyDownFeeIncomeType(PutLoanProductsProductIdRequest.BuyDownFeeIncomeTypeEnum.INTEREST));
Assertions.assertNotNull(loanProductsProductIdResponse.getAccountingMappings());
Assertions.assertEquals(buyDownExpenseAccount.getAccountID().longValue(),
loanProductsProductIdResponse.getAccountingMappings().getBuyDownExpenseAccount().getId());
Assertions.assertEquals(feeIncomeAccount.getAccountID().longValue(),
loanProductsProductIdResponse.getAccountingMappings().getIncomeFromBuyDownAccount().getId());
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(),
new PutLoanProductsProductIdRequest().enableBuyDownFee(false)
.buyDownFeeIncomeType(PutLoanProductsProductIdRequest.BuyDownFeeIncomeTypeEnum.INTEREST)
.incomeFromBuyDownAccountId(interestIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId());
@@ -357,6 +371,12 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType());
Assertions.assertEquals(LoanBuyDownFeeIncomeType.INTEREST.getCode(),
updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getAccountingMappings());
Assertions.assertEquals(buyDownExpenseAccount.getAccountID().longValue(),
updatedLoanProductsProductIdResponse.getAccountingMappings().getBuyDownExpenseAccount().getId());
Assertions.assertEquals(interestIncomeAccount.getAccountID().longValue(),
updatedLoanProductsProductIdResponse.getAccountingMappings().getIncomeFromBuyDownAccount().getId());
}
@Test
@@ -365,7 +385,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
() -> loanProductHelper.createLoanProduct(createOnePeriod30DaysPeriodicAccrualProduct(7.0).enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@Test
@@ -373,7 +395,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@Test
@@ -381,7 +405,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@Test
@@ -389,7 +415,29 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)));
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@Test
public void testBuyDownFeeEnabledBuyDownExpenseNotProvided() {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@Test
public void testBuyDownFeeEnabledIncomeFromBuyDownNotProvided() {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())));
}
}
}