2026-06-29 940c8481d2fdcf51341db4ccd6fd6fcc2d43debb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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 芋道源码
 */
@Service
@Validated
public class ErpStockRecordServiceImpl implements ErpStockRecordService {
 
    @Resource
    private ErpStockRecordMapper stockRecordMapper;
 
    @Resource
    private ErpStockService stockService;
 
    @Resource
    private WmsInventoryApi wmsInventoryApi;
 
    @Resource
    private MdmItemSkuApi mdmItemSkuApi;
 
    @Override
    public ErpStockRecordDO getStockRecord(Long id) {
        return stockRecordMapper.selectById(id);
    }
 
    @Override
    public PageResult<ErpStockRecordDO> getStockRecordPage(ErpStockRecordPageReqVO pageReqVO) {
        return stockRecordMapper.selectPage(pageReqVO);
    }
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createStockRecord(ErpStockRecordCreateReqBO createReqBO) {
        // 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(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();
    }
 
}