FINERACT-2311: Loan product - Buy down fees configuration

This commit is contained in:
adam.magyari
2025-06-24 15:06:54 +02:00
committed by Adam Saghy
parent 29d1ed3cd4
commit 1b1d6be956
23 changed files with 708 additions and 31 deletions
@@ -26,6 +26,9 @@ import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
@@ -237,4 +240,156 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())));
}
}
@Nested
public class BuyDownFeeTest {
@Test
public void testBuyDownFeeEnabled() {
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId());
Assertions.assertEquals(Boolean.TRUE, loanProductsProductIdResponse.getEnableBuyDownFee());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeCalculationType());
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
loanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeStrategy());
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
loanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeIncomeType());
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(),
loanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
runAt("20 December 2024", () -> {
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "20 December 2024",
430.0, 7.0, 6, null);
final GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
Assertions.assertEquals(Boolean.TRUE, loanDetails.getEnableBuyDownFee());
Assertions.assertNotNull(loanDetails.getBuyDownFeeCalculationType());
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(), loanDetails.getBuyDownFeeCalculationType().getCode());
Assertions.assertNotNull(loanDetails.getBuyDownFeeStrategy());
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(), loanDetails.getBuyDownFeeStrategy().getCode());
Assertions.assertNotNull(loanDetails.getBuyDownFeeIncomeType());
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(), loanDetails.getBuyDownFeeIncomeType().getCode());
Assertions.assertDoesNotThrow(() -> disburseLoan(loanId, BigDecimal.valueOf(430), "20 December 2024"));
});
}
@Test
public void testBuyDownFeeDisabled() {
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
.enableBuyDownFee(false).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId());
Assertions.assertEquals(Boolean.FALSE, loanProductsProductIdResponse.getEnableBuyDownFee());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeCalculationType());
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
loanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeStrategy());
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
loanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeIncomeType());
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(),
loanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
runAt("20 December 2024", () -> {
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "20 December 2024",
430.0, 7.0, 6, null);
final GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
Assertions.assertEquals(Boolean.FALSE, loanDetails.getEnableBuyDownFee());
Assertions.assertNotNull(loanDetails.getBuyDownFeeCalculationType());
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(), loanDetails.getBuyDownFeeCalculationType().getCode());
Assertions.assertNotNull(loanDetails.getBuyDownFeeStrategy());
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(), loanDetails.getBuyDownFeeStrategy().getCode());
Assertions.assertNotNull(loanDetails.getBuyDownFeeIncomeType());
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(), loanDetails.getBuyDownFeeIncomeType().getCode());
Assertions.assertDoesNotThrow(() -> disburseLoan(loanId, BigDecimal.valueOf(430), "20 December 2024"));
});
}
@Test
public void testBuyDownFeeUpdateProduct() {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId());
Assertions.assertEquals(Boolean.TRUE, loanProductsProductIdResponse.getEnableBuyDownFee());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeCalculationType());
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
loanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeStrategy());
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
loanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeIncomeType());
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(),
loanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(), new PutLoanProductsProductIdRequest()
.enableBuyDownFee(false).buyDownFeeIncomeType(PutLoanProductsProductIdRequest.BuyDownFeeIncomeTypeEnum.INTEREST));
final GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductsResponse.getResourceId());
Assertions.assertEquals(Boolean.FALSE, updatedLoanProductsProductIdResponse.getEnableBuyDownFee());
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeCalculationType());
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
updatedLoanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeStrategy());
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
updatedLoanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType());
Assertions.assertEquals(LoanBuyDownFeeIncomeType.INTEREST.getCode(),
updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
}
@Test
public void testBuyDownFeeCumulativeNotSupported() {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(createOnePeriod30DaysPeriodicAccrualProduct(7.0).enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
}
@Test
public void testBuyDownFeeEnabledCalculationTypeNotProvided() {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
}
@Test
public void testBuyDownFeeEnabledStrategyNotProvided() {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
}
@Test
public void testBuyDownFeeEnabledIncomeTypeNotProvided() {
Assertions.assertThrows(RuntimeException.class,
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)));
}
}
}