This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new e13a9cba0 FINERACT-2073: Client search v2 using Client Identifiers
e13a9cba0 is described below

commit e13a9cba018f674786fd3462513d3ec3949ef7f0
Author: Jose Alberto Hernandez <[email protected]>
AuthorDate: Tue Mar 26 01:06:12 2024 -0600

    FINERACT-2073: Client search v2 using Client Identifiers
---
 .../src/main/resources/jpa/branch/persistence.xml  |  1 +
 .../fineract/portfolio/client/domain/Client.java   |  5 ++++
 .../portfolio/client/domain/ClientIdentifier.java  |  0
 .../client/domain/ClientIdentifierRepository.java  |  0
 .../client/domain/ClientIdentifierStatus.java      |  0
 .../main/resources/jpa/document/persistence.xml    |  1 +
 .../main/resources/jpa/investor/persistence.xml    |  1 +
 .../src/main/resources/jpa/loan/persistence.xml    |  1 +
 .../api/ClientIdentifiersApiResourceSwagger.java   |  4 ++++
 .../search/SearchingClientRepositoryImpl.java      |  7 +++++-
 .../src/main/resources/jpa/persistence.xml         |  1 +
 .../src/main/resources/jpa/rates/persistence.xml   |  1 +
 .../src/main/resources/jpa/savings/persistence.xml |  1 +
 .../integrationtests/client/ClientSearchTest.java  | 27 ++++++++++++++++++++++
 .../integrationtests/common/ClientHelper.java      | 13 +++++++++++
 15 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/fineract-branch/src/main/resources/jpa/branch/persistence.xml 
b/fineract-branch/src/main/resources/jpa/branch/persistence.xml
index 49d7498ea..bf32dc798 100644
--- a/fineract-branch/src/main/resources/jpa/branch/persistence.xml
+++ b/fineract-branch/src/main/resources/jpa/branch/persistence.xml
@@ -48,6 +48,7 @@
         
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
         <class>org.apache.fineract.portfolio.group.domain.GroupRole</class>
         <class>org.apache.fineract.portfolio.client.domain.Client</class>
+        
<class>org.apache.fineract.portfolio.client.domain.ClientIdentifier</class>
         <class>org.apache.fineract.portfolio.rate.domain.Rate</class>
         <class>org.apache.fineract.portfolio.fund.domain.Fund</class>
         
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java
 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java
index f1a055199..a65f2d44b 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.portfolio.client.domain;
 
+import jakarta.persistence.CascadeType;
 import jakarta.persistence.Column;
 import jakarta.persistence.Entity;
 import jakarta.persistence.FetchType;
@@ -25,6 +26,7 @@ import jakarta.persistence.JoinColumn;
 import jakarta.persistence.JoinTable;
 import jakarta.persistence.ManyToMany;
 import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
 import jakarta.persistence.OneToOne;
 import jakarta.persistence.Table;
 import jakarta.persistence.Transient;
@@ -220,6 +222,9 @@ public class Client extends 
AbstractAuditableWithUTCDateTimeCustom {
     @Column(name = "proposed_transfer_date")
     private LocalDate proposedTransferDate;
 
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "client", orphanRemoval = 
true, fetch = FetchType.LAZY)
+    protected Set<ClientIdentifier> identifiers = new HashSet<>();
+
     public static Client instance(final AppUser currentUser, final 
ClientStatus status, final Office office, final Group clientParentGroup,
             final String accountNo, final String firstname, final String 
middlename, final String lastname, final String fullname,
             final LocalDate activationDate, final LocalDate officeJoiningDate, 
final ExternalId externalId, final String mobileNo,
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifier.java
 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifier.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifier.java
rename to 
fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifier.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifierRepository.java
 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifierRepository.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifierRepository.java
rename to 
fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifierRepository.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifierStatus.java
 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifierStatus.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifierStatus.java
rename to 
fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientIdentifierStatus.java
diff --git a/fineract-document/src/main/resources/jpa/document/persistence.xml 
b/fineract-document/src/main/resources/jpa/document/persistence.xml
index bf9980fa8..7849844df 100644
--- a/fineract-document/src/main/resources/jpa/document/persistence.xml
+++ b/fineract-document/src/main/resources/jpa/document/persistence.xml
@@ -48,6 +48,7 @@
         
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
         <class>org.apache.fineract.portfolio.group.domain.GroupRole</class>
         <class>org.apache.fineract.portfolio.client.domain.Client</class>
+        
<class>org.apache.fineract.portfolio.client.domain.ClientIdentifier</class>
         <class>org.apache.fineract.portfolio.fund.domain.Fund</class>
         <class>org.apache.fineract.portfolio.charge.domain.Charge</class>
         
<class>org.apache.fineract.portfolio.paymenttype.domain.PaymentType</class>
diff --git a/fineract-investor/src/main/resources/jpa/investor/persistence.xml 
b/fineract-investor/src/main/resources/jpa/investor/persistence.xml
index 2b5752f6c..885d58faa 100644
--- a/fineract-investor/src/main/resources/jpa/investor/persistence.xml
+++ b/fineract-investor/src/main/resources/jpa/investor/persistence.xml
@@ -47,6 +47,7 @@
         
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
         <class>org.apache.fineract.portfolio.group.domain.GroupRole</class>
         <class>org.apache.fineract.portfolio.client.domain.Client</class>
+        
<class>org.apache.fineract.portfolio.client.domain.ClientIdentifier</class>
         <class>org.apache.fineract.portfolio.rate.domain.Rate</class>
         <class>org.apache.fineract.portfolio.fund.domain.Fund</class>
         
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
diff --git a/fineract-loan/src/main/resources/jpa/loan/persistence.xml 
b/fineract-loan/src/main/resources/jpa/loan/persistence.xml
index 49d7498ea..bf32dc798 100644
--- a/fineract-loan/src/main/resources/jpa/loan/persistence.xml
+++ b/fineract-loan/src/main/resources/jpa/loan/persistence.xml
@@ -48,6 +48,7 @@
         
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
         <class>org.apache.fineract.portfolio.group.domain.GroupRole</class>
         <class>org.apache.fineract.portfolio.client.domain.Client</class>
+        
<class>org.apache.fineract.portfolio.client.domain.ClientIdentifier</class>
         <class>org.apache.fineract.portfolio.rate.domain.Rate</class>
         <class>org.apache.fineract.portfolio.fund.domain.Fund</class>
         
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientIdentifiersApiResourceSwagger.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientIdentifiersApiResourceSwagger.java
index fb69d6f2f..0f380a0b4 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientIdentifiersApiResourceSwagger.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientIdentifiersApiResourceSwagger.java
@@ -85,6 +85,8 @@ final class ClientIdentifiersApiResourceSwagger {
         public String documentKey;
         @Schema(example = "Document has been verified")
         public String description;
+        @Schema(example = "Active")
+        public String status;
     }
 
     @Schema(description = "PutClientsClientIdIdentifiersIdentifierIdRequest")
@@ -98,6 +100,8 @@ final class ClientIdentifiersApiResourceSwagger {
         public String documentKey;
         @Schema(example = "Document has been updated")
         public String description;
+        @Schema(example = "Active")
+        public String status;
     }
 
     @Schema(description = "PutClientsClientIdIdentifiersIdentifierIdResponse")
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/search/SearchingClientRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/search/SearchingClientRepositoryImpl.java
index 835ded075..f038ce7c5 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/search/SearchingClientRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/search/SearchingClientRepositoryImpl.java
@@ -22,6 +22,8 @@ import jakarta.persistence.EntityManager;
 import jakarta.persistence.TypedQuery;
 import jakarta.persistence.criteria.CriteriaBuilder;
 import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.Join;
+import jakarta.persistence.criteria.JoinType;
 import jakarta.persistence.criteria.Order;
 import jakarta.persistence.criteria.Path;
 import jakarta.persistence.criteria.Predicate;
@@ -32,6 +34,7 @@ import lombok.RequiredArgsConstructor;
 import org.apache.fineract.infrastructure.core.jpa.CriteriaQueryFactory;
 import org.apache.fineract.organisation.office.domain.Office;
 import org.apache.fineract.portfolio.client.domain.Client;
+import org.apache.fineract.portfolio.client.domain.ClientIdentifier;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.domain.Specification;
@@ -62,13 +65,15 @@ public class SearchingClientRepositoryImpl implements 
SearchingClientRepository
 
         Specification<Client> spec = (r, q, builder) -> {
             Path<Office> o = r.get("office");
+            Join<Client, ClientIdentifier> identity = r.join("identifiers", 
JoinType.LEFT);
 
             List<Predicate> predicates = new ArrayList<>();
             predicates.add(cb.like(o.get("hierarchy"), hierarchyLikeValue));
 
             String searchLikeValue = "%" + searchText + "%";
             predicates.add(cb.or(cb.like(r.get("accountNumber"), 
searchLikeValue), cb.like(r.get("displayName"), searchLikeValue),
-                    cb.like(r.get("externalId"), searchLikeValue), 
cb.like(r.get("mobileNo"), searchLikeValue)));
+                    cb.like(r.get("externalId"), searchLikeValue), 
cb.like(r.get("mobileNo"), searchLikeValue),
+                    cb.like(identity.get("documentKey"), searchLikeValue)));
 
             return cb.and(predicates.toArray(new Predicate[0]));
         };
diff --git a/fineract-provider/src/main/resources/jpa/persistence.xml 
b/fineract-provider/src/main/resources/jpa/persistence.xml
index b398f5f4d..0d7a3654e 100644
--- a/fineract-provider/src/main/resources/jpa/persistence.xml
+++ b/fineract-provider/src/main/resources/jpa/persistence.xml
@@ -48,6 +48,7 @@
         
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
         <class>org.apache.fineract.portfolio.group.domain.GroupRole</class>
         <class>org.apache.fineract.portfolio.client.domain.Client</class>
+        
<class>org.apache.fineract.portfolio.client.domain.ClientIdentifier</class>
         <class>org.apache.fineract.portfolio.rate.domain.Rate</class>
         <class>org.apache.fineract.portfolio.fund.domain.Fund</class>
         
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
diff --git a/fineract-rates/src/main/resources/jpa/rates/persistence.xml 
b/fineract-rates/src/main/resources/jpa/rates/persistence.xml
index 49d7498ea..bf32dc798 100644
--- a/fineract-rates/src/main/resources/jpa/rates/persistence.xml
+++ b/fineract-rates/src/main/resources/jpa/rates/persistence.xml
@@ -48,6 +48,7 @@
         
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
         <class>org.apache.fineract.portfolio.group.domain.GroupRole</class>
         <class>org.apache.fineract.portfolio.client.domain.Client</class>
+        
<class>org.apache.fineract.portfolio.client.domain.ClientIdentifier</class>
         <class>org.apache.fineract.portfolio.rate.domain.Rate</class>
         <class>org.apache.fineract.portfolio.fund.domain.Fund</class>
         
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
diff --git a/fineract-savings/src/main/resources/jpa/savings/persistence.xml 
b/fineract-savings/src/main/resources/jpa/savings/persistence.xml
index bf9980fa8..7849844df 100644
--- a/fineract-savings/src/main/resources/jpa/savings/persistence.xml
+++ b/fineract-savings/src/main/resources/jpa/savings/persistence.xml
@@ -48,6 +48,7 @@
         
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
         <class>org.apache.fineract.portfolio.group.domain.GroupRole</class>
         <class>org.apache.fineract.portfolio.client.domain.Client</class>
+        
<class>org.apache.fineract.portfolio.client.domain.ClientIdentifier</class>
         <class>org.apache.fineract.portfolio.fund.domain.Fund</class>
         <class>org.apache.fineract.portfolio.charge.domain.Charge</class>
         
<class>org.apache.fineract.portfolio.paymenttype.domain.PaymentType</class>
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 5d26ed4cb..537863f9f 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
@@ -27,6 +27,8 @@ import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
 import org.apache.fineract.client.models.GetClientsClientIdResponse;
 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.SortOrder;
@@ -242,4 +244,29 @@ public class ClientSearchTest {
         assertThat(result.getTotalElements()).isEqualTo(0);
         assertThat(result.getContent()).isEmpty();
     }
+
+    @Test
+    public void testClientSearchWorks_ByClientIdentifier() {
+        // given
+        PostClientsRequest request1 = 
ClientHelper.defaultClientCreationRequest();
+        request1.setMobileNo(Utils.randomNumberGenerator(8).toString());
+        PostClientsResponse clientResponse = 
clientHelper.createClient(request1);
+        final Long documentType = 1L;
+        PostClientsClientIdIdentifiersRequest identifierRequest = 
ClientHelper.createClientIdentifer(documentType);
+        final String documentKey = identifierRequest.getDocumentKey();
+        PostClientsClientIdIdentifiersResponse clientIdentifierResponse = 
clientHelper.createClientIdentifer(clientResponse.getClientId(),
+                identifierRequest);
+
+        PostClientsRequest request2 = 
ClientHelper.defaultClientCreationRequest();
+        clientHelper.createClient(request2);
+
+        PostClientsRequest request3 = 
ClientHelper.defaultClientCreationRequest();
+        clientHelper.createClient(request3);
+        // when
+        PageClientSearchData result = clientHelper.searchClients(documentKey);
+        // then
+        assertThat(result.getTotalElements()).isEqualTo(1);
+        
assertThat(result.getContent().get(0).getMobileNo()).isEqualTo(request1.getMobileNo());
+    }
+
 }
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 cfd9d50ee..82c8f54f8 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
@@ -52,6 +52,8 @@ import org.apache.fineract.client.models.PageClientSearchData;
 import org.apache.fineract.client.models.PagedRequestClientTextSearch;
 import org.apache.fineract.client.models.PostClientClientIdAddressesRequest;
 import org.apache.fineract.client.models.PostClientClientIdAddressesResponse;
+import org.apache.fineract.client.models.PostClientsClientIdIdentifiersRequest;
+import 
org.apache.fineract.client.models.PostClientsClientIdIdentifiersResponse;
 import org.apache.fineract.client.models.PostClientsClientIdResponse;
 import 
org.apache.fineract.client.models.PostClientsClientIdTransactionsTransactionIdResponse;
 import org.apache.fineract.client.models.PostClientsRequest;
@@ -105,6 +107,11 @@ public class ClientHelper extends IntegrationTest {
         return ok(fineract().clients.create6(request));
     }
 
+    public PostClientsClientIdIdentifiersResponse createClientIdentifer(final 
Long clientId,
+            final PostClientsClientIdIdentifiersRequest request) {
+        return 
ok(fineract().clientIdentifiers.createClientIdentifier(clientId, request));
+    }
+
     public PageClientSearchData searchClients(String text) {
         ClientTextSearch clientTextSearch = new ClientTextSearch();
         clientTextSearch.setText(text);
@@ -875,4 +882,10 @@ public class ClientHelper extends IntegrationTest {
     public GetLoanAccountLockResponse retrieveLockedAccounts(int page, int 
limit) {
         return ok(fineract().loanAccountLockApi.retrieveLockedAccounts(page, 
limit));
     }
+
+    public static PostClientsClientIdIdentifiersRequest 
createClientIdentifer(final Long documentType) {
+        return new 
PostClientsClientIdIdentifiersRequest().documentTypeId(documentType).documentKey(Utils.randomStringGenerator("ID_",
 10))
+                .description(Utils.randomStringGenerator("Desc_", 
50)).status("Active");
+    }
+
 }

Reply via email to