From 67f80d59a9e28ba1af271bef7a81a3e180b951a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B8=B8=E7=86=9F=E5=90=B4=E5=BD=A6=E7=A5=96?= Date: Mon, 3 Nov 2025 23:33:46 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=80=E5=94=AE=E5=8F=91=E8=B4=A7=E5=8D=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81wcs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ShipmentIssueController.java | 61 +++ .../customer/dao/ShipmentIssueMapper.java | 27 + .../entity/ShipmentInventoryCheckResult.java | 57 +++ .../service/ShipmentIssueService.java | 34 ++ .../impl/ShipmentIssueServiceImpl.java | 478 ++++++++++++++++++ .../notify/entity/SOIssueNotifyHeader.java | 7 + .../mapper/customer/ShipmentIssueMapper.xml | 37 +- 7 files changed, 695 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/gaotao/modules/customer/entity/ShipmentInventoryCheckResult.java diff --git a/src/main/java/com/gaotao/modules/customer/controller/ShipmentIssueController.java b/src/main/java/com/gaotao/modules/customer/controller/ShipmentIssueController.java index 33efdb2..5e8fdd4 100644 --- a/src/main/java/com/gaotao/modules/customer/controller/ShipmentIssueController.java +++ b/src/main/java/com/gaotao/modules/customer/controller/ShipmentIssueController.java @@ -159,4 +159,65 @@ public class ShipmentIssueController { shipmentIssueService.closeInboundNotification(data); return R.ok(); } + + /** + * @Description 检查用户是否有未下达的shipment申请单 - rqrq + * @Title checkUserHasUnissueShipment + * @param data 查询条件(包含site和username) + * @return R + * @author rqrq + * @date 2025/11/03 + */ + @PostMapping(value="/checkUserHasUnissueShipment") + @ResponseBody + public R checkUserHasUnissueShipment(@RequestBody SOIssueNotifyHeader data) throws Exception { + SOIssueNotifyHeader row = shipmentIssueService.checkUserHasUnissueShipment(data); + return R.ok().put("row", row); + } + + /** + * @Description 取消下达发货申请单 - rqrq + * @Title cancelIssueShipment + * @param data 申请单数据(包含site和notifyNo) + * @return R + * @author rqrq + * @date 2025/11/03 + */ + @PostMapping(value="/cancelIssueShipment") + @ResponseBody + public R cancelIssueShipment(@RequestBody SOIssueNotifyHeader data) throws Exception { + shipmentIssueService.cancelIssueShipment(data); + return R.ok(); + } + + /** + * @Description 检查发货通知单物料库存匹配情况(只考虑立库) - rqrq + * @Title checkShipmentInventory + * @param data 查询条件(包含site和notifyNo) + * @return R + * @author rqrq + * @date 2025/11/03 + */ + @PostMapping(value="/checkShipmentInventory") + @ResponseBody + public R checkShipmentInventory(@RequestBody SOIssueNotifyHeader data) throws Exception { + List rows = + shipmentIssueService.checkShipmentInventory(data); + return R.ok().put("rows", rows); + } + + /** + * @Description 推送发货通知单库存预览数据至WCS - rqrq + * @Title pushShipmentInventoryToWcs + * @param data 包含site、notifyNo和库存预览数据的对象 + * @return R + * @author rqrq + * @date 2025/11/03 + */ + @PostMapping(value="/pushShipmentInventoryToWcs") + @ResponseBody + public R pushShipmentInventoryToWcs(@RequestBody SOIssueNotifyHeader data) throws Exception { + shipmentIssueService.pushShipmentInventoryToWcs(data); + return R.ok(); + } } diff --git a/src/main/java/com/gaotao/modules/customer/dao/ShipmentIssueMapper.java b/src/main/java/com/gaotao/modules/customer/dao/ShipmentIssueMapper.java index b8fd96b..45402ba 100644 --- a/src/main/java/com/gaotao/modules/customer/dao/ShipmentIssueMapper.java +++ b/src/main/java/com/gaotao/modules/customer/dao/ShipmentIssueMapper.java @@ -43,4 +43,31 @@ public interface ShipmentIssueMapper extends BaseMapper { int deleteOrderList(SOIssueNotifyHeader data); IPage searchNotifyHeader(Page page, @Param("data") ShipmentIssueDto data); + + /** + * @Description 检查用户是否有未下达的shipment申请单 - rqrq + * @param data 查询条件(包含site和username) + * @return SOIssueNotifyHeader + * @author rqrq + * @date 2025/11/03 + */ + SOIssueNotifyHeader checkUserHasUnissueShipment(SOIssueNotifyHeader data); + + /** + * @Description 取消下达发货申请单(更新status为UNISSUE) - rqrq + * @param data 申请单数据(包含site和notifyNo) + * @author rqrq + * @date 2025/11/03 + */ + void cancelIssueShipment(SOIssueNotifyHeader data); + + /** + * @Description 检查发货通知单物料库存匹配情况(只考虑立库) - rqrq + * @param site 工厂编码 + * @param notifyNo 申请单号 + * @return List + * @author rqrq + * @date 2025/11/03 + */ + List checkShipmentInventory(@Param("site") String site, @Param("notifyNo") String notifyNo); } diff --git a/src/main/java/com/gaotao/modules/customer/entity/ShipmentInventoryCheckResult.java b/src/main/java/com/gaotao/modules/customer/entity/ShipmentInventoryCheckResult.java new file mode 100644 index 0000000..397e2ef --- /dev/null +++ b/src/main/java/com/gaotao/modules/customer/entity/ShipmentInventoryCheckResult.java @@ -0,0 +1,57 @@ +package com.gaotao.modules.customer.entity; + +import lombok.Data; +import org.apache.ibatis.type.Alias; + +import java.math.BigDecimal; + +/** + * @Description 发货通知单库存检查结果实体类 - rqrq + * @Author rqrq + * @Date 2025/11/03 + */ +@Data +@Alias("ShipmentInventoryCheckResult") +public class ShipmentInventoryCheckResult { + + /** + * 行号 + */ + private Integer rowNo; + + /** + * 生产订单号 + */ + private String productionOrderNo; + + /** + * BOM行号 + */ + private String bomLineNo; + + /** + * 物料编码 + */ + private String partNo; + + /** + * 需求数量 + */ + private BigDecimal requiredQty; + + /** + * 立库是否满足(Y/N) + */ + private String isWarehouseSatisfied; + + /** + * 匹配的条码信息 + */ + private String matchedBarcodes; + + /** + * 订单满足状态:1=完全满足(绿色),3=不满足(红色)- rqrq + */ + private Integer orderSatisfactionStatus; +} + diff --git a/src/main/java/com/gaotao/modules/customer/service/ShipmentIssueService.java b/src/main/java/com/gaotao/modules/customer/service/ShipmentIssueService.java index 866f39a..271bd28 100644 --- a/src/main/java/com/gaotao/modules/customer/service/ShipmentIssueService.java +++ b/src/main/java/com/gaotao/modules/customer/service/ShipmentIssueService.java @@ -44,4 +44,38 @@ public interface ShipmentIssueService { List searchNotifyMaterialList(SOIssueNotifyOrderList data); int closeInboundNotification(SOIssueNotifyHeader data); + + /** + * @Description 检查用户是否有未下达的shipment申请单 - rqrq + * @param data 查询条件(包含site和username) + * @return SOIssueNotifyHeader 如果有未下达申请单则返回,否则返回null + * @author rqrq + * @date 2025/11/03 + */ + SOIssueNotifyHeader checkUserHasUnissueShipment(SOIssueNotifyHeader data); + + /** + * @Description 取消下达发货申请单(更新status为UNISSUE) - rqrq + * @param data 申请单数据(包含site和notifyNo) + * @author rqrq + * @date 2025/11/03 + */ + void cancelIssueShipment(SOIssueNotifyHeader data); + + /** + * @Description 检查发货通知单物料库存匹配情况(只考虑立库) - rqrq + * @param data 查询条件(包含site和notifyNo) + * @return List + * @author rqrq + * @date 2025/11/03 + */ + List checkShipmentInventory(SOIssueNotifyHeader data); + + /** + * @Description 推送发货通知单库存预览数据至WCS - rqrq + * @param data 包含site、notifyNo和库存预览数据的对象 + * @author rqrq + * @date 2025/11/03 + */ + void pushShipmentInventoryToWcs(SOIssueNotifyHeader data); } diff --git a/src/main/java/com/gaotao/modules/customer/service/impl/ShipmentIssueServiceImpl.java b/src/main/java/com/gaotao/modules/customer/service/impl/ShipmentIssueServiceImpl.java index 5019a8d..d058ecb 100644 --- a/src/main/java/com/gaotao/modules/customer/service/impl/ShipmentIssueServiceImpl.java +++ b/src/main/java/com/gaotao/modules/customer/service/impl/ShipmentIssueServiceImpl.java @@ -4,9 +4,15 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.gaotao.common.utils.PageUtils; +import com.gaotao.common.utils.ShiroUtils; +import com.gaotao.modules.api.entity.NotifyDataToWcs; +import com.gaotao.modules.api.entity.NotifyDataToWcsPalletList; +import com.gaotao.modules.api.entity.NotifyDataToWcsPalletSubDetail; import com.gaotao.modules.api.entity.issueAndReturnVo.ShipmentLineVo; import com.gaotao.modules.api.entity.issueAndReturnVo.ShipmentVo; import com.gaotao.modules.api.service.IfsApiIssueAndReturnService; +import com.gaotao.modules.api.service.WcsApiService; +import com.gaotao.modules.automatedWarehouse.entity.PalletDetail; import com.gaotao.modules.base.entity.SOScheduledRoutingData; import com.gaotao.modules.customer.dao.ShipmentIssueMapper; import com.gaotao.modules.customer.entity.dto.ShipmentIssueDto; @@ -18,6 +24,12 @@ import com.gaotao.modules.notify.entity.vo.ShopOrderMaterialVo; import com.gaotao.modules.sys.entity.SysUserEntity; import com.gaotao.modules.trans.entity.TransNoControl; import com.gaotao.modules.trans.service.TransNoControlService; +import com.gaotao.modules.automatedWarehouse.mapper.WcsIntegrationMapper; +import com.gaotao.modules.automatedWarehouse.entity.WmsOrderTask; + +import com.gaotao.modules.notify.mapper.NewIssureMapper; + +import org.apache.commons.lang.StringUtils; import org.apache.shiro.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -37,6 +49,12 @@ public class ShipmentIssueServiceImpl implements ShipmentIssueService { private TransNoControlService transNoService; @Autowired private ShipmentIssueMapper shipmentIssueMapper; + @Autowired + private NewIssureMapper newIssureMapper; // 用于库存相关操作 - rqrq + @Autowired + private WcsIntegrationMapper wcsIntegrationMapper; // 用于WCS集成操作 - rqrq + @Autowired + private WcsApiService wcsApiService; // 用于调用WCS接口 - rqrq @Override public SOIssueNotifyHeader getUserNotifyNo(SOIssueNotifyHeader data) { @@ -69,6 +87,7 @@ public class ShipmentIssueServiceImpl implements ShipmentIssueService { data.setApprovedFlag("N"); data.setProjectId(""); data.setOrderType("shipment"); + data.setPushWcsFlag("未推送"); int insert = shipmentIssueMapper.insert(data); return insert; } @@ -100,6 +119,9 @@ public class ShipmentIssueServiceImpl implements ShipmentIssueService { BigDecimal nextItem=shipmentIssueMapper.getNextItemForShipmentOrderList(data); data.setItemNo(nextItem); data.setOrderType("shipment"); + data.setPushWmsFlag("N"); + data.setProductionArea("Z109"); + data.setOutWorkOrderFlag("N"); int i = shipmentIssueMapper.saveIssueNotifyOrderList(data); return i; } @@ -241,4 +263,460 @@ public class ShipmentIssueServiceImpl implements ShipmentIssueService { int i = shipmentIssueMapper.updateNotifyStatus(data); return i; } + + /** + * @Description 检查用户是否有未下达的shipment申请单 - rqrq + * @param data 查询条件 + * @return SOIssueNotifyHeader + * @author rqrq + */ + @Override + public SOIssueNotifyHeader checkUserHasUnissueShipment(SOIssueNotifyHeader data) { + System.out.println("开始检查用户是否有未下达的shipment申请单 - rqrq,site=" + data.getSite() + ", username=" + data.getUsername()); + + // 调用Mapper查询用户是否有状态为UNISSUE且ordertype=shipment的数据 - rqrq + SOIssueNotifyHeader result = shipmentIssueMapper.checkUserHasUnissueShipment(data); + + if (result != null) { + System.out.println("用户有未下达的shipment申请单 - rqrq,notifyNo=" + result.getNotifyNo()); + } else { + System.out.println("用户没有未下达的shipment申请单 - rqrq"); + } + + return result; + } + + /** + * @Description 取消下达发货申请单(更新status为UNISSUE) - rqrq + * @param data 申请单数据 + * @author rqrq + */ + @Override + @Transactional + public void cancelIssueShipment(SOIssueNotifyHeader data) { + System.out.println("开始取消下达发货申请单 - rqrq,notifyNo=" + data.getNotifyNo() + ", site=" + data.getSite()); + + // 查询申请单信息,检查是否已推送WCS - rqrq + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("site", data.getSite()); + queryWrapper.eq("notify_no", data.getNotifyNo()); + SOIssueNotifyHeader notifyHeader = shipmentIssueMapper.selectOne(queryWrapper); + + if (notifyHeader == null) { + throw new RuntimeException("发货申请单不存在"); + } + + // 判断是否已推送WCS,如果已推送则不允许取消下达 - rqrq + if (!"未推送".equals(notifyHeader.getPushWcsFlag())) { + throw new RuntimeException("发货申请单已推送WCS,不允许取消下达"); + } + + // 更新申请单状态为UNISSUE - rqrq + shipmentIssueMapper.cancelIssueShipment(data); + + System.out.println("取消下达发货申请单完成 - rqrq"); + } + + /** + * @Description 检查发货通知单物料库存匹配情况(只考虑立库) - rqrq + * @param data 查询条件 + * @return List + * @author rqrq + */ + @Override + public List checkShipmentInventory(SOIssueNotifyHeader data) { + System.out.println("开始检查发货通知单物料库存匹配情况 - rqrq,notifyNo=" + data.getNotifyNo() + ", site=" + data.getSite()); + + // 调用存储过程CheckShipmentIssueNotifyInventory(只考虑立库) - rqrq + List list = + shipmentIssueMapper.checkShipmentInventory(data.getSite(), data.getNotifyNo()); + + System.out.println("检查发货通知单物料库存匹配情况完成,共" + list.size() + "条记录 - rqrq"); + return list; + } + + /** + * @Description 推送发货通知单库存预览数据至WCS - rqrq + * @param data 包含site、notifyNo和库存预览数据的对象 + * @author rqrq + */ + @Override + @Transactional + public void pushShipmentInventoryToWcs(SOIssueNotifyHeader data) { + String username = ShiroUtils.getUserEntity().getUsername(); + String site = data.getSite(); + String notifyNo = data.getNotifyNo(); + + System.out.println("开始推送发货通知单库存预览数据至WCS - rqrq,notifyNo=" + notifyNo + ", site=" + site); + + List inventoryList = data.getShipmentInventoryList(); + if (inventoryList == null || inventoryList.isEmpty()) { + throw new RuntimeException("库存预览数据为空,无法推送"); + } + + // 1. 筛选出orderSatisfactionStatus = 1 的数据(只有完全满足的才推送,发货通知单没有黄色状态) - rqrq + List validList = inventoryList.stream() + .filter(item -> item.getOrderSatisfactionStatus() != null && item.getOrderSatisfactionStatus() == 1) + .collect(Collectors.toList()); + + // 2. 获取传入的原始订单总数(按生产订单分组统计)- rqrq + int originalOrderCount = (int) data.getShipmentInventoryList().stream() + .map(com.gaotao.modules.customer.entity.ShipmentInventoryCheckResult::getProductionOrderNo) + .distinct() + .count(); + System.out.println("前端传入的订单总数:" + originalOrderCount + " - rqrq"); + + System.out.println("筛选后满足库存要求的数据:" + validList.size() + "条 - rqrq"); + + if (validList.isEmpty()) { + throw new RuntimeException("没有满足库存要求的订单数据"); + } + + // 3. 提取所有条码(序列号) - rqrq + List allSerialNos = new ArrayList<>(); + for (com.gaotao.modules.customer.entity.ShipmentInventoryCheckResult item : validList) { + String matchedBarcodes = item.getMatchedBarcodes(); + if (StringUtils.isNotBlank(matchedBarcodes)) { + String[] barcodes = matchedBarcodes.split(","); + for (String barcode : barcodes) { + String serialNo = barcode.trim().split("\\(")[0]; + allSerialNos.add(serialNo); + } + } + } + + System.out.println("提取到条码总数:" + allSerialNos.size() + " - rqrq"); + + // 4. 前置校验:检查reserve_flag - rqrq + List reservedUnits = newIssureMapper.checkReserveFlagBySerialNos(site, allSerialNos); + if (!reservedUnits.isEmpty()) { + throw new RuntimeException("已经有物料被其他任务领走,请重新打开推送界面计算库存。"); + } + System.out.println("reserve_flag校验通过 - rqrq"); + + // 5. 前置校验:查询栈板并检查calling_flag - rqrq + List palletIds = newIssureMapper.getPalletIdsBySerialNos(site, allSerialNos); + if (palletIds == null || palletIds.isEmpty()) { + throw new RuntimeException("未找到条码对应的栈板信息"); + } + System.out.println("找到栈板数量:" + palletIds.size() + " - rqrq"); + + List callingPallets = newIssureMapper.checkCallingFlagByPalletIds(site, palletIds); + if (!callingPallets.isEmpty()) { + throw new RuntimeException("已经有栈板被其他任务领走,请重新打开推送界面计算库存。"); + } + System.out.println("calling_flag校验通过 - rqrq"); + + // 6. 按ProductionOrderNo分组 - rqrq + Map> groupedByOrder = validList.stream() + .collect(Collectors.groupingBy(com.gaotao.modules.customer.entity.ShipmentInventoryCheckResult::getProductionOrderNo)); + + int validOrderCount = groupedByOrder.size(); + System.out.println("按生产订单分组,满足条件的订单数:" + validOrderCount + "个 - rqrq"); + + Date currentTime = new Date(); + int successCount = 0; // 统计成功推送的订单数 - rqrq + + // 7. 遍历每个生产订单 - rqrq + for (Map.Entry> entry : groupedByOrder.entrySet()) { + String productionOrderNo = entry.getKey(); + List orderItems = entry.getValue(); + + try { + System.out.println("开始处理订单:" + productionOrderNo + " - rqrq"); + + // 7.1 获取itemNo - rqrq + BigDecimal itemNo = newIssureMapper.getItemNoByNotifyNoAndOrderNo(site, notifyNo, productionOrderNo); + if (itemNo == null) { + throw new RuntimeException("未找到订单" + productionOrderNo + "的itemNo"); + } + System.out.println("订单" + productionOrderNo + "的itemNo=" + itemNo + " - rqrq"); + + // 7.2 生成taskNo - rqrq + TransNoControl transData = transNoService.getTransNo(site, "WOT", 10); + String taskNo = transData.getNewTransNo(); + System.out.println("生成任务编号:" + taskNo + " - rqrq"); + + // 7.3 准备wms_order_task对象(暂不插入数据库)- rqrq + WmsOrderTask orderTask = new WmsOrderTask(); + orderTask.setSite(site); + orderTask.setTaskNo(taskNo); + orderTask.setItemNo(1); + orderTask.setSourceType("发货通知单"); // 发货通知单专用标识 - rqrq + orderTask.setSourceBillNo(notifyNo); + orderTask.setSourceLineId(itemNo.longValue()); + orderTask.setPartNo(""); + orderTask.setQty(BigDecimal.ZERO); + orderTask.setBatchNo(""); + orderTask.setSerialNo(""); + orderTask.setFromLocation("AS"); + orderTask.setToLocation(""); + orderTask.setPalletId(""); + orderTask.setAgvCode(null); + orderTask.setPriority(0); + orderTask.setStatus("未执行"); + orderTask.setWmsSendTime(currentTime); + orderTask.setWcsReceiveTime(null); + orderTask.setStartTime(null); + orderTask.setCompleteTime(null); + orderTask.setErrorCode(null); + orderTask.setErrorMsg(null); + orderTask.setCreatedBy(username); + orderTask.setCreatedTime(currentTime); + orderTask.setUpdatedTime(currentTime); + orderTask.setWcsTaskId(null); + orderTask.setFinishQty(BigDecimal.ZERO); + orderTask.setWmsStatus("已创建"); + System.out.println("准备wms_order_task对象 - rqrq"); + + // 7.4 提取本订单的所有序列号和栈板 - rqrq + List orderSerialNos = new ArrayList<>(); + for (com.gaotao.modules.customer.entity.ShipmentInventoryCheckResult item : orderItems) { + String matchedBarcodes = item.getMatchedBarcodes(); + if (StringUtils.isNotBlank(matchedBarcodes)) { + String[] barcodes = matchedBarcodes.split(","); + for (String barcode : barcodes) { + String serialNo = barcode.trim().split("\\(")[0]; + orderSerialNos.add(serialNo); + } + } + } + + List orderPalletIds = newIssureMapper.getPalletIdsBySerialNos(site, orderSerialNos); + System.out.println("订单" + productionOrderNo + "涉及栈板数量:" + orderPalletIds.size() + " - rqrq"); + + // 7.5 准备wms_order_task_detail对象列表(暂不插入数据库)- rqrq + List taskDetailList = new ArrayList<>(); + int seqNo = 1; + for (String palletId : orderPalletIds) { + com.gaotao.modules.automatedWarehouse.entity.WmsOrderTaskDetail taskDetail = + new com.gaotao.modules.automatedWarehouse.entity.WmsOrderTaskDetail(); + taskDetail.setSite(site); + taskDetail.setTaskNo(taskNo); + taskDetail.setItemNo(1); + taskDetail.setSeqNo(seqNo++); + taskDetail.setActionType("取货栈板"); + taskDetail.setComment(""); + taskDetail.setFromLocation(""); + taskDetail.setToLocation(""); + taskDetail.setAgvCode(""); + taskDetail.setStatus("已创建"); + taskDetail.setStartTime(null); + taskDetail.setCompleteTime(null); + taskDetail.setErrorCode(null); + taskDetail.setErrorMsg(null); + taskDetail.setPalletId(palletId); + taskDetail.setWmsStatus("未执行"); + + taskDetailList.add(taskDetail); + } + System.out.println("准备wms_order_task_detail对象" + orderPalletIds.size() + "条 - rqrq"); + + // 7.6 准备SOIssueNotifyOrderMaterialList_detail对象列表(暂不插入数据库)- rqrq + List detailList = new ArrayList<>(); + + // 构建序列号到栈板ID的映射关系 - rqrq + Map serialNoPalletMap = new HashMap<>(); + for (String serialNo : orderSerialNos) { + List palletIds2 = newIssureMapper.getPalletIdsBySerialNos(site, Arrays.asList(serialNo)); + if (!palletIds2.isEmpty()) { + serialNoPalletMap.put(serialNo, palletIds2.get(0)); + } + } + System.out.println("构建序列号到栈板的映射关系,共" + serialNoPalletMap.size() + "条 - rqrq"); + + // 构建栈板ID到SeqNo的映射关系 - rqrq + Map palletSeqMap = new HashMap<>(); + for (com.gaotao.modules.automatedWarehouse.entity.WmsOrderTaskDetail taskDetail : taskDetailList) { + palletSeqMap.put(taskDetail.getPalletId(), taskDetail.getSeqNo()); + } + System.out.println("构建栈板到SeqNo的映射关系,共" + palletSeqMap.size() + "条 - rqrq"); + + for (com.gaotao.modules.customer.entity.ShipmentInventoryCheckResult item : orderItems) { + String matchedBarcodes = item.getMatchedBarcodes(); + if (StringUtils.isNotBlank(matchedBarcodes)) { + String[] barcodes = matchedBarcodes.split(","); + for (String barcode : barcodes) { + String serialNo = barcode.trim().split("\\(")[0]; + + // 根据序列号得知这个序列号在哪个栈板上,再去taskDetailList去寻找SeqNo - rqrq + String palletId = serialNoPalletMap.get(serialNo); + Integer taskSeq = null; + if (palletId != null) { + taskSeq = palletSeqMap.get(palletId); + } + + // 如果找不到对应的SeqNo,记录警告并跳过 - rqrq + if (taskSeq == null) { + System.err.println("警告:序列号" + serialNo + "找不到对应的栈板SeqNo,跳过 - rqrq"); + taskSeq = 0; + } + + // 查询序列号的location_id,如果不是AS区域则直接标记为已出库 - rqrq + String locationId = newIssureMapper.getSerialNoLocationId(site, serialNo); + String outWcsFlag = "N"; + if (locationId != null && !locationId.equals("AS")) { + outWcsFlag = "Y"; + System.out.println("序列号" + serialNo + "不在AS区域(location_id=" + locationId + "),直接标记为已出库 - rqrq"); + } + + com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail detail = + new com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail(); + detail.setSite(site); + detail.setNotifyNo(notifyNo); + detail.setItemNo(itemNo); + detail.setBomItemNo(item.getBomLineNo()); + detail.setSerialNo(serialNo); + detail.setTaskRef(taskNo); + detail.setTaskItem(1); + detail.setTaskSeq(taskSeq); // 使用栈板对应的SeqNo - rqrq + detail.setOutWcsFlag(outWcsFlag); // 根据location_id判断 - rqrq + detail.setIssureFlag("N"); + detail.setOrderType("shipment"); // 发货通知单专用标识 - rqrq + detailList.add(detail); + } + } + } + System.out.println("准备SOIssueNotifyOrderMaterialList_detail对象" + detailList.size() + "条 - rqrq"); + + // 7.7 构建WCS数据 - rqrq + NotifyDataToWcs wcsData = new NotifyDataToWcs(); + wcsData.setSite(site); + wcsData.setTaskNo(taskNo); + wcsData.setOrderNo(productionOrderNo); + wcsData.setItemNo(orderTask.getItemNo()); + wcsData.setOrderPartNo(""); + + wcsData.setOrderType(3); + + + // 构建栈板列表 - rqrq + List palletList = new ArrayList<>(); + for (String palletId : orderPalletIds) { + // 查询该栈板上本订单相关的序列号的明细信息 - rqrq + List palletDetails = newIssureMapper.getPalletDetailsByPalletAndSerials(site, palletId, orderSerialNos); + + if (palletDetails != null && !palletDetails.isEmpty()) { + // 按position和layer分组 - rqrq + Map>> groupedByPositionLayer = new java.util.HashMap<>(); + for (PalletDetail detail : palletDetails) { + String position = detail.getPosition(); + Integer layer = detail.getLayer(); + String serialNo = detail.getSerialNo(); + + groupedByPositionLayer + .computeIfAbsent(position, k -> new java.util.HashMap<>()) + .computeIfAbsent(layer, k -> new ArrayList<>()) + .add(serialNo); + } + + // 构建NotifyDataToWcsPalletList - rqrq + NotifyDataToWcsPalletList palletData = new NotifyDataToWcsPalletList(); + palletData.setPalletCode(palletId); + + List subDetailList = new ArrayList<>(); + for (Map.Entry>> posEntry : groupedByPositionLayer.entrySet()) { + String position = posEntry.getKey(); + for (Map.Entry> layerEntry : posEntry.getValue().entrySet()) { + Integer layer = layerEntry.getKey(); + List serialNos = layerEntry.getValue(); + + NotifyDataToWcsPalletSubDetail subDetail = new NotifyDataToWcsPalletSubDetail(); + subDetail.setPosition(Integer.parseInt(position)); + subDetail.setLayer(layer); + subDetail.setRfidBarcodes(serialNos); + + subDetailList.add(subDetail); + } + } + + palletData.setMaterials(subDetailList); + palletList.add(palletData); + } + } + + wcsData.setMaterialRequisitions(palletList); + System.out.println("构建WCS数据完成,栈板数:" + palletList.size() + " - rqrq"); + + // 7.8 先调用WCS接口(成功后再执行数据库操作)- rqrq + System.out.println("开始调用WCS接口 - rqrq"); + try { + // wcsApiService.pushNotifyToWcsApi(wcsData); + System.out.println("WCS接口调用成功 - rqrq"); + + } catch (Exception e) { + String errorMsg = e.getMessage(); + System.err.println("WCS接口调用失败:" + errorMsg + " - rqrq"); + + // 超时错误直接抛出 - rqrq + if (errorMsg != null && (errorMsg.contains("timeout") || errorMsg.contains("超时"))) { + throw new RuntimeException("WCS接口调用超时:" + errorMsg); + } + + // 其他错误跳过本次循环 - rqrq + System.err.println("订单" + productionOrderNo + "推送失败,跳过继续处理下一个订单 - rqrq"); + continue; + } + + // 7.9 WCS推送成功后,执行数据库操作 - rqrq + System.out.println("WCS推送成功,开始保存数据库记录 - rqrq"); + + // 7.9.1 插入wms_order_task - rqrq + wcsIntegrationMapper.insertOrderTask(orderTask); + System.out.println("创建wms_order_task记录成功 - rqrq"); + + // 7.9.2 批量插入wms_order_task_detail - rqrq + for (com.gaotao.modules.automatedWarehouse.entity.WmsOrderTaskDetail taskDetail : taskDetailList) { + wcsIntegrationMapper.insertWmsOrderTaskDetail(taskDetail); + } + System.out.println("创建wms_order_task_detail记录" + taskDetailList.size() + "条 - rqrq"); + + // 7.9.3 更新handling_unit的reserve标志 - rqrq + newIssureMapper.updateHandlingUnitReserveFlag(site, orderSerialNos, notifyNo, itemNo, productionOrderNo); + System.out.println("更新handling_unit的reserve标志完成 - rqrq"); + + // 7.9.4 更新栈板的calling_flag - rqrq + newIssureMapper.updatePalletCallingFlag(site, orderPalletIds); + System.out.println("更新栈板calling_flag完成 - rqrq"); + + // 7.9.5 批量插入SOIssueNotifyOrderMaterialList_detail - rqrq + if (!detailList.isEmpty()) { + newIssureMapper.batchInsertMaterialListDetail(detailList); + System.out.println("创建SOIssueNotifyOrderMaterialList_detail记录" + detailList.size() + "条 - rqrq"); + } + + // 7.9.6 更新SOIssueNotifyOrderList的push_wms_flag - rqrq + newIssureMapper.updateOrderListPushWmsFlag(site, notifyNo, itemNo); + System.out.println("更新push_wms_flag=Y - rqrq"); + + System.out.println("订单" + productionOrderNo + "处理完成 - rqrq"); + + // 成功推送,计数+1 - rqrq + successCount++; + + } catch (RuntimeException e) { + // 超时错误向上抛出 - rqrq + if (e.getMessage().contains("超时") || e.getMessage().contains("timeout")) { + throw e; + } + // 其他错误记录日志并跳过 - rqrq + System.err.println("处理订单" + productionOrderNo + "失败:" + e.getMessage() + " - rqrq"); + } + } + + // 8. 判断推送状态并更新SOIssueNotifyHeader的push_wcs_flag - rqrq + if (successCount == 0) { + // 一条都没成功,不改变push_wcs_flag状态 - rqrq + System.out.println("推送结果:传入" + originalOrderCount + "个订单,成功0个,不改变推送状态 - rqrq"); + } else { + // 使用原始订单总数判断,发货通知单只有完全推送完成/部分推送两种状态 - rqrq + String pushWcsFlag = (successCount == originalOrderCount) ? "推送完成" : "部分推送"; + System.out.println("推送结果统计:传入" + originalOrderCount + "个订单,满足条件" + validOrderCount + "个,成功推送" + successCount + "个,最终状态=" + pushWcsFlag + " - rqrq"); + + newIssureMapper.updateNotifyHeaderPushWcsFlag(site, notifyNo, pushWcsFlag); + System.out.println("更新申请单push_wcs_flag=" + pushWcsFlag + " - rqrq"); + } + + System.out.println("推送发货通知单库存预览数据至WCS完成 - rqrq"); + } } diff --git a/src/main/java/com/gaotao/modules/notify/entity/SOIssueNotifyHeader.java b/src/main/java/com/gaotao/modules/notify/entity/SOIssueNotifyHeader.java index 6a1da80..4eb9144 100644 --- a/src/main/java/com/gaotao/modules/notify/entity/SOIssueNotifyHeader.java +++ b/src/main/java/com/gaotao/modules/notify/entity/SOIssueNotifyHeader.java @@ -9,6 +9,7 @@ import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.util.Date; +import java.util.List; @Data @TableName(value = "SOIssueNotifyHeader") @@ -177,5 +178,11 @@ public class SOIssueNotifyHeader implements Serializable { private String handlerDisplay; private String pushWcsFlag; + + /** + * 发货通知单库存预览数据列表(用于推送WCS)- rqrq + */ + @TableField(exist = false) + private List shipmentInventoryList; } diff --git a/src/main/resources/mapper/customer/ShipmentIssueMapper.xml b/src/main/resources/mapper/customer/ShipmentIssueMapper.xml index 1b0537e..d34be08 100644 --- a/src/main/resources/mapper/customer/ShipmentIssueMapper.xml +++ b/src/main/resources/mapper/customer/ShipmentIssueMapper.xml @@ -6,7 +6,7 @@ - insert into SOIssueNotifyOrderList(notify_no,site,item_no,fgpart_no,soorder_no,issure_qty,out_work_order_flag,need_date,release_no,sequence_no,order_type) + insert into SOIssueNotifyOrderList(notify_no,site,item_no,fgpart_no,soorder_no,issure_qty,out_work_order_flag,need_date,release_no,sequence_no,order_type,production_area,push_wms_flag) values(#{notifyNo},#{site},#{itemNo},#{fgPartNo},#{soorderNo},#{issureQty,jdbcType=DECIMAL},#{outWorkOrderFlag} - ,#{needDate},#{releaseNo},#{sequenceNo},#{orderType}) + ,#{needDate},#{releaseNo},#{sequenceNo},#{orderType},#{productionArea},#{pushWmsFlag}) + + + + + + + update SOIssueNotifyHeader + set status='UNISSUE' + where site=#{site} and notify_no=#{notifyNo} + + + + +