| /** |
| * 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"); |
| } |
| |
| } |