From 3bf81c083883d4861d53380423ee8a44c899b5f6 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期四, 26 三月 2026 18:04:46 +0800
Subject: [PATCH] fix:1.仓储库存单位转换记录和库存关联更新 2.原材料和非原材料的数量区分 3.入库和出库记录删除单位转换库存更新 4.过磅单单位转换更新

---
 src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java |  270 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 241 insertions(+), 29 deletions(-)

diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
index 76dc175..6e28436 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -1,34 +1,39 @@
 package com.ruoyi.stock.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
-import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
+import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
 import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.EnumUtil;
 import com.ruoyi.common.utils.OrderUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.stock.dto.StockInRecordDto;
 import com.ruoyi.stock.dto.StockInventoryDto;
 import com.ruoyi.stock.dto.StockOutRecordDto;
 import com.ruoyi.stock.dto.StockUninventoryDto;
-import com.ruoyi.stock.execl.StockInRecordExportData;
 import com.ruoyi.stock.execl.StockOutRecordExportData;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
 import com.ruoyi.stock.mapper.StockOutRecordMapper;
 import com.ruoyi.stock.mapper.StockUninventoryMapper;
-import com.ruoyi.stock.pojo.StockInRecord;
 import com.ruoyi.stock.pojo.StockInventory;
 import com.ruoyi.stock.pojo.StockOutRecord;
 import com.ruoyi.stock.pojo.StockUninventory;
 import com.ruoyi.stock.service.StockOutRecordService;
-import lombok.AllArgsConstructor;
+import com.ruoyi.stock.word.WeighbridgeDocGenerator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.List;
 
 /**
@@ -40,11 +45,17 @@
  * @since 2026-01-21 05:27:04
  */
 @Service
-@AllArgsConstructor
 public class StockOutRecordServiceImpl extends ServiceImpl<StockOutRecordMapper, StockOutRecord> implements StockOutRecordService {
+    @Autowired
     private StockOutRecordMapper stockOutRecordMapper;
+    @Autowired
     private StockInventoryMapper stockInventoryMapper;
+    @Autowired
     private StockUninventoryMapper stockUninventoryMapper;
+    @Autowired
+    private WeighbridgeDocGenerator weighbridgeDocGenerator;
+    @Autowired
+    private ProductModelMapper productModelMapper;
 
     @Override
     public IPage<StockOutRecordDto> listPage(Page page, StockOutRecordDto stockOutRecordDto) {
@@ -55,8 +66,6 @@
     public int add(StockOutRecordDto stockOutRecordDto) {
         String no = OrderUtils.countTodayByCreateTime(stockOutRecordMapper, "CK");
         stockOutRecordDto.setOutboundBatches(no);
-        StockInRecord stockInRecord = new StockInRecord();
-        BeanUtils.copyProperties(stockOutRecordDto, stockInRecord);
         return stockOutRecordMapper.insert(stockOutRecordDto);
     }
 
@@ -64,7 +73,7 @@
     public int update(Long id, StockOutRecordDto stockOutRecordDto) {
         // 鍒ゆ柇瀵硅薄鏄惁瀛樺湪
         StockOutRecord stockOutRecord = stockOutRecordMapper.selectById(id);
-        if (stockOutRecord == null){
+        if (stockOutRecord == null) {
             throw new BaseException("璇ュ嚭搴撹褰曚笉瀛樺湪,鏃犳硶鏇存柊!!!");
         }
 
@@ -74,31 +83,77 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public int batchDelete(List<Long> ids) {
         for (Long id : ids) {
+            // 1. 鏌ヨ鍑哄簱璁板綍
             StockOutRecord stockOutRecord = stockOutRecordMapper.selectById(id);
-            if (stockOutRecord.getType().equals("0")) {
-                StockInventory stockInventory = stockInventoryMapper.selectOne(new LambdaQueryWrapper<StockInventory>().eq(StockInventory::getProductModelId, stockOutRecord.getProductModelId()));
+            if (stockOutRecord == null) {
+                throw new BaseException("鍑哄簱璁板綍涓嶅瓨鍦紝ID锛�" + id);
+            }
+
+            // 2. 鏌ヨ浜у搧鍨嬪彿锛堢敤浜庡崟浣嶈浆鎹級
+            ProductModel productModel = productModelMapper.selectById(stockOutRecord.getProductModelId());
+            if (productModel == null) {
+                throw new BaseException("浜у搧鍨嬪彿涓嶅瓨鍦紝鏃犳硶鍒犻櫎");
+            }
+
+            // 3. 鑾峰彇鍑哄簱鏁伴噺骞惰繘琛屽崟浣嶈浆鎹�
+            BigDecimal stockOutNum = stockOutRecord.getStockOutNum();
+            String sourceUnit = stockOutRecord.getUnit(); // 鍑哄簱璁板綍涓繚瀛樼殑鍗曚綅
+            String targetUnit = productModel.getUnit();
+
+            // 杞崲鍑哄簱鏁伴噺涓哄簱瀛樺崟浣嶏紙鍒犻櫎鏃堕渶瑕佸姞鍥炲簱瀛橈紝鎵�浠ラ渶瑕佽浆鎹級
+            BigDecimal convertedQuantity = convertQuantityToStockUnit(stockOutNum, sourceUnit, targetUnit);
+
+            // 4. 鏍规嵁鍑哄簱绫诲瀷澶勭悊涓嶅悓鐨勫簱瀛樿〃
+            if ("0".equals(stockOutRecord.getType())) {
+                // 姝e父鍑哄簱锛屾仮澶嶅簱瀛�
+                StockInventory stockInventory = stockInventoryMapper.selectOne(
+                        new LambdaQueryWrapper<StockInventory>()
+                                .eq(StockInventory::getProductModelId, stockOutRecord.getProductModelId())
+                );
+
                 if (stockInventory == null) {
-                    throw new BaseException("搴撳瓨璁板綍涓病鏈夊搴旂殑浜у搧,鏃犳硶鍒犻櫎!!!");
-                }else {
-                    StockInventoryDto stockInRecordDto = new StockInventoryDto();
-                    stockInRecordDto.setProductModelId(stockInventory.getProductModelId());
-                    stockInRecordDto.setQualitity(stockOutRecord.getStockOutNum());
-                    stockInventoryMapper.updateAddStockInventory(stockInRecordDto);
+                    throw new BaseException("搴撳瓨璁板綍涓病鏈夊搴旂殑浜у搧锛屾棤娉曞垹闄�");
                 }
-            }else if (stockOutRecord.getType().equals("1")) {
-                StockUninventory stockUninventory = stockUninventoryMapper.selectOne(new LambdaQueryWrapper<StockUninventory>().eq(StockUninventory::getProductModelId, stockOutRecord.getProductModelId()));
+
+                // 鍒涘缓搴撳瓨鏇存柊DTO
+                StockInventoryDto inventoryDto = new StockInventoryDto();
+                inventoryDto.setProductModelId(stockInventory.getProductModelId());
+                inventoryDto.setQualitity(convertedQuantity);
+
+                // 鍔犲洖搴撳瓨
+                int affectedRows = stockInventoryMapper.updateAddStockInventory(inventoryDto);
+                if (affectedRows == 0) {
+                    throw new BaseException("鎭㈠搴撳瓨澶辫触");
+                }
+
+            } else if ("1".equals(stockOutRecord.getType())) {
+                // 闈炴甯稿嚭搴擄紝鎭㈠闈炴甯稿簱瀛�
+                StockUninventory stockUninventory = stockUninventoryMapper.selectOne(
+                        new LambdaQueryWrapper<StockUninventory>()
+                                .eq(StockUninventory::getProductModelId, stockOutRecord.getProductModelId())
+                );
+
                 if (stockUninventory == null) {
-                    throw new BaseException("搴撳瓨璁板綍涓病鏈夊搴旂殑浜у搧,鏃犳硶鍒犻櫎!!!");
-                }else {
-                    StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
-                    stockUninventoryDto.setProductModelId(stockUninventory.getProductModelId());
-                    stockUninventoryDto.setQualitity(stockOutRecord.getStockOutNum());
-                    stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
+                    throw new BaseException("闈炴甯稿簱瀛樿褰曚腑娌℃湁瀵瑰簲鐨勪骇鍝侊紝鏃犳硶鍒犻櫎");
+                }
+
+                // 鍒涘缓闈炴甯稿簱瀛樻洿鏂癉TO
+                StockUninventoryDto uninventoryDto = new StockUninventoryDto();
+                uninventoryDto.setProductModelId(stockUninventory.getProductModelId());
+                uninventoryDto.setQualitity(convertedQuantity);
+
+                // 鍔犲洖闈炴甯稿簱瀛�
+                int affectedRows = stockUninventoryMapper.updateAddStockUnInventory(uninventoryDto);
+                if (affectedRows == 0) {
+                    throw new BaseException("鎭㈠闈炴甯稿簱瀛樺け璐�");
                 }
             }
         }
+
+        // 5. 鎵归噺鍒犻櫎鍑哄簱璁板綍
         return stockOutRecordMapper.deleteBatchIds(ids);
     }
 
@@ -107,12 +162,169 @@
         List<StockOutRecordExportData> list = stockOutRecordMapper.listStockOutRecordExportData(stockOutRecordDto);
         for (StockOutRecordExportData stockInRecordExportData : list) {
             if (stockInRecordExportData.getType().equals("0")) {
-                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
-            }else {
-                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
+                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockOutQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
+            } else {
+                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockInUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
             }
         }
         ExcelUtil<StockOutRecordExportData> util = new ExcelUtil<>(StockOutRecordExportData.class);
-        util.exportExcel(response,list, "鍑哄簱璁板綍淇℃伅");
+        util.exportExcel(response, list, "鍑哄簱璁板綍淇℃伅");
+    }
+
+    @Override
+    public int editStockOut(StockOutRecordDto stockOutRecordDto) {
+        if (stockOutRecordDto.getId() == null) {
+            throw new BaseException("鍑哄簱璁板綍ID涓嶈兘涓虹┖");
+        }
+
+        // 1. 鏌ヨ鍘熷鍑哄簱璁板綍
+        StockOutRecord originalRecord = stockOutRecordMapper.selectById(stockOutRecordDto.getId());
+        if (originalRecord == null) {
+            throw new BaseException("鍑哄簱璁板綍涓嶅瓨鍦�");
+        }
+
+        // 2. 鏌ヨ浜у搧鍨嬪彿淇℃伅锛堢敤浜庡崟浣嶈浆鎹級
+        ProductModel productModel = productModelMapper.selectById(originalRecord.getProductModelId());
+        if (productModel == null) {
+            throw new BaseException("浜у搧鍨嬪彿涓嶅瓨鍦�");
+        }
+
+        // 3. 鑾峰彇鍘熷鍑哄簱鏁伴噺鍙婂叾鍗曚綅
+        BigDecimal originalOutNum = originalRecord.getStockOutNum();  // 鍘熷璁板綍涓瓨鍌ㄧ殑鏁伴噺锛堝彲鑳芥槸鍚ㄦ垨鍏枻锛�
+        String originalUnit = originalRecord.getUnit();  // 鍘熷璁板綍鐨勫崟浣嶏紙鍚ㄣ�佸叕鏂ょ瓑锛�
+        String stockUnit = productModel.getUnit();  // 搴撳瓨鍗曚綅
+
+        // 灏嗗師濮嬪嚭搴撴暟閲忚浆鎹负搴撳瓨鍗曚綅
+        BigDecimal originalOutNumInStockUnit = convertQuantityToStockUnit(originalOutNum, originalUnit, stockUnit);
+
+        // 4. 鑾峰彇鏂板嚭搴撴暟閲忓強鍏跺崟浣�
+        BigDecimal newOutNum = stockOutRecordDto.getNetWeight();  // 鏂拌緭鍏ョ殑鏁伴噺
+        if (newOutNum == null) {
+            throw new BaseException("鍑哄簱鏁伴噺涓嶈兘涓虹┖");
+        }
+        String newUnit = stockOutRecordDto.getUnit();  // 鏂拌緭鍏ョ殑鍗曚綅
+
+        // 灏嗘柊鍑哄簱鏁伴噺杞崲涓哄簱瀛樺崟浣�
+        BigDecimal newOutNumInStockUnit = convertQuantityToStockUnit(newOutNum, newUnit, stockUnit);
+
+        // 5. 璁$畻搴撳瓨鍙樺寲閲忥紙浣跨敤缁熶竴杞崲鍚庣殑搴撳瓨鍗曚綅鍊硷級
+        // 鍑哄簱鏁伴噺鍙樺寲閲忥紙姝f暟琛ㄧず鍑哄簱鍙樺锛岄渶瑕佸鎵e簱瀛橈紱璐熸暟琛ㄧず鍑哄簱鍙樺皯锛岄渶瑕佸姞鍥炲簱瀛橈級
+        BigDecimal diffQuantity = newOutNumInStockUnit.subtract(originalOutNumInStockUnit);
+        // 杞崲涓哄簱瀛樺彉鍖栭噺锛氬嚭搴撳彉澶氾紙diffQuantity > 0锛夋椂锛屽簱瀛樺噺灏戯紱鍑哄簱鍙樺皯锛坉iffQuantity < 0锛夋椂锛屽簱瀛樺鍔�
+        BigDecimal inventoryChange = diffQuantity.negate();
+
+        // 6. 鏇存柊鍑哄簱璁板綍锛堜繚瀛樼敤鎴疯緭鍏ョ殑鍘熷鏁板�煎拰鍗曚綅锛�
+        stockOutRecordDto.setStockOutNum(stockOutRecordDto.getNetWeight());  // 淇濆瓨鐢ㄦ埛杈撳叆鐨勫��
+        stockOutRecordDto.setUnit(stockOutRecordDto.getUnit());  // 淇濆瓨鐢ㄦ埛杈撳叆鐨勫崟浣�
+
+        // 7. 鐢熸垚纾呭崟
+        StockInRecordDto stockInRecordDto = new StockInRecordDto();
+        BeanUtils.copyProperties(stockOutRecordDto, stockInRecordDto);
+        stockInRecordDto.setStockInNum(stockOutRecordDto.getStockOutNum());
+        String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto);
+        stockOutRecordDto.setWeighbridgeDocPath(absoluteDocPath);
+        int updateResult = stockOutRecordMapper.updateById(stockOutRecordDto);
+
+        // 8. 鏇存柊搴撳瓨锛堜粎鍦ㄦ暟閲忓彂鐢熷彉鍖栨椂锛�
+        if (inventoryChange.compareTo(BigDecimal.ZERO) != 0) {
+            updateInventoryForStockOut(stockOutRecordDto.getProductId(), inventoryChange);
+        }
+
+        return updateResult;
+    }
+
+    /**
+     * 灏嗘暟閲忚浆鎹负搴撳瓨鍗曚綅
+     *
+     * @param quantity   鍘熷鏁伴噺
+     * @param sourceUnit 鍘熷鍗曚綅
+     * @param targetUnit 鐩爣鍗曚綅锛堝簱瀛樺崟浣嶏級
+     * @return 杞崲鍚庣殑鏁伴噺
+     */
+    private BigDecimal convertQuantityToStockUnit(BigDecimal quantity, String sourceUnit, String targetUnit) {
+        if (quantity == null) {
+            throw new BaseException("鏁伴噺涓嶈兘涓虹┖");
+        }
+
+        // 濡傛灉婧愬崟浣嶄负绌猴紝鐩存帴杩斿洖鍘熷��
+        if (sourceUnit == null || sourceUnit.isEmpty()) {
+            return quantity;
+        }
+
+        // 濡傛灉婧愬崟浣嶅拰鐩爣鍗曚綅鐩稿悓锛岀洿鎺ヨ繑鍥�
+        if (sourceUnit.equals(targetUnit)) {
+            return quantity;
+        }
+
+        // 鍗曚綅杞崲
+        if ("鍚�".equals(targetUnit)) {
+            // 鐩爣鍗曚綅鏄惃锛岄渶瑕佸皢婧愬崟浣嶈浆鎹负鍚�
+            if ("鍏枻".equals(sourceUnit)) {
+                // 鍏枻杞惃锛氶櫎浠�1000
+                return quantity.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP);
+            } else if ("鍏�".equals(sourceUnit)) {
+                // 鍏嬭浆鍚細闄や互1000000
+                return quantity.divide(BigDecimal.valueOf(1000000), 2, RoundingMode.HALF_UP);
+            }
+        } else if ("鍏枻".equals(targetUnit)) {
+            // 鐩爣鍗曚綅鏄叕鏂�
+            if ("鍚�".equals(sourceUnit)) {
+                // 鍚ㄨ浆鍏枻锛氫箻浠�1000
+                return quantity.multiply(BigDecimal.valueOf(1000));
+            } else if ("鍏�".equals(sourceUnit)) {
+                // 鍏嬭浆鍏枻锛氶櫎浠�1000
+                return quantity.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP);
+            }
+        } else if ("鍏�".equals(targetUnit)) {
+            // 鐩爣鍗曚綅鏄厠
+            if ("鍚�".equals(sourceUnit)) {
+                // 鍚ㄨ浆鍏嬶細涔樹互1000000
+                return quantity.multiply(BigDecimal.valueOf(1000000));
+            } else if ("鍏枻".equals(sourceUnit)) {
+                // 鍏枻杞厠锛氫箻浠�1000
+                return quantity.multiply(BigDecimal.valueOf(1000));
+            }
+        }
+
+        // 鏃犳硶杞崲鏃惰繑鍥炲師鍊�
+        return quantity;
+    }
+
+    /**
+     * 鏇存柊搴撳瓨锛堝嚭搴撳満鏅級
+     *
+     * @param productId       浜у搧ID
+     * @param inventoryChange 搴撳瓨鍙樺寲閲忥紙姝f暟涓哄鍔犲簱瀛橈紝璐熸暟涓哄噺灏戝簱瀛橈級
+     */
+    private void updateInventoryForStockOut(Long productId, BigDecimal inventoryChange) {
+        // 鏌ヨ褰撳墠搴撳瓨
+        StockInventory stockInventory = stockInventoryMapper.selectOne(
+                new QueryWrapper<StockInventory>().lambda()
+                        .eq(StockInventory::getProductId, productId)
+        );
+
+        if (stockInventory == null) {
+            throw new BaseException("搴撳瓨璁板綍涓嶅瓨鍦�");
+        }
+
+        // 鍒涘缓搴撳瓨鏇存柊DTO
+        StockInventoryDto inventoryDto = new StockInventoryDto();
+        BeanUtils.copyProperties(stockInventory, inventoryDto);
+        inventoryDto.setQualitity(inventoryChange.abs());
+
+        // 鏍规嵁搴撳瓨鍙樺寲閲忚皟鐢ㄤ笉鍚岀殑鏇存柊鏂规硶
+        if (inventoryChange.compareTo(BigDecimal.ZERO) > 0) {
+            // 搴撳瓨澧炲姞锛堝嚭搴撴暟閲忓彉灏戯紝闇�瑕佸姞鍥炲簱瀛橈級
+            int affectedRows = stockInventoryMapper.updateAddStockInventory(inventoryDto);
+            if (affectedRows == 0) {
+                throw new BaseException("鏇存柊搴撳瓨澶辫触");
+            }
+        } else {
+            // 搴撳瓨鍑忓皯锛堝嚭搴撴暟閲忓彉澶氾紝闇�瑕佸鎵e簱瀛橈級
+            int affectedRows = stockInventoryMapper.updateSubtractStockInventory(inventoryDto);
+            if (affectedRows == 0) {
+                throw new BaseException("搴撳瓨涓嶈冻锛屾棤娉曟墸鍑�");
+            }
+        }
     }
 }

--
Gitblit v1.9.3