From 8c7ffc8849af5219b544e9e5da025832c11778d8 Mon Sep 17 00:00:00 2001 From: Qiuyi LI Date: Fri, 26 Jan 2024 17:06:13 +0100 Subject: [PATCH] Create AddOrderAbnNumberJob to send AbnNumber to orders in Mabang --- .../AddOrderAbnNumberRequest.java | 15 ++ .../AddOrderAbnNumberRequestBody.java | 42 ++++++ .../domain/job/AddOrderAbnNumberJob.java | 138 ++++++++++++++++++ .../business/mapper/PlatformOrderMapper.java | 1 + .../mapper/xml/PlatformOrderMapper.xml | 20 +++ .../service/IPlatformOrderService.java | 2 + .../impl/PlatformOrderServiceImpl.java | 5 + 7 files changed, 223 insertions(+) create mode 100644 jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/dochangeorder/AddOrderAbnNumberRequest.java create mode 100644 jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/dochangeorder/AddOrderAbnNumberRequestBody.java create mode 100644 jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/AddOrderAbnNumberJob.java diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/dochangeorder/AddOrderAbnNumberRequest.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/dochangeorder/AddOrderAbnNumberRequest.java new file mode 100644 index 000000000..ec5a97d2f --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/dochangeorder/AddOrderAbnNumberRequest.java @@ -0,0 +1,15 @@ +package org.jeecg.modules.business.domain.api.mabang.dochangeorder; + +import org.jeecg.modules.business.domain.api.mabang.Request; + +public class AddOrderAbnNumberRequest extends Request { + public AddOrderAbnNumberRequest(AddOrderAbnNumberRequestBody body) { + super(body); + } + + @Override + public ChangeOrderResponse send() { + String jsonString = rawSend().getBody(); + return ChangeOrderResponse.parse(jsonString); + } +} diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/dochangeorder/AddOrderAbnNumberRequestBody.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/dochangeorder/AddOrderAbnNumberRequestBody.java new file mode 100644 index 000000000..7f6f56f5e --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/dochangeorder/AddOrderAbnNumberRequestBody.java @@ -0,0 +1,42 @@ +package org.jeecg.modules.business.domain.api.mabang.dochangeorder; + +import com.alibaba.fastjson.JSONObject; +import org.jeecg.modules.business.domain.api.mabang.RequestBody; + +public class AddOrderAbnNumberRequestBody implements RequestBody { + + private String platformOrderId; + private String abnNumber; + + public AddOrderAbnNumberRequestBody(String platformOrderId, String abnNumber) { + this.platformOrderId = platformOrderId; + this.abnNumber = abnNumber; + } + + @Override + public String api() { + return "order-do-change-order"; + } + + @Override + public JSONObject parameters() { + JSONObject json = new JSONObject(); + putNonNull(json, "platformOrderId", platformOrderId); + putNonNull(json, "abnnumber", abnNumber); + return json; + } + + public String getPlatformOrderId() { + return platformOrderId; + } + + public void setPlatformOrderId(String platformOrderId) { + this.platformOrderId = platformOrderId; + } + + private void putNonNull(JSONObject json, String key, E value) { + if (value != null) { + json.put(key, value); + } + } +} diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/AddOrderAbnNumberJob.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/AddOrderAbnNumberJob.java new file mode 100644 index 000000000..c817736a9 --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/AddOrderAbnNumberJob.java @@ -0,0 +1,138 @@ +package org.jeecg.modules.business.domain.job; + +import com.google.common.collect.Lists; +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.common.api.dto.message.TemplateMessageDTO; +import org.jeecg.common.system.api.ISysBaseAPI; +import org.jeecg.modules.business.domain.api.mabang.dochangeorder.*; +import org.jeecg.modules.business.domain.api.mabang.getorderlist.*; +import org.jeecg.modules.business.entity.PlatformOrder; +import org.jeecg.modules.business.entity.PlatformOrderShopSync; +import org.jeecg.modules.business.service.IPlatformOrderService; +import org.jetbrains.annotations.NotNull; +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.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +@Slf4j +public class AddOrderAbnNumberJob implements Job { + + private static final List DEFAULT_INCLUDED_SHOPS = Arrays.asList("JCH8 KR"); + private static final Integer DEFAULT_NUMBER_OF_THREADS = 10; + private static final Integer MABANG_API_RATE_LIMIT_PER_MINUTE = 300; + + @Autowired + private IPlatformOrderService platformOrderService; + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + List 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 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."); + } + } + + List platformOrders = platformOrderService.fetchOrderInShopsReadyForAbnNumberJob(shops); + Map shopifyNoteMap = platformOrders.stream() + .collect(Collectors.toMap(PlatformOrder::getPlatformOrderId, PlatformOrder::getShopifyNote)); + if (platformOrders.isEmpty()) { + log.info("No order with abnNumbers ready to be added via MabangAPI, quitting now."); + return; + } + log.info("{} orders with abnNumbers ready to be added via MabangAPI", platformOrders.size()); + List platformOrderIds = new ArrayList<>(shopifyNoteMap.keySet()); + List> platformOrderIdLists = Lists.partition(platformOrderIds, 10); + List requests = new ArrayList<>(); + for (List platformOrderIdList : platformOrderIdLists) { + requests.add(new OrderListRequestBody().setPlatformOrderIds(platformOrderIdList)); + } + + log.info("Started retrieving those orders from Mabang for comparison to avoid re-writing"); + List mabangOrders = new ArrayList<>(); + ExecutorService executor = Executors.newFixedThreadPool(DEFAULT_NUMBER_OF_THREADS); + List> futures = requests.stream() + .map(request -> CompletableFuture.supplyAsync(() -> { + boolean success = false; + try { + OrderListRawStream rawStream = new OrderListRawStream(request); + OrderListStream stream = new OrderListStream(rawStream); + List orders = stream.all(); + mabangOrders.addAll(orders); + success = !orders.isEmpty(); + } catch (RuntimeException e) { + log.error("Error communicating with MabangAPI", e); + } + return success; + }, executor)) + .collect(Collectors.toList()); + List results = futures.stream().map(CompletableFuture::join).collect(Collectors.toList()); + long nbSuccesses = results.stream().filter(b -> b).count(); + log.info("{}/{} requests have succeeded.", nbSuccesses, requests.size()); + int syncedOrderNumber = mabangOrders.size(); + log.info("{}/{} mabang orders have been retrieved.", syncedOrderNumber, platformOrderIds.size()); + + log.info("Started comparison of {} orders to construct order modification request", mabangOrders.size()); + List addOrderAbnNumberRequestBodies = new ArrayList<>(); + mabangOrders.forEach(order -> { + String taxNumber = order.getTaxNumber(); + String platformOrderId = order.getPlatformOrderId(); + String abnNumber = shopifyNoteMap.get(platformOrderId); + if (taxNumber == null || taxNumber.isEmpty()) { + addOrderAbnNumberRequestBodies.add(new AddOrderAbnNumberRequestBody(platformOrderId, abnNumber)); + } else { + if (order.getTaxNumber().equalsIgnoreCase(abnNumber)) { + log.info("AbnNumber {} already present for order {}, ignoring", order.getTaxNumber(), platformOrderId); + } else { + // If the number EVER changes (EXTREMELY UNLIKELY), send it to Mabang anyway + addOrderAbnNumberRequestBodies.add(new AddOrderAbnNumberRequestBody(platformOrderId, abnNumber)); + } + } + }); + + ExecutorService throttlingExecutorService = ThrottlingExecutorService.createExecutorService(DEFAULT_NUMBER_OF_THREADS, + MABANG_API_RATE_LIMIT_PER_MINUTE, TimeUnit.MINUTES); + List> changeOrderFutures = addOrderAbnNumberRequestBodies.stream() + .map(addOrderAbnNumberRequestBody -> CompletableFuture.supplyAsync(() -> { + boolean success = false; + try { + AddOrderAbnNumberRequest archiveOrderRequest = new AddOrderAbnNumberRequest(addOrderAbnNumberRequestBody); + ChangeOrderResponse response = archiveOrderRequest.send(); + success = response.success(); + } catch (RuntimeException e) { + log.error("Error communicating with MabangAPI", e); + } + return success; + }, throttlingExecutorService)) + .collect(Collectors.toList()); + results = changeOrderFutures.stream().map(CompletableFuture::join).collect(Collectors.toList()); + nbSuccesses = results.stream().filter(b -> b).count(); + log.info("{}/{} order abnNumber adding requests have succeeded.", nbSuccesses, addOrderAbnNumberRequestBodies.size()); + } +} diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PlatformOrderMapper.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PlatformOrderMapper.java index 0d4c15b80..6fd072949 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PlatformOrderMapper.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PlatformOrderMapper.java @@ -169,6 +169,7 @@ public interface PlatformOrderMapper extends BaseMapper { List fetchOrderInShopsReadyForShopifySync(@Param("shops") List shopCodes); List fetchOrderInShopsWithoutShopifyNote(@Param("shops") List shopCodes); + List fetchOrderInShopsReadyForAbnNumberJob(@Param("shops") List shopCodes); List fetchUninvoicedShippedOrderIDInShops(@Param("startDate") String startDate, @Param("endDate") String endDate, diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml index 287fa7fc3..5cb4065ec 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml @@ -485,6 +485,26 @@ ORDER BY order_time; + +