| | |
| | | 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 芋道源码 |
| | | */ |
| | |
| | | |
| | | @Resource |
| | | private ErpStockService stockService; |
| | | |
| | | @Resource |
| | | private WmsInventoryApi wmsInventoryApi; |
| | | |
| | | @Resource |
| | | private MdmItemSkuApi mdmItemSkuApi; |
| | | |
| | | @Override |
| | | public ErpStockRecordDO getStockRecord(Long id) { |
| | |
| | | @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(); |
| | | } |
| | | |
| | | } |