blob: d2a29aa94ab3e187cd153bf98fc7bfe4798fbc9f [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.integrationtests;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import com.google.gson.Gson;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.BusinessDateRequest;
import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO;
import org.apache.fineract.integrationtests.common.BusinessStepHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.ExternalEventConfigurationHelper;
import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
import org.apache.fineract.integrationtests.common.externalevents.ExternalEventHelper;
import org.apache.fineract.integrationtests.common.externalevents.ExternalEventsExtension;
import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@Slf4j
@ExtendWith({ LoanTestLifecycleExtension.class, ExternalEventsExtension.class })
public class CustomSnapshotEventIntegrationTest extends BaseLoanIntegrationTest {
private SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(this.requestSpec);
@Test
public void testSnapshotEventGenerationWhenLoanInstallmentIsNotPayed() {
runAt("31 January 2023", () -> {
// Enable Business Step
enableCOBBusinessStep("APPLY_CHARGE_TO_OVERDUE_LOANS", "LOAN_DELINQUENCY_CLASSIFICATION", "CHECK_LOAN_REPAYMENT_DUE",
"CHECK_LOAN_REPAYMENT_OVERDUE", "UPDATE_LOAN_ARREARS_AGING", "ADD_PERIODIC_ACCRUAL_ENTRIES",
"EXTERNAL_ASSET_OWNER_TRANSFER", "CHECK_DUE_INSTALLMENTS");
enableLoanAccountCustomSnapshotBusinessEvent();
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
PostLoanProductsRequest loanProductsRequest = create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(loanProductsRequest);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductResponse.getResourceId(), "01 January 2023", 1250.0, 4);
// Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(1250), "01 January 2023");
// Verify Repayment Schedule and Due Dates
verifyRepaymentSchedule(loanId, //
installment(0, null, "01 January 2023"), //
installment(313.0, false, "31 January 2023"), //
installment(313.0, false, "02 March 2023"), //
installment(313.0, false, "01 April 2023"), //
installment(311.0, false, "01 May 2023") //
);
// delete all external events
deleteAllExternalEvents();
// run cob
updateBusinessDateAndExecuteCOBJob("01 February 2023");
// verify external events
List<ExternalEventDTO> allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec);
Assertions.assertEquals(1, allExternalEvents.size());
Assertions.assertEquals("LoanAccountCustomSnapshotBusinessEvent", allExternalEvents.get(0).getType());
Assertions.assertEquals(loanId, allExternalEvents.get(0).getAggregateRootId());
});
}
@Test
public void testNoSnapshotEventGenerationWhenLoanInstallmentIsPayed() {
runAt("31 January 2023", () -> {
// Enable Business Step
enableCOBBusinessStep("APPLY_CHARGE_TO_OVERDUE_LOANS", "LOAN_DELINQUENCY_CLASSIFICATION", "CHECK_LOAN_REPAYMENT_DUE",
"CHECK_LOAN_REPAYMENT_OVERDUE", "UPDATE_LOAN_ARREARS_AGING", "ADD_PERIODIC_ACCRUAL_ENTRIES",
"EXTERNAL_ASSET_OWNER_TRANSFER", "CHECK_DUE_INSTALLMENTS");
enableLoanAccountCustomSnapshotBusinessEvent();
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
PostLoanProductsRequest loanProductsRequest = create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(loanProductsRequest);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductResponse.getResourceId(), "01 January 2023", 1250.0, 4);
// Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(1250), "01 January 2023");
// Verify Repayment Schedule and Due Dates
verifyRepaymentSchedule(loanId, //
installment(0, null, "01 January 2023"), //
installment(313.0, false, "31 January 2023"), //
installment(313.0, false, "02 March 2023"), //
installment(313.0, false, "01 April 2023"), //
installment(311.0, false, "01 May 2023") //
);
addRepaymentForLoan(loanId, 313.0, "31 January 2023");
// Verify Repayment Schedule and Due Dates
verifyRepaymentSchedule(loanId, //
installment(0, null, "01 January 2023"), //
installment(313.0, true, "31 January 2023"), //
installment(313.0, false, "02 March 2023"), //
installment(313.0, false, "01 April 2023"), //
installment(311.0, false, "01 May 2023") //
);
// delete all external events
deleteAllExternalEvents();
// run cob
updateBusinessDateAndExecuteCOBJob("01 February 2023");
// verify external events
List<ExternalEventDTO> allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec);
Assertions.assertEquals(0, allExternalEvents.size());
});
}
@Test
public void testNoSnapshotEventGenerationWhenWhenCustomSnapshotEventCOBTaskIsNotActive() {
runAt("31 January 2023", () -> {
// Enable Business Step
enableCOBBusinessStep("APPLY_CHARGE_TO_OVERDUE_LOANS", "LOAN_DELINQUENCY_CLASSIFICATION", "CHECK_LOAN_REPAYMENT_DUE",
"CHECK_LOAN_REPAYMENT_OVERDUE", "UPDATE_LOAN_ARREARS_AGING", "ADD_PERIODIC_ACCRUAL_ENTRIES",
"EXTERNAL_ASSET_OWNER_TRANSFER");
enableLoanAccountCustomSnapshotBusinessEvent();
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
PostLoanProductsRequest loanProductsRequest = create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(loanProductsRequest);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductResponse.getResourceId(), "01 January 2023", 1250.0, 4);
// Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(1250), "01 January 2023");
// Verify Repayment Schedule and Due Dates
verifyRepaymentSchedule(loanId, //
installment(0, null, "01 January 2023"), //
installment(313.0, false, "31 January 2023"), //
installment(313.0, false, "02 March 2023"), //
installment(313.0, false, "01 April 2023"), //
installment(311.0, false, "01 May 2023") //
);
// delete all external events
deleteAllExternalEvents();
// run cob
updateBusinessDateAndExecuteCOBJob("01 February 2023");
// verify external events
List<ExternalEventDTO> allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec);
Assertions.assertEquals(0, allExternalEvents.size());
});
}
@Test
public void testNoSnapshotEventGenerationWhenCOBDateIsNotMatchingWithInstallmentDueDate() {
runAt("30 January 2023", () -> {
// Enable Business Step
enableCOBBusinessStep("APPLY_CHARGE_TO_OVERDUE_LOANS", "LOAN_DELINQUENCY_CLASSIFICATION", "CHECK_LOAN_REPAYMENT_DUE",
"CHECK_LOAN_REPAYMENT_OVERDUE", "UPDATE_LOAN_ARREARS_AGING", "ADD_PERIODIC_ACCRUAL_ENTRIES",
"EXTERNAL_ASSET_OWNER_TRANSFER", "CHECK_DUE_INSTALLMENTS");
enableLoanAccountCustomSnapshotBusinessEvent();
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
PostLoanProductsRequest loanProductsRequest = create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(loanProductsRequest);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductResponse.getResourceId(), "01 January 2023", 1250.0, 4);
// Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(1250), "01 January 2023");
// Verify Repayment Schedule and Due Dates
verifyRepaymentSchedule(loanId, //
installment(0, null, "01 January 2023"), //
installment(313.0, false, "31 January 2023"), //
installment(313.0, false, "02 March 2023"), //
installment(313.0, false, "01 April 2023"), //
installment(311.0, false, "01 May 2023") //
);
// delete all external events
deleteAllExternalEvents();
// run cob
updateBusinessDateAndExecuteCOBJob("31 January 2023");
// verify external events
List<ExternalEventDTO> allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec);
Assertions.assertEquals(0, allExternalEvents.size());
});
}
@Test
public void testNoSnapshotEventGenerationWhenCustomSnapshotEventIsDisabled() {
runAt("31 January 2023", () -> {
// Enable Business Step
enableCOBBusinessStep("APPLY_CHARGE_TO_OVERDUE_LOANS", "LOAN_DELINQUENCY_CLASSIFICATION", "CHECK_LOAN_REPAYMENT_DUE",
"CHECK_LOAN_REPAYMENT_OVERDUE", "UPDATE_LOAN_ARREARS_AGING", "ADD_PERIODIC_ACCRUAL_ENTRIES",
"EXTERNAL_ASSET_OWNER_TRANSFER", "CHECK_DUE_INSTALLMENTS");
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
PostLoanProductsRequest loanProductsRequest = create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(loanProductsRequest);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductResponse.getResourceId(), "01 January 2023", 1250.0, 4);
// Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(1250), "01 January 2023");
// Verify Repayment Schedule and Due Dates
verifyRepaymentSchedule(loanId, //
installment(0, null, "01 January 2023"), //
installment(313.0, false, "31 January 2023"), //
installment(313.0, false, "02 March 2023"), //
installment(313.0, false, "01 April 2023"), //
installment(311.0, false, "01 May 2023") //
);
// delete all external events
deleteAllExternalEvents();
// run cob
updateBusinessDateAndExecuteCOBJob("01 February 2023");
// verify external events
List<ExternalEventDTO> allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec);
Assertions.assertEquals(0, allExternalEvents.size());
});
}
private void deleteAllExternalEvents() {
ExternalEventHelper.deleteAllExternalEvents(requestSpec, createResponseSpecification(Matchers.is(204)));
List<ExternalEventDTO> allExternalEvents = ExternalEventHelper.getAllExternalEvents(requestSpec, responseSpec);
Assertions.assertEquals(0, allExternalEvents.size());
}
private void enableCOBBusinessStep(String... steps) {
new BusinessStepHelper().updateSteps("LOAN_CLOSE_OF_BUSINESS", steps);
}
public static String getExternalEventConfigurationsForUpdateJSON() {
Map<String, Map<String, Boolean>> configurationsForUpdate = new HashMap<>();
Map<String, Boolean> configurations = new HashMap<>();
configurations.put("CentersCreateBusinessEvent", true);
configurations.put("ClientActivateBusinessEvent", true);
configurationsForUpdate.put("externalEventConfigurations", configurations);
return new Gson().toJson(configurationsForUpdate);
}
private void enableLoanAccountCustomSnapshotBusinessEvent() {
final Map<String, Boolean> updatedConfigurations = ExternalEventConfigurationHelper.updateExternalEventConfigurations(requestSpec,
responseSpec, "{\"externalEventConfigurations\":{\"LoanAccountCustomSnapshotBusinessEvent\":true}}\n");
Assertions.assertEquals(updatedConfigurations.size(), 1);
Assertions.assertTrue(updatedConfigurations.containsKey("LoanAccountCustomSnapshotBusinessEvent"));
Assertions.assertTrue(updatedConfigurations.get("LoanAccountCustomSnapshotBusinessEvent"));
}
private void updateBusinessDateAndExecuteCOBJob(String date) {
businessDateHelper.updateBusinessDate(
new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
schedulerJobHelper.executeAndAwaitJob("Loan COB");
}
}