liyong
2026-07-10 80ddf4c9c0bcb0f6c31524e0d9f5599c8001e904
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInServiceImpl.java
@@ -2,6 +2,7 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -18,16 +19,21 @@
import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.product.mapping.ErpMdmMappingService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService;
import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
import cn.iocoder.yudao.module.wms.api.dto.WmsPurchaseInboundReqDTO;
import cn.iocoder.yudao.module.wms.api.stock.WmsStockApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -46,6 +52,7 @@
 */
@Service
@Validated
@Slf4j
public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
    @Resource
@@ -65,6 +72,12 @@
    private ErpAccountService accountService;
    @Resource
    private ErpStockRecordService stockRecordService;
    @Resource
    private WmsStockApi wmsStockApi;
    @Resource
    private ErpMdmMappingService mdmMappingService;
    @Resource
    private AdminUserApi adminUserApi;
@@ -185,6 +198,69 @@
                    purchaseInItem.getProductId(), purchaseInItem.getWarehouseId(), count,
                    bizType, purchaseInItem.getInId(), purchaseInItem.getId(), purchaseIn.getNo()));
        });
        // 4. 同步 WMS 库存(MES 库存)
        if (approve) {
            syncToWmsPurchaseInbound(purchaseIn, purchaseInItems);
        }
    }
    /**
     * 同步采购入库到 WMS 库存
     */
    private void syncToWmsPurchaseInbound(ErpPurchaseInDO purchaseIn, List<ErpPurchaseInItemDO> purchaseInItems) {
        if (CollUtil.isEmpty(purchaseInItems)) {
            return;
        }
        log.info("[syncToWmsPurchaseInbound] 开始同步采购入库到WMS,purchaseInId={}", purchaseIn.getId());
        // 构建入库请求
        WmsPurchaseInboundReqDTO reqDTO = new WmsPurchaseInboundReqDTO()
                .setBizId(purchaseIn.getId())
                .setBizCode(purchaseIn.getNo())
                .setReceiptTime(LocalDateTime.now());
        // 转换明细项
        List<WmsPurchaseInboundReqDTO.Item> items = convertList(purchaseInItems, item -> {
            // ERP 产品 ID -> MDM 物料 ID
            Long mdmItemId = mdmMappingService.getMdmItemId(item.getProductId());
            // ERP 仓库 ID -> MES 仓库 ID
            Long mesWarehouseId = mdmMappingService.getMesWarehouseId(item.getWarehouseId());
            if (mdmItemId == null) {
                log.warn("[syncToWmsPurchaseInbound] 未找到MDM物料映射,erpProductId={}", item.getProductId());
                return null;
            }
            if (mesWarehouseId == null) {
                log.warn("[syncToWmsPurchaseInbound] 未找到MES仓库映射,erpWarehouseId={}", item.getWarehouseId());
                return null;
            }
            return new WmsPurchaseInboundReqDTO.Item()
                    .setItemId(mdmItemId)
                    .setWarehouseId(mesWarehouseId)
                    .setQuantity(item.getCount())
                    .setBizLineId(item.getId());
        });
        // 过滤掉映射失败的项
        items = items.stream().filter(java.util.Objects::nonNull).toList();
        if (CollUtil.isEmpty(items)) {
            log.warn("[syncToWmsPurchaseInbound] 无有效的入库明细,跳过WMS同步");
            return;
        }
        reqDTO.setItems(items);
        try {
            Long transactionId = wmsStockApi.purchaseInbound(reqDTO);
            log.info("[syncToWmsPurchaseInbound] 同步成功,transactionId={}", transactionId);
        } catch (Exception e) {
            log.error("[syncToWmsPurchaseInbound] 同步失败", e);
            // 注意:这里可以选择抛出异常回滚,或仅记录日志
            // throw exception(PURCHASE_IN_SYNC_WMS_FAIL);
        }
    }
    @Override