From 5677fd88b56cd69e416b52144734f3997ef8f8f4 Mon Sep 17 00:00:00 2001
From: cl <1442464845@qq.com>
Date: 星期二, 28 四月 2026 16:29:12 +0800
Subject: [PATCH] 找库位
---
src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java | 593 ++++++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 402 insertions(+), 191 deletions(-)
diff --git a/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java b/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
index 3d39bb7..1315844 100644
--- a/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
+++ b/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
@@ -7,6 +7,7 @@
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
+import com.zy.api.controller.params.ChangeLocParams;
import com.zy.api.controller.params.ReassignLocParams;
import com.zy.api.controller.params.ReceviceTaskParams;
import com.zy.api.controller.params.StopOutTaskParams;
@@ -17,21 +18,21 @@
import com.zy.api.service.WcsApiService;
import com.zy.asrs.entity.*;
import com.zy.asrs.service.*;
+import com.zy.asrs.task.support.OutboundBatchSeqReleaseGuard;
import com.zy.asrs.utils.Utils;
import com.zy.common.constant.MesConstant;
import com.zy.common.model.LocTypeDto;
import com.zy.common.model.StartupDto;
+import com.zy.common.model.CrnDepthRuleProfile;
+import com.zy.common.model.enums.WorkNoType;
import com.zy.common.service.CommonService;
import com.zy.common.utils.HttpHandler;
-import com.zy.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.support.TransactionSynchronizationAdapter;
-import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.io.IOException;
import java.math.BigDecimal;
@@ -49,6 +50,8 @@
private static final long OUT_LOCK_REPORT_PENDING_WRK_STS = 13L;
private static final long OUT_LOCK_REPORT_SUCCESS_WRK_STS = 21L;
private static final long OUT_LOCK_REPORT_FAIL_WRK_STS = 22L;
+ private static final long OUTBOUND_CRN_COMPLETE_WRK_STS = 25L;
+ private static final long OUTBOUND_STATION_COMPLETE_WRK_STS = 26L;
private static final String OUT_LOCK_REPORT_PENDING_FLAG = "P";
/** 鍚屼竴 WCS 璺緞銆佸悓涓�鍗曞彿涓嬩竴缁勪笅鍙戠殑浠诲姟鏉℃暟涓婇檺 */
@@ -56,8 +59,19 @@
/** 涓夋柟鎺ュ彛缁熻锛氭湰绯荤粺璋冪敤 WCS 鐨� namespace 绾﹀畾 */
private static final String NS_WMS_TO_WCS = "鏈郴缁熻姹俉CS";
- private static final String REASSIGN_CRN_LOCK_KEY_PREFIX = "wcs:reassign:inbound:crn:";
- private static final long REASSIGN_CRN_LOCK_SECONDS = 180L;
+ private static final String EMPTY_PALLET_MATNR = "emptyPallet";
+ private static final int EMPTY_PALLET_REASSIGN_TARGET_LEVEL = 8;
+ private static final short EMPTY_PALLET_REASSIGN_LOC_TYPE1 = 3;
+ private static final short EMPTY_PALLET_REASSIGN_LOC_TYPE2 = 0;
+ private static final int CHANGE_LOC_IO_TYPE = 5;
+
+ private static class ReassignCrnPool {
+ private final List<Integer> crnNos;
+
+ private ReassignCrnPool(List<Integer> crnNos) {
+ this.crnNos = crnNos;
+ }
+ }
@Autowired
private LocMastService locMastService;
@@ -105,9 +119,11 @@
@Autowired
private ApiLogService apiLogService;
@Autowired
- private RowLastnoService rowLastnoService;
+ private OutboundBatchSeqReleaseGuard outboundBatchSeqReleaseGuard;
@Autowired
- private RedisUtil redisUtil;
+ private BasCrnDepthRuleService basCrnDepthRuleService;
+ @Autowired
+ private RowLastnoService rowLastnoService;
/**
@@ -127,6 +143,10 @@
String validateMsg = validatePubTask(params, wrkMast);
if (!Cools.isEmpty(validateMsg)) {
return R.error(validateMsg);
+ }
+ String batchBlockMsg = validateOutboundBatchSeqReady(params, wrkMast);
+ if (!Cools.isEmpty(batchBlockMsg)) {
+ return R.error(batchBlockMsg);
}
String url = resolveTaskPath(params);
String requestJson = JSON.toJSONString(params);
@@ -485,49 +505,19 @@
return null;
}
WorkTaskParams head = chunk.get(0);
- if (!"out".equalsIgnoreCase(head.getType())) {
- return null;
- }
- WrkMast headMast = wrkMastMap.get(head.getTaskNo());
- String userNo = sortUserNoForPub(head, headMast);
- if (Cools.isEmpty(userNo)) {
- return null;
- }
- String batchSeq = sortBatchGroupForPub(head, headMast);
- String blockingBatchSeq = findFirstUnfinishedOutboundBatchSeq(userNo);
- if (blockingBatchSeq == null || compareBatchSeqNatural(batchSeq, blockingBatchSeq) == 0) {
- return null;
- }
- return "鍑哄簱鎵规鏈畬鎴愶紝鏆傚仠鍚庣画涓嬪彂, userNo=" + userNo
- + ", blockingBatchSeq=" + normalizeBatchSeq(blockingBatchSeq)
- + ", nextBatchSeq=" + normalizeBatchSeq(batchSeq);
+ return validateOutboundBatchSeqReady(head, wrkMastMap.get(head.getTaskNo()));
}
- private String findFirstUnfinishedOutboundBatchSeq(String userNo) {
- EntityWrapper<WrkMast> wrapper = new EntityWrapper<>();
- if (Cools.isEmpty(userNo)) {
- wrapper.isNull("user_no");
- } else {
- wrapper.eq("user_no", userNo);
- }
- wrapper.eq("io_type", 101);
- wrapper.last(" and (wrk_sts < 14 or wrk_sts in ("
- + OUT_LOCK_REPORT_SUCCESS_WRK_STS + "," + OUT_LOCK_REPORT_FAIL_WRK_STS + "))");
- List<WrkMast> rows = wrkMastService.selectList(wrapper);
- if (rows == null || rows.isEmpty()) {
+ private String validateOutboundBatchSeqReady(WorkTaskParams params, WrkMast wrkMast) {
+ if (params == null || !"out".equalsIgnoreCase(params.getType())) {
return null;
}
- String firstBatchSeq = null;
- for (WrkMast row : rows) {
- if (row == null) {
- continue;
- }
- String batchSeq = sortBatchGroupForPub(null, row);
- if (firstBatchSeq == null || compareBatchSeqNatural(batchSeq, firstBatchSeq) < 0) {
- firstBatchSeq = batchSeq;
- }
+ if (wrkMast == null || !Objects.equals(wrkMast.getIoType(), 101)) {
+ return null;
}
- return firstBatchSeq;
+ return outboundBatchSeqReleaseGuard.validateReady(
+ sortUserNoForPub(params, wrkMast),
+ sortBatchGroupForPub(params, wrkMast));
}
private boolean outboundPltSlotReleasedInWms(String userNo, String batchSeq, int pltType) {
@@ -714,11 +704,29 @@
throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
}
- } else if (params.getNotifyType().equals("task")) {
+ } else if (isOutboundCrnTaskComplete(params)) {
+ // WCS鍑哄簱浠诲姟瀹屾垚锛氬爢鍨涙満鍑哄簱浠诲姟鎵ц瀹屾垚锛屽伐浣滅姸鎬� -> 25銆�
+ if (isOutboundTask(mast) && canMarkOutboundCrnComplete(mast)) {
+ mast.setWrkSts(OUTBOUND_CRN_COMPLETE_WRK_STS);
+ mast.setModiTime(new Date());
+ if (!wrkMastService.updateById(mast)) {
+ throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+ }
+ }
+ } else if (isOutboundStationTaskRunComplete(params)) {
+ // WCS杈撻�佺珯鐐瑰嚭搴撲换鍔¤繍琛屽畬鎴愶細鎵樼洏宸插埌鐩殑鍦帮紝宸ヤ綔鐘舵�� -> 26銆�
+ if (isOutboundTask(mast) && canMarkOutboundStationComplete(mast)) {
+ mast.setWrkSts(OUTBOUND_STATION_COMPLETE_WRK_STS);
+ mast.setModiTime(new Date());
+ if (!wrkMastService.updateById(mast)) {
+ throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+ }
+ }
+ } else if ("task".equalsIgnoreCase(params.getNotifyType())) {
//浠诲姟
- if (params.getMsgType().equals("task_complete")) {
+ if ("task_complete".equalsIgnoreCase(params.getMsgType())) {
- if (mast.getIoType() == 1 || mast.getIoType() == 2 ||mast.getIoType() == 10) {
+ if (mast.getIoType() == 1 || mast.getIoType() == 2 || mast.getIoType() == 10 || mast.getIoType() == CHANGE_LOC_IO_TYPE) {
mast.setWrkSts(4L);
} else if (isOutboundTask(mast) && canMarkOutboundTaskComplete(mast)) {
mast.setWrkSts(14L);
@@ -730,7 +738,7 @@
throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
//wcs浠诲姟鍙栨秷鎺ュ彛
- } else if (params.getMsgType().equals("task_cancel")) {
+ } else if ("task_cancel".equalsIgnoreCase(params.getMsgType())) {
workService.cancelWrkMast(String.valueOf(mast.getWrkNo()), 9955L);
}
}
@@ -743,8 +751,29 @@
&& "crn_out_task_run".equalsIgnoreCase(params.getMsgType());
}
+ private boolean isOutboundCrnTaskComplete(ReceviceTaskParams params) {
+ return params != null
+ && "Crn".equalsIgnoreCase(params.getNotifyType())
+ && "crn_out_task_complete".equalsIgnoreCase(params.getMsgType());
+ }
+
+ private boolean isOutboundStationTaskRunComplete(ReceviceTaskParams params) {
+ return params != null
+ && "Devp".equalsIgnoreCase(params.getNotifyType())
+ && "station_out_task_run_complete".equalsIgnoreCase(params.getMsgType());
+ }
+
private boolean isOutboundTask(WrkMast mast) {
return mast != null && mast.getIoType() != null && (mast.getIoType() == 101 || mast.getIoType() == 110);
+ }
+
+ private boolean canMarkOutboundCrnComplete(WrkMast mast) {
+ if (mast == null || mast.getWrkSts() == null) {
+ return false;
+ }
+ return mast.getWrkSts() < 14
+ || mast.getWrkSts().equals(OUT_LOCK_REPORT_SUCCESS_WRK_STS)
+ || mast.getWrkSts().equals(OUT_LOCK_REPORT_FAIL_WRK_STS);
}
private boolean canMarkOutboundTaskComplete(WrkMast mast) {
@@ -753,7 +782,19 @@
}
return mast.getWrkSts() < 14
|| mast.getWrkSts().equals(OUT_LOCK_REPORT_SUCCESS_WRK_STS)
- || mast.getWrkSts().equals(OUT_LOCK_REPORT_FAIL_WRK_STS);
+ || mast.getWrkSts().equals(OUT_LOCK_REPORT_FAIL_WRK_STS)
+ || mast.getWrkSts().equals(OUTBOUND_CRN_COMPLETE_WRK_STS)
+ || mast.getWrkSts().equals(OUTBOUND_STATION_COMPLETE_WRK_STS);
+ }
+
+ private boolean canMarkOutboundStationComplete(WrkMast mast) {
+ if (mast == null || mast.getWrkSts() == null) {
+ return false;
+ }
+ return mast.getWrkSts() < 14
+ || mast.getWrkSts().equals(OUT_LOCK_REPORT_SUCCESS_WRK_STS)
+ || mast.getWrkSts().equals(OUT_LOCK_REPORT_FAIL_WRK_STS)
+ || mast.getWrkSts().equals(OUTBOUND_CRN_COMPLETE_WRK_STS);
}
@Override
@@ -814,28 +855,37 @@
return R.error("褰撳墠鐩爣搴撲綅涓嶅瓨鍦�");
}
- LocTypeDto locTypeDto = buildReassignLocTypeDto(currentLoc);
- List<Integer> areaOrder = buildReassignAreaOrder(wrkMast, currentLoc);
- if (Cools.isEmpty(areaOrder)) {
- return R.error("鏃犳硶纭畾浠诲姟鎵�灞炲簱鍖�");
+ boolean emptyPallet = isReassignEmptyPallet(wrkMast);
+ LocTypeDto locTypeDto = buildReassignLocTypeDto(currentLoc, emptyPallet);
+ BasDevp sourceStation = basDevpService.selectById(wrkMast.getSourceStaNo());
+ if (Cools.isEmpty(sourceStation)) {
+ return R.error("婧愮珯鏈厤缃叆搴撲紭鍏堟睜");
+ }
+ List<ReassignCrnPool> poolOrder;
+ try {
+ poolOrder = buildReassignCrnPoolOrder(sourceStation, wrkMast.getCrnNo());
+ } catch (CoolException e) {
+ return R.error(e.getMessage());
+ }
+ if (Cools.isEmpty(poolOrder)) {
+ return R.error("婧愮珯鏈厤缃叆搴撲紭鍏堟睜");
}
StartupDto startupDto = null;
- Integer preferredArea = null;
- for (Integer area : areaOrder) {
- List<Integer> candidateCrnNos = buildReassignCandidateCrnNos(area, wrkMast.getCrnNo());
+ Integer targetLevel = resolveReassignTargetLevel(emptyPallet);
+ for (ReassignCrnPool pool : poolOrder) {
+ List<Integer> candidateCrnNos = buildReassignCandidateCrnNos(pool.crnNos, wrkMast.getCrnNo());
if (candidateCrnNos.isEmpty()) {
continue;
}
startupDto = commonService.findRun2InboundLocByCandidateCrnNos(
- wrkMast.getSourceStaNo(), wrkMast.getIoType(), area, candidateCrnNos, locTypeDto);
+ wrkMast.getSourceStaNo(), wrkMast.getIoType(), candidateCrnNos, locTypeDto, targetLevel);
if (startupDto != null && !Cools.isEmpty(startupDto.getLocNo())) {
- preferredArea = area;
break;
}
}
if (startupDto == null || Cools.isEmpty(startupDto.getLocNo())) {
- return R.error("褰撳墠搴撳尯娌℃湁鍙噸鏂板垎閰嶇殑绌哄簱浣�");
+ return R.error("褰撳墠浼樺厛姹犳病鏈夊彲閲嶆柊鍒嗛厤鐨勭┖搴撲綅");
}
LocMast targetLoc = locMastService.selectById(startupDto.getLocNo());
@@ -850,11 +900,219 @@
updateReassignTargetLoc(targetLoc, wrkMast, currentLoc, now);
updateReassignWorkMast(wrkMast, startupDto, now);
releaseOldReservedLocIfNeeded(currentLoc, targetLoc.getLocNo(), now);
- lockReassignedCrnAfterCommit(preferredArea, targetLoc.getCrnNo(), wrkMast.getWrkNo());
Map<String, Object> result = new LinkedHashMap<>();
result.put("locNo", Utils.WMSLocToWCSLoc(targetLoc.getLocNo()));
return R.ok("鎿嶄綔鎴愬姛").add(result);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public R changeLoc(ChangeLocParams params) {
+ if (params == null || Cools.isEmpty(params.getLocNo())) {
+ return R.error("locNo涓嶈兘涓虹┖");
+ }
+ LocMast sourceLoc = locMastService.selectById(params.getLocNo());
+ if (sourceLoc == null) {
+ return R.error("褰撳墠搴撲綅涓嶅瓨鍦�");
+ }
+ CrnDepthRuleProfile profile = resolveChangeLocProfile(sourceLoc);
+ String validateMsg = validateChangeLocSource(sourceLoc, profile);
+ if (!Cools.isEmpty(validateMsg)) {
+ return R.error(validateMsg);
+ }
+ List<Integer> candidateRows = resolveChangeLocRows(params.getRow(), profile);
+ LocMast targetLoc = selectChangeLocTarget(sourceLoc, profile, candidateRows);
+ if (targetLoc == null) {
+ return R.error("褰撳墠鍫嗗灈鏈烘棤鍙敤绉诲簱鐩爣浣�");
+ }
+ Integer workNo = commonService.getWorkNo(WorkNoType.PICK.type);
+ Date now = new Date();
+ createChangeLocTask(workNo, sourceLoc, targetLoc, now);
+ reserveChangeLocTargetLoc(targetLoc, sourceLoc, now);
+ reserveChangeLocSourceLoc(sourceLoc, now);
+ Map<String, Object> result = new LinkedHashMap<>();
+ result.put("locNo", Utils.WMSLocToWCSLoc(targetLoc.getLocNo()));
+ result.put("taskNo", String.valueOf(workNo));
+ return R.ok("鎿嶄綔鎴愬姛").add(result);
+ }
+
+ private CrnDepthRuleProfile resolveChangeLocProfile(LocMast sourceLoc) {
+ RowLastno rowLastno = rowLastnoService.selectById(sourceLoc.getWhsType());
+ return basCrnDepthRuleService.resolveProfile(rowLastno, sourceLoc.getCrnNo(), sourceLoc.getRow1());
+ }
+
+ private String validateChangeLocSource(LocMast sourceLoc, CrnDepthRuleProfile profile) {
+ if (sourceLoc.getCrnNo() == null) {
+ return "褰撳墠搴撲綅鏈粦瀹氬爢鍨涙満";
+ }
+ if (profile == null || !profile.isDoubleExtension()) {
+ return "褰撳墠鍫嗗灈鏈洪潪鍙屾繁搴撲綅锛屼笉鏀寔绉诲簱";
+ }
+ if (sourceLoc.getRow1() == null || profile == null || !profile.isShallowRow(sourceLoc.getRow1())) {
+ return "褰撳墠搴撲綅涓嶆槸娴呭簱浣�";
+ }
+ if (!isChangeLocInStockLocSts(sourceLoc.getLocSts())) {
+ return "褰撳墠搴撲綅鐘舵�佷笉鍏佽绉诲簱";
+ }
+ return null;
+ }
+
+ private List<Integer> resolveChangeLocRows(List<Integer> requestRows, CrnDepthRuleProfile profile) {
+ if (!Cools.isEmpty(requestRows)) {
+ return requestRows.stream()
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(Collectors.toList());
+ }
+ return profile == null ? Collections.emptyList() : profile.getSearchRows();
+ }
+
+ private LocMast selectChangeLocTarget(LocMast sourceLoc, CrnDepthRuleProfile profile, List<Integer> candidateRows) {
+ List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
+ .eq("crn_no", sourceLoc.getCrnNo())
+ .eq("loc_type1",2)
+ .eq("loc_sts", "O")
+ .orderBy("row1", true)
+ .orderBy("lev1", true)
+ .orderBy("bay1", true));
+ if (Cools.isEmpty(locMasts)) {
+ return null;
+ }
+// for (LocMast locMast : locMasts) {
+// if (!isChangeLocRowAllowed(locMast, candidateRows)) {
+// continue;
+// }
+// if (locMast.getRow1() != null && Utils.isDeepLoc(slaveProperties, locMast.getRow1())) {
+// return locMast;
+// }
+// }
+// for (LocMast locMast : locMasts) {
+// if (!isChangeLocRowAllowed(locMast, candidateRows)) {
+// continue;
+// }
+// if (locMast.getRow1() == null || !Utils.isShallowLoc(slaveProperties, locMast.getRow1())) {
+// continue;
+// }
+// String deepLocNo = Utils.getDeepLoc(slaveProperties, locMast.getLocNo());
+// LocMast deepLoc = locMastService.selectById(deepLocNo);
+// if (deepLoc != null && ("F".equals(deepLoc.getLocSts()) || "D".equals(deepLoc.getLocSts()))) {
+// return locMast;
+// }
+// }
+ LocMast shallowFallback = null;
+ for (LocMast locMast : locMasts) {
+ //鎺掕繃婊�
+ if (!isChangeLocRowAllowed(locMast, candidateRows)) {
+ continue;
+ }
+ //娣变綅浼樺厛
+ if (isChangeLocDeepCandidate(locMast, profile)) {
+ return locMast;
+ }
+ //娴呬綅鍏滃簳
+ if (shallowFallback == null && isChangeLocShallowFallbackCandidate(locMast, profile)) {
+ shallowFallback = locMast;
+ }
+ }
+ return shallowFallback;
+ }
+
+ private boolean isChangeLocRowAllowed(LocMast locMast, List<Integer> candidateRows) {
+ if (Cools.isEmpty(candidateRows)) {
+ return true;
+ }
+ return locMast.getRow1() != null && candidateRows.contains(locMast.getRow1());
+ }
+
+ private boolean isChangeLocDeepCandidate(LocMast locMast, CrnDepthRuleProfile profile) {
+ return locMast.getRow1() != null
+ && profile != null
+ && profile.isDeepRow(locMast.getRow1());
+ }
+
+ private boolean isChangeLocShallowFallbackCandidate(LocMast locMast, CrnDepthRuleProfile profile) {
+ if (locMast.getRow1() == null || profile == null || !profile.isShallowRow(locMast.getRow1())) {
+ return false;
+ }
+ Integer deepRow = profile.getPairedDeepRow(locMast.getRow1());
+ if (deepRow == null) {
+ return false;
+ }
+ LocMast deepLoc = locMastService.selectOne(new EntityWrapper<LocMast>()
+ .eq("crn_no", locMast.getCrnNo())
+ .eq("row1", deepRow)
+ .eq("bay1", locMast.getBay1())
+ .eq("lev1", locMast.getLev1()));
+ return deepLoc != null && isChangeLocInStockLocSts(deepLoc.getLocSts());
+ }
+
+ private boolean isChangeLocInStockLocSts(String locSts) {
+ return "F".equals(locSts) || "D".equals(locSts);
+ }
+
+ private void createChangeLocTask(Integer workNo, LocMast sourceLoc, LocMast targetLoc, Date now) {
+ List<LocDetl> sourceDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", sourceLoc.getLocNo()));
+ WrkMast wrkMast = new WrkMast();
+ wrkMast.setWrkNo(workNo);
+ wrkMast.setIoTime(now);
+ wrkMast.setWrkSts(11L);
+ wrkMast.setIoType(CHANGE_LOC_IO_TYPE);
+ wrkMast.setIoPri(10D);
+ wrkMast.setCrnNo(sourceLoc.getCrnNo());
+ wrkMast.setSourceLocNo(sourceLoc.getLocNo());
+ wrkMast.setLocNo(targetLoc.getLocNo());
+ wrkMast.setFullPlt(Cools.isEmpty(sourceDetls) ? "N" : "Y");
+ wrkMast.setPicking("N");
+ wrkMast.setExitMk("N");
+ wrkMast.setEmptyMk("D".equals(sourceLoc.getLocSts()) ? "Y" : "N");
+ wrkMast.setBarcode(sourceLoc.getBarcode());
+ wrkMast.setLinkMis("N");
+ wrkMast.setMemo("CHANGE_LOC");
+ wrkMast.setAppeUser(WCS_SYNC_USER);
+ wrkMast.setAppeTime(now);
+ wrkMast.setModiUser(WCS_SYNC_USER);
+ wrkMast.setModiTime(now);
+ if (!wrkMastService.insert(wrkMast)) {
+ throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐�");
+ }
+ if (Cools.isEmpty(sourceDetls)) {
+ return;
+ }
+ for (LocDetl sourceDetl : sourceDetls) {
+ WrkDetl wrkDetl = new WrkDetl();
+ wrkDetl.sync(sourceDetl);
+ wrkDetl.setWrkNo(workNo);
+ wrkDetl.setIoTime(now);
+ wrkDetl.setAnfme(sourceDetl.getAnfme());
+ wrkDetl.setAppeTime(now);
+ wrkDetl.setAppeUser(WCS_SYNC_USER);
+ wrkDetl.setModiTime(now);
+ wrkDetl.setModiUser(WCS_SYNC_USER);
+ if (!wrkDetlService.insert(wrkDetl)) {
+ throw new CoolException("淇濆瓨宸ヤ綔妗f槑缁嗗け璐�");
+ }
+ }
+ }
+
+ private void reserveChangeLocTargetLoc(LocMast targetLoc, LocMast sourceLoc, Date now) {
+ targetLoc.setLocSts("S");
+ targetLoc.setBarcode(sourceLoc.getBarcode());
+ targetLoc.setScWeight(sourceLoc.getScWeight() == null ? BigDecimal.ZERO : sourceLoc.getScWeight());
+ targetLoc.setModiUser(WCS_SYNC_USER);
+ targetLoc.setModiTime(now);
+ if (!locMastService.updateById(targetLoc)) {
+ throw new CoolException("鏇存柊鐩爣搴撲綅鐘舵�佸け璐�");
+ }
+ }
+
+ private void reserveChangeLocSourceLoc(LocMast sourceLoc, Date now) {
+ sourceLoc.setLocSts("R");
+ sourceLoc.setModiUser(WCS_SYNC_USER);
+ sourceLoc.setModiTime(now);
+ if (!locMastService.updateById(sourceLoc)) {
+ throw new CoolException("鏇存柊婧愬簱浣嶇姸鎬佸け璐�");
+ }
}
private boolean requiresOutboundErpConfirm(WrkMast wrkMast) {
@@ -886,6 +1144,9 @@
if ("Y".equalsIgnoreCase(wrkMast.getPauseMk())) {
return "task paused";
}
+ if (Objects.equals(wrkMast.getIoType(), 101) && Cools.isEmpty(wrkMast.getBatchSeq())) {
+ return "鍑哄簱杩涗粨缂栧彿(batchSeq)涓虹┖锛岃烦杩囦笅鍙�";
+ }
if (requiresOutboundErpConfirm(wrkMast) && !"Y".equalsIgnoreCase(wrkMast.getPdcType())) {
return "task not confirmed by erp";
}
@@ -915,115 +1176,102 @@
return null;
}
- private Integer resolveReassignArea(WrkMast wrkMast, LocMast currentLoc) {
- List<Integer> stationAreas = Utils.getStationStorageAreas(wrkMast.getSourceStaNo());
- if (!Cools.isEmpty(stationAreas)) {
- for (Integer area : stationAreas) {
- if (belongsToArea(area, wrkMast.getCrnNo(), currentLoc)) {
- return area;
- }
- }
+ private List<ReassignCrnPool> buildReassignCrnPoolOrder(BasDevp sourceStation, Integer currentCrnNo) {
+ List<Integer> firstPoolCrnNos = Utils.distinctCrnNos(sourceStation.getInFirstCrnCsv());
+ List<Integer> secondPoolCrnNos = excludeReassignPoolCrnNos(
+ Utils.distinctCrnNos(sourceStation.getInSecondCrnCsv()), firstPoolCrnNos);
+ if (Cools.isEmpty(firstPoolCrnNos) && Cools.isEmpty(secondPoolCrnNos)) {
+ throw new CoolException("婧愮珯鏈厤缃叆搴撲紭鍏堟睜");
}
- Integer fallbackArea = findAreaByCurrentTask(wrkMast.getCrnNo(), currentLoc);
- if (fallbackArea != null) {
- return fallbackArea;
+ boolean inFirstPool = firstPoolCrnNos.contains(currentCrnNo);
+ boolean inSecondPool = secondPoolCrnNos.contains(currentCrnNo);
+ if (!inFirstPool && !inSecondPool) {
+ throw new CoolException("褰撳墠浠诲姟鍫嗗灈鏈烘湭閰嶇疆鍦ㄦ簮绔欏叆搴撲紭鍏堟睜");
}
- return Utils.getStationStorageArea(wrkMast.getSourceStaNo());
+ List<ReassignCrnPool> poolOrder = new ArrayList<>();
+ if (inFirstPool) {
+ poolOrder.add(new ReassignCrnPool(firstPoolCrnNos));
+ poolOrder.add(new ReassignCrnPool(secondPoolCrnNos));
+ return poolOrder;
+ }
+ poolOrder.add(new ReassignCrnPool(secondPoolCrnNos));
+ poolOrder.add(new ReassignCrnPool(firstPoolCrnNos));
+ return poolOrder;
}
- private Integer findAreaByCurrentTask(Integer currentCrnNo, LocMast currentLoc) {
- for (int area = 1; area <= 3; area++) {
- if (belongsToArea(area, currentCrnNo, currentLoc)) {
- return area;
+ private List<Integer> excludeReassignPoolCrnNos(List<Integer> crnNos, List<Integer> excludedCrnNos) {
+ List<Integer> result = new ArrayList<>();
+ if (Cools.isEmpty(crnNos)) {
+ return result;
+ }
+ LinkedHashSet<Integer> excluded = new LinkedHashSet<>(Utils.distinctCrnNos(excludedCrnNos));
+ for (Integer crnNo : Utils.distinctCrnNos(crnNos)) {
+ if (crnNo == null || excluded.contains(crnNo)) {
+ continue;
}
+ result.add(crnNo);
+ }
+ return result;
+ }
+
+ private List<Integer> buildReassignCandidateCrnNos(List<Integer> poolCrnNos, Integer currentCrnNo) {
+ return buildReassignCrnSearchOrder(poolCrnNos, currentCrnNo);
+ }
+
+ private List<Integer> buildReassignCrnSearchOrder(List<Integer> poolCrnNos, Integer currentCrnNo) {
+ List<Integer> orderedCrnNos = Utils.distinctCrnNos(poolCrnNos);
+ Collections.sort(orderedCrnNos);
+ if (Cools.isEmpty(orderedCrnNos) || currentCrnNo == null) {
+ return orderedCrnNos;
+ }
+ List<Integer> searchOrder = new ArrayList<>();
+ for (int index = orderedCrnNos.size() - 1; index >= 0; index--) {
+ Integer crnNo = orderedCrnNos.get(index);
+ if (crnNo == null || crnNo >= currentCrnNo) {
+ continue;
+ }
+ searchOrder.add(crnNo);
+ }
+ for (int index = orderedCrnNos.size() - 1; index >= 0; index--) {
+ Integer crnNo = orderedCrnNos.get(index);
+ if (crnNo == null || crnNo <= 0 || crnNo.equals(currentCrnNo) || crnNo < currentCrnNo) {
+ continue;
+ }
+ searchOrder.add(crnNo);
+ }
+ return searchOrder;
+ }
+
+ private Integer resolveReassignTargetLevel(boolean emptyPallet) {
+ if (emptyPallet) {
+ return EMPTY_PALLET_REASSIGN_TARGET_LEVEL;
}
return null;
}
- private List<Integer> buildReassignAreaOrder(WrkMast wrkMast, LocMast currentLoc) {
- LinkedHashSet<Integer> areaOrder = new LinkedHashSet<>();
- List<Integer> stationAreas = Utils.getStationStorageAreas(wrkMast.getSourceStaNo());
- if (!Cools.isEmpty(stationAreas)) {
- areaOrder.addAll(stationAreas);
+ private boolean isReassignEmptyPallet(WrkMast wrkMast) {
+ if (wrkMast == null || wrkMast.getWrkNo() == null) {
+ return false;
}
- Integer currentArea = findAreaByCurrentTask(wrkMast.getCrnNo(), currentLoc);
- if (currentArea != null) {
- areaOrder.add(currentArea);
+ List<WrkDetl> wrkDetls = wrkDetlService.selectByWrkNo(wrkMast.getWrkNo());
+ if (Cools.isEmpty(wrkDetls)) {
+ return false;
}
- if (areaOrder.isEmpty()) {
- Integer resolvedArea = resolveReassignArea(wrkMast, currentLoc);
- if (resolvedArea != null) {
- areaOrder.add(resolvedArea);
+ for (WrkDetl wrkDetl : wrkDetls) {
+ if (wrkDetl != null && EMPTY_PALLET_MATNR.equalsIgnoreCase(String.valueOf(wrkDetl.getMatnr()).trim())) {
+ return true;
}
}
- return new ArrayList<>(areaOrder);
+ return false;
}
- private boolean belongsToArea(Integer area, Integer currentCrnNo, LocMast currentLoc) {
- if (area == null || area <= 0) {
- return false;
- }
- RowLastno areaRowLastno = rowLastnoService.selectById(area);
- if (areaRowLastno == null) {
- return false;
- }
- Integer startCrnNo = resolveAreaStartCrnNo(areaRowLastno);
- Integer endCrnNo = resolveAreaEndCrnNo(areaRowLastno, startCrnNo);
- if (currentCrnNo != null && currentCrnNo >= startCrnNo && currentCrnNo <= endCrnNo) {
- return true;
- }
- Integer row = currentLoc == null ? null : currentLoc.getRow1();
- Integer startRow = areaRowLastno.getsRow();
- Integer endRow = areaRowLastno.geteRow();
- return row != null && startRow != null && endRow != null && row >= startRow && row <= endRow;
- }
-
- private List<Integer> buildReassignCandidateCrnNos(Integer area, Integer currentCrnNo) {
- RowLastno areaRowLastno = rowLastnoService.selectById(area);
- if (areaRowLastno == null) {
- throw new CoolException("鏈壘鍒板簱鍖鸿疆璇㈣鍒�");
- }
- int startCrnNo = resolveAreaStartCrnNo(areaRowLastno);
- int endCrnNo = resolveAreaEndCrnNo(areaRowLastno, startCrnNo);
- if (currentCrnNo == null || currentCrnNo < startCrnNo || currentCrnNo > endCrnNo) {
- throw new CoolException("褰撳墠浠诲姟鍫嗗灈鏈轰笉鍦ㄦ墍灞炲簱鍖鸿寖鍥村唴");
- }
- List<Integer> candidateCrnNos = new ArrayList<>();
- for (int crnNo = currentCrnNo - 1; crnNo >= startCrnNo; crnNo--) {
- addUnlockedReassignCandidate(candidateCrnNos, area, crnNo);
- }
- for (int crnNo = endCrnNo; crnNo > currentCrnNo; crnNo--) {
- addUnlockedReassignCandidate(candidateCrnNos, area, crnNo);
- }
- return candidateCrnNos;
- }
-
- private void addUnlockedReassignCandidate(List<Integer> candidateCrnNos, Integer area, int crnNo) {
- if (isReassignCrnLocked(area, crnNo)) {
- log.info("skip locked reassign crane. area={}, crnNo={}, ttl={}s",
- area, crnNo, redisUtil.getExpire(buildReassignCrnLockKey(area, crnNo)));
- return;
- }
- candidateCrnNos.add(crnNo);
- }
-
- private int resolveAreaStartCrnNo(RowLastno areaRowLastno) {
- if (areaRowLastno.getsCrnNo() != null && areaRowLastno.getsCrnNo() > 0) {
- return areaRowLastno.getsCrnNo();
- }
- return 1;
- }
-
- private int resolveAreaEndCrnNo(RowLastno areaRowLastno, int startCrnNo) {
- if (areaRowLastno.geteCrnNo() != null && areaRowLastno.geteCrnNo() >= startCrnNo) {
- return areaRowLastno.geteCrnNo();
- }
- int crnQty = areaRowLastno.getCrnQty() == null || areaRowLastno.getCrnQty() <= 0 ? 1 : areaRowLastno.getCrnQty();
- return startCrnNo + crnQty - 1;
- }
-
- private LocTypeDto buildReassignLocTypeDto(LocMast currentLoc) {
+ private LocTypeDto buildReassignLocTypeDto(LocMast currentLoc, boolean emptyPallet) {
LocTypeDto locTypeDto = new LocTypeDto();
+ if (emptyPallet) {
+ locTypeDto.setLocType1(EMPTY_PALLET_REASSIGN_LOC_TYPE1);
+ locTypeDto.setLocType2(EMPTY_PALLET_REASSIGN_LOC_TYPE2);
+ return locTypeDto;
+ }
if (currentLoc == null) {
return locTypeDto;
}
@@ -1089,43 +1337,6 @@
if (!locMastService.updateById(currentLoc)) {
throw new CoolException("閲婃斁鍘熺洰鏍囧簱浣嶅け璐�");
}
- }
-
- private boolean isReassignCrnLocked(Integer area, Integer crnNo) {
- if (area == null || crnNo == null) {
- return false;
- }
- return redisUtil.hasKey(buildReassignCrnLockKey(area, crnNo));
- }
-
- private String buildReassignCrnLockKey(Integer area, Integer crnNo) {
- return REASSIGN_CRN_LOCK_KEY_PREFIX + area + ":" + crnNo;
- }
-
- private void lockReassignedCrnAfterCommit(Integer area, Integer crnNo, Integer wrkNo) {
- if (area == null || crnNo == null) {
- return;
- }
- Runnable action = () -> {
- String key = buildReassignCrnLockKey(area, crnNo);
- boolean locked = redisUtil.set(key, String.valueOf(wrkNo), REASSIGN_CRN_LOCK_SECONDS);
- if (!locked) {
- log.warn("failed to lock reassigned crane in redis. area={}, crnNo={}, wrkNo={}", area, crnNo, wrkNo);
- return;
- }
- log.info("locked reassigned crane in redis. area={}, crnNo={}, wrkNo={}, ttl={}s",
- area, crnNo, wrkNo, REASSIGN_CRN_LOCK_SECONDS);
- };
- if (TransactionSynchronizationManager.isActualTransactionActive()) {
- TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
- @Override
- public void afterCommit() {
- action.run();
- }
- });
- return;
- }
- action.run();
}
/**
--
Gitblit v1.9.1