From 23317ed94a5e2d9b19c16627a70f9c7b69c908a2 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 29 十月 2026 16:36:54 +0800
Subject: [PATCH] feat: 发货支持无库存批号(未启用仓储模块的租户)

---
 src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java |   89 +++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 79 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
index 0beecd2..e8cd02b 100644
--- a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
+++ b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -4,9 +4,13 @@
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.ruoyi.common.enums.ReviewStatusEnum;
+import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
+import com.ruoyi.sales.mapper.ShippingProductDetailMapper;
+import com.ruoyi.sales.pojo.ShippingProductDetail;
 import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.dto.StockOutRecordDto;
 import com.ruoyi.stock.dto.StockUninventoryDto;
 import com.ruoyi.stock.pojo.StockInRecord;
 import com.ruoyi.stock.pojo.StockOutRecord;
@@ -18,7 +22,9 @@
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.Collections;
+import java.util.List;
 
 @Component
 @RequiredArgsConstructor
@@ -29,6 +35,7 @@
     private final StockInventoryService stockInventoryService;
     private final StockInRecordService stockInRecordService;
     private final StockOutRecordService stockOutRecordService;
+    private final ShippingProductDetailMapper shippingProductDetailMapper;
 
     /**
      * 涓嶅悎鏍煎叆搴�
@@ -88,11 +95,21 @@
      * @param recordId
      */
     public void addStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId) {
+        addStock(productModelId, quantity, recordType, recordId, null);
+    }
+
+    /**
+     * 鍚堟牸鍏ュ簱
+     * @param recordType
+     * @param recordId
+     */
+    public void addStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId, LocalDateTime createTime) {
         StockInventoryDto stockInventoryDto = new StockInventoryDto();
         stockInventoryDto.setRecordId(recordId);
         stockInventoryDto.setRecordType(String.valueOf(recordType));
         stockInventoryDto.setQualitity(quantity);
         stockInventoryDto.setProductModelId(productModelId);
+        stockInventoryDto.setCreateTime(createTime);
         stockInventoryService.addStockInRecordOnly(stockInventoryDto);
     }
 
@@ -104,12 +121,22 @@
      * @param recordId
      */
     public void addStockWithBatchNo(Long productModelId, BigDecimal quantity, String recordType, Long recordId, String batchNo) {
+        addStockWithBatchNo(productModelId, quantity, recordType, recordId, batchNo, null);
+    }
+
+    /**
+     * 鍚堟牸鍏ュ簱甯︽壒娆″彿
+     * @param recordType
+     * @param recordId
+     */
+    public void addStockWithBatchNo(Long productModelId, BigDecimal quantity, String recordType, Long recordId, String batchNo, LocalDateTime createTime) {
         StockInventoryDto stockInventoryDto = new StockInventoryDto();
         stockInventoryDto.setRecordId(recordId);
         stockInventoryDto.setRecordType(String.valueOf(recordType));
         stockInventoryDto.setQualitity(quantity);
         stockInventoryDto.setProductModelId(productModelId);
         stockInventoryDto.setBatchNo(batchNo);
+        stockInventoryDto.setCreateTime(createTime);
         stockInventoryService.addStockInRecordOnly(stockInventoryDto);
     }
 
@@ -132,15 +159,47 @@
     }
 
     /**
-     * 鍙戣揣瀹℃壒鐘舵�佹洿鏀�
+     * 鍙櫥璁板嚭搴撴祦姘达紝涓嶆牎楠屻�佷笉鎵e噺搴撳瓨銆�
+     * 鐢ㄤ簬鏈惎鐢ㄤ粨鍌ㄦā鍧椼�佸彂璐ф病鏈夊簱瀛樻壒鍙风殑鍦烘櫙銆�
+     *
+     * @param productModelId
+     * @param quantity
+     * @param recordType
+     * @param recordId
+     * @param batchNo
+     */
+    public void recordStockOutWithoutInventory(Long productModelId, BigDecimal quantity, String recordType, Long recordId, String batchNo) {
+        StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
+        stockOutRecordDto.setRecordId(recordId);
+        stockOutRecordDto.setRecordType(String.valueOf(recordType));
+        stockOutRecordDto.setStockOutNum(quantity);
+        stockOutRecordDto.setProductModelId(productModelId);
+        stockOutRecordDto.setBatchNo(batchNo);
+        stockOutRecordDto.setType("0");
+        stockOutRecordService.add(stockOutRecordDto);
+    }
+
+    /**
+     * 鍙戣揣瀹℃壒鐘舵�佹洿鏀广��
+     * 娌℃湁搴撳瓨鎵瑰彿鐨勫彂璐э紙鏈惎鐢ㄤ粨鍌ㄦā鍧楋級娌℃湁鍑哄簱瀹℃牳鐜妭锛屽鎵归�氳繃鍗宠涓哄凡鍑哄簱锛�
+     * 鍚﹀垯鍙戣揣鏁伴噺缁熻涓嶅埌銆�
+     *
      * @param recordType
      * @param recordId
      */
     public void shipmentStatus(String recordType, Long recordId) {
+        Long inventoryBatchCount = shippingProductDetailMapper.selectCount(new LambdaQueryWrapper<ShippingProductDetail>()
+                .eq(ShippingProductDetail::getShippingInfoId, recordId)
+                .isNotNull(ShippingProductDetail::getStockInventoryId));
+        boolean withoutInventoryBatch = StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode().equals(recordType)
+                && inventoryBatchCount == 0;
+        Integer approvalStatus = withoutInventoryBatch
+                ? ReviewStatusEnum.APPROVED.getCode()
+                : ReviewStatusEnum.PENDING_REVIEW.getCode();
         LambdaQueryWrapper<StockOutRecord> queryWrapper = new LambdaQueryWrapper<StockOutRecord>().eq(StockOutRecord::getRecordType, recordType)
                 .eq(StockOutRecord::getRecordId, recordId);
         stockOutRecordService.list(queryWrapper).stream().forEach(stockOutRecord -> {
-            stockOutRecord.setApprovalStatus(0);
+            stockOutRecord.setApprovalStatus(approvalStatus);
             stockOutRecordService.updateById(stockOutRecord);
         });
     }
@@ -162,15 +221,25 @@
 
     //鍒犻櫎鍑哄簱璁板綍
     public void deleteStockOutRecord(Long recordId, String recordType) {
-        StockOutRecord one = stockOutRecordService.getOne(new QueryWrapper<StockOutRecord>()
+        List<StockOutRecord> records = stockOutRecordService.list(new QueryWrapper<StockOutRecord>()
                 .lambda().eq(StockOutRecord::getRecordId, recordId)
-                .eq(StockOutRecord::getRecordType, recordType), false);
-        if (ObjectUtils.isNotEmpty(one)) {
-            if (ReviewStatusEnum.APPROVED.getCode().equals(one.getApprovalStatus())) {
-                stockOutRecordService.batchDelete(Collections.singletonList(one.getId()));
-            } else {
-                stockOutRecordService.removeById(one.getId());
-            }
+                .eq(StockOutRecord::getRecordType, recordType));
+        if (ObjectUtils.isEmpty(records)) {
+            return;
+        }
+        List<Long> approvedIds = records.stream()
+                .filter(one -> ReviewStatusEnum.APPROVED.getCode().equals(one.getApprovalStatus()))
+                .map(StockOutRecord::getId)
+                .toList();
+        List<Long> pendingIds = records.stream()
+                .filter(one -> !ReviewStatusEnum.APPROVED.getCode().equals(one.getApprovalStatus()))
+                .map(StockOutRecord::getId)
+                .toList();
+        if (!approvedIds.isEmpty()) {
+            stockOutRecordService.batchDelete(approvedIds);
+        }
+        if (!pendingIds.isEmpty()) {
+            stockOutRecordService.removeByIds(pendingIds);
         }
 
     }

--
Gitblit v1.9.3