FINERACT-2347: Introduce classification field on loan transactions

This commit is contained in:
Jose Alberto Hernandez
2025-09-03 11:43:06 +02:00
committed by Adam Saghy
parent 9ba17bf79a
commit 65538495aa
27 changed files with 442 additions and 21 deletions
@@ -29,10 +29,14 @@ import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.fineract.client.models.CapitalizedIncomeDetails;
import org.apache.fineract.client.models.GetCodesResponse;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
import org.apache.fineract.client.models.LoanCapitalizedIncomeData;
import org.apache.fineract.client.models.PostClientsResponse;
import org.apache.fineract.client.models.PostCodeValueDataResponse;
import org.apache.fineract.client.models.PostCodeValuesDataRequest;
import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
@@ -45,6 +49,7 @@ import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.externalevents.LoanAdjustTransactionBusinessEvent;
import org.apache.fineract.integrationtests.common.externalevents.LoanBusinessEvent;
import org.apache.fineract.integrationtests.common.externalevents.LoanTransactionBusinessEvent;
import org.apache.fineract.portfolio.loanaccount.api.LoanTransactionApiConstants;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -185,6 +190,11 @@ public class LoanCapitalizedIncomeTest extends BaseLoanIntegrationTest {
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())
.capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE));
final GetCodesResponse code = codeHelper.retrieveCodeByName(LoanTransactionApiConstants.CAPITALIZED_INCOME_CLASSIFICATION_CODE);
final PostCodeValueDataResponse classificationCode = codeHelper.createCodeValue(code.getId(),
new PostCodeValuesDataRequest().name(Utils.uniqueRandomStringGenerator("CLASS_", 6)).isActive(true).position(10));
final Long classificationId = classificationCode.getSubResourceId();
runAt("1 April 2024", () -> {
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "1 January 2024",
500.0, 7.0, 3, null);
@@ -192,9 +202,15 @@ public class LoanCapitalizedIncomeTest extends BaseLoanIntegrationTest {
disburseLoan(loanId, BigDecimal.valueOf(100), "1 January 2024");
PostLoansLoanIdTransactionsResponse capitalizedIncomeResponse = loanTransactionHelper.addCapitalizedIncome(loanId,
"1 January 2024", 50.0);
"1 January 2024", 50.0, classificationId);
capitalizedIncomeIdRef.set(capitalizedIncomeResponse.getResourceId());
// Validate Loan Transaction classification set value
GetLoansLoanIdTransactionsTransactionIdResponse transactionDetails = loanTransactionHelper.getLoanTransactionDetails(loanId,
capitalizedIncomeIdRef.get());
assertNotNull(transactionDetails.getClassification());
assertEquals(classificationId, transactionDetails.getClassification().getId());
PostLoansLoanIdTransactionsResponse capitalizedIncomeAdjustmentResponse = loanTransactionHelper
.capitalizedIncomeAdjustment(loanId, capitalizedIncomeIdRef.get(), "1 April 2024", 50.0);
assertNotNull(capitalizedIncomeAdjustmentResponse.getLoanId());
@@ -222,6 +238,12 @@ public class LoanCapitalizedIncomeTest extends BaseLoanIntegrationTest {
journalEntry(49.71, loansReceivableAccount, "CREDIT"), //
journalEntry(0.29, interestReceivableAccount, "CREDIT") //
);
// Validate Loan Transaction classification Inherit
transactionDetails = loanTransactionHelper.getLoanTransactionDetails(loanId,
capitalizedIncomeAdjustmentResponse.getResourceId());
assertNotNull(transactionDetails.getClassification());
assertEquals(classificationId, transactionDetails.getClassification().getId());
});
}
@@ -26,15 +26,20 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.GetCodesResponse;
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsResponse;
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTemplateResponse;
import org.apache.fineract.client.models.PostClientsResponse;
import org.apache.fineract.client.models.PostCodeValueDataResponse;
import org.apache.fineract.client.models.PostCodeValuesDataRequest;
import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
import org.apache.fineract.client.models.TransactionType;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.portfolio.loanaccount.api.LoanTransactionApiConstants;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -103,6 +108,9 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest {
@Test
public void testGetLoanTransactionTemplateForCapitalizedIncomeWithOverAppliedAmount() {
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
final GetCodesResponse code = codeHelper.retrieveCodeByName(LoanTransactionApiConstants.CAPITALIZED_INCOME_CLASSIFICATION_CODE);
final PostCodeValueDataResponse classificationCode = codeHelper.createCodeValue(code.getId(),
new PostCodeValuesDataRequest().name(Utils.uniqueRandomStringGenerator("CLASS_", 6)).isActive(true).position(10));
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
@@ -127,6 +135,7 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest {
assertEquals("loanTransactionType." + capitalizedIncomeCommand, transactionTemplate.getType().getCode());
assertEquals(transactionTemplate.getAmount(), 415);
assertThat(transactionTemplate.getPaymentTypeOptions().size() > 0);
assertThat(transactionTemplate.getClassificationOptions().size() > 0);
});
}
@@ -242,6 +251,9 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest {
@Test
public void testGetLoanTransactionTemplateForBuyDownFee() {
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
final GetCodesResponse code = codeHelper.retrieveCodeByName(LoanTransactionApiConstants.BUY_DOWN_FEE_CLASSIFICATION_CODE);
final PostCodeValueDataResponse classificationCode = codeHelper.createCodeValue(code.getId(),
new PostCodeValuesDataRequest().name(Utils.uniqueRandomStringGenerator("CLASS_", 6)).isActive(true).position(10));
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
@@ -266,6 +278,7 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest {
assertEquals("loanTransactionType." + buyDownFeeCommand, transactionTemplate.getType().getCode());
assertEquals(transactionTemplate.getAmount(), 0);
assertThat(transactionTemplate.getPaymentTypeOptions().size() > 0);
assertThat(transactionTemplate.getClassificationOptions().size() > 0);
});
}
}
@@ -930,6 +930,12 @@ public class LoanTransactionHelper {
.transactionDate(transactionDate).dateFormat("dd MMMM yyyy").locale("en"));
}
public PostLoansLoanIdTransactionsResponse addCapitalizedIncome(final Long loanId, final String transactionDate, final double amount,
final Long classificationId) {
return addCapitalizedIncome(loanId, new PostLoansLoanIdTransactionsRequest().transactionAmount(amount)
.transactionDate(transactionDate).dateFormat("dd MMMM yyyy").locale("en").classificationId(classificationId));
}
public Response<CommandProcessingResult> createInterestPause(Long loanId, String startDate, String endDate) {
log.info("Creating interest pause for Loan {} from {} to {}", loanId, startDate, endDate);
return Calls.executeU(FineractClientHelper.getFineractClient().loanInterestPauseApi.createInterestPause(loanId,
@@ -388,4 +388,8 @@ public final class CodeHelper {
public List<GetCodesResponse> retrieveCodes() {
return Calls.ok(FineractClientHelper.getFineractClient().codes.retrieveCodes());
}
public GetCodesResponse retrieveCodeByName(final String codeName) {
return Calls.ok(FineractClientHelper.getFineractClient().codes.retrieveCodeByName(codeName));
}
}