FINERACT-2232: Capitalized income - accounting configuration

This commit is contained in:
adam.magyari
2025-04-25 12:35:23 +02:00
committed by Adam Saghy
parent 834e90dce0
commit 85fac1e1b0
9 changed files with 103 additions and 15 deletions
@@ -100,6 +100,8 @@ public class ProductToGLAccountMappingHelper {
optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditInterestAccountId"); optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditInterestAccountId");
optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditFeesAccountId"); optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditFeesAccountId");
optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditPenaltyAccountId"); optionalProductToGLAccountMappingEntries.add("incomeFromGoodwillCreditPenaltyAccountId");
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue());
optionalProductToGLAccountMappingEntries.add(LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue());
if (optionalProductToGLAccountMappingEntries.contains(paramName)) { if (optionalProductToGLAccountMappingEntries.contains(paramName)) {
saveProductToAccountMapping(element, paramName, productId, accountTypeId, expectedAccountType, portfolioProductType); saveProductToAccountMapping(element, paramName, productId, accountTypeId, expectedAccountType, portfolioProductType);
@@ -167,6 +167,10 @@ public class ProductToGLAccountMappingReadPlatformServiceImpl implements Product
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY)) { } else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY)) {
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
gLAccountData); gLAccountData);
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY)) {
accountMappingDetails.put(LoanProductAccountingDataParams.DEFERRED_INCOME_LIABILITY.getValue(), gLAccountData);
} else if (glAccountForLoan.equals(AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION)) {
accountMappingDetails.put(LoanProductAccountingDataParams.INCOME_FROM_CAPITALIZATION.getValue(), gLAccountData);
} }
} }
@@ -109,7 +109,9 @@ public final class AccountingConstants {
INCOME_FROM_CHARGE_OFF_PENALTY(18), // INCOME_FROM_CHARGE_OFF_PENALTY(18), //
INCOME_FROM_GOODWILL_CREDIT_INTEREST(19), // INCOME_FROM_GOODWILL_CREDIT_INTEREST(19), //
INCOME_FROM_GOODWILL_CREDIT_FEES(20), // INCOME_FROM_GOODWILL_CREDIT_FEES(20), //
INCOME_FROM_GOODWILL_CREDIT_PENALTY(21); // INCOME_FROM_GOODWILL_CREDIT_PENALTY(21), //
INCOME_FROM_CAPITALIZATION(22), //
DEFERRED_INCOME_LIABILITY(23); //
private final Integer value; private final Integer value;
@@ -175,7 +177,9 @@ public final class AccountingConstants {
INCOME_FROM_GOODWILL_CREDIT_PENALTY("incomeFromGoodwillCreditPenaltyAccountId"), // INCOME_FROM_GOODWILL_CREDIT_PENALTY("incomeFromGoodwillCreditPenaltyAccountId"), //
CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS("chargeOffReasonToExpenseAccountMappings"), // CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS("chargeOffReasonToExpenseAccountMappings"), //
EXPENSE_GL_ACCOUNT_ID("expenseAccountId"), // EXPENSE_GL_ACCOUNT_ID("expenseAccountId"), //
CHARGE_OFF_REASON_CODE_VALUE_ID("chargeOffReasonCodeValueId"); // CHARGE_OFF_REASON_CODE_VALUE_ID("chargeOffReasonCodeValueId"), //
DEFERRED_INCOME_LIABILITY("deferredIncomeLiabilityAccountId"), //
INCOME_FROM_CAPITALIZATION("incomeFromCapitalizationAccountId"); //
private final String value; private final String value;
@@ -217,7 +221,9 @@ public final class AccountingConstants {
INCOME_FROM_CHARGE_OFF_PENALTY("incomeFromChargeOffPenaltyAccount"), // INCOME_FROM_CHARGE_OFF_PENALTY("incomeFromChargeOffPenaltyAccount"), //
INCOME_FROM_GOODWILL_CREDIT_INTEREST("incomeFromGoodwillCreditInterestAccount"), // INCOME_FROM_GOODWILL_CREDIT_INTEREST("incomeFromGoodwillCreditInterestAccount"), //
INCOME_FROM_GOODWILL_CREDIT_FEES("incomeFromGoodwillCreditFeesAccount"), // INCOME_FROM_GOODWILL_CREDIT_FEES("incomeFromGoodwillCreditFeesAccount"), //
INCOME_FROM_GOODWILL_CREDIT_PENALTY("incomeFromGoodwillCreditPenaltyAccount"); // INCOME_FROM_GOODWILL_CREDIT_PENALTY("incomeFromGoodwillCreditPenaltyAccount"), //
DEFERRED_INCOME_LIABILITY("deferredIncomeLiabilityAccount"), //
INCOME_FROM_CAPITALIZATION("incomeFromCapitalizationAccount"); //
private final String value; private final String value;
@@ -360,6 +360,9 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
loanProductId, AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), loanProductId, AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.toString(), changes); AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.toString(), changes);
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(),
loanProductId, AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.getValue(),
AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.toString(), changes);
// expenses // expenses
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), loanProductId, mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
@@ -377,6 +380,9 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
// liabilities // liabilities
mergeLoanToLiabilityAccountMappingChanges(element, LoanProductAccountingParams.OVERPAYMENT.getValue(), loanProductId, mergeLoanToLiabilityAccountMappingChanges(element, LoanProductAccountingParams.OVERPAYMENT.getValue(), loanProductId,
CashAccountsForLoan.OVERPAYMENT.getValue(), CashAccountsForLoan.OVERPAYMENT.toString(), changes); CashAccountsForLoan.OVERPAYMENT.getValue(), CashAccountsForLoan.OVERPAYMENT.toString(), changes);
mergeLoanToLiabilityAccountMappingChanges(element, LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue(),
loanProductId, AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.getValue(),
AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.toString(), changes);
break; break;
} }
} }
@@ -275,6 +275,10 @@ public final class LoanProductsApiResourceSwagger {
public Long incomeFromGoodwillCreditFeesAccountId; public Long incomeFromGoodwillCreditFeesAccountId;
@Schema(example = "11") @Schema(example = "11")
public Long incomeFromGoodwillCreditPenaltyAccountId; public Long incomeFromGoodwillCreditPenaltyAccountId;
@Schema(example = "25")
public Long deferredIncomeLiabilityAccountId;
@Schema(example = "37")
public Long incomeFromCapitalizationAccountId;
public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings; public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
public List<LoanProductChargeToGLAccountMapper> feeToIncomeAccountMappings; public List<LoanProductChargeToGLAccountMapper> feeToIncomeAccountMappings;
public List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings; public List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings;
@@ -1227,6 +1231,8 @@ public final class LoanProductsApiResourceSwagger {
public GetGlAccountMapping chargeOffExpenseAccount; public GetGlAccountMapping chargeOffExpenseAccount;
public GetGlAccountMapping chargeOffFraudExpenseAccount; public GetGlAccountMapping chargeOffFraudExpenseAccount;
public GetGlAccountMapping overpaymentLiabilityAccount; public GetGlAccountMapping overpaymentLiabilityAccount;
public GetGlAccountMapping deferredIncomeLiabilityAccount;
public GetGlAccountMapping incomeFromCapitalizationAccount;
} }
static final class GetLoanPaymentChannelToFundSourceMappings { static final class GetLoanPaymentChannelToFundSourceMappings {
@@ -1661,6 +1667,10 @@ public final class LoanProductsApiResourceSwagger {
@Schema(example = "11") @Schema(example = "11")
public Long incomeFromChargeOffPenaltyAccountId; public Long incomeFromChargeOffPenaltyAccountId;
@Schema(example = "25")
public Long deferredIncomeLiabilityAccountId;
@Schema(example = "37")
public Long incomeFromCapitalizationAccountId;
public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings; public List<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
public List<LoanProductChargeToGLAccountMapper> feeToIncomeAccountMappings; public List<LoanProductChargeToGLAccountMapper> feeToIncomeAccountMappings;
public List<PostLoanProductsRequest.PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings; public List<PostLoanProductsRequest.PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings;
@@ -187,6 +187,9 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
this.loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element, this.loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), loanProductId, LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), loanProductId,
AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue()); AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue());
this.loanProductToGLAccountMappingHelper.saveLoanToIncomeAccountMapping(element,
LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(), loanProductId,
AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.getValue());
// expenses // expenses
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element, this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
@@ -205,6 +208,9 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
// liabilities // liabilities
this.loanProductToGLAccountMappingHelper.saveLoanToLiabilityAccountMapping(element, this.loanProductToGLAccountMappingHelper.saveLoanToLiabilityAccountMapping(element,
LoanProductAccountingParams.OVERPAYMENT.getValue(), loanProductId, AccrualAccountsForLoan.OVERPAYMENT.getValue()); LoanProductAccountingParams.OVERPAYMENT.getValue(), loanProductId, AccrualAccountsForLoan.OVERPAYMENT.getValue());
this.loanProductToGLAccountMappingHelper.saveLoanToLiabilityAccountMapping(element,
LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue(), loanProductId,
AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.getValue());
// advanced accounting mappings // advanced accounting mappings
this.loanProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, loanProductId, null); this.loanProductToGLAccountMappingHelper.savePaymentChannelToFundSourceMappings(command, element, loanProductId, null);
@@ -148,7 +148,9 @@ public final class LoanProductDataValidator {
LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue(), LoanProductAccountingParams.CHARGE_OFF_REASON_TO_EXPENSE_ACCOUNT_MAPPINGS.getValue(),
LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue(), LoanProductAccountingParams.EXPENSE_GL_ACCOUNT_ID.getValue(),
LoanProductAccountingParams.CHARGE_OFF_REASON_CODE_VALUE_ID.getValue(), LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME, LoanProductAccountingParams.CHARGE_OFF_REASON_CODE_VALUE_ID.getValue(),
LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(),
LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue(), LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME,
LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME,
LoanProductConstants.INTEREST_RATE_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, LoanProductConstants.NUMBER_OF_REPAYMENT_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, LoanProductConstants.SHORT_NAME,
@@ -882,7 +884,7 @@ public final class LoanProductDataValidator {
"Charge off behaviour is only supported for Progressive loans"); "Charge off behaviour is only supported for Progressive loans");
} }
validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator); validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
throwExceptionIfValidationWarningsExist(dataValidationErrors); throwExceptionIfValidationWarningsExist(dataValidationErrors);
} }
@@ -1930,7 +1932,7 @@ public final class LoanProductDataValidator {
validateRepaymentPeriodWithGraceSettings(numberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, validateRepaymentPeriodWithGraceSettings(numberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment,
graceOnInterestCharged, recurringMoratoriumOnPrincipalPeriods, baseDataValidator); graceOnInterestCharged, recurringMoratoriumOnPrincipalPeriods, baseDataValidator);
validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator); validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
throwExceptionIfValidationWarningsExist(dataValidationErrors); throwExceptionIfValidationWarningsExist(dataValidationErrors);
} }
@@ -2671,7 +2673,7 @@ public final class LoanProductDataValidator {
} }
private void validateIncomeCapitalization(String transactionProcessingStrategyCode, JsonElement element, private void validateIncomeCapitalization(String transactionProcessingStrategyCode, JsonElement element,
DataValidatorBuilder baseDataValidator) { DataValidatorBuilder baseDataValidator, Integer accountingRuleType) {
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, element)) { if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, element)) {
final String capitalizedIncomeCalculationType = this.fromApiJsonHelper final String capitalizedIncomeCalculationType = this.fromApiJsonHelper
.extractStringNamed(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, element); .extractStringNamed(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, element);
@@ -2703,6 +2705,21 @@ public final class LoanProductDataValidator {
baseDataValidator.reset().parameter(LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME) baseDataValidator.reset().parameter(LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME)
.value(capitalizedIncomeStrategy).isOneOfEnumValues(LoanCapitalizedIncomeStrategy.class) .value(capitalizedIncomeStrategy).isOneOfEnumValues(LoanCapitalizedIncomeStrategy.class)
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, true); .cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, true);
// Accounting
if (AccountingValidations.isAccrualBasedAccounting(accountingRuleType)) {
final Long deferredIncomeLiabilityAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue())
.value(deferredIncomeLiabilityAccountId).notNull()
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, true)
.integerGreaterThanZero();
final Long incomeFromDeferredIncomeAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue())
.value(incomeFromDeferredIncomeAccountId).notNull()
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, true)
.integerGreaterThanZero();
}
} }
} else if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, element)) { } else if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, element)) {
Boolean enableIncomeCapitalization = this.fromApiJsonHelper Boolean enableIncomeCapitalization = this.fromApiJsonHelper
@@ -158,6 +158,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
protected final Account writtenOffAccount = accountHelper.createExpenseAccount("writtenOffAccount"); protected final Account writtenOffAccount = accountHelper.createExpenseAccount("writtenOffAccount");
protected final Account goodwillExpenseAccount = accountHelper.createExpenseAccount("goodwillExpenseAccount"); protected final Account goodwillExpenseAccount = accountHelper.createExpenseAccount("goodwillExpenseAccount");
protected final Account goodwillIncomeAccount = accountHelper.createIncomeAccount("goodwillIncomeAccount"); protected final Account goodwillIncomeAccount = accountHelper.createIncomeAccount("goodwillIncomeAccount");
protected final Account deferredIncomeLiabilityAccount = accountHelper.createLiabilityAccount("deferredIncomeLiabilityAccount");
protected final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec); protected final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
protected JournalEntryHelper journalEntryHelper = new JournalEntryHelper(requestSpec, responseSpec); protected JournalEntryHelper journalEntryHelper = new JournalEntryHelper(requestSpec, responseSpec);
protected ClientHelper clientHelper = new ClientHelper(requestSpec, responseSpec); protected ClientHelper clientHelper = new ClientHelper(requestSpec, responseSpec);
@@ -44,7 +44,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper final PostLoanProductsResponse loanProductsResponse = loanProductHelper
.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true) .createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT) .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)); .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId()); .retrieveLoanProductById(loanProductsResponse.getResourceId());
@@ -80,7 +82,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper final PostLoanProductsResponse loanProductsResponse = loanProductHelper
.createLoanProduct(create4IProgressive().enableIncomeCapitalization(false) .createLoanProduct(create4IProgressive().enableIncomeCapitalization(false)
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT) .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)); .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId()); .retrieveLoanProductById(loanProductsResponse.getResourceId());
@@ -114,7 +118,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper final PostLoanProductsResponse loanProductsResponse = loanProductHelper
.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true) .createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT) .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)); .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId()); .retrieveLoanProductById(loanProductsResponse.getResourceId());
@@ -125,9 +131,12 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
Assertions.assertNotNull(loanProductsProductIdResponse.getCapitalizedIncomeStrategy()); Assertions.assertNotNull(loanProductsProductIdResponse.getCapitalizedIncomeStrategy());
Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(), Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(),
loanProductsProductIdResponse.getCapitalizedIncomeStrategy().getCode()); loanProductsProductIdResponse.getCapitalizedIncomeStrategy().getCode());
Assertions.assertNotNull(loanProductsProductIdResponse.getAccountingMappings());
Assertions.assertEquals(feeIncomeAccount.getAccountID().longValue(),
loanProductsProductIdResponse.getAccountingMappings().getIncomeFromCapitalizationAccount().getId());
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(), loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(), new PutLoanProductsProductIdRequest()
new PutLoanProductsProductIdRequest().enableIncomeCapitalization(false)); .enableIncomeCapitalization(false).incomeFromCapitalizationAccountId(interestIncomeAccount.getAccountID().longValue()));
final GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper final GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId()); .retrieveLoanProductById(loanProductsResponse.getResourceId());
@@ -138,6 +147,9 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getCapitalizedIncomeStrategy()); Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getCapitalizedIncomeStrategy());
Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(), Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(),
updatedLoanProductsProductIdResponse.getCapitalizedIncomeStrategy().getCode()); updatedLoanProductsProductIdResponse.getCapitalizedIncomeStrategy().getCode());
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getAccountingMappings());
Assertions.assertEquals(interestIncomeAccount.getAccountID().longValue(),
updatedLoanProductsProductIdResponse.getAccountingMappings().getIncomeFromCapitalizationAccount().getId());
} }
@Test @Test
@@ -147,21 +159,45 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
() -> loanProductHelper.createLoanProduct(createOnePeriod30DaysPeriodicAccrualProduct(7.0) () -> loanProductHelper.createLoanProduct(createOnePeriod30DaysPeriodicAccrualProduct(7.0)
.enableIncomeCapitalization(true) .enableIncomeCapitalization(true)
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT) .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION))); .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())));
} }
@Test @Test
public void testIncomeCapitalizationEnabledCalculationTypeNotProvided() { public void testIncomeCapitalizationEnabledCalculationTypeNotProvided() {
Assertions.assertThrows(RuntimeException.class, Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true) () -> loanProductHelper.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION))); .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())));
} }
@Test @Test
public void testIncomeCapitalizationEnabledStrategyNotProvided() { public void testIncomeCapitalizationEnabledStrategyNotProvided() {
Assertions.assertThrows(RuntimeException.class, Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true) () -> loanProductHelper.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT))); .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@Test
public void testIncomeCapitalizationEnabledDeferredIncomeLiabilityNotProvided() {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())));
}
@Test
public void testIncomeCapitalizationEnabledIncomeFromCapitalizationNotProvided() {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())));
} }
} }
} }