From 38f537ea8a04e682db277c0f7fb522cf18bf377a Mon Sep 17 00:00:00 2001 From: Peter Kovacs Date: Wed, 2 Aug 2023 15:00:46 +0200 Subject: [PATCH] FINERACT-1724 Loan account lock API fix --- .../fineract/client/util/FineractClient.java | 3 + .../cob/api/LoanAccountLockApiResource.java | 14 +- .../ClientLoanAccountLockIntegrationTest.java | 134 ++++++++++++++++++ .../integrationtests/common/ClientHelper.java | 5 + 4 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanAccountLockIntegrationTest.java diff --git a/fineract-client/src/main/java/org/apache/fineract/client/util/FineractClient.java b/fineract-client/src/main/java/org/apache/fineract/client/util/FineractClient.java index 9df4eced1..a91363c1c 100644 --- a/fineract-client/src/main/java/org/apache/fineract/client/util/FineractClient.java +++ b/fineract-client/src/main/java/org/apache/fineract/client/util/FineractClient.java @@ -82,6 +82,7 @@ import org.apache.fineract.client.services.InterestRateChartApi; import org.apache.fineract.client.services.InterestRateSlabAKAInterestBandsApi; import org.apache.fineract.client.services.JournalEntriesApi; import org.apache.fineract.client.services.ListReportMailingJobHistoryApi; +import org.apache.fineract.client.services.LoanAccountLockApi; import org.apache.fineract.client.services.LoanChargesApi; import org.apache.fineract.client.services.LoanCobCatchUpApi; import org.apache.fineract.client.services.LoanCollateralApi; @@ -290,11 +291,13 @@ public final class FineractClient { public final WorkingDaysApi workingDays; public final ExternalAssetOwnersApi externalAssetOwners; + public final LoanAccountLockApi loanAccountLockApi; private FineractClient(OkHttpClient okHttpClient, Retrofit retrofit) { this.okHttpClient = okHttpClient; this.retrofit = retrofit; + loanAccountLockApi = retrofit.create(LoanAccountLockApi.class); externalAssetOwners = retrofit.create(ExternalAssetOwnersApi.class); glClosures = retrofit.create(AccountingClosureApi.class); accountingRules = retrofit.create(AccountingRulesApi.class); diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/api/LoanAccountLockApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/cob/api/LoanAccountLockApiResource.java index 4646f33d2..45c9d6e56 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/api/LoanAccountLockApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/api/LoanAccountLockApiResource.java @@ -19,7 +19,6 @@ package org.apache.fineract.cob.api; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -64,15 +63,14 @@ public class LoanAccountLockApiResource { @Produces({ MediaType.APPLICATION_JSON }) @Operation(summary = "List locked loan accounts", description = "Returns the locked loan IDs") @ApiResponses({ - @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = LoanAccountLockApiResourceSwagger.GetLoanAccountLockResponse.class)))) }) - public String retrieveLockedAccounts(@Context final UriInfo uriInfo, @QueryParam("page") String page, - @QueryParam("limit") String limit) { + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoanAccountLockApiResourceSwagger.GetLoanAccountLockResponse.class))) }) + public String retrieveLockedAccounts(@Context final UriInfo uriInfo, @QueryParam("page") Integer page, + @QueryParam("limit") Integer limit) { - List lockedLoanAccounts = loanAccountLockService.getLockedLoanAccountByPage(Integer.parseInt(page), - Integer.parseInt(limit)); + List lockedLoanAccounts = loanAccountLockService.getLockedLoanAccountByPage(page, limit); LoanAccountLockResponseDTO response = new LoanAccountLockResponseDTO(); - response.setPage(Integer.parseInt(page)); - response.setLimit(Integer.parseInt(limit)); + response.setPage(page); + response.setLimit(limit); response.setContent(lockedLoanAccounts); final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanAccountLockIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanAccountLockIntegrationTest.java new file mode 100644 index 000000000..b9c8508da --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanAccountLockIntegrationTest.java @@ -0,0 +1,134 @@ +/** + * 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 io.restassured.builder.RequestSpecBuilder; +import io.restassured.builder.ResponseSpecBuilder; +import io.restassured.http.ContentType; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import org.apache.fineract.client.models.GetLoanAccountLockResponse; +import org.apache.fineract.integrationtests.common.ClientHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.accounting.Account; +import org.apache.fineract.integrationtests.common.loans.LoanAccountLockHelper; +import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; +import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder; +import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker; +import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension; +import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings({ "rawtypes", "unchecked" }) +@ExtendWith(LoanTestLifecycleExtension.class) +public class ClientLoanAccountLockIntegrationTest { + + private static final Logger LOG = LoggerFactory.getLogger(ClientLoanAccountLockIntegrationTest.class); + + public static final String MINIMUM_OPENING_BALANCE = "1000.0"; + public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL"; + private static final String NONE = "1"; + + private ResponseSpecification responseSpec; + private RequestSpecification requestSpec; + private ClientHelper clientHelper; + private LoanTransactionHelper loanTransactionHelper; + private LoanAccountLockHelper loanAccountLockHelper; + + @BeforeEach + public void setup() { + Utils.initializeRESTAssured(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec); + this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); + loanAccountLockHelper = new LoanAccountLockHelper(requestSpec, new ResponseSpecBuilder().expectStatusCode(202).build()); + } + + @Test + public void checkRetrieveLockedLoanAccountsList() { + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + final Integer loanProductID = createLoanProduct(false, NONE); + + List collaterals = new ArrayList<>(); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, null, null, "12,000.00", collaterals); + HashMap loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 2011", loanID, "12,000.00"); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + loanAccountLockHelper.placeSoftLockOnLoanAccount(loanID, "LOAN_INLINE_COB_PROCESSING", "Sample error"); + + GetLoanAccountLockResponse getLoanAccountLockResponse = clientHelper.retrieveLockedAccounts(0, 1000); + Assertions.assertTrue(getLoanAccountLockResponse.getContent().size() > 0); + Assertions.assertTrue(getLoanAccountLockResponse.getContent().stream() + .anyMatch(loanAccountLock -> loanAccountLock.getLoanId().equals(Long.valueOf(loanID)))); + } + + private Integer createLoanProduct(final boolean multiDisburseLoan, final String accountingRule, final Account... accounts) { + LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------"); + LoanProductTestBuilder builder = new LoanProductTestBuilder() // + .withPrincipal("12,000.00") // + .withNumberOfRepayments("4") // + .withRepaymentAfterEvery("1") // + .withRepaymentTypeAsMonth() // + .withinterestRatePerPeriod("1") // + .withInterestRateFrequencyTypeAsMonths() // + .withAmortizationTypeAsEqualInstallments() // + .withInterestTypeAsDecliningBalance() // + .withTranches(multiDisburseLoan) // + .withAccounting(accountingRule, accounts); + if (multiDisburseLoan) { + builder = builder.withInterestCalculationPeriodTypeAsRepaymentPeriod(true); + } + final String loanProductJSON = builder.build(null); + return this.loanTransactionHelper.getLoanProductId(loanProductJSON); + } + + private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID, List charges, + final String savingsId, String principal, List collaterals) { + LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); + final String loanApplicationJSON = new LoanApplicationTestBuilder() // + .withPrincipal(principal) // + .withLoanTermFrequency("4") // + .withLoanTermFrequencyAsMonths() // + .withNumberOfRepayments("4") // + .withRepaymentEveryAfter("1") // + .withRepaymentFrequencyTypeAsMonths() // + .withInterestRatePerPeriod("2") // + .withAmortizationTypeAsEqualInstallments() // + .withInterestTypeAsDecliningBalance() // + .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() // + .withExpectedDisbursementDate("20 September 2011") // + .withSubmittedOnDate("20 September 2011") // + .withCollaterals(collaterals).withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId); + return this.loanTransactionHelper.getLoanId(loanApplicationJSON); + } +} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ClientHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ClientHelper.java index 4c18dbd71..642783afb 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ClientHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ClientHelper.java @@ -46,6 +46,7 @@ import org.apache.fineract.client.models.GetClientsClientIdAccountsResponse; import org.apache.fineract.client.models.GetClientsClientIdResponse; import org.apache.fineract.client.models.GetClientsClientIdTransactionsResponse; import org.apache.fineract.client.models.GetClientsClientIdTransactionsTransactionIdResponse; +import org.apache.fineract.client.models.GetLoanAccountLockResponse; import org.apache.fineract.client.models.GetObligeeData; import org.apache.fineract.client.models.PageClientSearchData; import org.apache.fineract.client.models.PagedRequestClientTextSearch; @@ -871,4 +872,8 @@ public class ClientHelper extends IntegrationTest { .externalId(UUID.randomUUID().toString()).dateFormat(Utils.DATE_FORMAT).locale("en").active(true) .activationDate(DEFAULT_DATE); } + + public GetLoanAccountLockResponse retrieveLockedAccounts(int page, int limit) { + return ok(fineract().loanAccountLockApi.retrieveLockedAccounts(page, limit)); + } }