From a9d2ef88a2ac9cdc0b07e98e9c3a8ba621cfb1d8 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 09 四月 2026 16:11:31 +0800
Subject: [PATCH] feat: 生产订单根据库存数量判断生产,发货与冻结解冻挂钩

---
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java |   90 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
index 2bab798..1d165ad 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -26,8 +26,10 @@
 import com.ruoyi.sales.mapper.ShippingInfoMapper;
 import com.ruoyi.sales.pojo.SalesLedger;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.pojo.SalesLedgerProductFrozen;
 import com.ruoyi.sales.pojo.ShippingInfo;
 import com.ruoyi.sales.service.ISalesLedgerProductService;
+import com.ruoyi.sales.service.ISalesLedgerProductFrozenService;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
 import com.ruoyi.stock.pojo.StockInventory;
 import lombok.AllArgsConstructor;
@@ -92,6 +94,8 @@
     private StockInventoryMapper stockInventoryMapper;
     @Autowired
     private ProductOrderServiceImpl productOrderServiceImpl;
+    @Autowired
+    private ISalesLedgerProductFrozenService salesLedgerProductFrozenService;
 
     @Override
     public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
@@ -183,6 +187,10 @@
         //鍒犻櫎瀵瑰簲鐨勭敓浜ц鍗�
         deleteProductionData(Arrays.asList(ids));
 
+        for (Long id : ids) {
+            revertFrozenStock(id);
+        }
+
         // 3. 瀵规瘡涓富琛↖D杩涜閲戦鏇存柊
         for (Long salesLedgerId : mainIds) {
             LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
@@ -222,9 +230,11 @@
         if (salesLedgerProduct.getId() == null) {
             salesLedgerProduct.setRegisterDate(LocalDateTime.now());
             result = salesLedgerProductMapper.insert(salesLedgerProduct);
-            addProductionData(salesLedgerProduct);
+            processStockAndProduction(salesLedgerProduct);
         } else {
             checkProductionDataExist(Collections.singletonList(salesLedgerProduct.getId()));
+
+            revertFrozenStock(salesLedgerProduct.getId());
 
             //鏌ヨ鍘熸湰鐨勪骇鍝佸瀷鍙穒d
             salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
@@ -233,7 +243,7 @@
             deleteProductionData(Arrays.asList(salesLedgerProduct.getId()));
             // 鍒犻櫎鐢熶骇鏍哥畻鏁版嵁
 
-            addProductionData(salesLedgerProduct);
+            processStockAndProduction(salesLedgerProduct);
         }
 
         // 濡傛灉鎻掑叆鎴栨洿鏂版垚鍔燂紝骞朵笖鏈� salesLedgerId锛屾墠缁х画鏇存柊涓昏〃閲戦
@@ -266,17 +276,87 @@
         return result;
     }
 
+    public void processStockAndProduction(SalesLedgerProduct salesLedgerProduct) {
+        BigDecimal salesQty = salesLedgerProduct.getQuantity();
+        if (salesQty == null) salesQty = BigDecimal.ZERO;
+
+        BigDecimal frozenQty = BigDecimal.ZERO;
+        BigDecimal productionQty = salesQty;
+
+        //  鏌ヨ鍙敤搴撳瓨
+        StockInventory stockInventory = stockInventoryMapper.selectOne(new LambdaQueryWrapper<StockInventory>()
+                .eq(StockInventory::getProductModelId, salesLedgerProduct.getProductModelId())
+                .last("for update"));
+        if (stockInventory != null) {
+            BigDecimal quality = stockInventory.getQualitity() != null ? stockInventory.getQualitity() : BigDecimal.ZERO;
+            BigDecimal lockedQty = stockInventory.getLockedQuantity() != null ? stockInventory.getLockedQuantity() : BigDecimal.ZERO;
+            BigDecimal availableStock = quality.subtract(lockedQty);
+
+            if (availableStock.compareTo(BigDecimal.ZERO) > 0) {
+                // 鏈夊彲鐢ㄥ簱瀛�
+                if (availableStock.compareTo(salesQty) >= 0) {
+                    frozenQty = salesQty;
+                    productionQty = BigDecimal.ZERO;
+                } else {
+                    frozenQty = availableStock;
+                    productionQty = salesQty.subtract(frozenQty);
+                }
+            }
+        }
+
+        // 鍐荤粨搴撳瓨
+        if (frozenQty.compareTo(BigDecimal.ZERO) > 0) {
+            SalesLedgerProductFrozen frozenRecord = new SalesLedgerProductFrozen();
+            frozenRecord.setSalesLedgerProductId(salesLedgerProduct.getId());
+            frozenRecord.setProductModelId(salesLedgerProduct.getProductModelId());
+            frozenRecord.setFrozenQuantity(frozenQty);
+            frozenRecord.setCreateTime(LocalDateTime.now());
+            salesLedgerProductFrozenService.save(frozenRecord);
+
+            if (stockInventory != null) {
+                BigDecimal currentLocked = stockInventory.getLockedQuantity() != null ? stockInventory.getLockedQuantity() : BigDecimal.ZERO;
+                stockInventory.setLockedQuantity(currentLocked.add(frozenQty));
+                stockInventoryMapper.updateById(stockInventory);
+            }
+        }
+
+        // 濡傛灉闇�瑕佺敓浜э紝鍒欑敓鎴愮敓浜ф暟鎹�
+        if (productionQty.compareTo(BigDecimal.ZERO) > 0) {
+            addProductionData(salesLedgerProduct, productionQty);
+        }
+    }
+
+    public void revertFrozenStock(Long salesLedgerProductId) {
+        SalesLedgerProductFrozen frozenRecord = salesLedgerProductFrozenService.getOne(new LambdaQueryWrapper<SalesLedgerProductFrozen>()
+                        .eq(SalesLedgerProductFrozen::getSalesLedgerProductId, salesLedgerProductId)
+                        .last("limit 1"));
+        if (frozenRecord != null) {
+            BigDecimal frozenQty = frozenRecord.getFrozenQuantity();
+            if (frozenQty != null && frozenQty.compareTo(BigDecimal.ZERO) > 0) {
+                StockInventory stockInventory = stockInventoryMapper.selectOne(new LambdaQueryWrapper<StockInventory>()
+                        .eq(StockInventory::getProductModelId, frozenRecord.getProductModelId())
+                        .last("for update"));
+                if (stockInventory != null) {
+                    BigDecimal currentLocked = stockInventory.getLockedQuantity() != null ? stockInventory.getLockedQuantity() : BigDecimal.ZERO;
+                    stockInventory.setLockedQuantity(currentLocked.subtract(frozenQty));
+                    stockInventoryMapper.updateById(stockInventory);
+                }
+            }
+            salesLedgerProductFrozenService.removeById(frozenRecord.getId());
+        }
+    }
+
     /**
      * 鏂板鐢熶骇鏁版嵁
      */
-    public void addProductionData(SalesLedgerProduct salesLedgerProduct) {
+    public void addProductionData(SalesLedgerProduct salesLedgerProduct, BigDecimal productionQty) {
         ProductOrder productOrder = new ProductOrder();
         productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
         productOrder.setProductModelId(salesLedgerProduct.getProductModelId());
         productOrder.setSaleLedgerProductId(salesLedgerProduct.getId());
         String string = productOrderServiceImpl.generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
         productOrder.setNpsNo(string);
-        productOrder.setQuantity(salesLedgerProduct.getQuantity());//闇�姹傛暟閲�
+        productOrder.setQuantity(productionQty);//闇�姹傛暟閲�
         productOrder.setCompleteQuantity(BigDecimal.ZERO);//瀹屾垚鏁伴噺
         productOrderMapper.insert(productOrder);
 
@@ -324,7 +404,7 @@
                     ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                     productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                     productWorkOrder.setProductOrderId(productOrder.getId());
-                    productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
+                    productWorkOrder.setPlanQuantity(productionQty);
                     productWorkOrder.setWorkOrderNo(workOrderNoStr);
                     productWorkOrder.setStatus(1);
 

--
Gitblit v1.9.3