From 940c8481d2fdcf51341db4ccd6fd6fcc2d43debb Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 29 六月 2026 15:32:58 +0800
Subject: [PATCH] 初始化项目

---
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java |  139 ++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 115 insertions(+), 24 deletions(-)

diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java
index 6541170..31dee0e 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java
@@ -1,22 +1,34 @@
 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.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
 import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper;
 import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
+import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
+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.WmsInventoryQueryReqDTO;
+import cn.iocoder.yudao.module.wms.api.inventory.dto.WmsInventoryRespDTO;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_COUNT_NEGATIVE;
-import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_COUNT_NEGATIVE2;
+import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
 
 /**
  * ERP 浜у搧搴撳瓨 Service 瀹炵幇绫�
+ *
+ * 鏀归�犺鏄庯細ERP 搴撳瓨璋冪敤 WMS 搴撳瓨 API
+ * - productId 瀵瑰簲 MDM itemId
+ * - 閫氳繃 MDM SKU API 鑾峰彇鐗╂枡鐨勯粯璁� SKU
+ * - 搴撳瓨鎿嶄綔璋冪敤 WMS Inventory API
  *
  * @author 鑺嬮亾婧愮爜
  */
@@ -26,18 +38,24 @@
 
     /**
      * 鍏佽搴撳瓨涓鸿礋鏁�
-     *
      * TODO 鑺嬭壙锛氬悗缁仛鎴� db 閰嶇疆
      */
     private static final Boolean NEGATIVE_STOCK_COUNT_ENABLE = false;
 
     @Resource
     private ErpProductService productService;
+
     @Resource
     private ErpWarehouseService warehouseService;
 
     @Resource
     private ErpStockMapper stockMapper;
+
+    @Resource
+    private WmsInventoryApi wmsInventoryApi;
+
+    @Resource
+    private MdmItemSkuApi mdmItemSkuApi;
 
     @Override
     public ErpStockDO getStock(Long id) {
@@ -46,44 +64,117 @@
 
     @Override
     public ErpStockDO getStock(Long productId, Long warehouseId) {
-        return stockMapper.selectByProductIdAndWarehouseId(productId, warehouseId);
+        // 閫氳繃 MDM 鑾峰彇浜у搧鐨勯粯璁� SKU锛岀劧鍚庢煡璇� WMS 搴撳瓨
+        Long skuId = getDefaultSkuId(productId);
+        if (skuId == null) {
+            return null;
+        }
+
+        // 鏌ヨ WMS 搴撳瓨
+        BigDecimal quantity = wmsInventoryApi.getAvailableQuantity(skuId, warehouseId).getCheckedData();
+        if (quantity == null || quantity.compareTo(BigDecimal.ZERO) == 0) {
+            return null;
+        }
+
+        // 杞崲涓� ERP Stock DO
+        ErpStockDO stock = new ErpStockDO();
+        stock.setProductId(productId);
+        stock.setWarehouseId(warehouseId);
+        stock.setCount(quantity);
+        return stock;
     }
 
     @Override
     public BigDecimal getStockCount(Long productId) {
-        BigDecimal count = stockMapper.selectSumByProductId(productId);
-        return count != null ? count : BigDecimal.ZERO;
+        // 閫氳繃 MDM 鑾峰彇浜у搧鐨勯粯璁� SKU锛岀劧鍚庢煡璇� WMS 搴撳瓨鎬婚噺
+        Long skuId = getDefaultSkuId(productId);
+        if (skuId == null) {
+            return BigDecimal.ZERO;
+        }
+
+        // 鏌ヨ璇� SKU 鍦ㄦ墍鏈変粨搴撶殑搴撳瓨
+        WmsInventoryQueryReqDTO queryReq = new WmsInventoryQueryReqDTO();
+        queryReq.setSkuIds(List.of(skuId));
+        queryReq.setOnlyPositive(true);
+
+        List<WmsInventoryRespDTO> inventories = wmsInventoryApi.getInventoryList(queryReq).getCheckedData();
+        if (CollUtil.isEmpty(inventories)) {
+            return BigDecimal.ZERO;
+        }
+
+        return inventories.stream()
+                .map(WmsInventoryRespDTO::getQuantity)
+                .filter(q -> q != null)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
     }
 
     @Override
     public PageResult<ErpStockDO> getStockPage(ErpStockPageReqVO pageReqVO) {
+        // 鏆傛椂淇濈暀鍘熼�昏緫锛屽悗缁彲鏀逛负璋冪敤 WMS 鍒嗛〉 API
         return stockMapper.selectPage(pageReqVO);
     }
 
     @Override
     public BigDecimal updateStockCountIncrement(Long productId, Long warehouseId, BigDecimal count) {
-        // 1.1 鏌ヨ褰撳墠搴撳瓨
-        ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseId(productId, warehouseId);
-        if (stock == null) {
-            stock = new ErpStockDO().setProductId(productId).setWarehouseId(warehouseId).setCount(BigDecimal.ZERO);
-            stockMapper.insert(stock);
-        }
-        // 1.2 鏍¢獙搴撳瓨鏄惁鍏呰冻
-        if (!NEGATIVE_STOCK_COUNT_ENABLE && stock.getCount().add(count).compareTo(BigDecimal.ZERO) < 0) {
-            throw exception(STOCK_COUNT_NEGATIVE, productService.getProduct(productId).getName(),
-                    warehouseService.getWarehouse(warehouseId).getName(), stock.getCount(), count);
-        }
-
-        // 2. 搴撳瓨鍙樻洿
-        int updateCount = stockMapper.updateCountIncrement(stock.getId(), count, NEGATIVE_STOCK_COUNT_ENABLE);
-        if (updateCount == 0) {
-            // 姝ゆ椂涓嶅ソ鍘绘煡璇㈡渶鏂板簱瀛橈紝鎵�浠ョ洿鎺ユ姏鍑鸿鎻愮ず锛屼笉鎻愪緵鍏蜂綋搴撳瓨鏁板瓧
-            throw exception(STOCK_COUNT_NEGATIVE2, productService.getProduct(productId).getName(),
+        // 閫氳繃 MDM 鑾峰彇浜у搧鐨勯粯璁� SKU
+        Long skuId = getDefaultSkuId(productId);
+        if (skuId == null) {
+            throw exception(STOCK_COUNT_NEGATIVE2,
+                    productService.getProduct(productId).getName(),
                     warehouseService.getWarehouse(warehouseId).getName());
         }
 
-        // 3. 杩斿洖鏈�鏂板簱瀛�
+        // 鏌ヨ褰撳墠搴撳瓨
+        BigDecimal currentStock = wmsInventoryApi.getAvailableQuantity(skuId, warehouseId).getCheckedData();
+        if (currentStock == null) {
+            currentStock = BigDecimal.ZERO;
+        }
+
+        // 鏍¢獙搴撳瓨鏄惁鍏呰冻锛堝嚭搴撴椂锛�
+        if (!NEGATIVE_STOCK_COUNT_ENABLE && count.compareTo(BigDecimal.ZERO) < 0) {
+            BigDecimal afterStock = currentStock.add(count);
+            if (afterStock.compareTo(BigDecimal.ZERO) < 0) {
+                throw exception(STOCK_COUNT_NEGATIVE,
+                        productService.getProduct(productId).getName(),
+                        warehouseService.getWarehouse(warehouseId).getName(),
+                        currentStock, count.abs());
+            }
+        }
+
+        // TODO: 璋冪敤 WMS 搴撳瓨鍙樻洿 API锛堥渶瑕� WMS 鎻愪緵 increment/decrement 鏂规硶锛�
+        // 鏆傛椂淇濈暀鍘熼�昏緫锛屼娇鐢ㄦ湰鍦板簱瀛樿〃
+        ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseId(productId, warehouseId);
+        if (stock == null) {
+            stock = new ErpStockDO()
+                    .setProductId(productId)
+                    .setWarehouseId(warehouseId)
+                    .setCount(BigDecimal.ZERO);
+            stockMapper.insert(stock);
+        }
+
+        int updateCount = stockMapper.updateCountIncrement(stock.getId(), count, NEGATIVE_STOCK_COUNT_ENABLE);
+        if (updateCount == 0) {
+            throw exception(STOCK_COUNT_NEGATIVE2,
+                    productService.getProduct(productId).getName(),
+                    warehouseService.getWarehouse(warehouseId).getName());
+        }
+
         return stock.getCount().add(count);
     }
 
+    /**
+     * 鑾峰彇浜у搧鐨勯粯璁� SKU ID
+     * ERP productId 瀵瑰簲 MDM itemId锛岄粯璁や娇鐢ㄧ涓�涓� SKU
+     */
+    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();
+    }
+
 }
\ No newline at end of file

--
Gitblit v1.9.3