2026-06-29 940c8481d2fdcf51341db4ccd6fd6fcc2d43debb
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockRecordServiceImpl.java
@@ -1,20 +1,33 @@
package cn.iocoder.yudao.module.erp.service.stock;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockRecordMapper;
import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemSkuApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemSkuRespDTO;
import cn.iocoder.yudao.module.wms.api.inventory.WmsInventoryApi;
import cn.iocoder.yudao.module.wms.api.inventory.dto.WmsReceiptReqDTO;
import cn.iocoder.yudao.module.wms.api.inventory.dto.WmsShipmentReqDTO;
import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryBizTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.util.List;
/**
 * ERP 产品库存明细 Service 实现类
 *
 * 改造说明:库存变更调用 WMS 库存 API
 * - 入库操作调用 WmsInventoryApi.receipt()
 * - 出库操作调用 WmsInventoryApi.shipment()
 * - productId 对应 MDM itemId,通过 SKU API 获取默认 SKU
 *
 * @author 芋道源码
 */
@@ -27,6 +40,12 @@
    @Resource
    private ErpStockService stockService;
    @Resource
    private WmsInventoryApi wmsInventoryApi;
    @Resource
    private MdmItemSkuApi mdmItemSkuApi;
    @Override
    public ErpStockRecordDO getStockRecord(Long id) {
@@ -41,13 +60,98 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createStockRecord(ErpStockRecordCreateReqBO createReqBO) {
        // 1. 更新库存
        BigDecimal totalCount = stockService.updateStockCountIncrement(
                createReqBO.getProductId(), createReqBO.getWarehouseId(), createReqBO.getCount());
        // 2. 创建库存明细
        // 1. 获取产品的默认 SKU ID(ERP productId = MDM itemId)
        Long skuId = getDefaultSkuId(createReqBO.getProductId());
        if (skuId == null) {
            // 如果没有 SKU,使用原有逻辑更新库存
            BigDecimal totalCount = stockService.updateStockCountIncrement(
                    createReqBO.getProductId(), createReqBO.getWarehouseId(), createReqBO.getCount());
            ErpStockRecordDO stockRecord = BeanUtils.toBean(createReqBO, ErpStockRecordDO.class)
                    .setTotalCount(totalCount);
            stockRecordMapper.insert(stockRecord);
            return;
        }
        // 2. 根据 count 正负判断入库还是出库
        BigDecimal count = createReqBO.getCount();
        if (count.compareTo(BigDecimal.ZERO) > 0) {
            // 入库操作
            WmsReceiptReqDTO receiptReq = buildReceiptReqDTO(createReqBO, skuId);
            wmsInventoryApi.receipt(receiptReq);
        } else if (count.compareTo(BigDecimal.ZERO) < 0) {
            // 出库操作(数量转为正数)
            WmsShipmentReqDTO shipmentReq = buildShipmentReqDTO(createReqBO, skuId);
            wmsInventoryApi.shipment(shipmentReq);
        }
        // 3. 创建库存明细(记录操作)
        BigDecimal currentStock = wmsInventoryApi.getAvailableQuantity(skuId, createReqBO.getWarehouseId()).getCheckedData();
        ErpStockRecordDO stockRecord = BeanUtils.toBean(createReqBO, ErpStockRecordDO.class)
                .setTotalCount(totalCount);
                .setTotalCount(currentStock != null ? currentStock : BigDecimal.ZERO);
        stockRecordMapper.insert(stockRecord);
    }
    /**
     * 获取产品的默认 SKU ID
     */
    private Long getDefaultSkuId(Long productId) {
        if (productId == null) {
            return null;
        }
        List<MdmItemSkuRespDTO> skuList = mdmItemSkuApi.getItemSkuListByItemId(productId).getCheckedData();
        if (CollUtil.isEmpty(skuList)) {
            return null;
        }
        return skuList.get(0).getId();
    }
    /**
     * 构建入库请求
     */
    private WmsReceiptReqDTO buildReceiptReqDTO(ErpStockRecordCreateReqBO createReqBO, Long skuId) {
        WmsReceiptReqDTO receiptReq = new WmsReceiptReqDTO();
        receiptReq.setBizType(convertBizType(createReqBO.getBizType()));
        receiptReq.setBizId(createReqBO.getBizId());
        receiptReq.setBizNo(createReqBO.getBizNo());
        receiptReq.setWarehouseId(createReqBO.getWarehouseId());
        receiptReq.setRemark(createReqBO.getRemark());
        WmsReceiptReqDTO.Item item = new WmsReceiptReqDTO.Item();
        item.setSkuId(skuId);
        item.setQuantity(createReqBO.getCount());
        receiptReq.setItems(List.of(item));
        return receiptReq;
    }
    /**
     * 构建出库请求
     */
    private WmsShipmentReqDTO buildShipmentReqDTO(ErpStockRecordCreateReqBO createReqBO, Long skuId) {
        WmsShipmentReqDTO shipmentReq = new WmsShipmentReqDTO();
        shipmentReq.setBizType(convertBizType(createReqBO.getBizType()));
        shipmentReq.setBizId(createReqBO.getBizId());
        shipmentReq.setBizNo(createReqBO.getBizNo());
        shipmentReq.setWarehouseId(createReqBO.getWarehouseId());
        shipmentReq.setRemark(createReqBO.getRemark());
        WmsShipmentReqDTO.Item item = new WmsShipmentReqDTO.Item();
        item.setSkuId(skuId);
        item.setQuantity(createReqBO.getCount().negate()); // 出库数量为正数
        shipmentReq.setItems(List.of(item));
        return shipmentReq;
    }
    /**
     * 转换业务类型(ERP 业务类型映射到 WMS 业务类型)
     */
    private Integer convertBizType(Integer erpBizType) {
        // ERP 业务类型映射到 WMS 业务类型
        // 可以根据实际业务需求扩展映射关系
        if (erpBizType == null) {
            return WmsInventoryBizTypeEnum.OTHER.getType();
        }
        // 默认返回 OTHER 类型,后续可根据 ERP 业务类型枚举扩展
        return WmsInventoryBizTypeEnum.OTHER.getType();
    }
}