FINERACT-1724: Client search V2 API
This commit is contained in:
committed by
Arnold Gálovics
parent
c18fead7f3
commit
68c6053bd7
@@ -52,6 +52,7 @@ import org.apache.fineract.client.services.ChargesApi;
|
||||
import org.apache.fineract.client.services.ClientApi;
|
||||
import org.apache.fineract.client.services.ClientChargesApi;
|
||||
import org.apache.fineract.client.services.ClientIdentifierApi;
|
||||
import org.apache.fineract.client.services.ClientSearchV2Api;
|
||||
import org.apache.fineract.client.services.ClientTransactionApi;
|
||||
import org.apache.fineract.client.services.ClientsAddressApi;
|
||||
import org.apache.fineract.client.services.CodeValuesApi;
|
||||
@@ -153,7 +154,7 @@ import retrofit2.Retrofit;
|
||||
import retrofit2.converter.scalars.ScalarsConverterFactory;
|
||||
|
||||
/**
|
||||
* Fineract Client Java SDK API entry point. Use this instead of the {@link ApiClient}.
|
||||
* Fineract Client Java SDK API entry point.
|
||||
*
|
||||
* @author Michael Vorburger.ch
|
||||
*/
|
||||
@@ -187,6 +188,8 @@ public final class FineractClient {
|
||||
public final CentersApi centers;
|
||||
public final ChargesApi charges;
|
||||
public final ClientApi clients;
|
||||
|
||||
public final ClientSearchV2Api clientSearchV2;
|
||||
public final ClientChargesApi clientCharges;
|
||||
public final ClientIdentifierApi clientIdentifiers;
|
||||
public final ClientsAddressApi clientAddresses;
|
||||
@@ -305,6 +308,7 @@ public final class FineractClient {
|
||||
centers = retrofit.create(CentersApi.class);
|
||||
charges = retrofit.create(ChargesApi.class);
|
||||
clients = retrofit.create(ClientApi.class);
|
||||
clientSearchV2 = retrofit.create(ClientSearchV2Api.class);
|
||||
clientCharges = retrofit.create(ClientChargesApi.class);
|
||||
clientIdentifiers = retrofit.create(ClientIdentifierApi.class);
|
||||
clientAddresses = retrofit.create(ClientsAddressApi.class);
|
||||
@@ -537,7 +541,6 @@ public final class FineractClient {
|
||||
* Obtain the internal Retrofit Builder. This method is typically not required to be invoked for simple API
|
||||
* usages, but can be a handy back door for non-trivial advanced customizations of the API client.
|
||||
*
|
||||
* @return the {@link ApiClient} which {@link #build()} will use.
|
||||
*/
|
||||
public retrofit2.Retrofit.Builder getRetrofitBuilder() {
|
||||
return retrofitBuilder;
|
||||
@@ -547,7 +550,6 @@ public final class FineractClient {
|
||||
* Obtain the internal OkHttp Builder. This method is typically not required to be invoked for simple API
|
||||
* usages, but can be a handy back door for non-trivial advanced customizations of the API client.
|
||||
*
|
||||
* @return the {@link ApiClient} which {@link #build()} will use.
|
||||
*/
|
||||
public okhttp3.OkHttpClient.Builder getOkBuilder() {
|
||||
return okBuilder;
|
||||
|
||||
@@ -37,6 +37,8 @@ import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.ResponseBody;
|
||||
import org.apache.fineract.client.models.ExternalId;
|
||||
import org.apache.fineract.client.util.adapter.ExternalIdAdapter;
|
||||
import retrofit2.Converter;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
@@ -51,12 +53,14 @@ public class JSON {
|
||||
private final SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
|
||||
private final OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
|
||||
private final LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
|
||||
private final ExternalIdAdapter externalIdAdapter = new ExternalIdAdapter();
|
||||
|
||||
public JSON() {
|
||||
gson = new GsonFireBuilder().createGsonBuilder().registerTypeAdapter(Date.class, dateTypeAdapter)
|
||||
.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter)
|
||||
.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
|
||||
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter).create();
|
||||
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter).registerTypeAdapter(ExternalId.class, externalIdAdapter)
|
||||
.create();
|
||||
}
|
||||
|
||||
public Gson getGson() {
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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.client.util.adapter;
|
||||
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import org.apache.fineract.client.models.ExternalId;
|
||||
|
||||
public class ExternalIdAdapter extends TypeAdapter<ExternalId> {
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, ExternalId value) throws IOException {
|
||||
if (value != null && Boolean.FALSE.equals(value.getEmpty())) {
|
||||
out.value(value.getValue());
|
||||
} else {
|
||||
out.nullValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalId read(JsonReader in) throws IOException {
|
||||
ExternalId result = new ExternalId().empty(true);
|
||||
switch (in.peek()) {
|
||||
case NULL:
|
||||
in.nextNull();
|
||||
return result;
|
||||
default:
|
||||
String value = in.nextString();
|
||||
return new ExternalId().empty(false).value(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jpa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.Order;
|
||||
import javax.persistence.criteria.Root;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CriteriaQueryFactory {
|
||||
|
||||
public List<Order> fromPageable(Pageable pageable, CriteriaBuilder cb, Root<?> root) {
|
||||
return fromPageable(pageable, cb, root, () -> null);
|
||||
}
|
||||
|
||||
public List<Order> fromPageable(Pageable pageable, CriteriaBuilder cb, Root<?> root, Supplier<Order> defaultOrderSupplier) {
|
||||
List<Order> orders = new ArrayList<>();
|
||||
Sort sort = pageable.getSort();
|
||||
if (sort.isSorted()) {
|
||||
for (Sort.Order order : sort) {
|
||||
if (order.isAscending()) {
|
||||
orders.add(cb.asc(root.get(order.getProperty())));
|
||||
} else {
|
||||
orders.add(cb.desc(root.get(order.getProperty())));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Order defaultOrder = defaultOrderSupplier.get();
|
||||
if (defaultOrder != null) {
|
||||
orders.add(defaultOrder);
|
||||
}
|
||||
}
|
||||
return orders;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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.infrastructure.core.service;
|
||||
|
||||
import static org.apache.commons.collections4.CollectionUtils.isEmpty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import lombok.Data;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
@Data
|
||||
public class PagedRequest<T> {
|
||||
|
||||
public static final int DEFAULT_PAGE_SIZE = 50;
|
||||
|
||||
private T request;
|
||||
|
||||
private int page;
|
||||
private int size = DEFAULT_PAGE_SIZE;
|
||||
|
||||
private List<SortOrder> sorts = new ArrayList<>();
|
||||
|
||||
public Optional<T> getRequest() {
|
||||
return Optional.ofNullable(request);
|
||||
}
|
||||
|
||||
public Pageable toPageable() {
|
||||
if (isEmpty(sorts)) {
|
||||
return PageRequest.of(page, size);
|
||||
} else {
|
||||
List<Sort.Order> orders = sorts.stream().map(SortOrder::toOrder).toList();
|
||||
return PageRequest.of(page, size, Sort.by(orders));
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@SuppressWarnings({ "unused" })
|
||||
private static class SortOrder {
|
||||
|
||||
private Direction direction;
|
||||
private String property;
|
||||
|
||||
private enum Direction {
|
||||
ASC, DESC;
|
||||
}
|
||||
|
||||
private Sort.Order toOrder() {
|
||||
Sort.Direction d = Sort.Direction.fromString(direction.name());
|
||||
return new Sort.Order(d, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.fineract.infrastructure.core.config;
|
||||
package org.apache.fineract.infrastructure.core.jersey;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jersey;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.infrastructure.core.jersey.converter.JsonConverter;
|
||||
import org.apache.fineract.infrastructure.core.jersey.serializer.JacksonDeserializerAdapter;
|
||||
import org.apache.fineract.infrastructure.core.jersey.serializer.JacksonSerializerAdapter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
|
||||
@Configuration
|
||||
public class JerseyJacksonConverterConfig {
|
||||
|
||||
@Bean
|
||||
public MappingJackson2HttpMessageConverter jacksonHttpConverter(List<JsonSerializer<?>> serializers,
|
||||
List<JsonDeserializer<?>> deserializers, List<JsonConverter<?>> jsonConverters) {
|
||||
List<JsonSerializer<?>> mergedSerializers = new ArrayList<>(serializers);
|
||||
mergedSerializers.addAll(jsonConverters.stream().map(JacksonSerializerAdapter::new).toList());
|
||||
|
||||
List<JsonDeserializer<?>> mergedDeserializers = new ArrayList<>(deserializers);
|
||||
mergedDeserializers.addAll(jsonConverters.stream().map(JacksonDeserializerAdapter::new).toList());
|
||||
|
||||
return new MappingJackson2HttpMessageConverter(new Jackson2ObjectMapperBuilder().indentOutput(true)
|
||||
.serializers(mergedSerializers.toArray(new JsonSerializer[0]))
|
||||
.deserializers(mergedDeserializers.toArray(new JsonDeserializer[0]))
|
||||
.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS).modulesToInstall(new ParameterNamesModule()).build());
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jersey;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.ext.MessageBodyReader;
|
||||
import javax.ws.rs.ext.MessageBodyWriter;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonInputMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Provider
|
||||
@Produces(MediaType.APPLICATION_JSON_VALUE)
|
||||
@Consumes(MediaType.APPLICATION_JSON_VALUE)
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class JerseyJacksonObjectArgumentHandler<T> implements MessageBodyReader<T>, MessageBodyWriter<T> {
|
||||
|
||||
private final MappingJackson2HttpMessageConverter converter;
|
||||
|
||||
@Override
|
||||
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, javax.ws.rs.core.MediaType mediaType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, javax.ws.rs.core.MediaType mediaType,
|
||||
MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
|
||||
if (String.class == genericType) {
|
||||
// If the request type is String, keep it that way.
|
||||
StringWriter writer = new StringWriter();
|
||||
IOUtils.copy(entityStream, writer, UTF_8);
|
||||
String json = writer.toString();
|
||||
return type.cast(json);
|
||||
} else {
|
||||
// Create the proper type from the JSON
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.putAll(httpHeaders);
|
||||
return (T) converter.read(genericType, type, new MappingJacksonInputMessage(entityStream, headers));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, javax.ws.rs.core.MediaType mediaType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(T t, Class<?> type, Type genericType, Annotation[] annotations, javax.ws.rs.core.MediaType mediaType,
|
||||
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
|
||||
if (String.class == genericType) {
|
||||
// If the response type is String, keep it that way.
|
||||
IOUtils.write((String) t, entityStream, UTF_8);
|
||||
} else {
|
||||
// Create the proper JSON string from the object
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
httpHeaders.forEach((header, rawValues) -> {
|
||||
List<String> values = rawValues.stream().map(Object::toString).toList();
|
||||
headers.put(header, values);
|
||||
});
|
||||
converter.write(t, genericType, MediaType.APPLICATION_JSON, new SimpleHttpOutputMessage(entityStream, headers));
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class SimpleHttpOutputMessage implements HttpOutputMessage {
|
||||
|
||||
private final OutputStream outputStream;
|
||||
private final HttpHeaders headers;
|
||||
|
||||
@Override
|
||||
public OutputStream getBody() throws IOException {
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jersey.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class DateJsonConverter implements JsonConverter<Date> {
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_INSTANT;
|
||||
|
||||
@Override
|
||||
public Date convertToObject(JsonParser parser) throws IOException {
|
||||
Date result = null;
|
||||
if (parser.hasToken(JsonToken.VALUE_STRING)) {
|
||||
String formattedDate = parser.getText();
|
||||
result = Date.from(Instant.from(FORMATTER.parse(formattedDate)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToJson(Date value, JsonGenerator generator) throws IOException {
|
||||
if (value != null) {
|
||||
generator.writeString(FORMATTER.format(value.toInstant()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Date> convertedType() {
|
||||
return Date.class;
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jersey.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import java.io.IOException;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ExternalIdJsonConverter implements JsonConverter<ExternalId> {
|
||||
|
||||
@Override
|
||||
public ExternalId convertToObject(JsonParser parser) throws IOException {
|
||||
ExternalId result = ExternalId.empty();
|
||||
if (parser.hasToken(JsonToken.VALUE_STRING)) {
|
||||
String externalId = parser.getText();
|
||||
result = new ExternalId(externalId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToJson(ExternalId value, JsonGenerator generator) throws IOException {
|
||||
if (value != null && !value.isEmpty()) {
|
||||
generator.writeString(value.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<ExternalId> convertedType() {
|
||||
return ExternalId.class;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jersey.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface JsonConverter<T> {
|
||||
|
||||
T convertToObject(JsonParser parser) throws IOException;
|
||||
|
||||
void convertToJson(T value, JsonGenerator generator) throws IOException;
|
||||
|
||||
Class<T> convertedType();
|
||||
}
|
||||
+55
@@ -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.infrastructure.core.jersey.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class LocalDateJsonConverter implements JsonConverter<LocalDate> {
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE;
|
||||
|
||||
@Override
|
||||
public LocalDate convertToObject(JsonParser parser) throws IOException {
|
||||
LocalDate result = null;
|
||||
if (parser.hasToken(JsonToken.VALUE_STRING)) {
|
||||
String formattedDate = parser.getText();
|
||||
result = LocalDate.parse(formattedDate, FORMATTER);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToJson(LocalDate value, JsonGenerator generator) throws IOException {
|
||||
if (value != null) {
|
||||
generator.writeString(FORMATTER.format(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<LocalDate> convertedType() {
|
||||
return LocalDate.class;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jersey.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class LocalDateTimeJsonConverter implements JsonConverter<LocalDateTime> {
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
|
||||
@Override
|
||||
public LocalDateTime convertToObject(JsonParser parser) throws IOException {
|
||||
LocalDateTime result = null;
|
||||
if (parser.hasToken(JsonToken.VALUE_STRING)) {
|
||||
String formattedDate = parser.getText();
|
||||
result = LocalDateTime.parse(formattedDate, FORMATTER);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToJson(LocalDateTime value, JsonGenerator generator) throws IOException {
|
||||
if (value != null) {
|
||||
generator.writeString(FORMATTER.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<LocalDateTime> convertedType() {
|
||||
return LocalDateTime.class;
|
||||
}
|
||||
}
|
||||
+55
@@ -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.infrastructure.core.jersey.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class LocalTimeJsonConverter implements JsonConverter<LocalTime> {
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_TIME;
|
||||
|
||||
@Override
|
||||
public LocalTime convertToObject(JsonParser parser) throws IOException {
|
||||
LocalTime result = null;
|
||||
if (parser.hasToken(JsonToken.VALUE_STRING)) {
|
||||
String formattedDate = parser.getText();
|
||||
result = LocalTime.parse(formattedDate, FORMATTER);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToJson(LocalTime value, JsonGenerator generator) throws IOException {
|
||||
if (value != null) {
|
||||
generator.writeString(FORMATTER.format(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<LocalTime> convertedType() {
|
||||
return LocalTime.class;
|
||||
}
|
||||
}
|
||||
+55
@@ -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.infrastructure.core.jersey.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import java.io.IOException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class OffsetDateTimeJsonConverter implements JsonConverter<OffsetDateTime> {
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||
|
||||
@Override
|
||||
public OffsetDateTime convertToObject(JsonParser parser) throws IOException {
|
||||
OffsetDateTime result = null;
|
||||
if (parser.hasToken(JsonToken.VALUE_STRING)) {
|
||||
String formattedDate = parser.getText();
|
||||
result = OffsetDateTime.parse(formattedDate, FORMATTER);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertToJson(OffsetDateTime value, JsonGenerator generator) throws IOException {
|
||||
if (value != null) {
|
||||
generator.writeString(FORMATTER.format(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<OffsetDateTime> convertedType() {
|
||||
return OffsetDateTime.class;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jersey.serializer;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import java.io.IOException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.jersey.converter.JsonConverter;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class JacksonDeserializerAdapter<T> extends JsonDeserializer<T> {
|
||||
|
||||
private final JsonConverter<T> converter;
|
||||
|
||||
@Override
|
||||
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
|
||||
return converter.convertToObject(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> handledType() {
|
||||
return converter.convertedType();
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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.infrastructure.core.jersey.serializer;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import java.io.IOException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.jersey.converter.JsonConverter;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class JacksonSerializerAdapter<T> extends JsonSerializer<T> {
|
||||
|
||||
private final JsonConverter<T> converter;
|
||||
|
||||
@Override
|
||||
public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
converter.convertToJson(value, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> handledType() {
|
||||
return converter.convertedType();
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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.client.api.v2.search;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.service.PagedRequest;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientSearchData;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientTextSearch;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
public interface ClientSearchV2Api {
|
||||
|
||||
Page<ClientSearchData> searchByText(PagedRequest<ClientTextSearch> request);
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 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.client.api.v2.search;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.service.PagedRequest;
|
||||
import org.apache.fineract.portfolio.client.service.search.ClientSearchService;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientSearchData;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientTextSearch;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ClientSearchV2ApiDelegate implements ClientSearchV2Api {
|
||||
|
||||
private final ClientSearchService searchService;
|
||||
|
||||
@Override
|
||||
public Page<ClientSearchData> searchByText(PagedRequest<ClientTextSearch> request) {
|
||||
return searchService.searchByText(request);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* 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.client.api.v2.search;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.service.PagedRequest;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientSearchData;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientTextSearch;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/v2/clients")
|
||||
@Component
|
||||
@Tag(name = "ClientSearchV2")
|
||||
@RequiredArgsConstructor
|
||||
public class ClientSearchV2ApiResource implements ClientSearchV2Api {
|
||||
|
||||
private final ClientSearchV2ApiDelegate delegate;
|
||||
|
||||
@Override
|
||||
@POST
|
||||
@Path("search")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(summary = "Search Clients by text")
|
||||
public Page<ClientSearchData> searchByText(@Parameter PagedRequest<ClientTextSearch> request) {
|
||||
return delegate.searchByText(request);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -19,12 +19,13 @@
|
||||
package org.apache.fineract.portfolio.client.domain;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.portfolio.client.domain.search.SearchingClientRepository;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
interface ClientRepository extends JpaRepository<Client, Long>, JpaSpecificationExecutor<Client> {
|
||||
public interface ClientRepository extends JpaRepository<Client, Long>, JpaSpecificationExecutor<Client>, SearchingClientRepository {
|
||||
|
||||
String FIND_CLIENT_BY_ACCOUNT_NUMBER = "select client from Client client where client.accountNumber = :accountNumber";
|
||||
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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.client.domain.search;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.OffsetDateTime;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class SearchedClient {
|
||||
|
||||
private final Long id;
|
||||
private final String displayName;
|
||||
private final ExternalId externalId;
|
||||
private final String accountNo;
|
||||
private final Long officeId;
|
||||
private final String officeName;
|
||||
private final String mobileNo;
|
||||
private final Integer status;
|
||||
private final LocalDate activationDate;
|
||||
private final OffsetDateTime createdDate;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.client.domain.search;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
public interface SearchingClientRepository {
|
||||
|
||||
Page<SearchedClient> searchByText(String searchText, Pageable pageable, String officeHierarchy);
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 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.client.domain.search;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Order;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
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.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class SearchingClientRepositoryImpl implements SearchingClientRepository {
|
||||
|
||||
private final EntityManager entityManager;
|
||||
private final CriteriaQueryFactory criteriaQueryFactory;
|
||||
|
||||
@Override
|
||||
public Page<SearchedClient> searchByText(String searchText, Pageable pageable, String officeHierarchy) {
|
||||
/*
|
||||
* this whole thing can be replaced with Spring Data JPA 3+ with a findBy(Specification, Pageable) call but at
|
||||
* this point the upgrade is too costly
|
||||
*
|
||||
* https://github.com/spring-projects/spring-data-jpa/issues/2499
|
||||
*/
|
||||
String hierarchyLikeValue = officeHierarchy + "%";
|
||||
|
||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<SearchedClient> query = cb.createQuery(SearchedClient.class);
|
||||
Root<Client> root = query.from(Client.class);
|
||||
Path<Office> office = root.get("office");
|
||||
|
||||
query.select(cb.construct(SearchedClient.class, root.get("id"), root.get("displayName"), root.get("externalId"),
|
||||
root.get("accountNumber"), office.get("id"), office.get("name"), root.get("mobileNo"), root.get("status"),
|
||||
root.get("activationDate"), root.get("createdDate")));
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
predicates.add(cb.like(office.get("hierarchy"), hierarchyLikeValue));
|
||||
|
||||
String searchLikeValue = "%" + searchText + "%";
|
||||
predicates.add(cb.or(cb.like(root.get("accountNumber"), searchLikeValue), cb.like(root.get("displayName"), searchLikeValue),
|
||||
cb.like(root.get("externalId"), searchLikeValue), cb.like(root.get("mobileNo"), searchLikeValue)));
|
||||
|
||||
query.where(cb.and(predicates.toArray(new Predicate[0])));
|
||||
|
||||
List<Order> orders = criteriaQueryFactory.fromPageable(pageable, cb, root, () -> cb.desc(root.get("id")));
|
||||
query.orderBy(orders);
|
||||
|
||||
List<SearchedClient> result = entityManager.createQuery(query).setFirstResult(pageable.getPageNumber())
|
||||
.setMaxResults(pageable.getPageSize()).getResultList();
|
||||
|
||||
return new PageImpl<>(result, pageable, result.size());
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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.client.service.search;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.PagedRequest;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientRepository;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientSearchData;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientTextSearch;
|
||||
import org.apache.fineract.portfolio.client.service.search.mapper.ClientSearchDataMapper;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
@Transactional(readOnly = true)
|
||||
@RequiredArgsConstructor
|
||||
public class ClientSearchService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final ClientRepository clientRepository;
|
||||
private final ClientSearchDataMapper clientSearchDataMapper;
|
||||
|
||||
public Page<ClientSearchData> searchByText(PagedRequest<ClientTextSearch> searchRequest) {
|
||||
validateTextSearchRequest(searchRequest);
|
||||
return executeTextSearch(searchRequest);
|
||||
}
|
||||
|
||||
private void validateTextSearchRequest(PagedRequest<ClientTextSearch> searchRequest) {
|
||||
Objects.requireNonNull(searchRequest, "searchRequest must not be null");
|
||||
|
||||
context.isAuthenticated();
|
||||
}
|
||||
|
||||
private Page<ClientSearchData> executeTextSearch(PagedRequest<ClientTextSearch> searchRequest) {
|
||||
final String hierarchy = context.authenticatedUser().getOffice().getHierarchy();
|
||||
|
||||
Optional<ClientTextSearch> request = searchRequest.getRequest();
|
||||
String requestSearchText = request.map(ClientTextSearch::getText).orElse(null);
|
||||
String searchText = StringUtils.defaultString(requestSearchText, "");
|
||||
|
||||
Pageable pageable = searchRequest.toPageable();
|
||||
|
||||
return clientRepository.searchByText(searchText, pageable, hierarchy).map(clientSearchDataMapper::map);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.client.service.search.domain;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.OffsetDateTime;
|
||||
import lombok.Data;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
|
||||
@Data
|
||||
public class ClientSearchData {
|
||||
|
||||
private Long id;
|
||||
private String displayName;
|
||||
private ExternalId externalId;
|
||||
private String accountNo;
|
||||
private Long officeId;
|
||||
private String officeName;
|
||||
private String mobileNo;
|
||||
private EnumOptionData status;
|
||||
private LocalDate activationDate;
|
||||
private OffsetDateTime createdDate;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.client.service.search.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ClientTextSearch {
|
||||
|
||||
private String text;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.client.service.search.mapper;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientEnumerations;
|
||||
import org.apache.fineract.portfolio.client.domain.search.SearchedClient;
|
||||
import org.apache.fineract.portfolio.client.service.search.domain.ClientSearchData;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Named;
|
||||
|
||||
@Mapper(config = MapstructMapperConfig.class)
|
||||
public interface ClientSearchDataMapper {
|
||||
|
||||
@Mapping(target = "status", source = "source", qualifiedByName = "toStatus")
|
||||
ClientSearchData map(SearchedClient source);
|
||||
|
||||
@Named("toStatus")
|
||||
default EnumOptionData toStatus(SearchedClient client) {
|
||||
return ClientEnumerations.status(client.getStatus());
|
||||
}
|
||||
}
|
||||
+1
@@ -22,6 +22,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.ws.rs.Path;
|
||||
import org.apache.fineract.AbstractSpringTest;
|
||||
import org.apache.fineract.infrastructure.core.jersey.JerseyConfig;
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.integrationtests.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 org.apache.fineract.client.models.GetClientsClientIdResponse;
|
||||
import org.apache.fineract.client.models.PageClientSearchData;
|
||||
import org.apache.fineract.client.models.PostClientsRequest;
|
||||
import org.apache.fineract.client.models.PostClientsResponse;
|
||||
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 {
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
private RequestSpecification requestSpec;
|
||||
private ClientHelper clientHelper;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
Utils.initializeRESTAssured();
|
||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||
clientHelper = new ClientHelper(requestSpec, responseSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientSearchWorks_WithLastnameTextOnDefaultOrdering() {
|
||||
// given
|
||||
String lastname = Utils.randomStringGenerator("Client_LastName_", 5);
|
||||
PostClientsRequest request1 = ClientHelper.defaultClientCreationRequest();
|
||||
request1.setLastname(lastname);
|
||||
clientHelper.createClient(request1);
|
||||
|
||||
PostClientsRequest request2 = ClientHelper.defaultClientCreationRequest();
|
||||
request2.setLastname(lastname);
|
||||
clientHelper.createClient(request2);
|
||||
|
||||
PostClientsRequest request3 = ClientHelper.defaultClientCreationRequest();
|
||||
request3.setLastname(lastname);
|
||||
clientHelper.createClient(request3);
|
||||
// when
|
||||
PageClientSearchData result = clientHelper.searchClients(lastname);
|
||||
// then
|
||||
assertThat(result.getTotalElements()).isEqualTo(3);
|
||||
assertThat(result.getContent().get(0).getExternalId().getValue()).isEqualTo(request3.getExternalId());
|
||||
assertThat(result.getContent().get(1).getExternalId().getValue()).isEqualTo(request2.getExternalId());
|
||||
assertThat(result.getContent().get(2).getExternalId().getValue()).isEqualTo(request1.getExternalId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientSearchWorks_WithLastnameText_OrderedByIdAsc() {
|
||||
// given
|
||||
String lastname = Utils.randomStringGenerator("Client_LastName_", 5);
|
||||
PostClientsRequest request1 = ClientHelper.defaultClientCreationRequest();
|
||||
request1.setLastname(lastname);
|
||||
clientHelper.createClient(request1);
|
||||
|
||||
PostClientsRequest request2 = ClientHelper.defaultClientCreationRequest();
|
||||
request2.setLastname(lastname);
|
||||
clientHelper.createClient(request2);
|
||||
|
||||
PostClientsRequest request3 = ClientHelper.defaultClientCreationRequest();
|
||||
request3.setLastname(lastname);
|
||||
clientHelper.createClient(request3);
|
||||
|
||||
SortOrder sortOrder = new SortOrder().property("id").direction(SortOrder.DirectionEnum.ASC);
|
||||
// when
|
||||
PageClientSearchData result = clientHelper.searchClients(lastname, sortOrder);
|
||||
// then
|
||||
assertThat(result.getTotalElements()).isEqualTo(3);
|
||||
assertThat(result.getContent().get(0).getExternalId().getValue()).isEqualTo(request1.getExternalId());
|
||||
assertThat(result.getContent().get(1).getExternalId().getValue()).isEqualTo(request2.getExternalId());
|
||||
assertThat(result.getContent().get(2).getExternalId().getValue()).isEqualTo(request3.getExternalId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientSearchWorks_ByExternalId() {
|
||||
// given
|
||||
PostClientsRequest request1 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request1);
|
||||
|
||||
PostClientsRequest request2 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request2);
|
||||
|
||||
PostClientsRequest request3 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request3);
|
||||
// when
|
||||
PageClientSearchData result = clientHelper.searchClients(request2.getExternalId());
|
||||
// then
|
||||
assertThat(result.getTotalElements()).isEqualTo(1);
|
||||
assertThat(result.getContent().get(0).getExternalId().getValue()).isEqualTo(request2.getExternalId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientSearchWorks_ByAccountNumber() {
|
||||
// given
|
||||
PostClientsRequest request1 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request1);
|
||||
|
||||
PostClientsRequest request2 = ClientHelper.defaultClientCreationRequest();
|
||||
PostClientsResponse response2 = clientHelper.createClient(request2);
|
||||
GetClientsClientIdResponse client2Data = ClientHelper.getClient(requestSpec, responseSpec,
|
||||
Math.toIntExact(response2.getClientId()));
|
||||
|
||||
PostClientsRequest request3 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request3);
|
||||
// when
|
||||
PageClientSearchData result = clientHelper.searchClients(client2Data.getAccountNo());
|
||||
// then
|
||||
assertThat(result.getTotalElements()).isEqualTo(1);
|
||||
assertThat(result.getContent().get(0).getAccountNo()).isEqualTo(client2Data.getAccountNo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientSearchWorks_ByDisplayName() {
|
||||
// given
|
||||
PostClientsRequest request1 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request1);
|
||||
|
||||
PostClientsRequest request2 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request2);
|
||||
String client2DisplayName = "%s %s".formatted(request2.getFirstname(), request2.getLastname());
|
||||
|
||||
PostClientsRequest request3 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request3);
|
||||
// when
|
||||
PageClientSearchData result = clientHelper.searchClients(client2DisplayName);
|
||||
// then
|
||||
assertThat(result.getTotalElements()).isEqualTo(1);
|
||||
assertThat(result.getContent().get(0).getDisplayName()).isEqualTo(client2DisplayName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientSearchWorks_ByMobileNo() {
|
||||
// given
|
||||
PostClientsRequest request1 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request1);
|
||||
|
||||
PostClientsRequest request2 = ClientHelper.defaultClientCreationRequest();
|
||||
request2.setMobileNo(Utils.randomNumberGenerator(8).toString());
|
||||
clientHelper.createClient(request2);
|
||||
|
||||
PostClientsRequest request3 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request3);
|
||||
// when
|
||||
PageClientSearchData result = clientHelper.searchClients(request2.getMobileNo());
|
||||
// then
|
||||
assertThat(result.getTotalElements()).isEqualTo(1);
|
||||
assertThat(result.getContent().get(0).getMobileNo()).isEqualTo(request2.getMobileNo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientSearchDoesntReturnAnything_ByMobileNo() {
|
||||
// given
|
||||
PostClientsRequest request1 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request1);
|
||||
|
||||
PostClientsRequest request2 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request2);
|
||||
|
||||
PostClientsRequest request3 = ClientHelper.defaultClientCreationRequest();
|
||||
clientHelper.createClient(request3);
|
||||
// when
|
||||
PageClientSearchData result = clientHelper.searchClients(Utils.randomNumberGenerator(8).toString());
|
||||
// then
|
||||
assertThat(result.getTotalElements()).isEqualTo(0);
|
||||
assertThat(result.getContent()).isEmpty();
|
||||
}
|
||||
}
|
||||
+25
@@ -38,18 +38,22 @@ import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.ClientTextSearch;
|
||||
import org.apache.fineract.client.models.DeleteClientsClientIdResponse;
|
||||
import org.apache.fineract.client.models.GetClientClientIdAddressesResponse;
|
||||
import org.apache.fineract.client.models.GetClientTransferProposalDateResponse;
|
||||
import org.apache.fineract.client.models.GetClientsClientIdAccountsResponse;
|
||||
import org.apache.fineract.client.models.GetClientsClientIdResponse;
|
||||
import org.apache.fineract.client.models.GetObligeeData;
|
||||
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.PostClientsClientIdResponse;
|
||||
import org.apache.fineract.client.models.PostClientsRequest;
|
||||
import org.apache.fineract.client.models.PostClientsResponse;
|
||||
import org.apache.fineract.client.models.PutClientsClientIdResponse;
|
||||
import org.apache.fineract.client.models.SortOrder;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
|
||||
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
||||
@@ -97,6 +101,27 @@ public class ClientHelper extends IntegrationTest {
|
||||
return ok(fineract().clients.create6(request));
|
||||
}
|
||||
|
||||
public PageClientSearchData searchClients(String text) {
|
||||
ClientTextSearch clientTextSearch = new ClientTextSearch();
|
||||
clientTextSearch.setText(text);
|
||||
PagedRequestClientTextSearch request = new PagedRequestClientTextSearch();
|
||||
request.setRequest(clientTextSearch);
|
||||
return searchClients(request);
|
||||
}
|
||||
|
||||
public PageClientSearchData searchClients(String text, SortOrder sortOrder) {
|
||||
ClientTextSearch clientTextSearch = new ClientTextSearch();
|
||||
clientTextSearch.setText(text);
|
||||
PagedRequestClientTextSearch request = new PagedRequestClientTextSearch();
|
||||
request.setRequest(clientTextSearch);
|
||||
request.setSorts(List.of(sortOrder));
|
||||
return searchClients(request);
|
||||
}
|
||||
|
||||
public PageClientSearchData searchClients(PagedRequestClientTextSearch request) {
|
||||
return ok(fineract().clientSearchV2.searchByText(request));
|
||||
}
|
||||
|
||||
public static PostClientsResponse addClientAsPerson(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String jsonPayload) {
|
||||
final String response = Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL, jsonPayload);
|
||||
|
||||
Reference in New Issue
Block a user