zhang_nuo
2026-09-22 0200b4092214d065adea7c7b9fef0c04b31be255
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
@@ -9,6 +9,7 @@
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.production.bean.dto.ProductionOrderPickDto;
import com.ruoyi.production.bean.vo.AutoPickResultVo;
import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
import com.ruoyi.production.mapper.ProductionOperationTaskMapper;
import com.ruoyi.production.mapper.ProductionOrderMapper;
@@ -16,6 +17,7 @@
import com.ruoyi.production.mapper.ProductionOrderPickRecordMapper;
import com.ruoyi.production.pojo.ProductionOrder;
import com.ruoyi.production.pojo.ProductionOrderPick;
import com.ruoyi.production.service.ProductionOrderService;
import com.ruoyi.production.pojo.ProductionOrderPickRecord;
import com.ruoyi.production.service.ProductionOrderPickService;
import com.ruoyi.stock.dto.StockInventoryDto;
@@ -51,6 +53,7 @@
    private static final String FEED_RETURN_IN_RECORD_TYPE = StockInQualifiedRecordTypeEnum.FEED_RETURN_IN.getCode();
    private final ProductionOrderMapper productionOrderMapper;
    private final ProductionOrderService productionOrderService;
    private final ProductionOperationTaskMapper productionOperationTaskMapper;
    private final ProductionOrderPickRecordMapper productionOrderPickRecordMapper;
    private final StockInventoryMapper stockInventoryMapper;
@@ -194,6 +197,147 @@
        return detailList;
    }
    @Override
    public AutoPickResultVo autoPick(List<Long> orderIds) {
        // 自动领料总流程:
        // 1) 遍历目标订单,读取BOM需求清单;
        // 2) 按 订单ID+规格ID+工序ID 去重判断是否已领料;
        // 3) 对未领料且有需求的物料,逐笔执行 savePick 领料;
        // 4) 汇总成功/跳过/失败明细并返回。
        AutoPickResultVo result = new AutoPickResultVo();
        if (orderIds == null || orderIds.isEmpty()) {
            return result;
        }
        result.setOrderTotal(orderIds.size());
        for (Long orderId : orderIds) {
            ProductionOrder order = productionOrderMapper.selectById(orderId);
            if (order == null) {
                result.setOrderFail(result.getOrderFail() + 1);
                AutoPickResultVo.ItemDetail failItem = new AutoPickResultVo.ItemDetail();
                failItem.setProductionOrderId(orderId);
                failItem.setReason("生产订单不存在");
                result.getFailList().add(failItem);
                continue;
            }
            // 获取BOM需求清单
            List<ProductionOrderPickVo> demandList = productionOrderService.pick(orderId);
            if (demandList == null || demandList.isEmpty()) {
                result.setOrderFail(result.getOrderFail() + 1);
                AutoPickResultVo.ItemDetail failItem = new AutoPickResultVo.ItemDetail();
                failItem.setProductionOrderId(orderId);
                failItem.setProductionOrderNo(order.getNpsNo());
                failItem.setReason("无BOM物料需求");
                result.getFailList().add(failItem);
                continue;
            }
            // 查询已领料记录(按 工序ID#规格ID 去重)
            Set<String> pickedKeys = list(Wrappers.<ProductionOrderPick>lambdaQuery()
                    .eq(ProductionOrderPick::getProductionOrderId, orderId)
                    .eq(ProductionOrderPick::getReturned, false)).stream()
                    .map(p -> (p.getTechnologyOperationId() == null ? "null" : p.getTechnologyOperationId())
                            + "#" + p.getProductModelId())
                    .collect(Collectors.toSet());
            boolean orderHasSuccess = false;
            boolean orderHasFail = false;
            for (ProductionOrderPickVo demand : demandList) {
                result.setMaterialTotal(result.getMaterialTotal() + 1);
                String key = (demand.getTechnologyOperationId() == null ? "null" : demand.getTechnologyOperationId())
                        + "#" + demand.getProductModelId();
                // 已领料的跳过
                if (pickedKeys.contains(key)) {
                    result.setMaterialSkip(result.getMaterialSkip() + 1);
                    AutoPickResultVo.ItemDetail skipItem = new AutoPickResultVo.ItemDetail();
                    skipItem.setProductionOrderId(orderId);
                    skipItem.setProductionOrderNo(order.getNpsNo());
                    skipItem.setProductModelId(demand.getProductModelId());
                    skipItem.setTechnologyOperationId(demand.getTechnologyOperationId());
                    skipItem.setOperationName(demand.getOperationName());
                    skipItem.setDemandedQuantity(demand.getDemandedQuantity());
                    skipItem.setReason("已领料");
                    result.getSkipList().add(skipItem);
                    continue;
                }
                BigDecimal demandQty = demand.getDemandedQuantity();
                if (demandQty == null || demandQty.compareTo(BigDecimal.ZERO) <= 0) {
                    result.setMaterialSkip(result.getMaterialSkip() + 1);
                    AutoPickResultVo.ItemDetail skipItem = new AutoPickResultVo.ItemDetail();
                    skipItem.setProductionOrderId(orderId);
                    skipItem.setProductionOrderNo(order.getNpsNo());
                    skipItem.setProductModelId(demand.getProductModelId());
                    skipItem.setTechnologyOperationId(demand.getTechnologyOperationId());
                    skipItem.setOperationName(demand.getOperationName());
                    skipItem.setDemandedQuantity(demandQty);
                    skipItem.setReason("需求数量为0或空");
                    result.getSkipList().add(skipItem);
                    continue;
                }
                // 执行领料
                try {
                    ProductionOrderPickDto dto = new ProductionOrderPickDto();
                    dto.setProductionOrderId(orderId);
                    dto.setProductModelId(demand.getProductModelId());
                    dto.setPickQuantity(demandQty);
                    dto.setPickType((byte) 1); // 1=正常领料
                    dto.setBatchNoList(demand.getBatchNoList());
                    dto.setTechnologyOperationId(demand.getTechnologyOperationId());
                    dto.setOperationName(demand.getOperationName());
                    dto.setDemandedQuantity(demand.getDemandedQuantity());
                    dto.setBom(demand.getBom());
                    dto.setRemark("自动领料");
                    savePick(dto);
                    result.setMaterialSuccess(result.getMaterialSuccess() + 1);
                    orderHasSuccess = true;
                    AutoPickResultVo.ItemDetail successItem = new AutoPickResultVo.ItemDetail();
                    successItem.setProductionOrderId(orderId);
                    successItem.setProductionOrderNo(order.getNpsNo());
                    successItem.setProductModelId(demand.getProductModelId());
                    successItem.setTechnologyOperationId(demand.getTechnologyOperationId());
                    successItem.setOperationName(demand.getOperationName());
                    successItem.setDemandedQuantity(demandQty);
                    successItem.setPickQuantity(demandQty);
                    result.getSuccessList().add(successItem);
                } catch (Exception e) {
                    result.setMaterialFail(result.getMaterialFail() + 1);
                    orderHasFail = true;
                    AutoPickResultVo.ItemDetail failItem = new AutoPickResultVo.ItemDetail();
                    failItem.setProductionOrderId(orderId);
                    failItem.setProductionOrderNo(order.getNpsNo());
                    failItem.setProductModelId(demand.getProductModelId());
                    failItem.setTechnologyOperationId(demand.getTechnologyOperationId());
                    failItem.setOperationName(demand.getOperationName());
                    failItem.setDemandedQuantity(demandQty);
                    failItem.setReason(e.getMessage());
                    result.getFailList().add(failItem);
                }
            }
            if (orderHasSuccess) {
                result.setOrderSuccess(result.getOrderSuccess() + 1);
            }
            if (orderHasFail) {
                result.setOrderFail(result.getOrderFail() + 1);
            }
            // 如果既没有成功也没有失败(全跳过),订单不算失败也不算成功
            if (!orderHasSuccess && !orderHasFail) {
                result.setOrderSuccess(result.getOrderSuccess() + 1);
            }
        }
        return result;
    }
    private void processDeletePickIds(ProductionOrderPickDto rootDto,
                                      Map<Long, ProductionOrderPick> existingPickMap,
                                      Long productionOrderId) {