|
|
@ -831,49 +831,6 @@ public class HaiAnPdaAutoWarehouseServiceImpl implements HaiAnPdaAutoWarehouseSe |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @author rqrq |
|
|
|
|
|
* @Description 托盘运输自动分配目标站点:优先IDLE站点,无则报错阻断 - rqrq |
|
|
|
|
|
*/ |
|
|
|
|
|
private String resolveTargetStationForChangeTask(String site, String targetArea, String targetStation, String startStation) { |
|
|
|
|
|
// 下发前验证立库目标必须明确为端口;禁止目标仅为A01时自动选到货架或其它立库点位 - rqrq |
|
|
|
|
|
validateWarehousePortTarget(targetArea, targetStation); |
|
|
|
|
|
if (StringUtils.hasText(targetStation)) { |
|
|
|
|
|
return targetStation.trim(); |
|
|
|
|
|
} |
|
|
|
|
|
HaiAnPdaRequest stationQuery = new HaiAnPdaRequest(); |
|
|
|
|
|
stationQuery.setSite(site); |
|
|
|
|
|
stationQuery.setAreaId(targetArea); |
|
|
|
|
|
HaiAnStationsByAreaResult stationResult = getStationsByArea(stationQuery); |
|
|
|
|
|
List<HaiAnStationRow> stationRows = stationResult == null ? null : stationResult.getRows(); |
|
|
|
|
|
if (stationRows == null || stationRows.isEmpty()) { |
|
|
|
|
|
throw new RuntimeException("选择区域没有空闲站点,请稍后重试"); |
|
|
|
|
|
} |
|
|
|
|
|
String firstIdleStationCode = null; |
|
|
|
|
|
for (HaiAnStationRow stationRow : stationRows) { |
|
|
|
|
|
String stationCode = resolveStationCode(stationRow); |
|
|
|
|
|
if (!StringUtils.hasText(stationCode)) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
if ("IDLE".equalsIgnoreCase(stationRow.getStatus())) { |
|
|
|
|
|
if (firstIdleStationCode == null) { |
|
|
|
|
|
firstIdleStationCode = stationCode; |
|
|
|
|
|
} |
|
|
|
|
|
if (!StringUtils.hasText(startStation) || !stationCode.equals(startStation.trim())) { |
|
|
|
|
|
// 自动分配结果也校验区域与端口配对,防止旧WCS区域清单把端口分配到非立库区域 - rqrq |
|
|
|
|
|
validateWarehousePortTarget(targetArea, stationCode); |
|
|
|
|
|
return stationCode; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (StringUtils.hasText(firstIdleStationCode)) { |
|
|
|
|
|
// 同站点兜底分配仍需通过端口归属校验,异常配置不得直接下发运输任务 - rqrq |
|
|
|
|
|
validateWarehousePortTarget(targetArea, firstIdleStationCode); |
|
|
|
|
|
return firstIdleStationCode; |
|
|
|
|
|
} |
|
|
|
|
|
throw new RuntimeException("选择区域没有空闲站点,请稍后重试"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @author rqrq |
|
|
* @author rqrq |
|
|
* @Description 根据业务区域编码定位海安区域配置:先按area_id匹配,未命中再按area_desc匹配,确保固定文案与下拉编码都可解析 - rqrq |
|
|
* @Description 根据业务区域编码定位海安区域配置:先按area_id匹配,未命中再按area_desc匹配,确保固定文案与下拉编码都可解析 - rqrq |
|
|
@ -963,7 +920,7 @@ public class HaiAnPdaAutoWarehouseServiceImpl implements HaiAnPdaAutoWarehouseSe |
|
|
* @author rqrq |
|
|
* @author rqrq |
|
|
* @Description 海安Call任务统一编排:先锁栈板calling_flag,再写WOT任务,最后调用WCS,确保时序与老链路一致 - rqrq |
|
|
* @Description 海安Call任务统一编排:先锁栈板calling_flag,再写WOT任务,最后调用WCS,确保时序与老链路一致 - rqrq |
|
|
*/ |
|
|
*/ |
|
|
private HaiAnWcsActionResult submitCallOutTaskAndInvokeWcs(HaiAnPdaRequest request, String sourceType, String operationDesc, boolean autoAllocateStationWhenBlank) { |
|
|
|
|
|
|
|
|
private HaiAnWcsActionResult submitCallOutTaskAndInvokeWcs(HaiAnPdaRequest request, String sourceType, String operationDesc) { |
|
|
String site = requireSite(request); |
|
|
String site = requireSite(request); |
|
|
guardSite54(site); |
|
|
guardSite54(site); |
|
|
String palletId = normalizePalletId(request.getPalletId()); |
|
|
String palletId = normalizePalletId(request.getPalletId()); |
|
|
@ -977,19 +934,21 @@ public class HaiAnPdaAutoWarehouseServiceImpl implements HaiAnPdaAutoWarehouseSe |
|
|
String wcsTargetAreaCode = requireWcsAreaCode(areaInfo, operationDesc); |
|
|
String wcsTargetAreaCode = requireWcsAreaCode(areaInfo, operationDesc); |
|
|
String targetStation = StringUtils.hasText(request.getTargetStation()) ? request.getTargetStation().trim() : ""; |
|
|
String targetStation = StringUtils.hasText(request.getTargetStation()) ? request.getTargetStation().trim() : ""; |
|
|
|
|
|
|
|
|
// 立库取货不能叫到边库暂存区,也不能指定站点;站点留空后按目标区域空闲点自动分配 - rqrq |
|
|
|
|
|
if (HaiAnTaskSourceStaticData.STOCK_PICK.equals(sourceType)) { |
|
|
|
|
|
|
|
|
// 立库取货是自动分配:后台不挑空闲点,站点固定空字符串交给WCS。指定了站点直接拒绝。- rqrq |
|
|
|
|
|
boolean stockPick = HaiAnTaskSourceStaticData.STOCK_PICK.equals(sourceType); |
|
|
|
|
|
if (stockPick) { |
|
|
if (HaiAnAreaStaticData.SIDE_BUFFER_AREA.equalsIgnoreCase(businessAreaId)) { |
|
|
if (HaiAnAreaStaticData.SIDE_BUFFER_AREA.equalsIgnoreCase(businessAreaId)) { |
|
|
throw new RuntimeException("立库取货不能选择边库暂存区"); |
|
|
throw new RuntimeException("立库取货不能选择边库暂存区"); |
|
|
} |
|
|
} |
|
|
if (StringUtils.hasText(targetStation)) { |
|
|
if (StringUtils.hasText(targetStation)) { |
|
|
throw new RuntimeException("立库取货只能自动分配站点,不能指定具体位置"); |
|
|
throw new RuntimeException("立库取货只能自动分配站点,不能指定具体位置"); |
|
|
} |
|
|
} |
|
|
|
|
|
targetStation = ""; |
|
|
|
|
|
} else { |
|
|
|
|
|
// Call料、合托仍带固定端口。立库区域必须同时有具体端口,避免空站点被当成自动分配。- rqrq |
|
|
|
|
|
validateWarehousePortTarget(businessAreaId, targetStation); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 固定端口出库必须同时传立库区域与具体端口,避免区域合并后WCS随机选择立库点位 - rqrq |
|
|
|
|
|
validateWarehousePortTarget(businessAreaId, targetStation); |
|
|
|
|
|
|
|
|
|
|
|
// 先读取托盘当前状态,确保“不在调用中+在立库内”才允许下达,避免并发重复下发 - rqrq |
|
|
// 先读取托盘当前状态,确保“不在调用中+在立库内”才允许下达,避免并发重复下发 - rqrq |
|
|
HaiAnPalletInfoResult palletInfo = haiAnPdaAutoWarehouseMapper.getPalletInfoWithTypeDetails(site, palletId); |
|
|
HaiAnPalletInfoResult palletInfo = haiAnPdaAutoWarehouseMapper.getPalletInfoWithTypeDetails(site, palletId); |
|
|
if (palletInfo == null) { |
|
|
if (palletInfo == null) { |
|
|
@ -1003,11 +962,6 @@ public class HaiAnPdaAutoWarehouseServiceImpl implements HaiAnPdaAutoWarehouseSe |
|
|
throw new RuntimeException("该托盘不在立库"); |
|
|
throw new RuntimeException("该托盘不在立库"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 仅在“立库取货”场景下,目标站点为空时按目标区域自动分配首个空闲站点 - rqrq |
|
|
|
|
|
if (autoAllocateStationWhenBlank && !StringUtils.hasText(targetStation)) { |
|
|
|
|
|
targetStation = resolveTargetStationForChangeTask(site, businessAreaId, null, null); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
String operator = resolveOperator(); |
|
|
String operator = resolveOperator(); |
|
|
Date now = new Date(); |
|
|
Date now = new Date(); |
|
|
TransNoControl transNoControl = transNoControlService.getTransNo(site, "WOT", 10); |
|
|
TransNoControl transNoControl = transNoControlService.getTransNo(site, "WOT", 10); |
|
|
@ -1092,7 +1046,8 @@ public class HaiAnPdaAutoWarehouseServiceImpl implements HaiAnPdaAutoWarehouseSe |
|
|
callRequest.setPalletId(palletId); |
|
|
callRequest.setPalletId(palletId); |
|
|
// 下发WCS时targetArea必须传wcs_area_code,不能直传业务area_id - rqrq |
|
|
// 下发WCS时targetArea必须传wcs_area_code,不能直传业务area_id - rqrq |
|
|
callRequest.setTargetArea(wcsTargetAreaCode); |
|
|
callRequest.setTargetArea(wcsTargetAreaCode); |
|
|
callRequest.setTargetPosition(targetStation); |
|
|
|
|
|
|
|
|
// 立库取货 targetPosition 固定空字符串,不能传 null,也不能再填 WMS 算出的站点。- rqrq |
|
|
|
|
|
callRequest.setTargetPosition(stockPick ? "" : targetStation); |
|
|
// 调用指定栈板出库接口:入参taskNo+palletId+wcs_area_code;HTTP 短路由接口层处理,失败回滚 WOT 与 calling_flag - rqrq |
|
|
// 调用指定栈板出库接口:入参taskNo+palletId+wcs_area_code;HTTP 短路由接口层处理,失败回滚 WOT 与 calling_flag - rqrq |
|
|
haiAnWcsApiService.callPalletOutWcs(callRequest); |
|
|
haiAnWcsApiService.callPalletOutWcs(callRequest); |
|
|
return buildActionResult(Boolean.FALSE, operationDesc + "下达成功,任务号:" + taskNo); |
|
|
return buildActionResult(Boolean.FALSE, operationDesc + "下达成功,任务号:" + taskNo); |
|
|
@ -3098,13 +3053,13 @@ public class HaiAnPdaAutoWarehouseServiceImpl implements HaiAnPdaAutoWarehouseSe |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @author rqrq |
|
|
* @author rqrq |
|
|
* @Description 海安立库取货下达:先锁托盘calling_flag,再写WOT,最后调WCS。拒绝边库暂存区A11,站点必须留空由后端自动分配。 - rqrq |
|
|
|
|
|
|
|
|
* @Description 海安立库取货下达:先锁托盘calling_flag,再写WOT,最后调WCS。拒绝边库暂存区A11。自动分配不计算站点,direct-material-call 的 targetPosition 固定空字符串。 - rqrq |
|
|
*/ |
|
|
*/ |
|
|
@Override |
|
|
@Override |
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
public HaiAnWcsActionResult callOutToStation(HaiAnPdaRequest request) { |
|
|
public HaiAnWcsActionResult callOutToStation(HaiAnPdaRequest request) { |
|
|
// 海安“立库取货”保持老链路时序:calling_flag -> WOT -> 调接口,且WOT来源类型固定“立库取货” - rqrq |
|
|
// 海安“立库取货”保持老链路时序:calling_flag -> WOT -> 调接口,且WOT来源类型固定“立库取货” - rqrq |
|
|
return submitCallOutTaskAndInvokeWcs(request, HaiAnTaskSourceStaticData.STOCK_PICK, HaiAnTaskSourceStaticData.STOCK_PICK, true); |
|
|
|
|
|
|
|
|
return submitCallOutTaskAndInvokeWcs(request, HaiAnTaskSourceStaticData.STOCK_PICK, HaiAnTaskSourceStaticData.STOCK_PICK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
@ -3129,7 +3084,7 @@ public class HaiAnPdaAutoWarehouseServiceImpl implements HaiAnPdaAutoWarehouseSe |
|
|
callRequest.setTargetArea(HaiAnAreaStaticData.STOCK_AREA); |
|
|
callRequest.setTargetArea(HaiAnAreaStaticData.STOCK_AREA); |
|
|
callRequest.setTargetStation(HaiAnStationStaticData.DIRECT_OUTBOUND_PORT); |
|
|
callRequest.setTargetStation(HaiAnStationStaticData.DIRECT_OUTBOUND_PORT); |
|
|
// 固定出库口属于“Call料”场景,WOT来源类型明确写Call料,避免与“立库取货”混淆 - rqrq |
|
|
// 固定出库口属于“Call料”场景,WOT来源类型明确写Call料,避免与“立库取货”混淆 - rqrq |
|
|
return submitCallOutTaskAndInvokeWcs(callRequest, HaiAnTaskSourceStaticData.CALL_MATERIAL, HaiAnTaskSourceStaticData.CALL_MATERIAL, false); |
|
|
|
|
|
|
|
|
return submitCallOutTaskAndInvokeWcs(callRequest, HaiAnTaskSourceStaticData.CALL_MATERIAL, HaiAnTaskSourceStaticData.CALL_MATERIAL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
@ -3653,7 +3608,7 @@ public class HaiAnPdaAutoWarehouseServiceImpl implements HaiAnPdaAutoWarehouseSe |
|
|
callRequest.setTargetArea(HaiAnAreaStaticData.STOCK_AREA); |
|
|
callRequest.setTargetArea(HaiAnAreaStaticData.STOCK_AREA); |
|
|
callRequest.setTargetStation(HaiAnStationStaticData.DIRECT_OUTBOUND_PORT); |
|
|
callRequest.setTargetStation(HaiAnStationStaticData.DIRECT_OUTBOUND_PORT); |
|
|
// 合托与 Call料同一出口:整托出库口;禁止打到入库口或普通出库口 - rqrq |
|
|
// 合托与 Call料同一出口:整托出库口;禁止打到入库口或普通出库口 - rqrq |
|
|
HaiAnWcsActionResult actionResult = submitCallOutTaskAndInvokeWcs(callRequest, HaiAnTaskSourceStaticData.MANUAL_MERGE_OUT, "合托Call板", false); |
|
|
|
|
|
|
|
|
HaiAnWcsActionResult actionResult = submitCallOutTaskAndInvokeWcs(callRequest, HaiAnTaskSourceStaticData.MANUAL_MERGE_OUT, "合托Call板"); |
|
|
boolean mockMode = actionResult != null && Boolean.TRUE.equals(actionResult.getMockMode()); |
|
|
boolean mockMode = actionResult != null && Boolean.TRUE.equals(actionResult.getMockMode()); |
|
|
String message = actionResult == null ? "合托Call板下达成功" : actionResult.getMessage(); |
|
|
String message = actionResult == null ? "合托Call板下达成功" : actionResult.getMessage(); |
|
|
return buildSingleCallResult(palletId, true, "", mockMode, message); |
|
|
return buildSingleCallResult(palletId, true, "", mockMode, message); |
|
|
|