FINERACT-2073: Client search v2 using Client Identifiers
This commit is contained in:
committed by
Adam Saghy
parent
63ee58aabd
commit
e13a9cba01
@@ -48,6 +48,7 @@
|
|||||||
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
||||||
<class>org.apache.fineract.portfolio.group.domain.GroupRole</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.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.rate.domain.Rate</class>
|
||||||
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
||||||
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.portfolio.client.domain;
|
package org.apache.fineract.portfolio.client.domain;
|
||||||
|
|
||||||
|
import jakarta.persistence.CascadeType;
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.FetchType;
|
import jakarta.persistence.FetchType;
|
||||||
@@ -25,6 +26,7 @@ import jakarta.persistence.JoinColumn;
|
|||||||
import jakarta.persistence.JoinTable;
|
import jakarta.persistence.JoinTable;
|
||||||
import jakarta.persistence.ManyToMany;
|
import jakarta.persistence.ManyToMany;
|
||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
import jakarta.persistence.OneToOne;
|
import jakarta.persistence.OneToOne;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.persistence.Transient;
|
import jakarta.persistence.Transient;
|
||||||
@@ -220,6 +222,9 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
@Column(name = "proposed_transfer_date")
|
@Column(name = "proposed_transfer_date")
|
||||||
private LocalDate proposedTransferDate;
|
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,
|
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 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,
|
final LocalDate activationDate, final LocalDate officeJoiningDate, final ExternalId externalId, final String mobileNo,
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
||||||
<class>org.apache.fineract.portfolio.group.domain.GroupRole</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.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.fund.domain.Fund</class>
|
||||||
<class>org.apache.fineract.portfolio.charge.domain.Charge</class>
|
<class>org.apache.fineract.portfolio.charge.domain.Charge</class>
|
||||||
<class>org.apache.fineract.portfolio.paymenttype.domain.PaymentType</class>
|
<class>org.apache.fineract.portfolio.paymenttype.domain.PaymentType</class>
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
||||||
<class>org.apache.fineract.portfolio.group.domain.GroupRole</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.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.rate.domain.Rate</class>
|
||||||
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
||||||
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
||||||
<class>org.apache.fineract.portfolio.group.domain.GroupRole</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.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.rate.domain.Rate</class>
|
||||||
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
||||||
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
||||||
|
|||||||
+4
@@ -85,6 +85,8 @@ final class ClientIdentifiersApiResourceSwagger {
|
|||||||
public String documentKey;
|
public String documentKey;
|
||||||
@Schema(example = "Document has been verified")
|
@Schema(example = "Document has been verified")
|
||||||
public String description;
|
public String description;
|
||||||
|
@Schema(example = "Active")
|
||||||
|
public String status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(description = "PutClientsClientIdIdentifiersIdentifierIdRequest")
|
@Schema(description = "PutClientsClientIdIdentifiersIdentifierIdRequest")
|
||||||
@@ -98,6 +100,8 @@ final class ClientIdentifiersApiResourceSwagger {
|
|||||||
public String documentKey;
|
public String documentKey;
|
||||||
@Schema(example = "Document has been updated")
|
@Schema(example = "Document has been updated")
|
||||||
public String description;
|
public String description;
|
||||||
|
@Schema(example = "Active")
|
||||||
|
public String status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(description = "PutClientsClientIdIdentifiersIdentifierIdResponse")
|
@Schema(description = "PutClientsClientIdIdentifiersIdentifierIdResponse")
|
||||||
|
|||||||
+6
-1
@@ -22,6 +22,8 @@ import jakarta.persistence.EntityManager;
|
|||||||
import jakarta.persistence.TypedQuery;
|
import jakarta.persistence.TypedQuery;
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
import jakarta.persistence.criteria.Join;
|
||||||
|
import jakarta.persistence.criteria.JoinType;
|
||||||
import jakarta.persistence.criteria.Order;
|
import jakarta.persistence.criteria.Order;
|
||||||
import jakarta.persistence.criteria.Path;
|
import jakarta.persistence.criteria.Path;
|
||||||
import jakarta.persistence.criteria.Predicate;
|
import jakarta.persistence.criteria.Predicate;
|
||||||
@@ -32,6 +34,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.apache.fineract.infrastructure.core.jpa.CriteriaQueryFactory;
|
import org.apache.fineract.infrastructure.core.jpa.CriteriaQueryFactory;
|
||||||
import org.apache.fineract.organisation.office.domain.Office;
|
import org.apache.fineract.organisation.office.domain.Office;
|
||||||
import org.apache.fineract.portfolio.client.domain.Client;
|
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.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
@@ -62,13 +65,15 @@ public class SearchingClientRepositoryImpl implements SearchingClientRepository
|
|||||||
|
|
||||||
Specification<Client> spec = (r, q, builder) -> {
|
Specification<Client> spec = (r, q, builder) -> {
|
||||||
Path<Office> o = r.get("office");
|
Path<Office> o = r.get("office");
|
||||||
|
Join<Client, ClientIdentifier> identity = r.join("identifiers", JoinType.LEFT);
|
||||||
|
|
||||||
List<Predicate> predicates = new ArrayList<>();
|
List<Predicate> predicates = new ArrayList<>();
|
||||||
predicates.add(cb.like(o.get("hierarchy"), hierarchyLikeValue));
|
predicates.add(cb.like(o.get("hierarchy"), hierarchyLikeValue));
|
||||||
|
|
||||||
String searchLikeValue = "%" + searchText + "%";
|
String searchLikeValue = "%" + searchText + "%";
|
||||||
predicates.add(cb.or(cb.like(r.get("accountNumber"), searchLikeValue), cb.like(r.get("displayName"), searchLikeValue),
|
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]));
|
return cb.and(predicates.toArray(new Predicate[0]));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
||||||
<class>org.apache.fineract.portfolio.group.domain.GroupRole</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.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.rate.domain.Rate</class>
|
||||||
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
||||||
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
||||||
<class>org.apache.fineract.portfolio.group.domain.GroupRole</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.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.rate.domain.Rate</class>
|
||||||
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
|
||||||
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
<class>org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory</class>
|
||||||
<class>org.apache.fineract.portfolio.group.domain.GroupRole</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.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.fund.domain.Fund</class>
|
||||||
<class>org.apache.fineract.portfolio.charge.domain.Charge</class>
|
<class>org.apache.fineract.portfolio.charge.domain.Charge</class>
|
||||||
<class>org.apache.fineract.portfolio.paymenttype.domain.PaymentType</class>
|
<class>org.apache.fineract.portfolio.paymenttype.domain.PaymentType</class>
|
||||||
|
|||||||
+27
@@ -27,6 +27,8 @@ import io.restassured.specification.RequestSpecification;
|
|||||||
import io.restassured.specification.ResponseSpecification;
|
import io.restassured.specification.ResponseSpecification;
|
||||||
import org.apache.fineract.client.models.GetClientsClientIdResponse;
|
import org.apache.fineract.client.models.GetClientsClientIdResponse;
|
||||||
import org.apache.fineract.client.models.PageClientSearchData;
|
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.PostClientsRequest;
|
||||||
import org.apache.fineract.client.models.PostClientsResponse;
|
import org.apache.fineract.client.models.PostClientsResponse;
|
||||||
import org.apache.fineract.client.models.SortOrder;
|
import org.apache.fineract.client.models.SortOrder;
|
||||||
@@ -242,4 +244,29 @@ public class ClientSearchTest {
|
|||||||
assertThat(result.getTotalElements()).isEqualTo(0);
|
assertThat(result.getTotalElements()).isEqualTo(0);
|
||||||
assertThat(result.getContent()).isEmpty();
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -52,6 +52,8 @@ import org.apache.fineract.client.models.PageClientSearchData;
|
|||||||
import org.apache.fineract.client.models.PagedRequestClientTextSearch;
|
import org.apache.fineract.client.models.PagedRequestClientTextSearch;
|
||||||
import org.apache.fineract.client.models.PostClientClientIdAddressesRequest;
|
import org.apache.fineract.client.models.PostClientClientIdAddressesRequest;
|
||||||
import org.apache.fineract.client.models.PostClientClientIdAddressesResponse;
|
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.PostClientsClientIdResponse;
|
||||||
import org.apache.fineract.client.models.PostClientsClientIdTransactionsTransactionIdResponse;
|
import org.apache.fineract.client.models.PostClientsClientIdTransactionsTransactionIdResponse;
|
||||||
import org.apache.fineract.client.models.PostClientsRequest;
|
import org.apache.fineract.client.models.PostClientsRequest;
|
||||||
@@ -105,6 +107,11 @@ public class ClientHelper extends IntegrationTest {
|
|||||||
return ok(fineract().clients.create6(request));
|
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) {
|
public PageClientSearchData searchClients(String text) {
|
||||||
ClientTextSearch clientTextSearch = new ClientTextSearch();
|
ClientTextSearch clientTextSearch = new ClientTextSearch();
|
||||||
clientTextSearch.setText(text);
|
clientTextSearch.setText(text);
|
||||||
@@ -875,4 +882,10 @@ public class ClientHelper extends IntegrationTest {
|
|||||||
public GetLoanAccountLockResponse retrieveLockedAccounts(int page, int limit) {
|
public GetLoanAccountLockResponse retrieveLockedAccounts(int page, int limit) {
|
||||||
return ok(fineract().loanAccountLockApi.retrieveLockedAccounts(page, 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");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user