diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQueryDataValidator.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQueryDataValidator.java deleted file mode 100644 index b52fedfb6ff..00000000000 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQueryDataValidator.java +++ /dev/null @@ -1,321 +0,0 @@ -/** - * 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.portfolio.search.data; - -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.apache.fineract.infrastructure.core.data.ApiParameterError; -import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; -import org.apache.fineract.infrastructure.core.exception.InvalidJsonException; -import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; -import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; -import org.apache.fineract.infrastructure.security.service.SqlValidator; -import org.springframework.stereotype.Component; - -@Slf4j -@RequiredArgsConstructor -@Component -public class AdHocQueryDataValidator { - - private final SqlValidator sqlValidator; - private final FromJsonHelper fromApiJsonHelper; - private static final Set AD_HOC_SEARCH_QUERY_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList( - AdHocQuerySearchConstants.entitiesParamName, AdHocQuerySearchConstants.loanStatusParamName, - AdHocQuerySearchConstants.loanProductsParamName, AdHocQuerySearchConstants.officesParamName, - AdHocQuerySearchConstants.loanDateOptionParamName, AdHocQuerySearchConstants.loanFromDateParamName, - AdHocQuerySearchConstants.loanToDateParamName, AdHocQuerySearchConstants.includeOutStandingAmountPercentageParamName, - AdHocQuerySearchConstants.outStandingAmountPercentageConditionParamName, - AdHocQuerySearchConstants.minOutStandingAmountPercentageParamName, - AdHocQuerySearchConstants.maxOutStandingAmountPercentageParamName, - AdHocQuerySearchConstants.outStandingAmountPercentageParamName, AdHocQuerySearchConstants.includeOutstandingAmountParamName, - AdHocQuerySearchConstants.outstandingAmountConditionParamName, AdHocQuerySearchConstants.minOutstandingAmountParamName, - AdHocQuerySearchConstants.maxOutstandingAmountParamName, AdHocQuerySearchConstants.outstandingAmountParamName, - AdHocQuerySearchConstants.localeParamName, AdHocQuerySearchConstants.dateFormatParamName)); - - private static final Set AD_HOC_SEARCH_QUERY_CONDITIONS = new HashSet<>(Arrays.asList("between", "<=", ">=", "<", ">", "=")); - - private static final Object[] loanDateOptions = { AdHocQuerySearchConstants.approvalDateOption, - AdHocQuerySearchConstants.createDateOption, AdHocQuerySearchConstants.disbursalDateOption }; - - private static final Object[] loanStatusOptions = { AdHocQuerySearchConstants.allLoanStatusOption, - AdHocQuerySearchConstants.activeLoanStatusOption, AdHocQuerySearchConstants.overpaidLoanStatusOption, - AdHocQuerySearchConstants.arrearsLoanStatusOption, AdHocQuerySearchConstants.closedLoanStatusOption, - AdHocQuerySearchConstants.writeoffLoanStatusOption }; - - public void validateAdHocQueryParameters(final String json) { - - if (StringUtils.isBlank(json)) { - throw new InvalidJsonException(); - } - - final Type typeOfMap = new TypeToken>() {}.getType(); - this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, AD_HOC_SEARCH_QUERY_REQUEST_DATA_PARAMETERS); - - final JsonElement element = this.fromApiJsonHelper.parse(json); - - final List dataValidationErrors = new ArrayList<>(); - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) - .resource(AdHocQuerySearchConstants.AD_HOC_SEARCH_QUERY_RESOURCE_NAME); - - final String[] entities = this.fromApiJsonHelper.extractArrayNamed(AdHocQuerySearchConstants.entitiesParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.entitiesParamName).value(entities).arrayNotEmpty(); - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanStatusParamName, element)) { - final String[] loanStatus = this.fromApiJsonHelper.extractArrayNamed(AdHocQuerySearchConstants.loanStatusParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.loanStatusParamName).value(loanStatus).arrayNotEmpty(); - if (loanStatus != null && loanStatus.length > 0) { - for (String status : loanStatus) { - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.loanStatusParamName).value(status) - .isOneOfTheseValues(loanStatusOptions); - } - } - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanProductsParamName, element)) { - final String[] loanProducts = this.fromApiJsonHelper.extractArrayNamed(AdHocQuerySearchConstants.loanProductsParamName, - element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.loanProductsParamName).value(loanProducts).arrayNotEmpty(); - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.officesParamName, element)) { - final String[] offices = this.fromApiJsonHelper.extractArrayNamed(AdHocQuerySearchConstants.officesParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.officesParamName).value(offices).arrayNotEmpty(); - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanDateOptionParamName, element)) { - final String loanDateOption = this.fromApiJsonHelper.extractStringNamed(AdHocQuerySearchConstants.loanDateOptionParamName, - element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.loanDateOptionParamName).value(loanDateOption) - .isOneOfTheseValues(loanDateOptions); - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanFromDateParamName, element)) { - final LocalDate loanFromDate = this.fromApiJsonHelper.extractLocalDateNamed(AdHocQuerySearchConstants.loanFromDateParamName, - element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.loanFromDateParamName).value(loanFromDate).notNull(); - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanToDateParamName, element)) { - final LocalDate loanToDate = this.fromApiJsonHelper.extractLocalDateNamed(AdHocQuerySearchConstants.loanToDateParamName, - element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.loanToDateParamName).value(loanToDate).notNull(); - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.includeOutStandingAmountPercentageParamName, element)) { - final boolean includeOutStandingAmountPercentage = this.fromApiJsonHelper - .extractBooleanNamed(AdHocQuerySearchConstants.includeOutStandingAmountPercentageParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.includeOutStandingAmountPercentageParamName) - .value(includeOutStandingAmountPercentage).notNull(); - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.outStandingAmountPercentageConditionParamName, element)) { - final String outStandingAmountPercentageCondition = this.fromApiJsonHelper - .extractStringNamed(AdHocQuerySearchConstants.outStandingAmountPercentageConditionParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.outStandingAmountPercentageConditionParamName) - .value(outStandingAmountPercentageCondition).isNotOneOfTheseValues(AD_HOC_SEARCH_QUERY_CONDITIONS); - if (outStandingAmountPercentageCondition.equals("between")) { - final BigDecimal minOutStandingAmountPercentage = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.minOutStandingAmountPercentageParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.minOutStandingAmountPercentageParamName) - .value(minOutStandingAmountPercentage).notNull().notLessThanMin(BigDecimal.ZERO); - final BigDecimal maxOutStandingAmountPercentage = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.maxOutStandingAmountPercentageParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.maxOutStandingAmountPercentageParamName) - .value(maxOutStandingAmountPercentage).notNull().notLessThanMin(BigDecimal.ZERO); - baseDataValidator.reset().compareMinAndMaxOfTwoBigDecmimalNos(minOutStandingAmountPercentage, - maxOutStandingAmountPercentage); - } else { - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.outStandingAmountPercentageParamName, element)) { - final BigDecimal outStandingAmountPercentage = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.outStandingAmountPercentageParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.outStandingAmountPercentageParamName) - .value(outStandingAmountPercentage).notNull().notLessThanMin(BigDecimal.ZERO); - } - } - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.includeOutstandingAmountParamName, element)) { - final Boolean includeOutstandingAmountParamName = this.fromApiJsonHelper - .extractBooleanNamed(AdHocQuerySearchConstants.includeOutstandingAmountParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.includeOutstandingAmountParamName) - .value(includeOutstandingAmountParamName).notNull(); - } - - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.outstandingAmountConditionParamName, element)) { - final String outstandingAmountCondition = this.fromApiJsonHelper - .extractStringNamed(AdHocQuerySearchConstants.outstandingAmountConditionParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.outstandingAmountConditionParamName) - .value(outstandingAmountCondition).isNotOneOfTheseValues(AD_HOC_SEARCH_QUERY_CONDITIONS); - if (outstandingAmountCondition.equals("between")) { - final BigDecimal minOutstandingAmount = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.minOutstandingAmountParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.minOutstandingAmountParamName).value(minOutstandingAmount) - .notNull().notLessThanMin(BigDecimal.ZERO); - final BigDecimal maxOutstandingAmount = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.maxOutstandingAmountParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.maxOutstandingAmountParamName).value(maxOutstandingAmount) - .notNull().notLessThanMin(BigDecimal.ZERO); - baseDataValidator.reset().compareMinAndMaxOfTwoBigDecmimalNos(minOutstandingAmount, maxOutstandingAmount); - } else { - final BigDecimal outstandingAmount = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.outstandingAmountParamName, element); - baseDataValidator.reset().parameter(AdHocQuerySearchConstants.outstandingAmountParamName).value(outstandingAmount).notNull() - .notLessThanMin(BigDecimal.ZERO); - } - } - - throwExceptionIfValidationWarningsExist(dataValidationErrors); - - } - - private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException(dataValidationErrors); - } - } - - public AdHocQuerySearchConditions retrieveSearchConditions(String json) { - - validateAdHocQueryParameters(json); - - final JsonElement element = this.fromApiJsonHelper.parse(json); - - List loanStatus = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanStatusParamName, element)) { - loanStatus = Arrays.asList(this.fromApiJsonHelper.extractArrayNamed(AdHocQuerySearchConstants.loanStatusParamName, element)); - } - - List loanProducts = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanProductsParamName, element)) { - loanProducts = extractLongValuesList( - Arrays.asList(this.fromApiJsonHelper.extractArrayNamed(AdHocQuerySearchConstants.loanProductsParamName, element))); - } - - List offices = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.officesParamName, element)) { - offices = extractLongValuesList( - Arrays.asList(this.fromApiJsonHelper.extractArrayNamed(AdHocQuerySearchConstants.officesParamName, element))); - } - - String loanDateOption = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanDateOptionParamName, element)) { - loanDateOption = this.fromApiJsonHelper.extractStringNamed(AdHocQuerySearchConstants.loanDateOptionParamName, element); - sqlValidator.validate(loanDateOption); - } - - LocalDate loanFromDate = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanFromDateParamName, element)) { - loanFromDate = this.fromApiJsonHelper.extractLocalDateNamed(AdHocQuerySearchConstants.loanFromDateParamName, element); - } - - LocalDate loanToDate = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.loanToDateParamName, element)) { - loanToDate = this.fromApiJsonHelper.extractLocalDateNamed(AdHocQuerySearchConstants.loanToDateParamName, element); - } - - Boolean includeOutStandingAmountPercentage = false; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.includeOutStandingAmountPercentageParamName, element)) { - includeOutStandingAmountPercentage = this.fromApiJsonHelper - .extractBooleanNamed(AdHocQuerySearchConstants.includeOutStandingAmountPercentageParamName, element); - } - - String outStandingAmountPercentageCondition = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.outStandingAmountPercentageConditionParamName, element)) { - outStandingAmountPercentageCondition = this.fromApiJsonHelper - .extractStringNamed(AdHocQuerySearchConstants.outStandingAmountPercentageConditionParamName, element); - sqlValidator.validate(outStandingAmountPercentageCondition); - } - - BigDecimal minOutStandingAmountPercentage = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.minOutStandingAmountPercentageParamName, element)) { - minOutStandingAmountPercentage = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.minOutStandingAmountPercentageParamName, element); - } - - BigDecimal maxOutStandingAmountPercentage = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.maxOutStandingAmountPercentageParamName, element)) { - maxOutStandingAmountPercentage = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.maxOutStandingAmountPercentageParamName, element); - } - - BigDecimal outStandingAmountPercentage = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.outStandingAmountPercentageParamName, element)) { - outStandingAmountPercentage = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.outStandingAmountPercentageParamName, element); - } - - Boolean includeOutstandingAmountParamName = false; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.includeOutstandingAmountParamName, element)) { - includeOutstandingAmountParamName = this.fromApiJsonHelper - .extractBooleanNamed(AdHocQuerySearchConstants.includeOutstandingAmountParamName, element); - } - - String outstandingAmountCondition = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.outstandingAmountConditionParamName, element)) { - outstandingAmountCondition = this.fromApiJsonHelper - .extractStringNamed(AdHocQuerySearchConstants.outstandingAmountConditionParamName, element); - sqlValidator.validate(outstandingAmountCondition); - } - - BigDecimal minOutstandingAmount = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.minOutstandingAmountParamName, element)) { - minOutstandingAmount = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.minOutstandingAmountParamName, element); - } - - BigDecimal maxOutstandingAmount = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.maxOutstandingAmountParamName, element)) { - maxOutstandingAmount = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.maxOutstandingAmountParamName, element); - } - - BigDecimal outstandingAmount = null; - if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.outstandingAmountParamName, element)) { - outstandingAmount = this.fromApiJsonHelper - .extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.outstandingAmountParamName, element); - } - - return AdHocQuerySearchConditions.instance(loanStatus, loanProducts, offices, loanDateOption, loanFromDate, loanToDate, - includeOutStandingAmountPercentage, outStandingAmountPercentageCondition, minOutStandingAmountPercentage, - maxOutStandingAmountPercentage, outStandingAmountPercentage, includeOutstandingAmountParamName, outstandingAmountCondition, - minOutstandingAmount, maxOutstandingAmount, outstandingAmount); - - } - - private List extractLongValuesList(List listTobeConverted) { - List tempList = new ArrayList<>(); - for (String temp : listTobeConverted) { - tempList.add(Long.valueOf(temp)); - } - return tempList; - } - -} diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQuerySearchConstants.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQuerySearchConstants.java deleted file mode 100644 index 855a3f1f963..00000000000 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQuerySearchConstants.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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.portfolio.search.data; - -import java.util.Arrays; -import java.util.List; - -public interface AdHocQuerySearchConstants { - - String AD_HOC_SEARCH_QUERY_RESOURCE_NAME = "adHocQuery"; - - String localeParamName = "locale"; - String dateFormatParamName = "dateFormat"; - String entitiesParamName = "entities"; - String loanStatusParamName = "loanStatus"; - String loanProductsParamName = "loanProducts"; - String officesParamName = "offices"; - String loanDateOptionParamName = "loanDateOption"; - String loanFromDateParamName = "loanFromDate"; - String loanToDateParamName = "loanToDate"; - String includeOutStandingAmountPercentageParamName = "includeOutStandingAmountPercentage"; - String outStandingAmountPercentageConditionParamName = "outStandingAmountPercentageCondition"; - String minOutStandingAmountPercentageParamName = "minOutStandingAmountPercentage"; - String maxOutStandingAmountPercentageParamName = "maxOutStandingAmountPercentage"; - String outStandingAmountPercentageParamName = "outStandingAmountPercentage"; - String includeOutstandingAmountParamName = "includeOutstandingAmount"; - String outstandingAmountConditionParamName = "outstandingAmountCondition"; - String minOutstandingAmountParamName = "minOutstandingAmount"; - String maxOutstandingAmountParamName = "maxOutstandingAmount"; - String outstandingAmountParamName = "outstandingAmount"; - - String approvalDateOption = "approvalDate"; - String createDateOption = "createdDate"; - String disbursalDateOption = "disbursalDate"; - - String allLoanStatusOption = "all"; - String activeLoanStatusOption = "active"; - String overpaidLoanStatusOption = "overpaid"; - String arrearsLoanStatusOption = "arrears"; - String closedLoanStatusOption = "closed"; - String writeoffLoanStatusOption = "writeoff"; - - List entityTypeOptions = List.copyOf(Arrays.asList("clients", "groups", "loans", "clientIdentifiers")); - -} diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/SearchConditions.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/SearchConditions.java index 633ebe85432..8138606db83 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/SearchConditions.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/search/data/SearchConditions.java @@ -31,11 +31,13 @@ public class SearchConditions { private final Boolean shareSeach; private final Boolean clientIdentifierSearch; private Boolean exactMatch; + private final String hierarchy; - public SearchConditions(final String searchQueryParam, final String searchResource, Boolean exactMatch) { + public SearchConditions(final String searchQueryParam, final String searchResource, Boolean exactMatch, final String hierarchy) { this.searchQuery = searchQueryParam; this.searchResource = searchResource; this.exactMatch = exactMatch; + this.hierarchy = hierarchy; this.clientSearch = null == searchResource || searchResource.toLowerCase().contains(SearchSupportedResources.CLIENTS.name().toLowerCase()); this.groupSearch = null == searchResource @@ -52,7 +54,7 @@ public SearchConditions(final String searchQueryParam, final String searchResour public SearchConditions(final String searchQueryParam, final String searchResource, final Boolean clientSearch, final Boolean groupSearch, final Boolean loanSeach, final Boolean savingSeach, final Boolean shareSeach, - final Boolean clientIdentifierSearch, Boolean exactMatch) { + final Boolean clientIdentifierSearch, Boolean exactMatch, final String hierarchy) { this.searchQuery = searchQueryParam; this.searchResource = searchResource; this.clientSearch = clientSearch; @@ -62,6 +64,7 @@ public SearchConditions(final String searchQueryParam, final String searchResour this.shareSeach = shareSeach; this.clientIdentifierSearch = clientIdentifierSearch; this.exactMatch = exactMatch; + this.hierarchy = hierarchy; } public String getSearchQuery() { @@ -100,4 +103,8 @@ public Boolean isClientIdentifierSearch() { return this.clientIdentifierSearch; } + public String getHierarchy() { + return this.hierarchy; + } + } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/api/SearchApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/api/SearchApiResource.java index 58b3db138ca..e1d3c2ebd5a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/api/SearchApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/api/SearchApiResource.java @@ -35,69 +35,79 @@ import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import java.util.List; -import java.util.Set; import lombok.RequiredArgsConstructor; -import org.apache.fineract.portfolio.search.SearchConstants.SearchResponseParameters; -import org.apache.fineract.portfolio.search.data.AdHocQueryDataValidator; -import org.apache.fineract.portfolio.search.data.AdHocQuerySearchConditions; +import org.apache.fineract.portfolio.search.data.AdHocQuerySearchRequest; import org.apache.fineract.portfolio.search.data.AdHocSearchQueryData; import org.apache.fineract.portfolio.search.data.SearchConditions; import org.apache.fineract.portfolio.search.data.SearchData; -import org.apache.fineract.portfolio.search.service.SearchReadPlatformService; +import org.apache.fineract.portfolio.search.service.SearchReadService; +import org.apache.fineract.useradministration.domain.AppUser; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; @Path("/v1/search") @Component @Tag(name = "Search API", description = "Search API allows to search scoped resources clients, loans and groups on specified fields.") @RequiredArgsConstructor +@Consumes({ MediaType.APPLICATION_JSON }) +@Produces({ MediaType.APPLICATION_JSON }) public class SearchApiResource { - private static final Set SEARCH_RESPONSE_PARAMETERS = SearchResponseParameters.getAllValues(); - - private final SearchReadPlatformService searchReadPlatformService; - private final AdHocQueryDataValidator fromApiJsonDeserializer; + private final SearchReadService searchReadService; @GET @Path("/template") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - @Operation(summary = "Retrive Adhoc Search query template", description = "Mandatory Fields\n" + "\n" + "search?query=000000001\n") + @Operation(summary = "Retrive Adhoc Search query template", description = """ + Mandatory Fields + + search?query=000000001 + """) public AdHocSearchQueryData retrieveAdHocSearchQueryTemplate() { - return this.searchReadPlatformService.retrieveAdHocQueryTemplate(); + return searchReadService.retrieveAdHocQueryTemplate(); } @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - @Operation(summary = "Search Resources", description = "Example Requests:\n" + "\n" + "search?query=000000001\n" + "\n" + "\n" - + "search?query=Petra&resource=clients,groups\n" + "\n" + "\n" + "search?query=Petra&resource=clients,groups&exactMatch=true") + @Operation(summary = "Search Resources", description = """ + Example Requests: + + search?query=000000001 + + + search?query=Petra&resource=clients,groups + + + search?query=Petra&resource=clients,groups&exactMatch=true""") @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = SearchApiResourceSwagger.GetSearchResponse.class)))) public List searchData(@QueryParam("query") @Parameter(description = "query") final String query, @QueryParam("resource") @Parameter(description = "resource") final String resource, @DefaultValue("false") @QueryParam("exactMatch") @Parameter(description = "exactMatch") Boolean exactMatch) { - final SearchConditions searchConditions = new SearchConditions(query, resource, exactMatch); + final AppUser currentUser = (AppUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final SearchConditions searchConditions = new SearchConditions(query, resource, exactMatch, hierarchy); - return this.searchReadPlatformService.retriveMatchingData(searchConditions); + return searchReadService.retriveMatchingData(searchConditions); } @POST @Path("/advance") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - @Operation(summary = "Adhoc query search", description = "AdHocQuery search has more search options, it is a POST request, it uses request body to send search parameters\n" - + "\n" + "\n" + "Mandatory fields:" + "entities" + "\n" + "\n" + "Optional fields:" - + "loanStatus, loanProducts, offices, loanDateOption, loanFromDate, loanToDate, \n" - + "includeOutStandingAmountPercentage, outStandingAmountPercentageCondition, \n" - + "minOutStandingAmountPercentage and maxOutStandingAmountPercentage OR outStandingAmountPercentage, \n" - + "includeOutstandingAmount, outstandingAmountCondition, \n" - + "minOutstandingAmount and maxOutstandingAmount OR outstandingAmount") - @RequestBody(required = true, content = @Content(schema = @Schema(implementation = SearchApiResourceSwagger.PostAdhocQuerySearchRequest.class))) - public List advancedSearch(final String json) { + @Operation(summary = "Adhoc query search", description = """ + AdHocQuery search has more search options, it is a POST request, \ + it uses request body to send search parameters + - final AdHocQuerySearchConditions searchConditions = this.fromApiJsonDeserializer.retrieveSearchConditions(json); + Mandatory fields: entities + + Optional fields: \ + loanStatus, loanProducts, offices, loanDateOption, loanFromDate, loanToDate, + includeOutStandingAmountPercentage, outStandingAmountPercentageCondition, + minOutStandingAmountPercentage and maxOutStandingAmountPercentage OR outStandingAmountPercentage, + includeOutstandingAmount, outstandingAmountCondition, + minOutstandingAmount and maxOutstandingAmount OR outstandingAmount""") + @RequestBody(required = true, content = @Content(schema = @Schema(implementation = SearchApiResourceSwagger.PostAdhocQuerySearchRequest.class))) + public List advancedSearch(final AdHocQuerySearchRequest request) { - return this.searchReadPlatformService.retrieveAdHocQueryMatchingData(searchConditions); + return searchReadService.retrieveAdHocQueryMatchingData(request); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQuerySearchRequest.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQuerySearchRequest.java new file mode 100644 index 00000000000..75090df0a25 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/data/AdHocQuerySearchRequest.java @@ -0,0 +1,55 @@ +/** + * 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.portfolio.search.data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AdHocQuerySearchRequest implements Serializable { + + private String locale; + private String dateFormat; + private List entities; + private List loanStatus; + private List loanProducts; + private List offices; + private String loanDateOption; + private LocalDate loanFromDate; + private LocalDate loanToDate; + private Boolean includeOutStandingAmountPercentage; + private String outStandingAmountPercentageCondition; + private BigDecimal minOutStandingAmountPercentage; + private BigDecimal maxOutStandingAmountPercentage; + private BigDecimal outStandingAmountPercentage; + private Boolean includeOutstandingAmount; + private String outstandingAmountCondition; + private BigDecimal minOutstandingAmount; + private BigDecimal maxOutstandingAmount; + private BigDecimal outstandingAmount; +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadService.java similarity index 92% rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadPlatformService.java rename to fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadService.java index c64155d7826..7b3d791b7bf 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadService.java @@ -19,16 +19,16 @@ package org.apache.fineract.portfolio.search.service; import java.util.List; -import org.apache.fineract.portfolio.search.data.AdHocQuerySearchConditions; +import org.apache.fineract.portfolio.search.data.AdHocQuerySearchRequest; import org.apache.fineract.portfolio.search.data.AdHocSearchQueryData; import org.apache.fineract.portfolio.search.data.SearchConditions; import org.apache.fineract.portfolio.search.data.SearchData; -public interface SearchReadPlatformService { +public interface SearchReadService { List retriveMatchingData(SearchConditions searchConditions); AdHocSearchQueryData retrieveAdHocQueryTemplate(); - List retrieveAdHocQueryMatchingData(AdHocQuerySearchConditions searchConditions); + List retrieveAdHocQueryMatchingData(AdHocQuerySearchRequest request); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadServiceImpl.java similarity index 69% rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadPlatformServiceImpl.java rename to fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadServiceImpl.java index af383784982..fcc8f159cac 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/service/SearchReadServiceImpl.java @@ -28,7 +28,7 @@ import org.apache.fineract.infrastructure.core.data.EnumOptionData; import org.apache.fineract.infrastructure.core.domain.JdbcSupport; import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.infrastructure.security.service.SqlValidator; import org.apache.fineract.organisation.monetary.domain.MoneyHelper; import org.apache.fineract.organisation.office.data.OfficeData; import org.apache.fineract.organisation.office.service.OfficeReadPlatformService; @@ -42,29 +42,28 @@ import org.apache.fineract.portfolio.savings.service.SavingsEnumerations; import org.apache.fineract.portfolio.search.SearchConstants; import org.apache.fineract.portfolio.search.data.AdHocQuerySearchConditions; +import org.apache.fineract.portfolio.search.data.AdHocQuerySearchRequest; import org.apache.fineract.portfolio.search.data.AdHocSearchQueryData; import org.apache.fineract.portfolio.search.data.SearchConditions; import org.apache.fineract.portfolio.search.data.SearchData; import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData; import org.apache.fineract.portfolio.shareaccounts.service.SharesEnumerations; -import org.apache.fineract.useradministration.domain.AppUser; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; @RequiredArgsConstructor -public class SearchReadPlatformServiceImpl implements SearchReadPlatformService { +public class SearchReadServiceImpl implements SearchReadService { private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; - private final PlatformSecurityContext context; private final LoanProductReadPlatformService loanProductReadPlatformService; private final OfficeReadPlatformService officeReadPlatformService; private final DatabaseSpecificSQLGenerator sqlGenerator; + private final SqlValidator sqlValidator; @Override public List retriveMatchingData(final SearchConditions searchConditions) { - final AppUser currentUser = context.authenticatedUser(); - final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchy = searchConditions.getHierarchy(); final SearchMapper rm = new SearchMapper(); @@ -81,37 +80,79 @@ public List retriveMatchingData(final SearchConditions searchConditi public String searchSchema(final SearchConditions searchConditions) { final String union = " union "; - final String clientMatchSql = "( (select 'CLIENT' as entityType, c.id as entityId, c.display_name as entityName, c.external_id as entityExternalId, c.account_no as entityAccountNo " - + " , c.office_id as parentId, o.name as parentName, c.mobile_no as entityMobileNo,c.status_enum as entityStatusEnum, null as subEntityType, null as parentType " - + " from m_client c join m_office o on o.id = c.office_id where o.hierarchy like :hierarchy and (c.account_no like :search or c.display_name like :search or c.external_id like :search or c.mobile_no like :search)) " - + " order by c.id desc)"; - - final String loanMatchSql = "( (select 'LOAN' as entityType, l.id as entityId, pl.name as entityName, l.external_id as entityExternalId, l.account_no as entityAccountNo " - + " , coalesce(c.id,g.id) as parentId, coalesce(c.display_name,g.display_name) as parentName, null as entityMobileNo, l.loan_status_id as entityStatusEnum, null as subEntityType, CASE WHEN g.id is null THEN 'client' ELSE 'group' END as parentType " - + " from m_loan l left join m_client c on l.client_id = c.id left join m_group g ON l.group_id = g.id left join m_office o on o.id = c.office_id left join m_product_loan pl on pl.id=l.product_id where (o.hierarchy IS NULL OR o.hierarchy like :hierarchy) and (l.account_no like :search or l.external_id like :search)) " - + " order by l.id desc)"; - - final String savingMatchSql = "( (select 'SAVING' as entityType, s.id as entityId, sp.name as entityName, s.external_id as entityExternalId, s.account_no as entityAccountNo " - + " , coalesce(c.id,g.id) as parentId, coalesce(c.display_name, g.display_name) as parentName, null as entityMobileNo, s.status_enum as entityStatusEnum, concat(s.deposit_type_enum, '') as subEntityType, CASE WHEN g.id is null THEN 'client' ELSE 'group' END as parentType " - + " from m_savings_account s left join m_client c on s.client_id = c.id left join m_group g ON s.group_id = g.id left join m_office o on o.id = c.office_id left join m_savings_product sp on sp.id=s.product_id " - + " where (o.hierarchy IS NULL OR o.hierarchy like :hierarchy) and (s.account_no like :search or s.external_id like :search)) " - + " order by s.id desc)"; - - final String shareMatchSql = "( (select 'SHARE' as entityType, s.id as entityId, sp.name as entityName, s.external_id as entityExternalId, s.account_no as entityAccountNo " - + " , c.id as parentId, c.display_name as parentName, null as entityMobileNo, s.status_enum as entityStatusEnum, null as subEntityType, 'client' as parentType " - + " from m_share_account s left join m_client c on s.client_id = c.id left join m_office o on o.id = c.office_id left join m_share_product sp on sp.id=s.product_id " - + " where (o.hierarchy IS NULL OR o.hierarchy like :hierarchy) and (s.account_no like :search or s.external_id like :search)) " - + " order by s.id desc)"; - - final String clientIdentifierMatchSql = "( (select 'CLIENTIDENTIFIER' as entityType, ci.id as entityId, ci.document_key as entityName, " - + " null as entityExternalId, null as entityAccountNo, c.id as parentId, c.display_name as parentName,null as entityMobileNo, c.status_enum as entityStatusEnum, null as subEntityType, null as parentType " - + " from m_client_identifier ci join m_client c on ci.client_id=c.id join m_office o on o.id = c.office_id " - + " where o.hierarchy like :hierarchy and ci.document_key like :search ) " + " order by ci.id desc)"; - - final String groupMatchSql = "( (select CASE WHEN g.level_id=1 THEN 'CENTER' ELSE 'GROUP' END as entityType, g.id as entityId, g.display_name as entityName, g.external_id as entityExternalId, g.account_no as entityAccountNo, " - + " g.office_id as parentId, o.name as parentName, null as entityMobileNo, g.status_enum as entityStatusEnum, null as subEntityType, null as parentType " - + " from m_group g join m_office o on o.id = g.office_id where o.hierarchy like :hierarchy and (g.account_no like :search or g.display_name like :search or g.external_id like :search )) " - + " order by g.id desc)"; + final String clientMatchSql = """ + ( (select 'CLIENT' as entityType, c.id as entityId, c.display_name as entityName, \ + c.external_id as entityExternalId, c.account_no as entityAccountNo, \ + c.office_id as parentId, o.name as parentName, c.mobile_no as entityMobileNo, \ + c.status_enum as entityStatusEnum, null as subEntityType, null as parentType \ + from m_client c join m_office o on o.id = c.office_id \ + where o.hierarchy like :hierarchy \ + and (c.account_no like :search or c.display_name like :search \ + or c.external_id like :search or c.mobile_no like :search)) \ + order by c.id desc)"""; + + final String loanMatchSql = """ + ( (select 'LOAN' as entityType, l.id as entityId, pl.name as entityName, \ + l.external_id as entityExternalId, l.account_no as entityAccountNo, \ + coalesce(c.id,g.id) as parentId, coalesce(c.display_name,g.display_name) as parentName, \ + null as entityMobileNo, l.loan_status_id as entityStatusEnum, null as subEntityType, \ + CASE WHEN g.id is null THEN 'client' ELSE 'group' END as parentType \ + from m_loan l left join m_client c on l.client_id = c.id \ + left join m_group g ON l.group_id = g.id \ + left join m_office o on o.id = c.office_id \ + left join m_product_loan pl on pl.id=l.product_id \ + where (o.hierarchy IS NULL OR o.hierarchy like :hierarchy) \ + and (l.account_no like :search or l.external_id like :search)) \ + order by l.id desc)"""; + + final String savingMatchSql = """ + ( (select 'SAVING' as entityType, s.id as entityId, sp.name as entityName, \ + s.external_id as entityExternalId, s.account_no as entityAccountNo, \ + coalesce(c.id,g.id) as parentId, coalesce(c.display_name, g.display_name) as parentName, \ + null as entityMobileNo, s.status_enum as entityStatusEnum, \ + concat(s.deposit_type_enum, '') as subEntityType, \ + CASE WHEN g.id is null THEN 'client' ELSE 'group' END as parentType \ + from m_savings_account s left join m_client c on s.client_id = c.id \ + left join m_group g ON s.group_id = g.id \ + left join m_office o on o.id = c.office_id \ + left join m_savings_product sp on sp.id=s.product_id \ + where (o.hierarchy IS NULL OR o.hierarchy like :hierarchy) \ + and (s.account_no like :search or s.external_id like :search)) \ + order by s.id desc)"""; + + final String shareMatchSql = """ + ( (select 'SHARE' as entityType, s.id as entityId, sp.name as entityName, \ + s.external_id as entityExternalId, s.account_no as entityAccountNo, \ + c.id as parentId, c.display_name as parentName, null as entityMobileNo, \ + s.status_enum as entityStatusEnum, null as subEntityType, 'client' as parentType \ + from m_share_account s left join m_client c on s.client_id = c.id \ + left join m_office o on o.id = c.office_id \ + left join m_share_product sp on sp.id=s.product_id \ + where (o.hierarchy IS NULL OR o.hierarchy like :hierarchy) \ + and (s.account_no like :search or s.external_id like :search)) \ + order by s.id desc)"""; + + final String clientIdentifierMatchSql = """ + ( (select 'CLIENTIDENTIFIER' as entityType, ci.id as entityId, ci.document_key as entityName, \ + null as entityExternalId, null as entityAccountNo, c.id as parentId, \ + c.display_name as parentName, null as entityMobileNo, \ + c.status_enum as entityStatusEnum, null as subEntityType, null as parentType \ + from m_client_identifier ci join m_client c on ci.client_id=c.id \ + join m_office o on o.id = c.office_id \ + where o.hierarchy like :hierarchy and ci.document_key like :search) \ + order by ci.id desc)"""; + + final String groupMatchSql = """ + ( (select CASE WHEN g.level_id=1 THEN 'CENTER' ELSE 'GROUP' END as entityType, \ + g.id as entityId, g.display_name as entityName, \ + g.external_id as entityExternalId, g.account_no as entityAccountNo, \ + g.office_id as parentId, o.name as parentName, null as entityMobileNo, \ + g.status_enum as entityStatusEnum, null as subEntityType, null as parentType \ + from m_group g join m_office o on o.id = g.office_id \ + where o.hierarchy like :hierarchy \ + and (g.account_no like :search or g.display_name like :search \ + or g.external_id like :search)) \ + order by g.id desc)"""; final StringBuilder sql = new StringBuilder(); @@ -192,9 +233,6 @@ public SearchData mapRow(final ResultSet rs, @SuppressWarnings("unused") final i @Override public AdHocSearchQueryData retrieveAdHocQueryTemplate() { - - context.authenticatedUser(); - final Collection loanProducts = loanProductReadPlatformService.retrieveAllLoanProductsForLookup(); final Collection offices = officeReadPlatformService.retrieveAllOfficesForDropdown(); @@ -202,9 +240,8 @@ public AdHocSearchQueryData retrieveAdHocQueryTemplate() { } @Override - public List retrieveAdHocQueryMatchingData(final AdHocQuerySearchConditions searchConditions) { - - context.authenticatedUser(); + public List retrieveAdHocQueryMatchingData(final AdHocQuerySearchRequest request) { + final AdHocQuerySearchConditions searchConditions = convertToSearchConditions(request); final AdHocQuerySearchMapper rm = new AdHocQuerySearchMapper(); final MapSqlParameterSource params = new MapSqlParameterSource(); @@ -212,6 +249,27 @@ public List retrieveAdHocQueryMatchingData(final AdHocQuer return namedParameterJdbcTemplate.query(rm.schema(searchConditions, params), params, rm); } + private AdHocQuerySearchConditions convertToSearchConditions(final AdHocQuerySearchRequest request) { + if (request.getLoanDateOption() != null) { + sqlValidator.validate(request.getLoanDateOption()); + } + if (request.getOutStandingAmountPercentageCondition() != null) { + sqlValidator.validate(request.getOutStandingAmountPercentageCondition()); + } + if (request.getOutstandingAmountCondition() != null) { + sqlValidator.validate(request.getOutstandingAmountCondition()); + } + + return AdHocQuerySearchConditions.instance(request.getLoanStatus(), request.getLoanProducts(), request.getOffices(), + request.getLoanDateOption(), request.getLoanFromDate(), request.getLoanToDate(), + request.getIncludeOutStandingAmountPercentage() != null ? request.getIncludeOutStandingAmountPercentage() : false, + request.getOutStandingAmountPercentageCondition(), request.getMinOutStandingAmountPercentage(), + request.getMaxOutStandingAmountPercentage(), request.getOutStandingAmountPercentage(), + request.getIncludeOutstandingAmount() != null ? request.getIncludeOutstandingAmount() : false, + request.getOutstandingAmountCondition(), request.getMinOutstandingAmount(), request.getMaxOutstandingAmount(), + request.getOutstandingAmount()); + } + private static final class AdHocQuerySearchMapper implements RowMapper { private boolean isWhereClauseAdded = false; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/starter/SearchConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/starter/SearchConfiguration.java index 222cb63cc0c..3a600afe1c1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/starter/SearchConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/search/starter/SearchConfiguration.java @@ -19,11 +19,11 @@ package org.apache.fineract.portfolio.search.starter; import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.infrastructure.security.service.SqlValidator; import org.apache.fineract.organisation.office.service.OfficeReadPlatformService; import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService; -import org.apache.fineract.portfolio.search.service.SearchReadPlatformService; -import org.apache.fineract.portfolio.search.service.SearchReadPlatformServiceImpl; +import org.apache.fineract.portfolio.search.service.SearchReadService; +import org.apache.fineract.portfolio.search.service.SearchReadServiceImpl; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -33,11 +33,11 @@ public class SearchConfiguration { @Bean - @ConditionalOnMissingBean(SearchReadPlatformService.class) - public SearchReadPlatformService searchReadPlatformService(NamedParameterJdbcTemplate namedParameterJdbcTemplate, - PlatformSecurityContext context, LoanProductReadPlatformService loanProductReadPlatformService, - OfficeReadPlatformService officeReadPlatformService, DatabaseSpecificSQLGenerator sqlGenerator) { - return new SearchReadPlatformServiceImpl(namedParameterJdbcTemplate, context, loanProductReadPlatformService, - officeReadPlatformService, sqlGenerator); + @ConditionalOnMissingBean(SearchReadService.class) + public SearchReadService searchReadService(NamedParameterJdbcTemplate namedParameterJdbcTemplate, + LoanProductReadPlatformService loanProductReadPlatformService, OfficeReadPlatformService officeReadPlatformService, + DatabaseSpecificSQLGenerator sqlGenerator, SqlValidator sqlValidator) { + return new SearchReadServiceImpl(namedParameterJdbcTemplate, loanProductReadPlatformService, officeReadPlatformService, + sqlGenerator, sqlValidator); } }