From b0877a3275ed5bc96fb80f84949904e149946cf2 Mon Sep 17 00:00:00 2001
From: zwl <1051256694@qq.com>
Date: 星期三, 29 四月 2026 19:37:51 +0800
Subject: [PATCH] 将erp下发直接生成任务改成先生成订单再出库
---
src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java | 507 ++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 400 insertions(+), 107 deletions(-)
diff --git a/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
index 9a001d8..4ccb39e 100644
--- a/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -51,6 +51,8 @@
private static final Map<Integer, BigDecimal> INBOUND_WEIGHT_FACTOR_BY_SOURCE_STA;
private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
+ private static final int DEFAULT_OUT_ORDER_BATCH_PRIORITY = 100;
+ private static final int DEFAULT_OUT_ORDER_BATCH_PRIORITY_THRESHOLD = 1;
// ERP 鍑哄簱鍙eぇ浜庤闃堝�兼椂锛�/outOrder 鍙惤鍑哄簱璁㈠崟锛岀敱瀹氭椂鍣ㄥ悗缁敓鎴愪换鍔°��
private static final int PENDING_OUT_ORDER_STATION_THRESHOLD = 600;
// 寤惰繜鍑哄簱璁㈠崟浣跨敤鐙珛鍗曟嵁绫诲瀷锛屼究浜庡拰浜哄伐/椤甸潰鍒涘缓鐨勫嚭搴撳崟鍖哄垎鏉ユ簮銆�
@@ -429,49 +431,28 @@
return R.error("姝e湪涓嬪彂浠诲姟缁橶CS锛屾棤娉曚腑姝�");
}
+ if (Objects.equals(param.getExecute(), 1)) {
+ // execute=1 鐨勫惈涔夊凡缁忎粠鈥滀粎纭宸茬敓鎴愪换鍔♀�濇墿灞曚负鈥滃惎鍔�/鎭㈠璁㈠崟鈥濓細
+ // 1. 璁㈠崟 status=0 鏃舵仮澶嶄负 1锛�
+ // 2. 宸叉湁 wrk_sts=11 鐨勪换鍔¤缃� pdcType=Y锛�
+ // 3. 鏈敓鎴愮殑璁㈠崟鏄庣粏绔嬪嵆灏濊瘯鐢熸垚褰撳墠鍙斁琛屾壒娆°��
+ // 鍥犳杩欓噷鐩存帴澶嶇敤鍏紑鎵ц鎺ュ彛鐨勭粺涓�瀹炵幇锛岄伩鍏� pause 鍜� execute 涓ゅ閫昏緫鍒嗗弶銆�
+ return executePakoutOrder(param.getOrderId());
+ }
+
OrderPakout orderPakout = orderPakoutService.selectByNo(param.getOrderId());
List<WrkMast> activeTasks = findActiveOutboundTasks(param.getOrderId());
- if (Objects.equals(param.getExecute(), 1)) {
- // execute=1 鍚屾椂澶勭悊涓ょ被瀵硅薄锛�
- // 1. 鏈敓鎴愪换鍔$殑鍑哄簱璁㈠崟锛氭仮澶� order.status=1锛岃瀹氭椂鍣ㄥ彲浠ョ户缁壂鎻忋��
- // 2. 宸茬敓鎴愪絾寰呬笅鍙戠殑浠诲姟锛氳缃� pdcType=Y锛屽厑璁� WorkMastScheduler 涓嬪彂缁� WCS銆�
- Map<String, Object> result = new HashMap<>();
- result.put("orderNo", param.getOrderId());
- result.put("execute", param.getExecute());
- boolean orderStatusUpdated = false;
- if (orderPakout != null && !Objects.equals(orderPakout.getStatus(), 1)) {
- orderPakout.setStatus(1);
- orderPakout.setUpdateBy(9527L);
- orderPakout.setUpdateTime(new Date());
- if (!orderPakoutService.updateById(orderPakout)) {
- throw new CoolException("鍚姩鍑哄簱璁㈠崟澶辫触锛�" + param.getOrderId());
- }
- orderStatusUpdated = true;
- }
- int confirmedCount = confirmPendingOutboundTasks(activeTasks);
- R generateResult = null;
- int generatedConfirmedCount = 0;
- if (orderPakout != null) {
- // 鍚姩鍚庣珛鍗冲皾璇曠敓鎴愬綋鍓嶅彲鏀捐鐨勮繘浠撶紪鍙锋壒娆★紝閬垮厤蹇呴』绛夊緟涓嬩竴杞畾鏃舵壂鎻忋��
- generateResult = generatePendingPakoutOrderTasks(param.getOrderId());
- // 鍒氱敓鎴愮殑浠诲姟鍒濆鐘舵�佷粛鏄� 11锛岃繖閲屽啀娆$‘璁わ紝淇濇寔鈥滃惎鍔ㄦ帴鍙h皟鐢ㄥ悗鍗冲彲涓嬪彂鈥濈殑璇箟銆�
- generatedConfirmedCount = confirmPendingOutboundTasks(findActiveOutboundTasks(param.getOrderId()));
- }
- result.put("orderStatusUpdated", orderStatusUpdated);
- result.put("confirmedCount", confirmedCount + generatedConfirmedCount);
- result.put("generatedConfirmedCount", generatedConfirmedCount);
- result.put("generateResult", generateResult);
- return R.ok("鍑哄簱璁㈠崟鍚姩鎴愬姛").add(result);
- }
if (Objects.equals(param.getExecute(), 2)) {
// execute=2 鍏堝叧闂鍗曞紑鍏筹紝闃绘瀹氭椂鍣ㄧ户缁负鏈敓鎴愪换鍔$殑鏄庣粏寤� WrkMast銆�
- // 宸茬粡鐢熸垚鐨勪换鍔℃寜鐘舵�佸垎娴侊細11 灏氭湭涓嬪彂锛岃蛋鏈湴鍙栨秷锛�12/13 宸蹭笅鍙戞垨鎵ц涓紝闇�瑕侀�氱煡 WCS 鏆傚仠銆�
+ // 宸茬粡鐢熸垚鐨勪换鍔℃寜鐘舵�佸垎娴侊細11 灏氭湭涓嬪彂锛岃蛋鏈湴鍙栨秷锛�12/13 宸蹭笅鍙戞垨鎵ц涓紝闇�瑕侀�氱煡 WCS 鍙栨秷銆�
Map<String, Object> result = new HashMap<>();
result.put("orderNo", param.getOrderId());
result.put("execute", param.getExecute());
result.put("taskCount", activeTasks.size());
boolean orderStatusUpdated = false;
if (orderPakout != null && !Objects.equals(orderPakout.getStatus(), 0)) {
+ // status=0 鏄鍗曠骇涓寮�鍏炽�傚厛鍏宠鍗曪紝鍐嶅彇娑堜换鍔★紝
+ // 鍙互闃绘瀹氭椂鍣ㄥ湪鍙栨秷杩囩▼涓張鐢熸垚涓嬩竴鎵规湭涓嬪彂浠诲姟銆�
orderPakout.setStatus(0);
orderPakout.setUpdateBy(9527L);
orderPakout.setUpdateTime(new Date());
@@ -487,25 +468,36 @@
return R.ok("鍑哄簱璁㈠崟宸蹭腑姝�").add(result);
}
List<HashMap<String,Object>> taskList = new ArrayList<>();
+ List<WrkMast> wcsCancelTasks = new ArrayList<>();
int cancelledLocalTaskCount = 0;
for (WrkMast wrkMast : activeTasks) {
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("taskNo", wrkMast.getWrkNo());
if (!Cools.isEmpty(wrkMast) && Objects.equals(wrkMast.getWrkSts(), 11L)) {
// wrk_sts=11 杩樻病鍙戝埌 WCS锛屾湰鍦板彇娑堝嵆鍙紝涓嶉渶瑕佷骇鐢� WCS 鏆傚仠鎸囦护銆�
+ // cancelWrkMast 浼氭妸宸ヤ綔妗h浆鍘嗗彶銆侀噴鏀惧簱浣嶏紝骞跺洖婊氳鍗曟槑缁� work_qty銆�
workService.cancelWrkMast(wrkMast.getWrkNo()+"", 9955L);
cancelledLocalTaskCount++;
continue;
}
taskList.add(hashMap);
+ wcsCancelTasks.add(wrkMast);
}
+ int cancelledWcsTaskCount = 0;
if (!taskList.isEmpty()) {
- // wrk_sts=12/13 绛夊凡杩涘叆 WCS 渚х殑浠诲姟蹇呴』鏍¢獙 WCS 杩斿洖锛屽け璐ュ垯浜嬪姟鍥炴粴锛岄伩鍏嶆湰鍦拌鎶ュ凡鏆傚仠銆�
+ // wrk_sts=12/13 绛夊凡杩涘叆 WCS 渚х殑浠诲姟蹇呴』鏍¢獙 WCS 杩斿洖锛屽け璐ュ垯浜嬪姟鍥炴粴锛岄伩鍏嶆湰鍦拌鎶ュ凡鍙栨秷銆�
R wcsR = wcsApiService.pauseOutTasks(taskList);
requireWcsPauseOk(wcsR);
+ // WCS 宸茬‘璁ゅ彇娑堝悗锛屾湰鍦颁篃瑕佸彇娑堜换鍔″苟鍥炴粴璁㈠崟鏄庣粏 work_qty銆�
+ // 鍥炴粴閫昏緫鍦� WorkService.cancelWrkMast 涓粺涓�澶勭悊锛岀‘淇� WCS 鍥炶皟 task_cancel 璧板悓涓�濂楀彛寰勩��
+ for (WrkMast wrkMast : wcsCancelTasks) {
+ workService.cancelWrkMast(wrkMast.getWrkNo()+"", 9955L);
+ cancelledWcsTaskCount++;
+ }
}
result.put("cancelledLocalTaskCount", cancelledLocalTaskCount);
result.put("pausedWcsTaskCount", taskList.size());
+ result.put("cancelledWcsTaskCount", cancelledWcsTaskCount);
return R.ok("鍑哄簱璁㈠崟宸蹭腑姝�").add(result);
}
throw new CoolException("reason浠呮敮鎸�1鎴�2");
@@ -517,6 +509,11 @@
* pdcType 鏄幇鏈� WorkMastScheduler 鐨勪笅鍙戝紑鍏筹細
* - wrk_sts=11 涓� pdcType=Y 鏃讹紝璋冨害鍣ㄥ彲浠ョ户缁笅鍙戠粰 WCS銆�
* - 宸茬粡鏄� Y 鐨勪换鍔′繚鎸佸箓绛夛紝涓嶉噸澶嶆洿鏂般��
+ *
+ * 涓轰粈涔堜笉鍦� outOrderBatch 閲岀洿鎺ュ己鍒� Y锛�
+ * - outOrderBatch 浠嶈鍏朵粬鍏ュ彛澶嶇敤锛�
+ * - MQTT/IoT autoConfirm=false 鐨勮鍗曢渶瑕佸厛寤哄崟浣嗕笉涓嬪彂锛�
+ * - 鎵�浠ユ斁琛屽繀椤荤敱鈥滆鍗� status=1 鐨勫畾鏃剁敓鎴愨�濇垨鈥滄墽琛屾帴鍙b�濇樉寮忓畬鎴愩��
*/
private int confirmPendingOutboundTasks(List<WrkMast> activeTasks) {
if (Cools.isEmpty(activeTasks)) {
@@ -553,8 +550,102 @@
}
@Override
+ @Transactional
public R pakoutOrderExecute(OpenOrderPakoutExecuteParam param) {
- return null;
+ if (param == null || Cools.isEmpty(param.getOrderId())) {
+ throw new CoolException("orderNo涓嶈兘涓虹┖");
+ }
+ if (param.getExecute() == null) {
+ throw new CoolException("execute涓嶈兘涓虹┖");
+ }
+ if (!Objects.equals(param.getExecute(), 1)) {
+ throw new CoolException("execute浠呮敮鎸�1");
+ }
+ return executePakoutOrder(param.getOrderId());
+ }
+
+ /**
+ * 鍑哄簱璁㈠崟鎵ц/鎭㈠鐨勭粺涓�鍏ュ彛銆�
+ *
+ * 璇ユ柟娉曞悓鏃舵湇鍔★細
+ * - 鏂板鍏紑鎵ц鎺ュ彛锛�
+ * - pakoutOrderPause(execute=1) 鐨勬仮澶嶉�昏緫锛�
+ * - IoT/MQTT autoConfirm=true 鐨勫嵆鏃舵墽琛岄�昏緫銆�
+ *
+ * 鎵ц璇箟鍒嗕笁姝ワ細
+ * 1. 鎶婅鍗� status 鎭㈠涓� 1锛岃瀹氭椂鍣ㄥ拰褰撳墠璋冪敤閮藉彲浠ョ敓鎴愪换鍔★紱
+ * 2. 瀵瑰凡缁忓瓨鍦ㄤ笖 wrk_sts=11 鐨勪换鍔¤缃� pdcType=Y锛�
+ * 3. 绔嬪嵆灏濊瘯鐢熸垚褰撳墠鍏佽鐨勪竴涓壒娆★紝骞跺啀娆$‘璁ゆ柊鐢熸垚浠诲姟鍙笅鍙戙��
+ *
+ * 骞傜瓑鎬э細
+ * - 璁㈠崟宸叉槸 status=1 鏃朵笉浼氶噸澶嶆洿鏂帮紱
+ * - 宸茬粡 pdcType=Y 鐨勪换鍔′笉浼氶噸澶嶇‘璁わ紱
+ * - 宸茬粡 work_qty 瑕嗙洊鐨勬槑缁嗕笉浼氬啀娆$敓鎴愪换鍔°��
+ */
+ private R executePakoutOrder(String orderNo) {
+ if (Cools.isEmpty(orderNo)) {
+ throw new CoolException("orderNo涓嶈兘涓虹┖");
+ }
+ OrderPakout orderPakout = orderPakoutService.selectByNo(orderNo);
+ List<WrkMast> activeTasks = findActiveOutboundTasks(orderNo);
+
+ Map<String, Object> result = new LinkedHashMap<>();
+ result.put("orderNo", orderNo);
+ result.put("execute", 1);
+ boolean orderStatusUpdated = false;
+ if (orderPakout != null && !Objects.equals(orderPakout.getStatus(), 1)) {
+ orderPakout.setStatus(1);
+ orderPakout.setUpdateBy(9527L);
+ orderPakout.setUpdateTime(new Date());
+ if (!orderPakoutService.updateById(orderPakout)) {
+ throw new CoolException("鍚姩鍑哄簱璁㈠崟澶辫触锛�" + orderNo);
+ }
+ orderStatusUpdated = true;
+ }
+
+ int confirmedCount = confirmPendingOutboundTasks(activeTasks);
+ R generateResult = null;
+ int generatedConfirmedCount = 0;
+ if (orderPakout != null) {
+ // 涓诲姩璋冪敤鎵ц鎺ュ彛鏃讹紝涓嶇瓑涓嬩竴杞畾鏃跺櫒锛岀洿鎺ョ敓鎴愬綋鍓嶅彲鏀捐鐨勪竴涓壒娆°��
+ // 濡傛灉褰撳墠鎵规琚� OutboundBatchSeqReleaseGuard 闃诲锛実enerateResult 浼氳繑鍥為樆濉炲師鍥狅紝
+ // 涓嶄細鎶涢敊锛屼篃涓嶄細鎻愬墠鐢熸垚鍚庣画鎵规銆�
+ generateResult = generatePendingPakoutOrderTasks(orderNo);
+ // 鏂扮敓鎴愮殑浠诲姟鍒濆鐘舵�佷负 11锛岃繖閲屽啀娆$‘璁わ紝璁╂墽琛屾帴鍙h繑鍥炲悗浠诲姟鍗冲彲琚皟搴﹀櫒涓嬪彂銆�
+ generatedConfirmedCount = confirmPendingOutboundTasks(findActiveOutboundTasks(orderNo));
+ }
+
+ List<Integer> wrkNos = collectActiveOutboundWrkNos(orderNo);
+ result.put("orderStatusUpdated", orderStatusUpdated);
+ result.put("confirmedCount", confirmedCount + generatedConfirmedCount);
+ result.put("generatedConfirmedCount", generatedConfirmedCount);
+ result.put("generateResult", generateResult);
+ result.put("wrkNos", wrkNos);
+ if (!wrkNos.isEmpty()) {
+ // IoT 鍗曟墭鐩樿皟鐢ㄤ緷璧栭《灞� wrkNo 鍥炲啓浠诲姟鍙凤紱澶氭墭鐩樻椂杩斿洖褰撳墠璁㈠崟娲诲姩浠诲姟鐨勭涓�鏉°��
+ result.put("wrkNo", wrkNos.get(0));
+ }
+ R response = R.ok("鍑哄簱璁㈠崟鍚姩鎴愬姛").add(result);
+ if (!wrkNos.isEmpty()) {
+ // add(Map) 鍦ㄩ儴鍒嗚皟鐢ㄦ柟浼氭寜 data 璇诲彇锛岃繖閲屽啀鏄惧紡鍐欓《灞傚瓧娈碉紝鍏煎 IoT 鐨� resolveWrkNo銆�
+ response.put("wrkNo", wrkNos.get(0));
+ response.put("wrkNos", wrkNos);
+ }
+ return response;
+ }
+
+ private List<Integer> collectActiveOutboundWrkNos(String orderNo) {
+ List<WrkMast> activeTasks = findActiveOutboundTasks(orderNo);
+ if (Cools.isEmpty(activeTasks)) {
+ return Collections.emptyList();
+ }
+ List<Integer> wrkNos = new ArrayList<>();
+ for (WrkMast wrkMast : activeTasks) {
+ if (wrkMast != null && wrkMast.getWrkNo() != null) {
+ wrkNos.add(wrkMast.getWrkNo());
+ }
+ }
+ return wrkNos;
}
private List<WrkMast> findActiveOutboundTasks(String orderNo) {
@@ -1615,7 +1706,7 @@
wrkMast.setIoTime(now);
wrkMast.setWrkSts(11L); // 宸ヤ綔鐘舵�侊細11.鐢熸垚鍑哄簱ID
wrkMast.setIoType(ioType); // 鍏ュ嚭搴撶姸鎬�
- wrkMast.setIoPri(13D); // 浼樺厛绾э細13
+ wrkMast.setIoPri(Double.valueOf(i)); // 浼樺厛绾�
wrkMast.setCrnNo(locMast.getCrnNo());
wrkMast.setSourceStaNo(staDesc.getCrnStn()); // 婧愮珯
wrkMast.setStaNo(staDesc.getStnNo()); // 鐩爣绔�
@@ -1626,9 +1717,9 @@
wrkMast.setExitMk("N"); // 閫�鍑�
wrkMast.setEmptyMk("N"); // 绌烘澘
wrkMast.setLinkMis("N");
- wrkMast.setPdcType("N");
wrkMast.setContainerNo(param.getContainerNo());
wrkMast.setTeu(teu);
+ wrkMast.setPdcType(locMast.getCrnNo()>=19?"Y":"N");//鑷姩浠诲姟涓嬪彂鏍囪
wrkMast.setPlateNo(param.getPlateNo());
wrkMast.setTrainNo(param.getTrainNo());
wrkMast.setFreqType(param.getFreqType());
@@ -1700,18 +1791,21 @@
@Override
@Transactional(rollbackFor = Exception.class)
public R outOrderBatch(Map<String, List<OutTaskParam>> linesByBatchSeq,int count) {
- int i = 0;
+
for (Map.Entry<String, List<OutTaskParam>> entry : linesByBatchSeq.entrySet()) {
+ int i = DEFAULT_OUT_ORDER_BATCH_PRIORITY;
+ int j = 0;
+ int priorityThreshold = getOutOrderBatchPriorityThreshold();
for (OutTaskParam outTaskParam : entry.getValue()) {
- if(outTaskParam.getSeq()!=0){
- i= outTaskParam.getSeq();
- }else{
- i++;
- }
int teu = Cools.isEmpty(outTaskParam.getTeu())?0:outTaskParam.getTeu();
R r = outOrder(outTaskParam, count, teu ,i);
if (!Objects.equals(r.get("code"), 200)) {
throw new CoolException("鍑哄簱寤哄崟澶辫触");
+ }
+ j++;
+ if (j >= priorityThreshold) {
+ i--;
+ j = 0;
}
}
@@ -1719,15 +1813,37 @@
return R.ok();
}
+ private int getOutOrderBatchPriorityThreshold() {
+ Parameter parameter = Parameter.get();
+ if (parameter == null || Cools.isEmpty(parameter.getOutOrderBatchPriorityThreshold())) {
+ return DEFAULT_OUT_ORDER_BATCH_PRIORITY_THRESHOLD;
+ }
+ try {
+ int threshold = Integer.parseInt(parameter.getOutOrderBatchPriorityThreshold().trim());
+ return threshold <= 0 ? DEFAULT_OUT_ORDER_BATCH_PRIORITY_THRESHOLD : threshold;
+ } catch (NumberFormatException ignored) {
+ return DEFAULT_OUT_ORDER_BATCH_PRIORITY_THRESHOLD;
+ }
+ }
+
@Override
@Transactional(rollbackFor = Exception.class)
public R outOrderCreatePakoutOrder(List<OutTaskParam> params) {
+ return outOrderCreatePakoutOrder(params, true);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public R outOrderCreatePakoutOrder(List<OutTaskParam> params, boolean executable) {
if (Cools.isEmpty(params)) {
return R.ok();
}
// 涓�涓� /outOrder 璇锋眰鍙兘鍖呭惈澶氫釜 orderId銆傛寜璁㈠崟鍙峰垎缁勫悗鍒嗗埆鍒涘缓璁㈠崟澶达紝
// 淇濊瘉 orderId 濮嬬粓瀵瑰簲 man_order_pakout.order_no锛屾槑缁嗘寕鍦ㄥ搴旇鍗曚笅銆�
+ //
+ // 杩欓噷涓嶆寜鎵规鍒嗙粍钀借鍗曞ご锛氬悓涓�涓� ERP 鍗曞彿涓嬪彲鑳藉悓鏃跺寘鍚涓� entryWmsCode锛�
+ // 瀹冧滑搴旇鏄悓涓�寮犲嚭搴撹鍗曠殑澶氫釜鎵规锛岃�屼笉鏄寮犺鍗曘��
Map<String, List<OutTaskParam>> paramsByOrderNo = new LinkedHashMap<>();
for (OutTaskParam param : params) {
validatePendingOutOrderParam(param);
@@ -1737,42 +1853,27 @@
Date now = new Date();
int orderCount = 0;
int detailCount = 0;
+ int removedUndispatchedDetailCount = 0;
List<String> orderNos = new ArrayList<>();
for (Map.Entry<String, List<OutTaskParam>> entry : paramsByOrderNo.entrySet()) {
String orderNo = entry.getKey();
- // 寤惰繜寤哄崟鍏佽瑕嗙洊鈥滃皻鏈敓鎴愪换鍔°�佹湭杩涘叆鎵ц鈥濈殑鏃ц鍗曪紱
- // 涓�鏃﹀凡鏈夋椿鍔ㄤ换鍔℃垨鍘嗗彶浠诲姟锛屽垯绂佹瑕嗙洊锛岄伩鍏嶉噸澶嶅嚭搴撳悓涓�璁㈠崟銆�
+ // 寤惰繜寤哄崟鍏佽鍚屼竴涓� orderNo 鍐嶆涓嬪彂锛�
+ // 宸蹭笅鍙�/宸插畬鎴愭槑缁嗕繚鐣欒拷婧紱鏈笅鍙戞槑缁嗗垹闄ゅ悗锛屼娇鐢ㄦ湰娆℃帴鍙e弬鏁伴噸鏂版彃鍏ャ��
+ // 濡傛灉褰撳墠璁㈠崟杩樻湁娲诲姩 WrkMast锛屽垯涓嶅厑璁歌鐩栵紝閬垮厤鍚屼竴鎵樼洏鍚屾椂瀛樺湪涓ゆ潯鎵ц閾俱��
assertPendingPakoutOrderCanReplace(orderNo);
OrderPakout order = orderPakoutService.selectByNo(orderNo);
- if (order != null) {
- orderPakoutService.remove(order.getId());
- }
-
- DocType docType = docTypeService.selectOrAdd(OUT_ORDER_PENDING_DOC_TYPE, Boolean.FALSE);
- order = new OrderPakout();
- order.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
- order.setOrderNo(orderNo);
- order.setOrderTime(DateUtils.convert(now));
- order.setDocType(docType.getDocId());
- // settle=1 琛ㄧず寰呯敓鎴愪换鍔★紱鐢熸垚杩囪嚦灏戜竴涓繘浠撶紪鍙锋壒娆″悗缃负 2銆�
- // status=1 鏄惎鍔ㄥ紑鍏筹紝pakoutOrderPause(execute=2) 浼氱疆 0 闃绘瀹氭椂鍣ㄧ户缁敓鎴愩��
- order.setSettle(1L);
- order.setStatus(1);
- order.setCreateBy(9527L);
- order.setCreateTime(now);
- order.setUpdateBy(9527L);
- order.setUpdateTime(now);
- // moveStatus 淇濈暀鐜版湁鈥滃璐�/绉诲簱鈥濊涔夛紝杩欓噷涓嶅鐢ㄥ畠鍋氭殏鍋滃紑鍏炽��
- order.setMoveStatus(0);
- // 2 琛ㄧず鍑哄簱鏂瑰悜锛屽拰 man_order_detl_pakout 鏄庣粏淇濇寔涓�鑷淬��
- order.setPakinPakoutStatus(2);
- if (!orderPakoutService.insert(order)) {
- throw new CoolException("鐢熸垚鍑哄簱璁㈠崟澶辫触锛�" + orderNo);
+ if (order == null) {
+ order = createPendingPakoutOrderHeader(orderNo, now, executable);
+ } else {
+ assertNoNonReplaceablePendingDetailConflict(order, entry.getValue());
+ removedUndispatchedDetailCount += removeUndispatchedPendingDetails(order.getId());
+ refreshPendingPakoutOrderForResubmit(order, now, executable);
}
for (OutTaskParam param : entry.getValue()) {
// 鏄庣粏瀹屾暣淇濆瓨鎺ュ彛瀛楁锛屽悗缁畾鏃跺櫒鍙互鏃犳崯杩樺師 OutTaskParam 鍐嶅鐢� outOrderBatch銆�
+ // 璁㈠崟鍖栫殑鏍稿績鏄�滃弬鏁板厛鎸佷箙鍖栥�佷换鍔″悗鐢熸垚鈥濓細鍗充娇鏈嶅姟閲嶅惎锛屽畾鏃跺櫒浠嶈兘缁х画澶勭悊鏈敓鎴愭槑缁嗐��
OrderDetlPakout detail = buildPendingPakoutOrderDetl(order, param, now);
if (!orderDetlPakoutService.insert(detail)) {
throw new CoolException("鐢熸垚鍑哄簱璁㈠崟鏄庣粏澶辫触锛�" + orderNo);
@@ -1786,7 +1887,9 @@
Map<String, Object> result = new LinkedHashMap<>();
result.put("orderCount", orderCount);
result.put("detailCount", detailCount);
+ result.put("removedUndispatchedDetailCount", removedUndispatchedDetailCount);
result.put("orderNos", orderNos);
+ result.put("executable", executable);
return R.ok("鍑哄簱璁㈠崟鐢熸垚鎴愬姛").add(result);
}
@@ -1797,6 +1900,10 @@
// status=1 琛ㄧず鏈 pakoutOrderPause 涓锛�
// settle in (1,2) 琛ㄧず鏈畬鎴愬叏閮ㄤ换鍔$敓鎴愶紱
// pakin_pakout_status=2 闄愬畾鍑哄簱鍗曪紝閬垮厤璇壂鍏ュ簱/鍏朵粬鏂瑰悜鍗曟嵁銆�
+ //
+ // status=0 鐨勮鍗曚笉浼氳杩欓噷鎵弿锛屽吀鍨嬫潵婧愭槸锛�
+ // - IoT/MQTT autoConfirm=false 棰勫垱寤鸿鍗曪紱
+ // - pakoutOrderPause execute=2 涓鍚庣殑璁㈠崟銆�
List<OrderPakout> orders = orderPakoutService.selectList(new EntityWrapper<OrderPakout>()
.eq("status", 1)
.in("settle", Arrays.asList(1L, 2L))
@@ -1813,7 +1920,9 @@
continue;
}
scannedOrderCount++;
- // 姣忎釜璁㈠崟鍗曠嫭璧扮敓鎴愰�昏緫銆傚崟璁㈠崟鏂规硶鍐呴儴鍙細鐢熸垚褰撳墠鍏佽鐨勪竴涓� entryWmsCode 鎵规锛�
+ // 姣忎釜璁㈠崟鍗曠嫭璧扮敓鎴愰�昏緫銆傚崟璁㈠崟鏂规硶鍐呴儴鍙細鐢熸垚褰撳墠鍏佽鐨勪竴涓壒娆★細
+ // - 楂樼珯鐐癸細涓�涓� entryWmsCode 鎵规锛�
+ // - 浣庣珯鐐癸細涓�涓� orderNo 鎵规銆�
// 鍥犳瀹氭椂鍣ㄩ噸澶嶆墽琛屼篃涓嶄細涓�娆℃�ф妸鍚庣画鎵�鏈夎繘浠撶紪鍙峰叏閮ㄩ噴鏀俱��
R r = generatePendingPakoutOrderTasks(order.getOrderNo());
details.add(r);
@@ -1860,48 +1969,61 @@
return R.ok("鍑哄簱璁㈠崟涓嶅瓨鍦�").add(buildGeneratePendingResult(orderNo, null, 0, 0, "order not found"));
}
if (!Objects.equals(order.getStatus(), 1)) {
+ // 璁㈠崟 status=0 鏃跺彧杩斿洖鈥滆鏆傚仠/涓鈥濓紝涓嶆姏寮傚父銆�
+ // 杩欐牱瀹氭椂鍣ㄦ壂鎻忓拰浜哄伐鎵ц鎺ュ彛閮藉彲浠ュ箓绛夎皟鐢紝璋冪敤鏂规牴鎹� reason 鍒ゆ柇鍗冲彲銆�
return R.ok("鍑哄簱璁㈠崟宸蹭腑姝�").add(buildGeneratePendingResult(orderNo, null, 0, 0, "order status disabled"));
}
if (!Objects.equals(order.getSettle(), 1L) && !Objects.equals(order.getSettle(), 2L)) {
return R.ok("鍑哄簱璁㈠崟宸插鐞�").add(buildGeneratePendingResult(orderNo, null, 0, 0, "order settle not pending"));
}
- // 鎸夊師鏄庣粏 id 椤哄簭璇诲彇锛孡inkedHashMap 浼氫繚鎸侀娆″嚭鐜扮殑 entryWmsCode 椤哄簭銆�
- // 杩欐牱鈥滆繘浠撶紪鍙� A 鍋氬畬鍚庡啀鐢熸垚 B鈥濈殑椤哄簭鍜� ERP 鍘熷鏄庣粏椤哄簭涓�鑷淬��
+ // 鎸夊師鏄庣粏 id 椤哄簭璇诲彇锛孡inkedHashMap 浼氫繚鎸侀娆″嚭鐜扮殑鎵规閿『搴忋��
+ // 楂樼珯鐐规壒娆¢敭涓� entryWmsCode锛屽彲缁х画瀹炵幇鈥滆繘浠撶紪鍙� A 鍋氬畬鍚庡啀鐢熸垚 B鈥濓紱
+ // 浣庣珯鐐规壒娆¢敭涓� orderNo锛屽悓涓�璁㈠崟鍙舰鎴愪竴涓壒娆°��
List<OrderDetlPakout> details = orderDetlPakoutService.selectList(new EntityWrapper<OrderDetlPakout>()
.eq("order_id", order.getId())
.eq("status", 1)
.orderBy("id", true));
- LinkedHashMap<String, List<OrderDetlPakout>> detailsByEntryWmsCode = new LinkedHashMap<>();
+ LinkedHashMap<String, List<OrderDetlPakout>> detailsByTaskBatchSeq = new LinkedHashMap<>();
for (OrderDetlPakout detail : details) {
if (!isPendingPakoutDetail(detail)) {
continue;
}
- detailsByEntryWmsCode
- .computeIfAbsent(detail.getEntryWmsCode(), key -> new ArrayList<>())
+ String taskBatchSeq = resolvePakoutTaskBatchSeq(orderNo, detail);
+ // LinkedHashMap 淇濇寔棣栨鍑虹幇椤哄簭锛屼繚璇佸悓涓�璁㈠崟鍐呯殑鎵规鐢熸垚椤哄簭鍜� ERP 鏄庣粏椤哄簭涓�鑷淬��
+ // 杩欏楂樼珯鐐瑰挨鍏跺叧閿細绗簩涓� entryWmsCode 鍙湁鍦ㄧ涓�涓壒娆℃弧瓒抽噴鏀炬潯浠跺悗鎵嶄細琚鐞嗐��
+ detailsByTaskBatchSeq
+ .computeIfAbsent(taskBatchSeq, key -> new ArrayList<>())
.add(detail);
}
- if (detailsByEntryWmsCode.isEmpty()) {
+ if (detailsByTaskBatchSeq.isEmpty()) {
return R.ok("鏃犲緟鐢熸垚鍑哄簱浠诲姟").add(buildGeneratePendingResult(orderNo, null, 0, 0, "no pending detail"));
}
- // 涓�娆″彧鍙栧綋鍓嶆渶闈犲墠鐨勮繘浠撶紪鍙锋壒娆°�傚悗缁繘浠撶紪鍙锋槸鍚﹀厑璁哥敓鎴愶紝
- // 鐢� OutboundBatchSeqReleaseGuard 鏍规嵁宸叉湁 WrkMast 鐨� batchSeq銆亀rk_sts=25 鏁伴噺闃堝�肩瓑鍒ゆ柇銆�
- Map.Entry<String, List<OrderDetlPakout>> candidate = detailsByEntryWmsCode.entrySet().iterator().next();
- String entryWmsCode = candidate.getKey();
- String blockMsg = outboundBatchSeqReleaseGuard.validateReady(orderNo, entryWmsCode);
+ // 涓�娆″彧鍙栧綋鍓嶆渶闈犲墠鐨勬壒娆°�傞珮绔欑偣鐨勫悗缁繘浠撶紪鍙锋槸鍚﹀厑璁哥敓鎴愶紝
+ // 鐢� OutboundBatchSeqReleaseGuard 鏍规嵁宸叉湁 WrkMast.batchSeq銆亀rk_sts=25 鏁伴噺闃堝�肩瓑鍒ゆ柇銆�
+ Map.Entry<String, List<OrderDetlPakout>> candidate = detailsByTaskBatchSeq.entrySet().iterator().next();
+ String taskBatchSeq = candidate.getKey();
+ // 鎵规瀹堝崼璇诲彇 WrkMast.userNo/orderNo + WrkMast.batchSeq锛�
+ // - 濡傛灉鍓嶅簭鎵规鏈畬鎴愶紝闃诲锛�
+ // - 濡傛灉褰撳墠鎵规 wrk_sts=25 鏁伴噺杈惧埌閰嶇疆闃堝�硷紝闃诲锛�
+ // - 鍚﹀垯鍏佽鐢熸垚褰撳墠鎵规鐨勪笅涓�缁勪换鍔°��
+ String blockMsg = outboundBatchSeqReleaseGuard.validateReady(orderNo, taskBatchSeq);
if (!Cools.isEmpty(blockMsg)) {
- return R.ok("鍑哄簱杩涗粨缂栧彿鏆備笉婊¤冻鐢熸垚鏉′欢").add(buildGeneratePendingResult(orderNo, entryWmsCode, 0, candidate.getValue().size(), blockMsg));
+ return R.ok("鍑哄簱鎵规鏆備笉婊¤冻鐢熸垚鏉′欢").add(buildGeneratePendingResult(orderNo, taskBatchSeq, 0, candidate.getValue().size(), blockMsg));
}
List<OutTaskParam> outTaskParams = new ArrayList<>();
for (OrderDetlPakout detail : candidate.getValue()) {
- outTaskParams.add(buildOutTaskParam(orderNo, entryWmsCode, detail));
+ outTaskParams.add(buildOutTaskParam(orderNo, taskBatchSeq, detail));
}
Map<String, List<OutTaskParam>> linesByBatchSeq = new LinkedHashMap<>();
- // outOrderBatch 鐨勫垎缁� key 灏辨槸浠诲姟 batchSeq銆傝繖閲屽己鍒朵娇鐢� entryWmsCode锛�
- // 纭繚 WrkMast.userNo=orderId 涓� WrkMast.batchSeq=entryWmsCode锛岀幇鏈夋壒娆″畧鍗墠鑳界敓鏁堛��
- linesByBatchSeq.put(entryWmsCode, outTaskParams);
+ // outOrderBatch 鐨勫垎缁� key 灏辨槸浠诲姟 batchSeq銆傝繖閲屽己鍒朵娇鐢ㄨ绠楀悗鐨勪换鍔℃壒娆¢敭锛�
+ // 纭繚 WrkMast.userNo=orderId 涓� WrkMast.batchSeq 涓庢壒娆″畧鍗彛寰勪竴鑷淬��
+ //
+ // 涓嶇洿鎺ヤ娇鐢ㄨ鍗曟槑缁嗛噷鐨� batchSeq锛屽洜涓轰綆绔欑偣瑕佹眰鍥哄畾 orderId锛�
+ // 楂樼珯鐐硅姹傚浐瀹� entryWmsCode锛孍RP 鍘熷 batchSeq 鍙綔涓鸿拷婧瓧娈典繚瀛樸��
+ linesByBatchSeq.put(taskBatchSeq, outTaskParams);
R r = outOrderBatch(linesByBatchSeq, outTaskParams.size());
if (!Objects.equals(r.get("code"), 200)) {
throw new CoolException("鍑哄簱璁㈠崟鐢熸垚浠诲姟澶辫触锛�" + orderNo);
@@ -1911,6 +2033,9 @@
double remaining = getPendingDetailQty(detail);
// work_qty 琛ㄧず鈥滃凡鐢熸垚浠诲姟鏁伴噺鈥濓紝涓嶆槸瀹屾垚鏁伴噺銆�
// 浠诲姟瀹屾垚鍚庣敱 WorkMastHandler 閫掑 qty锛屽洜姝ら噸澶嶅畾鏃舵壂鎻忎笉浼氫负鍚屼竴鎵樼洏閲嶅寤轰换鍔°��
+ //
+ // 涓鍙栨秷鏃� WorkService.cancelWrkMast 浼氭妸杩欓儴鍒� work_qty 鍥炴粴锛�
+ // 鍥炴粴鍚庡啀娆℃墽琛岃鍗曪紝鏈笅鍙�/宸插彇娑堢殑鏄庣粏鍙互閲嶆柊鐢熸垚浠诲姟銆�
detail.setWorkQty(safeDouble(detail.getWorkQty()) + remaining);
detail.setUpdateBy(9527L);
detail.setUpdateTime(new Date());
@@ -1928,7 +2053,12 @@
}
}
- return R.ok("鍑哄簱璁㈠崟鐢熸垚浠诲姟鎴愬姛").add(buildGeneratePendingResult(orderNo, entryWmsCode, outTaskParams.size(), candidate.getValue().size(), null));
+ // status=1 鐨勮鍗曚唬琛ㄥ綋鍓嶅厑璁告墽琛屻�傛棤璁烘潵鑷� ERP 鑷姩璁㈠崟杩樻槸鎵ц鎺ュ彛鎭㈠鍚庣殑璁㈠崟锛�
+ // 鐢熸垚浠诲姟鍚庨兘绔嬪嵆璁剧疆 pdcType=Y锛屼繚璇� WorkMastScheduler 鍙互缁х画涓嬪彂銆�
+ int confirmedCount = confirmPendingOutboundTasks(findActiveOutboundTasks(orderNo));
+ Map<String, Object> result = buildGeneratePendingResult(orderNo, taskBatchSeq, outTaskParams.size(), candidate.getValue().size(), null);
+ result.put("confirmedCount", confirmedCount);
+ return R.ok("鍑哄簱璁㈠崟鐢熸垚浠诲姟鎴愬姛").add(result);
}
private void validatePendingOutOrderParam(OutTaskParam param) {
@@ -1938,20 +2068,160 @@
if (Cools.isEmpty(param.getPalletId())) {
throw new CoolException("鎵樼洏鍙蜂笉鑳戒负绌�");
}
- if (Cools.isEmpty(param.getEntryWmsCode())) {
+ if (Cools.isEmpty(param.getStationId())) {
+ throw new CoolException("鎵樼洏銆�" + param.getPalletId() + "銆嶅嚭搴撳彛缂栫爜涓嶈兘涓虹┖");
+ }
+ try {
+ Integer.valueOf(param.getStationId());
+ } catch (NumberFormatException ex) {
+ throw new CoolException("鎵樼洏銆�" + param.getPalletId() + "銆嶅嚭搴撳彛缂栫爜鏍煎紡閿欒锛�" + param.getStationId());
+ }
+ if (isPendingOutOrderStation(param.getStationId()) && Cools.isEmpty(param.getEntryWmsCode())) {
throw new CoolException("鎵樼洏銆�" + param.getPalletId() + "銆嶈繘浠撶紪鍙蜂笉鑳戒负绌�");
}
- if (!isPendingOutOrderStation(param.getStationId())) {
- throw new CoolException("鎵樼洏銆�" + param.getPalletId() + "銆嶅嚭搴撳彛涓嶅睘浜庡欢杩熺敓鎴愪换鍔¤寖鍥�");
+ if (Cools.isEmpty(param.getBatchSeq())) {
+ // batchSeq 鏄帴鍙e師瀛楁锛屼繚瀛樺湪璁㈠崟鏄庣粏鐢ㄤ簬杩芥函锛涘疄闄呬换鍔℃壒娆¢敭鐢� resolvePakoutTaskBatchSeq 鍐冲畾銆�
+ param.setBatchSeq(param.getOrderId());
}
+ }
+
+ private OrderPakout createPendingPakoutOrderHeader(String orderNo, Date now, boolean executable) {
+ DocType docType = docTypeService.selectOrAdd(OUT_ORDER_PENDING_DOC_TYPE, Boolean.FALSE);
+ OrderPakout order = new OrderPakout();
+ order.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
+ order.setOrderNo(orderNo);
+ order.setOrderTime(DateUtils.convert(now));
+ order.setDocType(docType.getDocId());
+ // settle 浠嶆部鐢ㄧ幇鏈夎鍗曡繘搴﹁涔夛細
+ // - 1锛氳鍗曞凡鍒涘缓锛岃繕娌℃湁鐢熸垚杩囦换鍔★紱
+ // - 2锛氳嚦灏戠敓鎴愯繃涓�涓换鍔℃壒娆★紝鍚庣画鏄惁杩樻湁寰呯敓鎴愭槑缁嗙户缁湅 anfme - work_qty锛�
+ // - 澶т簬 2锛氬叾浠栦笟鍔℃祦绋嬪凡澶勭悊/瀹屾垚锛屼笉鍏佽鏈帴鍙h鐩栥��
+ // status 鏄惎鍔ㄥ紑鍏筹細
+ // - ERP /outOrder 鍒涘缓 executable=true锛宻tatus=1锛屽畾鏃跺櫒鍙嚜鍔ㄧ敓鎴愶紱
+ // - IoT/MQTT 鍒涘缓 executable=false锛宻tatus=0锛屽繀椤昏皟鐢ㄦ墽琛屾帴鍙e悗鎵嶇敓鎴愩��
+ order.setSettle(1L);
+ order.setStatus(executable ? 1 : 0);
+ order.setCreateBy(9527L);
+ order.setCreateTime(now);
+ order.setUpdateBy(9527L);
+ order.setUpdateTime(now);
+ // moveStatus 淇濈暀鐜版湁鈥滃璐�/绉诲簱鈥濊涔夛紝杩欓噷涓嶅鐢ㄥ畠鍋氭殏鍋滃紑鍏炽��
+ order.setMoveStatus(0);
+ // 2 琛ㄧず鍑哄簱鏂瑰悜锛屽拰 man_order_detl_pakout 鏄庣粏淇濇寔涓�鑷淬��
+ order.setPakinPakoutStatus(2);
+ if (!orderPakoutService.insert(order)) {
+ throw new CoolException("鐢熸垚鍑哄簱璁㈠崟澶辫触锛�" + orderNo);
+ }
+ return order;
+ }
+
+ private void refreshPendingPakoutOrderForResubmit(OrderPakout order, Date now, boolean executable) {
+ if (order == null) {
+ return;
+ }
+ boolean hasDispatchedDetail = hasDispatchedPendingDetail(order.getId());
+ // 閲嶅涓嬪彂鏃舵寜鏈鍏ュ彛閲嶆柊鍐冲畾鏄惁绔嬪嵆鍙墽琛岋細
+ // ERP 閲嶅彂缁х画 status=1锛汭oT/MQTT 棰勫垱寤虹户缁� status=0锛岀瓑寰呮墽琛屾帴鍙c��
+ //
+ // settle 鐨勬仮澶嶅彛寰勶細
+ // - 濡傛灉宸叉湁宸蹭笅鍙�/宸插畬鎴愭槑缁嗭紝淇濇寔 2锛岃鏄庤璁㈠崟鏇捐繘鍏ョ敓鎴愪换鍔¢樁娈碉紱
+ // - 濡傛灉鍙墿鏈笅鍙戞槑缁嗭紝閲嶇疆涓� 1锛岃〃绀哄彲浠ヤ綔涓烘柊璁㈠崟鎵规閲嶆柊鐢熸垚銆�
+ order.setStatus(executable ? 1 : 0);
+ order.setSettle(hasDispatchedDetail ? 2L : 1L);
+ order.setUpdateBy(9527L);
+ order.setUpdateTime(now);
+ order.setPakinPakoutStatus(2);
+ if (!orderPakoutService.updateById(order)) {
+ throw new CoolException("鏇存柊鍑哄簱璁㈠崟澶辫触锛�" + order.getOrderNo());
+ }
+ }
+
+ private boolean hasDispatchedPendingDetail(Long orderId) {
+ // 鍙瀛樺湪 work_qty>0 鎴� qty>0 鐨勬槑缁嗭紝灏辫涓鸿璁㈠崟宸茬粡杩涘叆杩囨墽琛岄摼璺��
+ // 杩欑被鏄庣粏涓嶈兘鍦ㄩ噸鍙戞椂鐩存帴鍒犻櫎锛屽惁鍒欎細涓㈠け浠诲姟杩芥函鎴栧畬鎴愭暟閲忋��
+ List<OrderDetlPakout> details = orderDetlPakoutService.selectList(new EntityWrapper<OrderDetlPakout>()
+ .eq("order_id", orderId)
+ .eq("status", 1));
+ if (Cools.isEmpty(details)) {
+ return false;
+ }
+ for (OrderDetlPakout detail : details) {
+ if (!isUndispatchedPendingDetail(detail)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 鍒犻櫎鍚岃鍗曚腑灏氭湭涓嬪彂鐨勬槑缁嗐��
+ *
+ * 鍒ゆ柇鍙e緞锛�
+ * - work_qty <= 0锛氬皻鏈敓鎴愭湁鏁堜换鍔★紝鎴栦腑姝㈠悗浠诲姟宸茶鍙栨秷骞跺畬鎴愬洖婊氥��
+ * - qty <= 0锛氭病鏈変笟鍔″畬鎴愰噺锛屽垹闄ゅ悗涓嶄細涓㈠け宸插畬鎴愬嚭搴撹褰曘��
+ */
+ private int removeUndispatchedPendingDetails(Long orderId) {
+ List<OrderDetlPakout> details = orderDetlPakoutService.selectList(new EntityWrapper<OrderDetlPakout>()
+ .eq("order_id", orderId)
+ .eq("status", 1));
+ if (Cools.isEmpty(details)) {
+ return 0;
+ }
+ int removed = 0;
+ for (OrderDetlPakout detail : details) {
+ if (!isUndispatchedPendingDetail(detail)) {
+ continue;
+ }
+ if (!orderDetlPakoutService.deleteById(detail.getId())) {
+ throw new CoolException("鍒犻櫎鏈笅鍙戝嚭搴撹鍗曟槑缁嗗け璐ワ細" + detail.getOrderNo());
+ }
+ removed++;
+ }
+ return removed;
+ }
+
+ private void assertNoNonReplaceablePendingDetailConflict(OrderPakout order, List<OutTaskParam> params) {
+ if (order == null || Cools.isEmpty(params)) {
+ return;
+ }
+ Set<String> newPalletIds = params.stream()
+ .filter(Objects::nonNull)
+ .map(OutTaskParam::getPalletId)
+ .filter(palletId -> !Cools.isEmpty(palletId))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ if (newPalletIds.isEmpty()) {
+ return;
+ }
+ List<OrderDetlPakout> details = orderDetlPakoutService.selectList(new EntityWrapper<OrderDetlPakout>()
+ .eq("order_id", order.getId())
+ .eq("status", 1));
+ if (Cools.isEmpty(details)) {
+ return;
+ }
+ for (OrderDetlPakout detail : details) {
+ // 鏈閲嶅彂濡傛灉鍖呭惈浜嗗凡缁忎笅鍙�/瀹屾垚鐨勫悓鎵樼洏鏄庣粏锛岀洿鎺ユ嫆缁濄��
+ // 鏈笅鍙戞槑缁嗗彲浠ュ垹闄ら噸寤猴紱宸蹭笅鍙�/瀹屾垚鏄庣粏蹇呴』淇濈暀锛屼互鍏嶇牬鍧忓彇娑堝洖婊氬拰瀹屾垚鍥炲啓銆�
+ if (detail == null || !newPalletIds.contains(detail.getPalletId()) || isUndispatchedPendingDetail(detail)) {
+ continue;
+ }
+ throw new CoolException("鎵樼洏銆�" + detail.getPalletId() + "銆嶅凡瀛樺湪宸蹭笅鍙戞垨宸插畬鎴愬嚭搴撴槑缁嗭紝鏃犳硶瑕嗙洊");
+ }
+ }
+
+ private boolean isUndispatchedPendingDetail(OrderDetlPakout detail) {
+ // 鈥滄湭涓嬪彂鈥濅笉鏄湅璁㈠崟鐘舵�侊紝鑰屾槸鐪嬫槑缁嗚繘搴︼細
+ // work_qty=0 涓� qty=0 鎵嶈鏄庢棦娌℃湁鐢熸垚浠诲姟锛屼篃娌℃湁瀹屾垚閲忥紝鍙互瀹夊叏鍒犻櫎閲嶅缓銆�
+ return detail != null
+ && safeDouble(detail.getWorkQty()) <= 0.0D
+ && safeDouble(detail.getQty()) <= 0.0D;
}
/**
* 鍒ゆ柇寤惰繜鍑哄簱璁㈠崟鏄惁杩樿兘琚綋鍓嶆帴鍙h姹傝鐩栥��
*
- * 鍏佽瑕嗙洊鐨勮竟鐣屽彧闄愪簬鈥滃凡寤鸿鍗曚絾灏氭湭鐢熸垚浠讳綍浠诲姟鈥濈殑鎯呭喌銆�
- * 鍙 WrkMast 鎴� WrkMastLog 宸插瓨鍦紝灏辫鏄庤鍗曞凡缁忚繘鍏ユ墽琛岄摼璺垨鍘嗗彶閾捐矾锛�
- * 鍐嶈鐩栦細鐮村潖浠诲姟銆佸簱瀛樺拰 ERP 鍥炰紶涔嬮棿鐨勫彲杩芥函鍏崇郴銆�
+ * 娲诲姩浠诲姟浠嶇劧瀛樺湪鏃朵笉鍏佽瑕嗙洊锛屽洜涓轰换鍔°�佸簱浣嶃�乄CS 鎸囦护杩樺湪鎵ц閾捐矾涓娿��
+ * 宸茬粡鍙栨秷骞跺綊妗e埌 WrkMastLog 鐨勪换鍔″厑璁搁噸涓嬪彂锛涘叾璁㈠崟鏄庣粏 work_qty 宸插湪鍙栨秷鏃跺洖婊氾紝
+ * 鏈鎺ュ彛浼氬垹闄ゆ湭涓嬪彂鏄庣粏骞舵彃鍏ユ柊鏄庣粏銆�
*/
private void assertPendingPakoutOrderCanReplace(String orderNo) {
List<WrkMast> activeTasks = findActiveOutboundTasks(orderNo);
@@ -1961,14 +2231,11 @@
int activeWrkCount = wrkMastService.selectCount(new EntityWrapper<WrkMast>()
.eq("io_type", 101)
.eq("user_no", orderNo));
- int historyWrkCount = wrkMastLogService.selectCount(new EntityWrapper<WrkMastLog>()
- .eq("io_type", 101)
- .eq("user_no", orderNo));
- if (activeWrkCount > 0 || historyWrkCount > 0) {
- throw new CoolException("鍑哄簱璁㈠崟宸插瓨鍦ㄤ换鍔℃。鎴栦换鍔″巻鍙叉。锛屾棤娉曡鐩栵細" + orderNo);
+ if (activeWrkCount > 0) {
+ throw new CoolException("鍑哄簱璁㈠崟宸插瓨鍦ㄤ换鍔℃。锛屾棤娉曡鐩栵細" + orderNo);
}
OrderPakout order = orderPakoutService.selectByNo(orderNo);
- if (order != null && order.getSettle() != null && order.getSettle() > 1L) {
+ if (order != null && order.getSettle() != null && order.getSettle() > 2L) {
throw new CoolException(orderNo + "姝e湪鍑哄簱锛屾棤娉曚慨鏀瑰崟鎹�");
}
}
@@ -1989,9 +2256,12 @@
}
OrderDetlPakout detail = new OrderDetlPakout();
detail.sync(locDetl);
+ // order_id/order_no 浣跨敤 man_order_pakout 鐨勪富妗d俊鎭紝涓嶈兘浣跨敤 ERP 鍘熷瀛楁鐩存帴鍐欏叆 id銆�
detail.setOrderId(order.getId());
detail.setOrderNo(order.getOrderNo());
detail.setAnfme(resolvePendingOrderAnfme(param, locDetl));
+ // work_qty锛氬凡鐢熸垚浠诲姟鏁伴噺锛泀ty锛氬凡瀹屾垚鍑哄簱鏁伴噺銆�
+ // 涓よ�呭垵濮嬮兘涓� 0锛岀敓鎴愪换鍔″彧鍔� work_qty锛屼换鍔″畬鎴愬洖鍐欐墠鍔� qty銆�
detail.setWorkQty(0.0D);
detail.setQty(0.0D);
detail.setStatus(1);
@@ -2000,6 +2270,8 @@
detail.setUpdateBy(9527L);
detail.setUpdateTime(now);
detail.setPakinPakoutStatus(2);
+ // 浠ヤ笅瀛楁瀹屾暣淇濆瓨 OutTaskParam 鍘熷�硷紝淇濊瘉鍚庣画瀹氭椂鍣ㄥ彲浠ヨ繕鍘熷嚭 OutTaskParam銆�
+ // 娉ㄦ剰锛歞etail.batchSeq 鍙槸 ERP 鍘熷鎵规瀛楁锛涚湡姝g敓鎴� WrkMast.batchSeq 鏃朵細閲嶆柊璁$畻銆�
detail.setBatchSeq(param.getBatchSeq());
detail.setSeq(param.getSeq());
detail.setPalletId(param.getPalletId());
@@ -2013,6 +2285,7 @@
detail.setCubeNumber(param.getCubeNumber());
detail.setTeu(param.getTeu());
// standby1/standby2 缁х画闀滃儚杩涗粨缂栧彿鍜屽嚭搴撻棬鍙凤紝鍏煎鐜版湁瀹屾垚鍥炲啓鐨� selectItem 鍖归厤閫昏緫銆�
+ // 浣庣珯鐐瑰厑璁� entryWmsCode 涓虹┖锛屼篃瑕佹樉寮忚惤绌哄�硷紝淇濊瘉璁㈠崟鏄庣粏鍜� WrkDetl 缁村害涓�鑷淬��
detail.setStandby1(param.getEntryWmsCode());
detail.setStandby2(param.getOutDoorNo());
return detail;
@@ -2039,22 +2312,40 @@
* 杩欓噷鍙湅 anfme - work_qty锛岄伩鍏嶅畾鏃跺櫒鍥犱负浠诲姟鏈畬鎴愯�岄噸澶嶇敓鎴愬悓涓�鎵樼洏浠诲姟銆�
*/
private boolean isPendingPakoutDetail(OrderDetlPakout detail) {
+ // 鍙杩樺瓨鍦ㄥ緟鐢熸垚鏁伴噺锛屽苟涓旇兘璁$畻鍑轰换鍔℃壒娆¢敭锛屽氨璁や负璇ユ槑缁嗗彲杩涘叆鐢熸垚娴佺▼銆�
+ // 鏄惁鐪熺殑鐢熸垚鐢卞悗缁� OutboundBatchSeqReleaseGuard 鍐冲畾銆�
return detail != null
- && isPendingOutOrderStation(detail.getStationId())
- && !Cools.isEmpty(detail.getEntryWmsCode())
+ && !Cools.isEmpty(resolvePakoutTaskBatchSeq(detail.getOrderNo(), detail))
&& getPendingDetailQty(detail) > 0.0D;
+ }
+
+ /**
+ * 璁㈠崟鏄庣粏杞换鍔℃椂鐨勬壒娆¢敭銆�
+ *
+ * entryWmsCode 瀛樺湪鏃朵紭鍏堜綔涓鸿繘浠撶紪鍙锋壒娆★紝鍏煎 stationId > 600 鐨勫垎鎵规斁琛岋紱
+ * entryWmsCode 涓虹┖鏃朵娇鐢ㄨ鍗曞彿锛屾弧瓒充綆绔欑偣 ERP 鍑哄簱缁熶竴璁㈠崟鍖栧悗鐨勬壒娆¤竟鐣屻��
+ *
+ * stationId <= 600 鍗充娇浼犱簡 entryWmsCode锛屼篃涓嶅弬涓庢壒娆¢敭璁$畻锛�
+ * 杩欐槸涓轰簡婊¤冻鈥滀綆绔欑偣鎵规杈圭晫鎸� orderId 澶勭悊鈥濈殑鎺ュ彛绾﹀畾銆�
+ */
+ private String resolvePakoutTaskBatchSeq(String orderNo, OrderDetlPakout detail) {
+ if (detail != null && isPendingOutOrderStation(detail.getStationId()) && !Cools.isEmpty(detail.getEntryWmsCode())) {
+ return detail.getEntryWmsCode();
+ }
+ return orderNo;
}
/**
* 浠庤鍗曟槑缁嗚繕鍘� outOrderBatch 闇�瑕佺殑鍙傛暟銆�
*
- * batchSeq 蹇呴』寮哄埗鏀逛负 entryWmsCode锛岃�屼笉鏄部鐢� ERP 鍘熷 batchSeq锛�
- * 杩欐牱鍚庣画 WCS 涓嬪彂瀹堝崼鎵嶈兘浠ヨ繘浠撶紪鍙蜂负椤哄簭杈圭晫銆�
+ * batchSeq 蹇呴』寮哄埗鏀逛负浠诲姟鎵规閿細
+ * - 楂樼珯鐐癸細entryWmsCode锛學CS 涓嬪彂瀹堝崼浠ヨ繘浠撶紪鍙蜂负椤哄簭杈圭晫锛�
+ * - 浣庣珯鐐癸細orderNo锛屾暣寮� ERP 璁㈠崟浣滀负涓�涓壒娆°��
*/
- private OutTaskParam buildOutTaskParam(String orderNo, String entryWmsCode, OrderDetlPakout detail) {
+ private OutTaskParam buildOutTaskParam(String orderNo, String taskBatchSeq, OrderDetlPakout detail) {
OutTaskParam param = new OutTaskParam();
param.setOrderId(orderNo);
- param.setBatchSeq(entryWmsCode);
+ param.setBatchSeq(taskBatchSeq);
param.setSeq(detail.getSeq());
param.setPalletId(detail.getPalletId());
param.setStationId(detail.getStationId());
@@ -2071,10 +2362,12 @@
return param;
}
- private Map<String, Object> buildGeneratePendingResult(String orderNo, String entryWmsCode, int generatedTaskCount, int pendingDetailCount, String reason) {
+ private Map<String, Object> buildGeneratePendingResult(String orderNo, String taskBatchSeq, int generatedTaskCount, int pendingDetailCount, String reason) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("orderNo", orderNo);
- result.put("entryWmsCode", entryWmsCode);
+ result.put("batchSeq", taskBatchSeq);
+ // 淇濈暀鏃� key锛岄伩鍏嶅閮ㄦ棩蹇楁垨椤甸潰浠嶆寜 entryWmsCode 璇诲彇楂樼珯鐐规壒娆°��
+ result.put("entryWmsCode", taskBatchSeq);
result.put("generatedTaskCount", generatedTaskCount);
result.put("pendingDetailCount", pendingDetailCount);
if (!Cools.isEmpty(reason)) {
--
Gitblit v1.9.1