From 76c84d95506998f546e6f3ebbf70414c0dd9da9d Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期五, 15 五月 2026 17:15:15 +0800
Subject: [PATCH] refactor(stock): 优化库存记录服务中的仓库信息处理逻辑

---
 src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java |  265 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 244 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
index e3c88e5..11e28d0 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -4,11 +4,13 @@
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
-import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
-import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.domain.R;
@@ -20,18 +22,24 @@
 import com.ruoyi.stock.dto.StockUninventoryDto;
 import com.ruoyi.stock.execl.StockInventoryExportData;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
+import com.ruoyi.stock.mapper.WarehouseInfoMapper;
+import com.ruoyi.stock.pojo.StockInRecord;
 import com.ruoyi.stock.pojo.StockInventory;
+import com.ruoyi.stock.pojo.WarehouseInfo;
 import com.ruoyi.stock.service.StockInRecordService;
 import com.ruoyi.stock.service.StockInventoryService;
 import com.ruoyi.stock.service.StockOutRecordService;
 import com.ruoyi.stock.service.StockUninventoryService;
+import com.ruoyi.warehouse.service.impl.WarehouseServiceImpl;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
-import jakarta.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -49,11 +57,14 @@
 @AllArgsConstructor
 public class StockInventoryServiceImpl extends ServiceImpl<StockInventoryMapper, StockInventory> implements StockInventoryService {
 
+    private final WarehouseServiceImpl warehouseServiceImpl;
+    private final WarehouseInfoMapper warehouseInfoMapper;
     private  StockInventoryMapper stockInventoryMapper;
     private StockInRecordService stockInRecordService;
     private StockOutRecordService stockOutRecordService;
     private StockUninventoryService stockUninventoryService;
     private SalesLedgerProductMapper salesLedgerProductMapper;
+    private ProductModelMapper productModelMapper;
     @Override
     public IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto) {
         return stockInventoryMapper.pagestockInventory(page, stockInventoryDto);
@@ -67,15 +78,18 @@
     //鍏ュ簱璋冪敤
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Boolean addstockInventory(StockInventoryDto stockInventoryDto) {
-        LambdaQueryWrapper<StockInventory> eq = new QueryWrapper<StockInventory>().lambda()
-                .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId());
-        if (StringUtils.isEmpty(stockInventoryDto.getBatchNo())) {
-            eq.isNull(StockInventory::getBatchNo);
-            stockInventoryDto.setBatchNo(null);
-        } else {
-            eq.eq(StockInventory::getBatchNo, stockInventoryDto.getBatchNo());
+    public StockInRecordDto addstockInventory(StockInventoryDto stockInventoryDto) {
+        Long warehouseInfoId = requireWarehouseInfoId(stockInventoryDto.getWarehouseInfoId());
+        String batchNo = StringUtils.trim(stockInventoryDto.getBatchNo());
+        if (StringUtils.isEmpty(batchNo)) {
+            batchNo = generateAutoBatchNo(stockInventoryDto.getProductModelId());
         }
+        stockInventoryDto.setBatchNo(batchNo);
+        LambdaQueryWrapper<StockInventory> eq = buildQualifiedInventoryQuery(
+                stockInventoryDto.getProductModelId(),
+                stockInventoryDto.getBatchNo(),
+                stockInventoryDto.getWarehouseInfoId()
+        );
         //鏂板鍏ュ簱璁板綍鍐嶆坊鍔犲簱瀛�
         StockInRecordDto stockInRecordDto = new StockInRecordDto();
         stockInRecordDto.setRecordId(stockInventoryDto.getRecordId());
@@ -84,6 +98,7 @@
         stockInRecordDto.setBatchNo(stockInventoryDto.getBatchNo());
         stockInRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
         stockInRecordDto.setType("0");
+        stockInRecordDto.setWarehouseInfoId(warehouseInfoId);
         stockInRecordService.add(stockInRecordDto);
         //鍐嶈繘琛屾柊澧炲簱瀛樻暟閲忓簱瀛�
         //鍏堟煡璇㈠簱瀛樿〃涓殑浜у搧鏄惁瀛樺湪锛屼笉瀛樺湪鏂板锛屽瓨鍦ㄦ洿鏂�
@@ -96,35 +111,40 @@
             newStockInventory.setRemark(stockInventoryDto.getRemark());
             newStockInventory.setBatchNo(stockInventoryDto.getBatchNo());
             newStockInventory.setLockedQuantity(stockInventoryDto.getLockedQuantity());
+            newStockInventory.setWarehouseInfoId(stockInventoryDto.getWarehouseInfoId());
             newStockInventory.setWarnNum(stockInventoryDto.getWarnNum());
             stockInventoryMapper.insert(newStockInventory);
         }else {
              stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
         }
-        return true;
+        return stockInRecordDto;
     }
 
     //鍑哄簱璋冪敤
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) {
-        LambdaQueryWrapper<StockInventory> eq = new QueryWrapper<StockInventory>().lambda()
-            .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId());
+    public StockOutRecordDto subtractStockInventory(StockInventoryDto stockInventoryDto) {
+        Long warehouseInfoId = requireWarehouseInfoId(stockInventoryDto.getWarehouseInfoId());
         if (StringUtils.isEmpty(stockInventoryDto.getBatchNo())) {
-            eq.isNull(StockInventory::getBatchNo);
             stockInventoryDto.setBatchNo(null);
-        } else {
-            eq.eq(StockInventory::getBatchNo, stockInventoryDto.getBatchNo());
         }
+        LambdaQueryWrapper<StockInventory> eq = buildQualifiedInventoryQuery(
+                stockInventoryDto.getProductModelId(),
+                stockInventoryDto.getBatchNo(),
+                stockInventoryDto.getWarehouseInfoId()
+        );
         //  鏂板鍑哄簱璁板綍
         StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
         stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId());
         stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType());
         stockOutRecordDto.setStockOutNum(stockInventoryDto.getQualitity());
         stockOutRecordDto.setBatchNo(stockInventoryDto.getBatchNo());
+        stockOutRecordDto.setApprovalStatus(0);
         stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
         stockOutRecordDto.setType("0");
-        stockOutRecordService.add(stockOutRecordDto);
+        stockOutRecordDto.setWarehouseInfoId(warehouseInfoId);
+        Long id = stockOutRecordService.add(stockOutRecordDto);
+        stockInventoryDto.setId(id);
 
 
         StockInventory oldStockInventory = stockInventoryMapper.selectOne(eq);
@@ -140,7 +160,179 @@
         }
 
         stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
-        return true;
+        return stockOutRecordDto;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public StockInRecordDto addStockInRecordOnly(StockInventoryDto stockInventoryDto) {
+        Long warehouseInfoId = requireWarehouseInfoId(stockInventoryDto.getWarehouseInfoId());
+        String batchNo = StringUtils.trim(stockInventoryDto.getBatchNo());
+        if (StringUtils.isEmpty(batchNo)) {
+            batchNo = generateAutoBatchNo(stockInventoryDto.getProductModelId());
+        }
+        stockInventoryDto.setBatchNo(batchNo);
+
+        StockInRecordDto stockInRecordDto = new StockInRecordDto();
+        stockInRecordDto.setRecordId(stockInventoryDto.getRecordId());
+        stockInRecordDto.setRecordType(stockInventoryDto.getRecordType());
+        stockInRecordDto.setStockInNum(stockInventoryDto.getQualitity());
+        stockInRecordDto.setBatchNo(batchNo);
+        stockInRecordDto.setApprovalStatus(0);
+        stockInRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
+        stockInRecordDto.setType("0");
+        stockInRecordDto.setWarehouseInfoId(warehouseInfoId);
+        stockInRecordDto.setRemark(stockInventoryDto.getRemark());
+        Long add = stockInRecordService.add(stockInRecordDto);
+        stockInRecordDto.setId( add);
+        return stockInRecordDto;
+    }
+
+    //瑙勫垯鐢熸垚锛�20260424-浜у搧缂栧彿-001
+    private String generateAutoBatchNo(Long productModelId) {
+        if (productModelId == null) {
+            throw new ServiceException("浜у搧瑙勬牸ID涓嶈兘涓虹┖");
+        }
+        ProductModel productModel = productModelMapper.selectById(productModelId);
+        if (productModel == null) {
+            throw new ServiceException("浜у搧瑙勬牸涓嶅瓨鍦紝ID=" + productModelId);
+        }
+        String productCode = StringUtils.trim(productModel.getProductCode());
+        if (StringUtils.isEmpty(productCode)) {
+            throw new ServiceException("浜у搧瑙勬牸鏈淮鎶や骇鍝佺紪鐮侊紝ID=" + productModelId);
+        }
+
+        String dateText = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
+        String prefix = dateText + "-" + productCode + "-";
+        int maxSequence = resolveMaxSequence(prefix);
+        int sequence = maxSequence + 1;
+        while (sequence < 1_000_000) {
+            String batchNo = prefix + String.format("%03d", sequence);
+            if (!isBatchNoExists(batchNo)) {
+                return batchNo;
+            }
+            sequence++;
+        }
+        throw new ServiceException("鎵瑰彿搴忓彿瓒呭嚭鑼冨洿锛岃妫�鏌ユ壒鍙锋暟鎹�");
+    }
+
+    private int resolveMaxSequence(String prefix) {
+        int maxSequence = 0;
+        List<StockInventory> stockInventoryList = stockInventoryMapper.selectList(
+                Wrappers.<StockInventory>lambdaQuery()
+                        .select(StockInventory::getBatchNo)
+                        .likeRight(StockInventory::getBatchNo, prefix));
+        for (StockInventory stockInventory : stockInventoryList) {
+            maxSequence = Math.max(maxSequence, parseSequence(stockInventory.getBatchNo(), prefix));
+        }
+
+        List<StockInRecord> stockInRecordList = stockInRecordService.list(
+                Wrappers.<StockInRecord>lambdaQuery()
+                        .select(StockInRecord::getBatchNo)
+                        .likeRight(StockInRecord::getBatchNo, prefix));
+        for (StockInRecord stockInRecord : stockInRecordList) {
+            maxSequence = Math.max(maxSequence, parseSequence(stockInRecord.getBatchNo(), prefix));
+        }
+        return maxSequence;
+    }
+
+    private int parseSequence(String batchNo, String prefix) {
+        if (StringUtils.isEmpty(batchNo) || StringUtils.isEmpty(prefix) || !batchNo.startsWith(prefix)) {
+            return 0;
+        }
+        String sequenceText = batchNo.substring(prefix.length());
+        if (StringUtils.isEmpty(sequenceText) || !sequenceText.matches("\\d+")) {
+            return 0;
+        }
+        try {
+            return Integer.parseInt(sequenceText);
+        } catch (NumberFormatException ignored) {
+            return 0;
+        }
+    }
+
+    private boolean isBatchNoExists(String batchNo) {
+        if (StringUtils.isEmpty(batchNo)) {
+            return false;
+        }
+        Long inventoryCount = stockInventoryMapper.selectCount(
+                Wrappers.<StockInventory>lambdaQuery().eq(StockInventory::getBatchNo, batchNo));
+        if (inventoryCount != null && inventoryCount > 0) {
+            return true;
+        }
+        return stockInRecordService.count(
+                Wrappers.<StockInRecord>lambdaQuery().eq(StockInRecord::getBatchNo, batchNo)) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public StockOutRecordDto addStockOutRecordOnly(StockInventoryDto stockInventoryDto) {
+        if (StringUtils.isEmpty(stockInventoryDto.getBatchNo())) {
+            stockInventoryDto.setBatchNo(null);
+        }
+        Long warehouseInfoId = requireWarehouseInfoId(stockInventoryDto.getWarehouseInfoId());
+        LambdaQueryWrapper<StockInventory> eq = buildQualifiedInventoryQuery(
+                stockInventoryDto.getProductModelId(),
+                stockInventoryDto.getBatchNo(),
+                warehouseInfoId
+        );
+        StockInventory stockInventory = stockInventoryMapper.selectOne(eq);
+        if (stockInventory == null) {
+            throw new ServiceException("搴撳瓨璁板綍涓嶅瓨鍦�");
+        }
+        BigDecimal lockedQty = stockInventory.getLockedQuantity();
+        if (lockedQty == null) {
+            lockedQty = BigDecimal.ZERO;
+        }
+        BigDecimal pendingOut = stockInventoryMapper.selectPendingOutQuantity(
+                stockInventoryDto.getProductModelId(),
+                stockInventoryDto.getBatchNo(),
+                warehouseInfoId,
+                "0"
+        );
+        if (pendingOut == null) {
+            pendingOut = BigDecimal.ZERO;
+        }
+        BigDecimal availableQty = stockInventory.getQualitity().subtract(lockedQty).subtract(pendingOut);
+        if (stockInventoryDto.getQualitity().compareTo(availableQty) > 0) {
+            throw new ServiceException("鐢宠鏁伴噺瓒呰繃鍙敤搴撳瓨锛屽綋鍓嶅彲鐢ㄥ簱瀛樹负锛�" + availableQty);
+        }
+        StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
+        stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId());
+        stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType());
+        stockOutRecordDto.setStockOutNum(stockInventoryDto.getQualitity());
+        stockOutRecordDto.setBatchNo(stockInventoryDto.getBatchNo());
+        stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
+        stockOutRecordDto.setType("0");
+        stockOutRecordDto.setWarehouseInfoId(warehouseInfoId);
+        stockOutRecordDto.setRemark(stockInventoryDto.getRemark());
+        Long add = stockOutRecordService.add(stockOutRecordDto);
+        stockInventoryDto.setId(add);
+        return stockOutRecordDto;
+    }
+
+    private Long requireWarehouseInfoId(Long warehouseInfoId) {
+        if (warehouseInfoId == null) {
+//            throw new ServiceException("浠撳簱涓嶈兘涓虹┖");
+            warehouseInfoId = 1L;
+        }
+        return warehouseInfoId;
+    }
+
+    private LambdaQueryWrapper<StockInventory> buildQualifiedInventoryQuery(Long productModelId, String batchNo, Long warehouseInfoId) {
+        LambdaQueryWrapper<StockInventory> wrapper = new QueryWrapper<StockInventory>().lambda()
+                .eq(StockInventory::getProductModelId, productModelId);
+        if (warehouseInfoId == null) {
+            wrapper.isNull(StockInventory::getWarehouseInfoId);
+        } else {
+            wrapper.eq(StockInventory::getWarehouseInfoId, warehouseInfoId);
+        }
+        if (StringUtils.isEmpty(batchNo)) {
+            wrapper.isNull(StockInventory::getBatchNo);
+        } else {
+            wrapper.eq(StockInventory::getBatchNo, batchNo);
+        }
+        return wrapper;
     }
 
     @Override
@@ -149,6 +341,7 @@
         try {
             // 鏌ヨ鎵�鏈夌殑浜у搧骞舵瀯寤烘槧灏勶紝鎻愰珮鏌ユ壘鏁堢巼
             List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectProduct();
+            List<WarehouseInfo> warehouseInfos = warehouseInfoMapper.selectList(null);
             Map<String, SalesLedgerProduct> productMap = new HashMap<>();
             for (SalesLedgerProduct product : salesLedgerProducts) {
                 // 浣跨敤浜у搧绫诲埆鍜岃鏍煎瀷鍙蜂綔涓洪敭
@@ -178,6 +371,14 @@
                         stockInventoryDto.setQualitity(dto.getQualifiedQuantity());
                         stockInventoryDto.setRemark(dto.getRemark());
                         stockInventoryDto.setWarnNum(dto.getWarnNum());
+                        stockInventoryDto.setBatchNo(dto.getBatchNo());
+                        stockInventoryDto.setWarehouseName(dto.getWarehouseName());
+                        Long warehouseInfoId = warehouseInfos.stream()
+                                .filter(warehouseInfo -> dto.getWarehouseName().equals(warehouseInfo.getWarehouseName()))
+                                .map(WarehouseInfo::getId)
+                                .findFirst()
+                                .orElseThrow(() -> new RuntimeException("绯荤粺鏈壘鍒颁粨搴擄細" + dto.getWarehouseName()));
+                        stockInventoryDto.setWarehouseInfoId(warehouseInfoId);
 
                         // 楠岃瘉鍚堟牸鍐荤粨鏁伴噺
                         if (ObjectUtils.isNotEmpty(dto.getQualifiedLockedQuantity())) {
@@ -198,9 +399,11 @@
                     if (dto.getUnQualifiedQuantity() != null && dto.getUnQualifiedQuantity().compareTo(BigDecimal.ZERO) > 0) {
                         StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
                         stockUninventoryDto.setRecordId(0L);
-                        stockUninventoryDto.setRecordType(StockInUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode());
+                        stockUninventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode());
                         stockUninventoryDto.setQualitity(dto.getUnQualifiedQuantity());
                         stockUninventoryDto.setRemark(dto.getRemark());
+                        stockUninventoryDto.setBatchNo(dto.getBatchNo());
+                        stockUninventoryDto.setWarehouseName(dto.getWarehouseName());
 
                         // 楠岃瘉涓嶅悎鏍煎喕缁撴暟閲�
                         if (ObjectUtils.isNotEmpty(dto.getUnQualifiedLockedQuantity())) {
@@ -282,4 +485,24 @@
         stockInventory.setLockedQuantity(stockInventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity()));
         return this.updateById(stockInventory);
     }
+
+    @Override
+    public List<StockInventory> getByModelId(Long modelId) {
+        return stockInventoryMapper.getByModelId(modelId);
+    }
+
+    @Override
+    public List<StockInventoryDto> selectStockInvenrory(Long productModelId) {
+        return stockInventoryMapper.selectStockInvenrory(productModelId);
+    }
+
+    @Override
+    public IPage<StockInventoryDto> pagestockInventoryNoQua(Page page, StockInventoryDto stockInventoryDto) {
+        return stockInventoryMapper.pagestockInventoryNoQua(page, stockInventoryDto);
+    }
+
+    @Override
+    public boolean updateLocked(Long productModelId, String batchNo, boolean b) {
+        return stockInventoryMapper.updateLocked(productModelId, batchNo, b) > 0;
+    }
 }

--
Gitblit v1.9.3