liu
昨天 6d1bf32bc0b51dc12048fe6bb70badfbd31d67ac
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
@@ -30,6 +30,7 @@
import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mdm.enums.MdmItemTypeEnum;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
@@ -221,8 +222,22 @@
        int createdCount = 0;
        int reusedCount = 0;
        int skippedCount = 0;
        for (ErpSaleOrderItemDO item : items) {
            if (item.getNeedProduction() == null || item.getNeedProduction() != 1) {
                continue;
            }
            MdmItemRespDTO mdmItem = mdmItemApi.getItem(item.getProductId()).getCheckedData();
            if (mdmItem == null || !MdmItemTypeEnum.isProduct(mdmItem.getItemType())) {
                // 兼容修复前由合同生成的历史订单:当时所有明细都会被标记为需要生产。
                // 非产品明细不应创建 MPS,同时纠正标记,避免后续发货状态一直等待生产完成。
                saleOrderItemMapper.updateById(new ErpSaleOrderItemDO()
                        .setId(item.getId())
                        .setNeedProduction(0));
                skippedCount++;
                log.info("[createMpsForSaleOrder] 销售订单明细({}) 为非产品物料({}),跳过 MPS 并取消需要生产标记",
                        item.getId(), item.getProductId());
                continue;
            }
@@ -241,7 +256,7 @@
            }
            // 与销售订单审核共用事务;任一明细创建失败都会回滚审核状态和本次已创建的 MPS
            Long mpsId = createMpsForSaleOrderItem(saleOrder, item);
            Long mpsId = createMpsForSaleOrderItem(saleOrder, item, mdmItem);
            saleOrderItemMapper.updateById(new ErpSaleOrderItemDO()
                    .setId(item.getId())
                    .setMpsId(mpsId));
@@ -254,31 +269,21 @@
                    .set(ErpSaleOrderDO::getProductionStatus, ErpSaleOrderProductionStatusEnum.NOT_FINISHED.getStatus())
                    .set(ErpSaleOrderDO::getProductionFinishTime, null));
        }
        log.info("[createMpsForSaleOrder] 销售订单({}) 审核完成,创建 MPS {} 条,复用 MPS {} 条",
                orderId, createdCount, reusedCount);
        log.info("[createMpsForSaleOrder] 销售订单({}) 审核完成,创建 MPS {} 条,复用 MPS {} 条,跳过非产品 {} 条",
                orderId, createdCount, reusedCount, skippedCount);
    }
    /**
     * 为销售订单明细创建 MPS
     */
    private Long createMpsForSaleOrderItem(ErpSaleOrderDO saleOrder, ErpSaleOrderItemDO item) {
        // 获取 MDM 物料信息(用于获取产品名称)
        String productName = null;
        try {
            MdmItemRespDTO mdmItem = mdmItemApi.getItem(item.getProductId()).getCheckedData();
            if (mdmItem != null) {
                productName = mdmItem.getName();
            }
        } catch (Exception e) {
            log.warn("[createMpsForSaleOrderItem] 获取 MDM 物料信息失败,productId={}", item.getProductId(), e);
        }
    private Long createMpsForSaleOrderItem(ErpSaleOrderDO saleOrder, ErpSaleOrderItemDO item,
                                           MdmItemRespDTO mdmItem) {
        MesProMpsCreateReqDTO createReqDTO = new MesProMpsCreateReqDTO();
        createReqDTO.setSaleOrderId(saleOrder.getId());
        createReqDTO.setSaleOrderNo(saleOrder.getNo());
        createReqDTO.setSaleOrderItemId(item.getId());
        createReqDTO.setMdmItemId(item.getProductId());
        createReqDTO.setProductName(productName);
        createReqDTO.setProductName(mdmItem.getName());
        createReqDTO.setQuantity(item.getCount());
        createReqDTO.setClientId(saleOrder.getCustomerId());
        createReqDTO.setRequestDate(formatRequestDate(saleOrder.getOrderTime()));