mirror of https://github.com/jeecgboot/jeecg-boot
Create ShopifyNoteJob to retrieve notes in Shopify orders
parent
8be315c617
commit
2e9c129b77
|
@ -0,0 +1,16 @@
|
|||
package org.jeecg.modules.business.domain.api.shopify;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
public class GetOrderListRequest extends ShopifyRequest {
|
||||
|
||||
public GetOrderListRequest(ShopifyRequestBody body) {
|
||||
super(HttpMethod.GET, body);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject generateJson(ShopifyRequestBody body) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.jeecg.modules.business.domain.api.shopify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GetOrderListRequestBody extends ShopifyRequestBody {
|
||||
|
||||
public static final String ENDPOINT = "orders.json?status=open&limit=250&fields=id,note&ids=%s";
|
||||
|
||||
private final List<String> ids;
|
||||
|
||||
public GetOrderListRequestBody(String sitePrefix, String shopToken, List<String> ids) {
|
||||
super(sitePrefix, shopToken);
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String endpoint() {
|
||||
return String.format(ENDPOINT, String.join(",", ids));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.jeecg.modules.business.domain.api.shopify;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Data
|
||||
public class GetOrderListResponse {
|
||||
|
||||
@JsonProperty("orders")
|
||||
private List<Order> orders;
|
||||
|
||||
public GetOrderListResponse() {
|
||||
}
|
||||
|
||||
public GetOrderListResponse(List<Order> orders) {
|
||||
this.orders = orders;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.jeecg.modules.business.domain.api.shopify;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
@Slf4j
|
||||
@Data
|
||||
public class Order {
|
||||
|
||||
@JSONField(deserialize = false)
|
||||
private BigInteger id;
|
||||
|
||||
@JsonProperty("note")
|
||||
private String note;
|
||||
|
||||
public Order() {
|
||||
}
|
||||
|
||||
public boolean hasNote() {
|
||||
return note != null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package org.jeecg.modules.business.domain.job;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.codehaus.jettison.json.JSONArray;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
import org.jeecg.modules.business.domain.api.shopify.*;
|
||||
import org.jeecg.modules.business.entity.PlatformOrder;
|
||||
import org.jeecg.modules.business.entity.PlatformOrderShopSync;
|
||||
import org.jeecg.modules.business.entity.Shop;
|
||||
import org.jeecg.modules.business.service.IPlatformOrderService;
|
||||
import org.jeecg.modules.business.service.IShopService;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
@Slf4j
|
||||
public class ShopifyNoteJob implements Job {
|
||||
|
||||
private static final List<String> DEFAULT_INCLUDED_SHOPS = Arrays.asList("JCH8 KR");
|
||||
|
||||
private static final Integer DEFAULT_NUMBER_OF_THREADS = 10;
|
||||
|
||||
@Autowired
|
||||
private IPlatformOrderService platformOrderService;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
List<String> shops = DEFAULT_INCLUDED_SHOPS;
|
||||
JobDataMap jobDataMap = context.getMergedJobDataMap();
|
||||
String parameter = ((String) jobDataMap.get("parameter"));
|
||||
if (parameter != null) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(parameter);
|
||||
if (!jsonObject.isNull("includedShops")) {
|
||||
JSONArray shopsArray = jsonObject.getJSONArray("includedShops");
|
||||
List<String> shopList = new ArrayList<>();
|
||||
for (int i = 0; i < shopsArray.length(); i++) {
|
||||
shopList.add(shopsArray.getString(i));
|
||||
}
|
||||
shops = shopList;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Error while parsing parameter as JSON, falling back to default parameters.");
|
||||
}
|
||||
}
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
|
||||
List<PlatformOrderShopSync> ordersWithoutShopifyNote = platformOrderService.fetchOrderInShopsWithoutShopifyNote(shops);
|
||||
log.info("Fetched {} orders without Shopify note", ordersWithoutShopifyNote.size());
|
||||
Map<String, List<PlatformOrderShopSync>> ordersByShop = ordersWithoutShopifyNote.stream().collect(
|
||||
groupingBy(PlatformOrderShopSync::getShopifyPrefix));
|
||||
|
||||
List<Order> orders = new ArrayList<>();
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(DEFAULT_NUMBER_OF_THREADS);
|
||||
log.info("Constructing order retrieval requests");
|
||||
List<GetOrderListRequestBody> getOrderListRequestBodyList = new ArrayList<>();
|
||||
ordersByShop.values().forEach(platformOrderShopSyncs -> {
|
||||
if (!platformOrderShopSyncs.isEmpty()) {
|
||||
List<String> orderIds = platformOrderShopSyncs.stream().map(PlatformOrderShopSync::getPlatformOrderId).collect(Collectors.toList());
|
||||
String shopifyPrefix = platformOrderShopSyncs.get(0).getShopifyPrefix();
|
||||
String shopifyToken = platformOrderShopSyncs.get(0).getShopifyToken();
|
||||
getOrderListRequestBodyList.add(new GetOrderListRequestBody(shopifyPrefix, shopifyToken, orderIds));
|
||||
}
|
||||
});
|
||||
|
||||
List<CompletableFuture<Boolean>> futures = getOrderListRequestBodyList.stream()
|
||||
.map(body -> CompletableFuture.supplyAsync(() -> {
|
||||
boolean success = false;
|
||||
try {
|
||||
GetOrderListRequest getOrderListRequest = new GetOrderListRequest(body);
|
||||
String responseStr = getOrderListRequest.rawSend().getBody();
|
||||
GetOrderListResponse response = mapper.readValue(responseStr, GetOrderListResponse.class);
|
||||
orders.addAll(response.getOrders());
|
||||
success = true;
|
||||
} catch (RuntimeException e) {
|
||||
log.error("Error communicating with ShopifyAPI", e);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("Error processing json", e);
|
||||
}
|
||||
return success;
|
||||
}, executor))
|
||||
.collect(Collectors.toList());
|
||||
List<Boolean> results = futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||
long nbSuccesses = results.stream().filter(b -> b).count();
|
||||
log.info("{}/{} order retrieval requests have succeeded.", nbSuccesses, getOrderListRequestBodyList.size());
|
||||
log.info("{} orders have been retrieved.", orders.size());
|
||||
|
||||
log.info("Started adding Shopify notes to orders without one");
|
||||
Map<String, String> orderNoteMap = orders.stream().filter(Order::hasNote).collect(toMap(order -> order.getId().toString(), Order::getNote));
|
||||
if (orderNoteMap.isEmpty()) {
|
||||
log.info("No notes can be added to orders, quitting now");
|
||||
return;
|
||||
}
|
||||
List<PlatformOrder> platformOrders = platformOrderService.selectByPlatformOrderIds(new ArrayList<>(orderNoteMap.keySet()));
|
||||
platformOrders.forEach(platformOrder -> platformOrder.setShopifyNote(orderNoteMap.get(platformOrder.getPlatformOrderId()).trim()));
|
||||
platformOrderService.updateBatchById(platformOrders);
|
||||
log.info("Finished adding Shopify notes to {} orders without one into DB.", platformOrders.size());
|
||||
}
|
||||
}
|
|
@ -168,6 +168,7 @@ public interface PlatformOrderMapper extends BaseMapper<PlatformOrder> {
|
|||
@Param("excludedTrackingNumbersRegex") String excludedTrackingNumbersRegex);
|
||||
|
||||
List<PlatformOrderShopSync> fetchOrderInShopsReadyForShopifySync(@Param("shops") List<String> shopCodes);
|
||||
List<PlatformOrderShopSync> fetchOrderInShopsWithoutShopifyNote(@Param("shops") List<String> shopCodes);
|
||||
|
||||
List<PlatformOrder> fetchUninvoicedShippedOrderIDInShops(@Param("startDate") String startDate,
|
||||
@Param("endDate") String endDate,
|
||||
|
|
|
@ -466,6 +466,25 @@
|
|||
ORDER BY shipping_time;
|
||||
</select>
|
||||
|
||||
<select id="fetchOrderInShopsWithoutShopifyNote" resultType="org.jeecg.modules.business.entity.PlatformOrderShopSync">
|
||||
SELECT po.platform_order_id, po.tracking_number, s.shopify_prefix, s.shopify_token, po.postcode
|
||||
FROM platform_order po join shop s ON po.shop_id = s.id
|
||||
WHERE erp_code IN
|
||||
<foreach
|
||||
collection="shops"
|
||||
separator=","
|
||||
open="("
|
||||
close=")"
|
||||
index="index"
|
||||
item="shop"
|
||||
>
|
||||
#{shop}
|
||||
</foreach>
|
||||
AND erp_status <> 5
|
||||
AND shopify_note IS NULL
|
||||
ORDER BY order_time;
|
||||
</select>
|
||||
|
||||
<select id="fetchUninvoicedShippedOrderIDInShops" resultType="org.jeecg.modules.business.entity.PlatformOrder">
|
||||
SELECT po.id
|
||||
FROM platform_order po
|
||||
|
|
|
@ -142,6 +142,7 @@ public interface IPlatformOrderService extends IService<PlatformOrder> {
|
|||
|
||||
List<PlatformOrderShopSync> fetchOrderInShopsReadyForShopifySync(List<String> shopCodes);
|
||||
|
||||
List<PlatformOrderShopSync> fetchOrderInShopsWithoutShopifyNote(List<String> shopCodes);
|
||||
List<PlatformOrder> fetchUninvoicedShippedOrderIDInShops(String startDate, String endDate, List<String> shops, List<String> warehouses);
|
||||
|
||||
/**
|
||||
|
|
|
@ -374,6 +374,11 @@ public class PlatformOrderServiceImpl extends ServiceImpl<PlatformOrderMapper, P
|
|||
return platformOrderMap.fetchOrderInShopsReadyForShopifySync(shopCodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlatformOrderShopSync> fetchOrderInShopsWithoutShopifyNote(List<String> shopCodes) {
|
||||
return platformOrderMap.fetchOrderInShopsWithoutShopifyNote(shopCodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlatformOrder> fetchUninvoicedShippedOrderIDInShops(String startDate, String endDate, List<String> shops, List<String> warehouses) {
|
||||
return platformOrderMap.fetchUninvoicedShippedOrderIDInShops(startDate, endDate, shops, warehouses);
|
||||
|
|
Loading…
Reference in New Issue