fr.lecomptoirdespharmacies.medipim.api.MedipimProductsApi Maven / Gradle / Ivy
package fr.lecomptoirdespharmacies.medipim.api;
import fr.lecomptoirdespharmacies.medipim.api.client.Client;
import fr.lecomptoirdespharmacies.medipim.api.client.Response;
import fr.lecomptoirdespharmacies.medipim.api.entities.products.MedipimProduct;
import fr.lecomptoirdespharmacies.medipim.api.query.PaginatedResponse;
import fr.lecomptoirdespharmacies.medipim.api.query.QueryFilterHasContent;
import fr.lecomptoirdespharmacies.medipim.api.query.QueryPage;
import fr.lecomptoirdespharmacies.medipim.api.query.SortingValue;
import fr.lecomptoirdespharmacies.medipim.api.query.products.Query;
import fr.lecomptoirdespharmacies.medipim.api.query.products.QueryFilter;
import fr.lecomptoirdespharmacies.medipim.api.query.products.QuerySorting;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.StringUtils;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
public class MedipimProductsApi extends MedipimApi {
public MedipimProductsApi(Client ws, String baseUrl, String username, String password) {
super(ws, baseUrl, username, password);
}
private List streamToProducts(Response response) {
if (!Arrays.asList(200, 204).contains(response.getStatus())) {
throw new RuntimeException(String.format("Medipim API returned status %s - %s", response.getStatus(), response.getBody()));
}
List results = this.readStream(response)
.map(jsonNode -> jsonNode.get("result"))
/**
* If result is 204, we got empty body and the preceding line will return an array of one null item.
* Filter them to get empty array
*/
.filter(Objects::nonNull)
.collect(Collectors.toList());
return this.deserializeList(results, MedipimProduct.class);
}
public MedipimProduct searchProductById(String id) {
try {
MedipimProduct product = this.createAuthenticatedRequest("/v4/products/find")
.addQueryParameter("id", id)
.get()
.thenApply(response -> {
if (response.getStatus() != 200) {
// Product not found
return null;
}
JsonNode result = response.asJson().get("product");;
return this.deserialize(result, MedipimProduct.class);
})
.toCompletableFuture()
.get();
return product;
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
private List postProductStream(JsonNode query) {
try {
List products = this.createAuthenticatedRequest("/v4/products/stream")
.post(query)
.thenApply(this::streamToProducts)
.toCompletableFuture()
.get();
return products;
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
private PaginatedResponse postProductsQuery(JsonNode query) {
try {
Response response = this.createAuthenticatedRequest("/v4/products/query")
.post(query)
.toCompletableFuture()
.get();
if (response.getStatus() != 200) {
throw new RuntimeException(String.format("Medipim API returned status %s - %s", response.getStatus(), response.getBody()));
}
JsonNode jsonResponse = response.asJson();
JsonNode meta = jsonResponse.get("meta");
JsonNode results = jsonResponse.get("results");
long totalRecord = meta.get("total").asLong();
JsonNode page = meta.get("page");
long pageOffset = page.get("offset").asLong();
long pageSize = page.get("size").asLong();
boolean isExhaustive = totalRecord <= pageOffset + pageSize;
List products = this.deserializeList(results, MedipimProduct.class);
return new PaginatedResponse(
isExhaustive,
products
);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
public MedipimProduct searchProductByBarcode(String barcode) {
return postProductStream(buildSearchProductByBarcodeQuery(barcode))
.stream()
.findFirst()
.orElse(null);
}
private JsonNode buildSearchProductByBarcodeQuery(String barcode) {
List barcodeFilters = new ArrayList<>();
if (StringUtils.isNumeric(barcode) &&
StringUtils.startsWith(barcode, "3400") ) {
barcodeFilters.add(
new QueryFilter.QueryFilterBuilder()
.cip13(StringUtils.left(barcode, 13))
.build()
);
}
if (StringUtils.isNumeric(barcode) &&
StringUtils.startsWith(barcode, "3401")) {
barcodeFilters.add(
new QueryFilter.QueryFilterBuilder()
.acl13(StringUtils.left(barcode, 13))
.build()
);
}
barcodeFilters.add(
new QueryFilter.QueryFilterBuilder()
.ean(barcode)
.build()
);
if (StringUtils.isNumeric(barcode)) {
barcodeFilters.add(
new QueryFilter.QueryFilterBuilder()
.cipOrAcl7(StringUtils.left(barcode, 7))
.build()
);
}
QueryFilter filter = new QueryFilter.QueryFilterBuilder()
.or(barcodeFilters).build();
QuerySorting sorting = new QuerySorting.QuerySortingBuilder()
.id(SortingValue.DESC)
.build();
Query query = new Query(
filter,
sorting,
null
);
return this.serialize(query);
}
public List getProductsByMediaIds(List mediaIds) {
QueryFilter filter = new QueryFilter.QueryFilterBuilder()
.media(mediaIds)
.build();
QuerySorting sorting = new QuerySorting.QuerySortingBuilder()
.id(SortingValue.DESC)
.build();
Query query = new Query(
filter,
sorting,
null
);
return postProductStream(this.serialize(query));
}
public PaginatedResponse getModifiedProductSince(OffsetDateTime updatedAtGe,
boolean containMedia) {
return postProductsQuery(buildGetModifiedProductSinceQuery(updatedAtGe, containMedia));
}
public JsonNode buildGetModifiedProductSinceQuery(OffsetDateTime updatedAtGe,
boolean containMedia) {
List filters = new ArrayList<>();
if (containMedia) {
filters.add(
new QueryFilter.QueryFilterBuilder()
.hasContent(new QueryFilterHasContent.QueryFilterHasContentBuilder()
.flag("media")
.locale("fr")
.build())
.build()
);
}
filters.add(
new QueryFilter.QueryFilterBuilder()
.updatedSince(updatedAtGe.toEpochSecond())
.build()
);
QueryFilter filter = new QueryFilter.QueryFilterBuilder()
.and(filters)
.build();
QuerySorting sorting = new QuerySorting.QuerySortingBuilder()
.touchedAt(SortingValue.ASC)
.build();
QueryPage page = new QueryPage(0, 250);
Query query = new Query(
filter,
sorting,
page
);
return this.serialize(query);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy