11 小时以前 e85a60b1778ed442545c00e14bbfe4f8d33c68ac
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemconsume/MesWmItemConsumeServiceImpl.java
@@ -2,8 +2,10 @@
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemconsume.MesWmItemConsumeLineDO;
@@ -15,8 +17,9 @@
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemConsumeStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService;
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
@@ -24,6 +27,8 @@
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -40,10 +45,11 @@
/**
 * MES 物料消耗记录 Service 实现类
 *
 * @author 芋道源码
 * @author 超级管理员
 */
@Service
@Validated
@Slf4j
public class MesWmItemConsumeServiceImpl implements MesWmItemConsumeService {
    @Resource
@@ -54,9 +60,7 @@
    @Resource
    private MesWmItemConsumeDetailService itemConsumeDetailService;
    @Resource
    private MesProRouteProductBomService routeProductBomService;
    @Resource
    private MesProRouteService routeService;
    private MesProWorkOrderBomService workOrderBomService;
    @Resource
    private MesWmTransactionService wmTransactionService;
    @Resource
@@ -67,17 +71,18 @@
    private MesWmWarehouseAreaService areaService;
    @Resource
    private MesWmMaterialStockService materialStockService;
    @Autowired
    private MesMdItemService mesMdItemService;
    @Override
    public MesWmItemConsumeDO generateItemConsume(MesProFeedbackDO feedback) {
        // 1.1 避免 routeId 等为 null 时 getRouteProductBomList 因 eqIfPresent 放宽条件导致误查
        if (feedback.getRouteId() == null || feedback.getProcessId() == null || feedback.getItemId() == null) {
        // 1.1 校验工单编号有效
        if (feedback.getWorkOrderId() == null) {
            throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID);
        }
        routeService.validateRouteExists(feedback.getRouteId());
        // 1.2 查询当前工序的 BOM 物料配置
        List<MesProRouteProductBomDO> boms = routeProductBomService.getRouteProductBomList(
                feedback.getRouteId(), feedback.getProcessId(), feedback.getItemId());
        // 1.2 查询工单 BOM 物料列表(倒冲按工单投料,非工艺路线)
        List<MesProWorkOrderBomDO> boms = workOrderBomService.getWorkOrderBomListByWorkOrderId(
                feedback.getWorkOrderId());
        if (CollUtil.isEmpty(boms)) {
            return null;
        }
@@ -177,9 +182,15 @@
        // 2. 遍历明细,创建库存事务(按批次精确扣减线边库)
        for (MesWmItemConsumeDetailDO detail : details) {
            MesMdItemDO item = mesMdItemService.getItem(detail.getItemId());
            // 物料主数据缺失(BOM 引用了已删除/未同步的物料)时跳过该行,避免 NPE 阻断报工
            if (item == null || item.getMdmItemId() == null) {
                log.warn("[finishItemConsume] 消耗明细({}) 物料({}) 在 mes_md_item 中不存在,跳过扣库", detail.getId(), detail.getItemId());
                continue;
            }
            wmTransactionService.createTransaction(new MesWmTransactionSaveReqDTO()
                    .setType(MesWmTransactionTypeEnum.OUT.getType())
                    .setItemId(detail.getItemId())
                    .setItemId(item.getMdmItemId())
                    .setQuantity(detail.getQuantity().negate())
                    .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode())
                    .setWarehouseId(detail.getWarehouseId())