From c79de9bb7ad97bebf129870cadd310de658019d8 Mon Sep 17 00:00:00 2001 From: Adam Saghy Date: Fri, 16 May 2025 13:24:31 +0200 Subject: [PATCH] FINERACT-2282: Support Client filtering by legal form --- .../core/service/SearchParameters.java | 13 ++++++ .../client/api/ClientApiConstants.java | 2 +- .../client/api/ClientsApiResource.java | 14 ++++--- .../client/api/ClientsApiResourceSwagger.java | 2 +- .../ClientReadPlatformServiceImpl.java | 5 +++ .../client/api/SelfClientsApiResource.java | 7 ++-- .../client/ClientSearchTest.java | 41 +++++++++++++++++-- .../integrationtests/client/ClientTest.java | 2 +- 8 files changed, 71 insertions(+), 15 deletions(-) diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java index 1401b2fde..2f09780ab 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/SearchParameters.java @@ -56,6 +56,7 @@ public class SearchParameters { private Long categoryId; @Getter(AccessLevel.NONE) private Boolean isSelfUser; + private Integer legalForm; public Integer getLimit() { if (limit == null) { @@ -128,4 +129,16 @@ public class SearchParameters { public boolean hasCategoryId() { return this.categoryId != null && this.categoryId != 0; } + + public boolean isPerson() { + return this.legalForm != null && this.legalForm == 1; + } + + public boolean isEntity() { + return this.legalForm != null && this.legalForm == 2; + } + + public boolean hasLegalForm() { + return this.legalForm != null; + } } diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java index 86bd93231..e95a41521 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java @@ -197,7 +197,7 @@ public class ClientApiConstants { officeNameParamName, transferToOfficeIdParamName, transferToOfficeNameParamName, hierarchyParamName, imageIdParamName, imagePresentParamName, staffIdParamName, staffNameParamName, timelineParamName, groupsParamName, officeOptionsParamName, staffOptionsParamName, dateOfBirthParamName, genderParamName, clientTypeParamName, clientClassificationParamName, - legalFormParamName, clientNonPersonDetailsParamName, isStaffParamName)); + legalFormParamName, clientNonPersonDetailsParamName, isStaffParamName, legalFormParamName)); protected static final Set CLIENT_CHARGES_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(chargeIdParamName, clientIdParamName, chargeNameParamName, penaltyParamName, chargeTimeTypeParamName, dueAsOfDateParamName, diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java index 7a1140235..ac2d891a9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java @@ -151,10 +151,11 @@ public class ClientsApiResource { @QueryParam("limit") @Parameter(description = "limit") final Integer limit, @QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy, @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder, - @QueryParam("orphansOnly") @Parameter(description = "orphansOnly") final Boolean orphansOnly) { + @QueryParam("orphansOnly") @Parameter(description = "orphansOnly") final Boolean orphansOnly, + @QueryParam("legalForm") final Integer legalForm) { - return retrieveAll(uriInfo, officeId, externalId, displayName, firstname, lastname, status, hierarchy, offset, limit, orderBy, - sortOrder, orphansOnly, false); + return retrieveAll(uriInfo, officeId, externalId, displayName, firstname, lastname, status, legalForm, hierarchy, offset, limit, + orderBy, sortOrder, orphansOnly, false); } @GET @@ -442,8 +443,9 @@ public class ClientsApiResource { } public String retrieveAll(final UriInfo uriInfo, final Long officeId, final String externalId, final String displayName, - final String firstname, final String lastname, final String status, final String hierarchy, final Integer offset, - final Integer limit, final String orderBy, final String sortOrder, final Boolean orphansOnly, final boolean isSelfUser) { + final String firstname, final String lastname, final String status, final Integer legalForm, final String hierarchy, + final Integer offset, final Integer limit, final String orderBy, final String sortOrder, final Boolean orphansOnly, + final boolean isSelfUser) { context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME); sqlValidator.validate(orderBy); sqlValidator.validate(sortOrder); @@ -451,7 +453,7 @@ public class ClientsApiResource { sqlValidator.validate(hierarchy); final SearchParameters searchParameters = SearchParameters.builder().limit(limit).officeId(officeId).externalId(externalId) .name(displayName).hierarchy(hierarchy).firstname(firstname).lastname(lastname).status(status).orphansOnly(orphansOnly) - .isSelfUser(isSelfUser).offset(offset).orderBy(orderBy).sortOrder(sortOrder).build(); + .isSelfUser(isSelfUser).offset(offset).orderBy(orderBy).sortOrder(sortOrder).legalForm(legalForm).build(); final Page clientData = clientReadPlatformService.retrieveAll(searchParameters); final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return toApiJsonSerializer.serialize(settings, clientData, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java index 7ab477c00..27fc9e368 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java @@ -168,7 +168,7 @@ final class ClientsApiResourceSwagger { @Schema(example = "2") public Integer totalFilteredRecords; - public Set pageItems; + public List pageItems; } @Schema(description = "GetClientsClientIdResponse") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java index 74d45fcb4..6ddcd3a1d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java @@ -195,6 +195,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService extraCriteria += " and c.id NOT IN (select client_id from m_group_client) "; } + if (searchParameters.hasLegalForm()) { + paramList.add(searchParameters.getLegalForm()); + extraCriteria += " and c.legal_form_enum = ? "; + } + if (StringUtils.isNotBlank(extraCriteria)) { extraCriteria = extraCriteria.substring(4); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/api/SelfClientsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/api/SelfClientsApiResource.java index 5ae049e4b..f149a8c84 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/api/SelfClientsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/client/api/SelfClientsApiResource.java @@ -89,14 +89,15 @@ public class SelfClientsApiResource { @QueryParam("status") @Parameter(description = "status") final String status, @QueryParam("limit") @Parameter(description = "limit") final Integer limit, @QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy, - @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) { + @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder, + @QueryParam("legalForm") final Integer legalForm) { final Long officeId = null; final String externalId = null; final String hierarchy = null; final Boolean orphansOnly = null; - return this.clientApiResource.retrieveAll(uriInfo, officeId, externalId, displayName, firstname, lastname, status, hierarchy, - offset, limit, orderBy, sortOrder, orphansOnly, true); + return this.clientApiResource.retrieveAll(uriInfo, officeId, externalId, displayName, firstname, lastname, status, legalForm, + hierarchy, offset, limit, orderBy, sortOrder, orphansOnly, true); } @GET diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ClientSearchTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ClientSearchTest.java index 537863f9f..eed2076d6 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ClientSearchTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ClientSearchTest.java @@ -18,26 +18,28 @@ */ package org.apache.fineract.integrationtests.client; -import static org.assertj.core.api.Assertions.assertThat; - 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.time.LocalDate; import org.apache.fineract.client.models.GetClientsClientIdResponse; +import org.apache.fineract.client.models.GetClientsResponse; import org.apache.fineract.client.models.PageClientSearchData; import org.apache.fineract.client.models.PostClientsClientIdIdentifiersRequest; import org.apache.fineract.client.models.PostClientsClientIdIdentifiersResponse; import org.apache.fineract.client.models.PostClientsRequest; import org.apache.fineract.client.models.PostClientsResponse; +import org.apache.fineract.client.models.PostOfficesRequest; +import org.apache.fineract.client.models.PostOfficesResponse; import org.apache.fineract.client.models.SortOrder; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.Utils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class ClientSearchTest { +public class ClientSearchTest extends IntegrationTest { private ResponseSpecification responseSpec; private RequestSpecification requestSpec; @@ -269,4 +271,37 @@ public class ClientSearchTest { assertThat(result.getContent().get(0).getMobileNo()).isEqualTo(request1.getMobileNo()); } + @Test + public void testClientSearchByLegalForm() { + // given + PostOfficesResponse newOffice = ok( + fineractClient().offices.createOffice(new PostOfficesRequest().name(Utils.randomStringGenerator("TestOffice_", 6)) + .parentId(1L).openingDate(LocalDate.of(1970, 1, 1)).dateFormat("yyyy-MM-dd").locale("en_US"))); + PostClientsRequest individualClientRequest = ClientHelper.defaultClientCreationRequest(); + individualClientRequest.setLegalFormId(1L); + individualClientRequest.setOfficeId(newOffice.getOfficeId()); + PostClientsResponse individualClientResponse = clientHelper.createClient(individualClientRequest); + + PostClientsRequest entityClientRequest = ClientHelper.defaultClientCreationRequest(); + entityClientRequest.setOfficeId(newOffice.getOfficeId()); + entityClientRequest.setLegalFormId(2L); + PostClientsResponse entityClientResponse = clientHelper.createClient(entityClientRequest); + + PostClientsRequest secondEntityClientRequest = ClientHelper.defaultClientCreationRequest(); + secondEntityClientRequest.setOfficeId(newOffice.getOfficeId()); + secondEntityClientRequest.setLegalFormId(2L); + PostClientsResponse secondEntityClientResponse = clientHelper.createClient(secondEntityClientRequest); + // when + GetClientsResponse individualClients = ok(fineractClient().clients.retrieveAll21(newOffice.getOfficeId(), null, null, null, null, + null, null, null, null, null, null, null, 1)); + GetClientsResponse entityClients = ok(fineractClient().clients.retrieveAll21(newOffice.getOfficeId(), null, null, null, null, null, + null, null, null, "id", null, null, 2)); + // then + assertThat(individualClients.getTotalFilteredRecords()).isEqualTo(1); + assertThat(individualClients.getPageItems().get(0).getId()).isEqualTo(individualClientResponse.getClientId()); + assertThat(entityClients.getTotalFilteredRecords()).isEqualTo(2); + assertThat(entityClients.getPageItems().get(0).getId()).isEqualTo(entityClientResponse.getClientId()); + assertThat(entityClients.getPageItems().get(1).getId()).isEqualTo(secondEntityClientResponse.getClientId()); + } + } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ClientTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ClientTest.java index a32811792..182646c7a 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ClientTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ClientTest.java @@ -63,7 +63,7 @@ public class ClientTest extends IntegrationTest { Optional retrieveFirst() { GetClientsResponse clients = ok( - fineractClient().clients.retrieveAll21(null, null, null, null, null, null, null, 0, 1, null, null, false)); + fineractClient().clients.retrieveAll21(null, null, null, null, null, null, null, 0, 1, null, null, false, null)); if (clients.getTotalFilteredRecords() != null && clients.getTotalFilteredRecords() > 0) { return clients.getPageItems().stream().findFirst().map(item -> item.getId()); }