Create YDTrackingNumberJob to retrieve local tracking numbers, and to update them in database, also set ready_for_shopify_sync

pull/8040/head
Qiuyi LI 2024-06-27 17:19:12 +02:00
parent f2c5040a4b
commit 3bb661f535
5 changed files with 178 additions and 0 deletions

View File

@ -0,0 +1,122 @@
package org.jeecg.modules.business.domain.job;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
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.yd.YDRequest;
import org.jeecg.modules.business.domain.api.yd.YDTrackingNumberData;
import org.jeecg.modules.business.domain.api.yd.YDTrackingNumberRequestBody;
import org.jeecg.modules.business.domain.api.yd.YDTrackingNumberResponse;
import org.jeecg.modules.business.service.IPlatformOrderService;
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.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
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;
@Slf4j
public class YDTrackingNumberJob implements Job {
@Autowired
private IPlatformOrderService platformOrderService;
private static final Integer DEFAULT_NUMBER_OF_THREADS = 10;
private final static String APP_TOKEN = "y553qci626dds5d6lcughy3ogicvfaxmh";
private final static String APP_KEY = "ynpoeds5511hg791mmksg6xccqxhax11j16eqz1itylq7whijki20egl0nmyql5h9";
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
List<String> shops = new ArrayList<>();
Map<String, List<String>> transportersByShop = new HashMap<>();
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
JobDataMap jobDataMap = context.getMergedJobDataMap();
String parameter = ((String) jobDataMap.get("parameter"));
if (parameter != null) {
try {
JSONObject jsonObject = new JSONObject(parameter);
if (!jsonObject.isNull("transportersByShop")) {
JSONArray transportersByShopArray = jsonObject.getJSONArray("transportersByShop");
for (int i = 0; i < transportersByShopArray.length(); i++) {
JSONObject object = transportersByShopArray.getJSONObject((i));
if (!object.isNull("shop")) {
String shopCode = object.getString("shop");
shops.add(shopCode);
if (!object.isNull("transporters")) {
JSONArray transportersArray = object.getJSONArray("transporters");
List<String> transporters = new ArrayList<>();
for (int j = 0; j < transportersArray.length(); j++) {
transporters.add(transportersArray.getString(j));
}
transportersByShop.put(shopCode, transporters);
}
}
}
}
} catch (JSONException e) {
log.error("Error while parsing parameter as JSON, falling back to default parameters.");
}
}
log.info("Starting to retrieve local tracking numbers");
List<YDTrackingNumberData> localTrackingNumbers = new ArrayList<>();
List<String> platformOrderIds = new ArrayList<>();
for (Map.Entry<String, List<String>> entry : transportersByShop.entrySet()) {
platformOrderIds.addAll(platformOrderService.fetchShippedOrdersFromShopAndTransporters(entry.getKey(), entry.getValue()));
}
List<YDRequest> ydRequests = new ArrayList<>();
platformOrderIds.forEach(platformOrderId -> {
YDTrackingNumberRequestBody ydParcelTraceRequestBody = new YDTrackingNumberRequestBody(platformOrderId);
YDRequest ydRequest = new YDRequest(APP_TOKEN, APP_KEY, ydParcelTraceRequestBody);
ydRequests.add(ydRequest);
});
ExecutorService executor = Executors.newFixedThreadPool(DEFAULT_NUMBER_OF_THREADS);
List<CompletableFuture<Boolean>> futures = ydRequests.stream()
.map(request -> CompletableFuture.supplyAsync(() -> {
boolean success = false;
HttpEntity entity = request.send().getEntity();
try {
// String of the response
String responseString = EntityUtils.toString(entity, "UTF-8");
YDTrackingNumberResponse ydResponse = mapper.readValue(responseString, YDTrackingNumberResponse.class);
if (ydResponse.getTrackingNumberData().getLocalTrackingNumber() != null &&
!ydResponse.getTrackingNumberData().getLocalTrackingNumber().isEmpty()) {
localTrackingNumbers.add(ydResponse.getTrackingNumberData());
}
success = true;
} catch (IOException e) {
log.error("Error while parsing response into String", 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("{}/{} local tracking numbers have been retrieved.", nbSuccesses, ydRequests.size());
log.info("Started updating {} local tracking numbers", localTrackingNumbers.size());
platformOrderService.updateLocalTrackingNumber(localTrackingNumbers);
log.info("Ended updating local tracking numbers for the following orders : {}", localTrackingNumbers.stream()
.map(YDTrackingNumberData::getPlatformOrderId)
.collect(Collectors.toList()));
}
}

View File

@ -3,6 +3,7 @@ package org.jeecg.modules.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.business.domain.api.mabang.getorderlist.Order;
import org.jeecg.modules.business.domain.api.yd.YDTrackingNumberData;
import org.jeecg.modules.business.entity.PlatformOrder;
import org.jeecg.modules.business.entity.PlatformOrderShopSync;
import org.jeecg.modules.business.vo.OrderKpi;
@ -233,4 +234,8 @@ public interface PlatformOrderMapper extends BaseMapper<PlatformOrder> {
List<String> findReadyAbnormalOrdersWithSkus(@Param("skus") List<String> skus);
void updateShopifySynced(@Param("platformOrderIds") Collection<String> platformOrderIds);
List<String> fetchShippedOrdersFromShopAndTransporters(@Param("shopCode")String shopCode, @Param("transporters") List<String> transporters);
void updateLocalTrackingNumber(@Param("data") List<YDTrackingNumberData> data);
}

View File

@ -1074,4 +1074,38 @@
#{platformOrderId}
</foreach>
</update>
<select id="fetchShippedOrdersFromShopAndTransporters" resultType="java.lang.String">
SELECT platform_order_id
FROM platform_order po join shop s ON po.shop_id = s.id
WHERE erp_code = #{shopCode}
AND erp_status = 3
AND shopify_synced = 0
AND logistic_channel_name IN
<foreach
collection="transporters"
separator=","
open="("
close=")"
index="index"
item="transporter">
#{transporter}
</foreach>
;
</select>
<update id="updateLocalTrackingNumber">
UPDATE platform_order
SET ready_for_shopify_sync = 1,
local_tracking_number =
case platform_order_id
<foreach collection="data" separator=" " open="" close="" index="index" item="item">
when #{item.platformOrderId} then #{item.localTrackingNumber}
</foreach>
end
where platform_order_id in
<foreach collection="data" separator="," open="(" close=")" index="index" item="item">
#{item.platformOrderId}
</foreach>
</update>
</mapper>

View File

@ -3,6 +3,7 @@ package org.jeecg.modules.business.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.business.controller.UserException;
import org.jeecg.modules.business.domain.api.yd.YDTrackingNumberData;
import org.jeecg.modules.business.entity.*;
import org.jeecg.modules.business.vo.PlatformOrderOption;
import org.jeecg.modules.business.vo.PlatformOrderQuantity;
@ -256,4 +257,8 @@ public interface IPlatformOrderService extends IService<PlatformOrder> {
List<String> findReadyAbnormalOrdersWithSkus(List<String> skus);
void updateShopifySynced(Collection<String> platformOrderIds);
List<String> fetchShippedOrdersFromShopAndTransporters(String shopCode, List<String> transporters);
void updateLocalTrackingNumber(List<YDTrackingNumberData> data);
}

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.controller.UserException;
import org.jeecg.modules.business.domain.api.yd.YDTrackingNumberData;
import org.jeecg.modules.business.entity.*;
import org.jeecg.modules.business.mapper.ExchangeRatesMapper;
import org.jeecg.modules.business.mapper.PlatformOrderContentMapper;
@ -520,8 +521,19 @@ public class PlatformOrderServiceImpl extends ServiceImpl<PlatformOrderMapper, P
public List<String> findReadyAbnormalOrdersWithSkus(List<String> skus) {
return platformOrderMap.findReadyAbnormalOrdersWithSkus(skus);
}
@Override
public void updateShopifySynced(Collection<String> platformOrderIds) {
platformOrderMap.updateShopifySynced(platformOrderIds);
}
@Override
public List<String> fetchShippedOrdersFromShopAndTransporters(String shopCode, List<String> transporters) {
return platformOrderMap.fetchShippedOrdersFromShopAndTransporters(shopCode, transporters);
}
@Override
public void updateLocalTrackingNumber(List<YDTrackingNumberData> data) {
platformOrderMap.updateLocalTrackingNumber(data);
}
}