Selaa lähdekoodia

到货质检改为统一库存操作

yzc 1 vuosi sitten
vanhempi
commit
d804e90892

+ 65 - 36
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/service/quality/impl/QualityInfoServiceImpl.java

@@ -4,7 +4,6 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson2.JSONObject;
-import com.alibaba.fastjson2.JSONWriter;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -32,8 +31,10 @@ import com.fjhx.victoriatourist.service.quality.QualityDetailsService;
 import com.fjhx.victoriatourist.service.quality.QualityInfoService;
 import com.fjhx.wms.entity.arrival.po.ArrivalStockRecords;
 import com.fjhx.wms.entity.arrival.po.ArrivalStockRecordsDetails;
+import com.fjhx.wms.entity.stock.bo.InOutBo;
+import com.fjhx.wms.entity.stock.emums.InOutType;
 import com.fjhx.wms.entity.stock.emums.JournalType;
-import com.fjhx.wms.entity.stock.po.Stock;
+import com.fjhx.wms.entity.stock.emums.StockType;
 import com.fjhx.wms.entity.stock.po.StockJournal;
 import com.fjhx.wms.entity.stock.po.StockJournalDetails;
 import com.fjhx.wms.entity.stock.po.StockWait;
@@ -114,13 +115,13 @@ public class QualityInfoServiceImpl extends ServiceImpl<QualityInfoMapper, Quali
             //根据采购单号 供应商
             List<Long> suppIds = supplierInfoService.listObject(SupplierInfo::getId, q -> q.like(SupplierInfo::getName, dto.getKeyword()));
             wrapper.and(q -> q
-                    .like("json_unquote(p.victoriatourist_json -> '$.contractCode')", dto.getKeyword())
-                    .or().in("p.supply_id", suppIds)
-                    .or().like("dg.code", dto.getKeyword())
+                            .like("json_unquote(p.victoriatourist_json -> '$.contractCode')", dto.getKeyword())
+                            .or().in("p.supply_id", suppIds)
+                            .or().like("dg.code", dto.getKeyword())
 //                    .or().like("pi.custom_code", dto.getKeyword())
 //                    .or().like("pi.name", dto.getKeyword())
-                    //exists
-                    .or().inSql("asr.id","SELECT asrd.arrival_stock_records_id FROM bytesailing_wms.arrival_stock_records_details asrd LEFT JOIN bytesailing_item.product_info pi ON asrd.product_info_id = pi.id  AND pi.del_flag = 0 WHERE asrd.del_flag = 0 and ( pi.`name` LIKE CONCAT( '%', '"+dto.getKeyword()+"', '%' ) OR pi.custom_code LIKE CONCAT( '%', '"+dto.getKeyword()+"', '%' ))")
+                            //exists
+                            .or().inSql("asr.id", "SELECT asrd.arrival_stock_records_id FROM bytesailing_wms.arrival_stock_records_details asrd LEFT JOIN bytesailing_item.product_info pi ON asrd.product_info_id = pi.id  AND pi.del_flag = 0 WHERE asrd.del_flag = 0 and ( pi.`name` LIKE CONCAT( '%', '" + dto.getKeyword() + "', '%' ) OR pi.custom_code LIKE CONCAT( '%', '" + dto.getKeyword() + "', '%' ))")
             );
         }
         wrapper.orderByDesc("asr", QualityInfo::getCreateTime);
@@ -277,8 +278,8 @@ public class QualityInfoServiceImpl extends ServiceImpl<QualityInfoMapper, Quali
                 List<Long> ids = logisticsInfosList.stream().map(LogisticsInfos::getId).collect(Collectors.toList());
                 AbnormalInfo oldAbnormalInfo = abnormalInfoService.getOne(q -> q
                         .in(AbnormalInfo::getLogisticsInfosId, ids)
-                        .eq(AbnormalInfo::getType,10)
-                        .eq(AbnormalInfo::getPurchaseId,purchase.getId())
+                        .eq(AbnormalInfo::getType, 10)
+                        .eq(AbnormalInfo::getPurchaseId, purchase.getId())
                 );
                 if (ObjectUtil.isNotEmpty(oldAbnormalInfo)) {
                     abnormalInfo = oldAbnormalInfo;
@@ -318,39 +319,59 @@ public class QualityInfoServiceImpl extends ServiceImpl<QualityInfoMapper, Quali
         stockJournalService.save(stockJournal);
         List<StockJournalDetails> stockJournalDetailsList = new ArrayList<>();
 
-        List<Stock> stockList = new ArrayList<>();
-        for (QualityDetails qualityDetails : qualityDetailsList) {
-            Stock stock = stockService.getOne(q -> q.eq(Stock::getProductId, qualityDetails.getProductInfoId()).eq(Stock::getWarehouseId, qualityInfoDto.getWarehouseId()));
-            if (ObjectUtil.isEmpty(stock)) {
-                stock = new Stock();
-                stock.setProductId(qualityDetails.getProductInfoId());
-                stock.setWarehouseId(arrivalStockRecords.getWarehouseId());
-                stock.setQuantity(BigDecimal.ZERO);
-            }
-            String victoriatouristJson = stock.getVictoriatouristJson();
-            JSONObject json = ObjectUtil.isEmpty(victoriatouristJson) ? new JSONObject() : JSONObject.parseObject(victoriatouristJson);
-
-            BigDecimal defectiveQuantity = json.getBigDecimal("defectiveQuantity");//次品库存
-            defectiveQuantity = ObjectUtil.isEmpty(defectiveQuantity) ? BigDecimal.ZERO : defectiveQuantity;
+        List<InOutBo> qualifiedInOutList = new ArrayList<>();
+        List<InOutBo> frozenQuantityInOutList = new ArrayList<>();
+        List<InOutBo> defectiveQuantityInOutList = new ArrayList<>();
 
-            BigDecimal frozenQuantity = json.getBigDecimal("frozenQuantity");//冻结库存
-            frozenQuantity = ObjectUtil.isEmpty(frozenQuantity) ? BigDecimal.ZERO : frozenQuantity;
+//        List<Stock> stockList = new ArrayList<>();
+        for (QualityDetails qualityDetails : qualityDetailsList) {
+//            Stock stock = stockService.getOne(q -> q.eq(Stock::getProductId, qualityDetails.getProductInfoId()).eq(Stock::getWarehouseId, qualityInfoDto.getWarehouseId()));
+//            if (ObjectUtil.isEmpty(stock)) {
+//                stock = new Stock();
+//                stock.setProductId(qualityDetails.getProductInfoId());
+//                stock.setWarehouseId(arrivalStockRecords.getWarehouseId());
+//                stock.setQuantity(BigDecimal.ZERO);
+//            }
+//            String victoriatouristJson = stock.getVictoriatouristJson();
+//            JSONObject json = ObjectUtil.isEmpty(victoriatouristJson) ? new JSONObject() : JSONObject.parseObject(victoriatouristJson);
+
+//            BigDecimal defectiveQuantity = json.getBigDecimal("defectiveQuantity");//次品库存
+//            defectiveQuantity = ObjectUtil.isEmpty(defectiveQuantity) ? BigDecimal.ZERO : defectiveQuantity;
+
+//            BigDecimal frozenQuantity = json.getBigDecimal("frozenQuantity");//冻结库存
+//            frozenQuantity = ObjectUtil.isEmpty(frozenQuantity) ? BigDecimal.ZERO : frozenQuantity;
 
             //质检合格增加可用库存
-            stock.setQuantity(stock.getQuantity().add(qualityDetails.getQualifiedQuantity()));
+            InOutBo inOutBo1 = new InOutBo();
+            inOutBo1.setProductId(qualityDetails.getProductInfoId());
+            inOutBo1.setQuantity(qualityDetails.getQualifiedQuantity());
+            qualifiedInOutList.add(inOutBo1);
+
+//            stock.setQuantity(stock.getQuantity().add(qualityDetails.getQualifiedQuantity()));
             //质检不合格增加次品库存
-            defectiveQuantity = defectiveQuantity.add(qualityDetails.getDisqualificationQuantity());
-            json.put("defectiveQuantity", defectiveQuantity);
+            InOutBo inOutBo2 = new InOutBo();
+            inOutBo2.setProductId(qualityDetails.getProductInfoId());
+            inOutBo2.setQuantity(qualityDetails.getDisqualificationQuantity());
+            defectiveQuantityInOutList.add(inOutBo2);
+
+//            defectiveQuantity = defectiveQuantity.add(qualityDetails.getDisqualificationQuantity());
+//            json.put("defectiveQuantity", defectiveQuantity);
+
             //减少冻结库存
             BigDecimal count = qualityDetails.getQualifiedQuantity().add(qualityDetails.getDisqualificationQuantity());
-            frozenQuantity = frozenQuantity.subtract(count);
-            if (frozenQuantity.compareTo(BigDecimal.ZERO) < 0) {
-                throw new ServiceException("冻结库存不足");
-            }
-            json.put("frozenQuantity", frozenQuantity);
+            InOutBo inOutBo3 = new InOutBo();
+            inOutBo3.setProductId(qualityDetails.getProductInfoId());
+            inOutBo3.setQuantity(count);
+            frozenQuantityInOutList.add(inOutBo3);
+
+//            frozenQuantity = frozenQuantity.subtract(count);
+//            if (frozenQuantity.compareTo(BigDecimal.ZERO) < 0) {
+//                throw new ServiceException("冻结库存不足");
+//            }
+//            json.put("frozenQuantity", frozenQuantity);
 
-            stock.setVictoriatouristJson(JSONObject.toJSONString(json, JSONWriter.Feature.WriteLongAsString));
-            stockList.add(stock);
+//            stock.setVictoriatouristJson(JSONObject.toJSONString(json, JSONWriter.Feature.WriteLongAsString));
+//            stockList.add(stock);
 
             StockJournalDetails stockJournalDetails = new StockJournalDetails();
             stockJournalDetails.setStockJournalId(stockJournal.getId());
@@ -358,7 +379,15 @@ public class QualityInfoServiceImpl extends ServiceImpl<QualityInfoMapper, Quali
             stockJournalDetails.setQuantity(qualityDetails.getQualifiedQuantity().add(qualityDetails.getDisqualificationQuantity()));
             stockJournalDetailsList.add(stockJournalDetails);
         }
-        stockService.saveOrUpdateBatch(stockList);
+//        stockService.saveOrUpdateBatch(stockList);
+
+        //增加可用库存
+        stockService.changeStockComm(qualifiedInOutList, StockType.QUANTITY, InOutType.IN, qualityInfoDto.getWarehouseId());
+        //增加次品库存
+        stockService.changeStockComm(defectiveQuantityInOutList, StockType.DEFECTIVE_QUANTITY, InOutType.IN, qualityInfoDto.getWarehouseId());
+        //减少冻结库存
+        stockService.changeStockComm(frozenQuantityInOutList, StockType.FROZEN_QUANTITY, InOutType.OUT, qualityInfoDto.getWarehouseId());
+
         stockJournalDetailsService.saveBatch(stockJournalDetailsList);
     }
 

+ 5 - 0
hx-wms/src/main/java/com/fjhx/wms/entity/stock/emums/InOutType.java

@@ -11,4 +11,9 @@ public enum InOutType {
      * 出库
      */
     OUT,
+
+    /**
+     * 修改
+     */
+    SET
 }

+ 19 - 0
hx-wms/src/main/java/com/fjhx/wms/entity/stock/emums/StockType.java

@@ -0,0 +1,19 @@
+package com.fjhx.wms.entity.stock.emums;
+
+public enum StockType {
+
+    /**
+     * 普通库存
+     */
+    QUANTITY,
+
+    /**
+     * 冻结库存
+     */
+    FROZEN_QUANTITY,
+
+    /**
+     * 次品库存
+     */
+    DEFECTIVE_QUANTITY
+}

+ 7 - 0
hx-wms/src/main/java/com/fjhx/wms/service/stock/StockService.java

@@ -5,7 +5,9 @@ import com.fjhx.item.entity.product.IssueImportExcelBo;
 import com.fjhx.wms.entity.stock.bo.InOutBo;
 import com.fjhx.wms.entity.stock.dto.StockDto;
 import com.fjhx.wms.entity.stock.dto.StockSelectDto;
+import com.fjhx.wms.entity.stock.emums.InOutType;
 import com.fjhx.wms.entity.stock.emums.JournalType;
+import com.fjhx.wms.entity.stock.emums.StockType;
 import com.fjhx.wms.entity.stock.po.Stock;
 import com.fjhx.wms.entity.stock.po.StockAnalysis;
 import com.fjhx.wms.entity.stock.po.StockJournalDetails;
@@ -109,4 +111,9 @@ public interface StockService extends BaseService<Stock> {
     void exportExcel(StockSelectDto dto, HttpServletResponse httpServletResponse);
 
     List<IssueImportExcelBo> issueExcelImport(MultipartFile file, Long warehouseId);
+
+    /**
+     * 库存操作公共方法
+     */
+    void changeStockComm(List<? extends InOutBo> inOutList, StockType stockType, InOutType inOutType, Long warehouseId);
 }

+ 288 - 154
hx-wms/src/main/java/com/fjhx/wms/service/stock/impl/StockServiceImpl.java

@@ -1,7 +1,7 @@
 package com.fjhx.wms.service.stock.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
 import com.alibaba.fastjson2.JSONWriter;
@@ -29,6 +29,7 @@ import com.fjhx.wms.entity.stock.dto.StockJournalDetailsDto;
 import com.fjhx.wms.entity.stock.dto.StockSelectDto;
 import com.fjhx.wms.entity.stock.emums.InOutType;
 import com.fjhx.wms.entity.stock.emums.JournalType;
+import com.fjhx.wms.entity.stock.emums.StockType;
 import com.fjhx.wms.entity.stock.po.Stock;
 import com.fjhx.wms.entity.stock.po.StockAnalysis;
 import com.fjhx.wms.entity.stock.po.StockJournal;
@@ -533,108 +534,22 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
      */
     @Override
     public synchronized List<StockJournalDetails> ModifyInventory(Long stockJournalId, int type, List<Stock> list, Long warehouseId) {
-        List<Stock> data = new ArrayList<>();
+        InOutType inOutType = type == 1 ? InOutType.IN : type == 2 ? InOutType.OUT : type == 3 ? InOutType.IN : type == 4 ? InOutType.OUT : null;
+        if (inOutType == null) {
+            throw new ServiceException("未知出入库类型!");
+        }
+        StockType stockType = type == 1 ? StockType.QUANTITY : type == 2 ? StockType.QUANTITY : type == 3 ? StockType.FROZEN_QUANTITY : type == 4 ? StockType.DEFECTIVE_QUANTITY : null;
+        if (inOutType == null) {
+            throw new ServiceException("未知库存类型!");
+        }
 
-        //获取现有库存
-        List<Long> productIds = list.stream().map(Stock::getProductId).collect(Collectors.toList());
-        List<Stock> stockList = list(q -> q.in(Stock::getProductId, productIds).eq(Stock::getWarehouseId, warehouseId));
-        Map<Long, Stock> stockMap = stockList.stream().collect(Collectors.groupingBy(Stock::getProductId,
-                Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
+        List<InOutBo> inOutBoList = BeanUtil.copyToList(list, InOutBo.class);
+        //操作库存
+        changeStockComm(inOutBoList, stockType, inOutType, warehouseId);
 
+        //生成流水明细
         List<StockJournalDetails> stockJournalDetailsList = new ArrayList<>();
         for (Stock stock : list) {
-            Stock oldStocks = stockMap.get(stock.getProductId());
-            //如果库存不存在 就创建一条空库存
-            if (ObjectUtil.isEmpty(oldStocks)) {
-                oldStocks = new Stock();
-                oldStocks.setProductId(stock.getProductId());
-                oldStocks.setWarehouseId(warehouseId);
-                oldStocks.setQuantity(BigDecimal.ZERO);
-                this.save(oldStocks);
-            }
-
-            if (type == 1) {
-                //入库库存相加
-                BigDecimal quantity = oldStocks.getQuantity().add(stock.getQuantity());
-                oldStocks.setQuantity(quantity);
-            } else if (type == 2) {
-                //出库库存相减
-                ProductInfo productInfo = productInfoService.getById(stock.getProductId());
-                if (productInfo == null) {
-                    throw new ServiceException("产品id:" + stock.getProductId() + "不存在");
-                }
-                BigDecimal quantity = oldStocks.getQuantity().subtract(stock.getQuantity());
-                if (quantity.compareTo(BigDecimal.ZERO) < 0) {
-                    //库存不足判断是否是组合
-                    String victoriatouristJson = productInfo.getVictoriatouristJson();
-                    JSONObject json = ObjectUtil.isNotEmpty(victoriatouristJson) ? JSONObject.parseObject(victoriatouristJson) : new JSONObject();
-                    Integer combination = json.getInteger("combination");
-                    if (combination != 1) {
-                        //不是组合直接报错
-                        throw new ServiceException("以下商品库存不足,无法出库:" + productInfo.getName());
-                    }
-                    //计算差多少 自动组合差的那部分
-                    BigDecimal differenceQuantity = stock.getQuantity().subtract(oldStocks.getQuantity());
-                    //获取产品组合信息
-                    JSONArray productCombinationListArr = json.getJSONArray("productCombinationList");
-                    Assert.notEmpty(productCombinationListArr, "产品组合信息为空");
-                    List<JSONObject> productCombinationList = productCombinationListArr.toJavaList(JSONObject.class);
-                    List<Long> linkProductIds = productCombinationList.stream().map(item -> item.getLong("linkProductId")).collect(Collectors.toList());
-                    Map<Long, Stock> combinationStockMap = this.mapKEntity(Stock::getProductId, q -> q
-                            .eq(Stock::getWarehouseId, warehouseId)
-                            .in(Stock::getProductId, linkProductIds));
-                    //检查是否满足自动组合条件
-                    for (JSONObject jsonObject : productCombinationList) {
-                        Stock stockInfo = combinationStockMap.get(jsonObject.getLong("linkProductId"));
-                        BigDecimal requiredQuantity = jsonObject.getBigDecimal("linkQuantity").multiply(differenceQuantity);
-                        if (ObjectUtil.isEmpty(stockInfo) || stockInfo.getQuantity().compareTo(requiredQuantity) < 0) {
-                            throw new ServiceException("该组合产品,子产品库存不足无法自动组合出库:" + productInfo.getName());
-                        }
-                    }
-                    //创建组合信息
-                    wmsService.autoCombination(productInfo.getId(), differenceQuantity, warehouseId);
-
-                    //组合完成 再次尝试出库
-                    oldStocks = this.getOne(q -> q.eq(Stock::getProductId, productInfo.getId()).eq(Stock::getWarehouseId, warehouseId));
-                    quantity = oldStocks.getQuantity().subtract(stock.getQuantity());
-                    oldStocks.setQuantity(quantity);
-                    if (quantity.compareTo(BigDecimal.ZERO) < 0) {
-                        throw new ServiceException("以下商品库存不足,无法出库:" + productInfo.getName());
-                    }
-                }
-                oldStocks.setQuantity(quantity);
-            } else if (type == 3) {
-                //维多利亚待入库增加冻结库存
-                String victoriatouristJson = oldStocks.getVictoriatouristJson();
-                JSONObject json = ObjectUtil.isEmpty(victoriatouristJson) ? new JSONObject() : JSONObject.parseObject(victoriatouristJson);
-                BigDecimal frozenQuantity = json.getBigDecimal("frozenQuantity");
-                frozenQuantity = frozenQuantity == null ? BigDecimal.ZERO : frozenQuantity;
-                frozenQuantity = frozenQuantity.add(stock.getQuantity());
-                json.put("frozenQuantity", frozenQuantity);
-                oldStocks.setVictoriatouristJson(JSONObject.toJSONString(json, JSONWriter.Feature.WriteLongAsString));
-            } else if (type == 4) {
-                //维多利亚待出库操作次品库存
-                String victoriatouristJson = oldStocks.getVictoriatouristJson();
-                JSONObject json = ObjectUtil.isEmpty(victoriatouristJson) ? new JSONObject() : JSONObject.parseObject(victoriatouristJson);
-                BigDecimal defectiveQuantity = json.getBigDecimal("defectiveQuantity");
-                defectiveQuantity = defectiveQuantity == null ? BigDecimal.ZERO : defectiveQuantity;
-                defectiveQuantity = defectiveQuantity.subtract(stock.getQuantity());
-                if (defectiveQuantity.compareTo(BigDecimal.ZERO) < 0) {
-                    ProductInfo productInfo = productInfoService.getById(stock.getProductId());
-                    if (productInfo == null) {
-                        throw new ServiceException("产品id:" + stock.getProductId() + "不存在");
-                    }
-                    throw new ServiceException("以下商品次品库存不足,无法出库:" + productInfo.getName());
-                }
-                json.put("defectiveQuantity", defectiveQuantity);
-                oldStocks.setVictoriatouristJson(JSONObject.toJSONString(json, JSONWriter.Feature.WriteLongAsString));
-            } else if (type == 5) {
-                //直接修改库存数量
-                oldStocks.setQuantity(stock.getQuantity());
-            } else {
-                throw new ServiceException("未知库存操作类型");
-            }
-            data.add(oldStocks);
             //创建出入库明细 忽略操作数量为0的记录 避免出现出入库记录为0的条目
             if (BigDecimal.ZERO.compareTo(stock.getQuantity()) != 0) {
                 StockJournalDetails stockJournalDetails = new StockJournalDetailsDto();
@@ -644,11 +559,126 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
                 stockJournalDetailsList.add(stockJournalDetails);
             }
         }
-        //操作库存
-        saveOrUpdateBatch(data);
-
-        //返回库存操作明细列表
         return stockJournalDetailsList;
+//
+//
+//
+//        List<Stock> data = new ArrayList<>();
+//
+//        //获取现有库存
+//        List<Long> productIds = list.stream().map(Stock::getProductId).collect(Collectors.toList());
+//        List<Stock> stockList = list(q -> q.in(Stock::getProductId, productIds).eq(Stock::getWarehouseId, warehouseId));
+//        Map<Long, Stock> stockMap = stockList.stream().collect(Collectors.groupingBy(Stock::getProductId,
+//                Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
+//
+//        List<StockJournalDetails> stockJournalDetailsList = new ArrayList<>();
+//        for (Stock stock : list) {
+//            Stock oldStocks = stockMap.get(stock.getProductId());
+//            //如果库存不存在 就创建一条空库存
+//            if (ObjectUtil.isEmpty(oldStocks)) {
+//                oldStocks = new Stock();
+//                oldStocks.setProductId(stock.getProductId());
+//                oldStocks.setWarehouseId(warehouseId);
+//                oldStocks.setQuantity(BigDecimal.ZERO);
+//                this.save(oldStocks);
+//            }
+//
+//            if (type == 1) {
+//                //入库库存相加
+//                BigDecimal quantity = oldStocks.getQuantity().add(stock.getQuantity());
+//                oldStocks.setQuantity(quantity);
+//            } else if (type == 2) {
+//                //出库库存相减
+//                ProductInfo productInfo = productInfoService.getById(stock.getProductId());
+//                if (productInfo == null) {
+//                    throw new ServiceException("产品id:" + stock.getProductId() + "不存在");
+//                }
+//                BigDecimal quantity = oldStocks.getQuantity().subtract(stock.getQuantity());
+//                if (quantity.compareTo(BigDecimal.ZERO) < 0) {
+//                    //库存不足判断是否是组合
+//                    String victoriatouristJson = productInfo.getVictoriatouristJson();
+//                    JSONObject json = ObjectUtil.isNotEmpty(victoriatouristJson) ? JSONObject.parseObject(victoriatouristJson) : new JSONObject();
+//                    Integer combination = json.getInteger("combination");
+//                    if (combination != 1) {
+//                        //不是组合直接报错
+//                        throw new ServiceException("以下商品库存不足,无法出库:" + productInfo.getName());
+//                    }
+//                    //计算差多少 自动组合差的那部分
+//                    BigDecimal differenceQuantity = stock.getQuantity().subtract(oldStocks.getQuantity());
+//                    //获取产品组合信息
+//                    JSONArray productCombinationListArr = json.getJSONArray("productCombinationList");
+//                    Assert.notEmpty(productCombinationListArr, "产品组合信息为空");
+//                    List<JSONObject> productCombinationList = productCombinationListArr.toJavaList(JSONObject.class);
+//                    List<Long> linkProductIds = productCombinationList.stream().map(item -> item.getLong("linkProductId")).collect(Collectors.toList());
+//                    Map<Long, Stock> combinationStockMap = this.mapKEntity(Stock::getProductId, q -> q
+//                            .eq(Stock::getWarehouseId, warehouseId)
+//                            .in(Stock::getProductId, linkProductIds));
+//                    //检查是否满足自动组合条件
+//                    for (JSONObject jsonObject : productCombinationList) {
+//                        Stock stockInfo = combinationStockMap.get(jsonObject.getLong("linkProductId"));
+//                        BigDecimal requiredQuantity = jsonObject.getBigDecimal("linkQuantity").multiply(differenceQuantity);
+//                        if (ObjectUtil.isEmpty(stockInfo) || stockInfo.getQuantity().compareTo(requiredQuantity) < 0) {
+//                            throw new ServiceException("该组合产品,子产品库存不足无法自动组合出库:" + productInfo.getName());
+//                        }
+//                    }
+//                    //创建组合信息
+//                    wmsService.autoCombination(productInfo.getId(), differenceQuantity, warehouseId);
+//
+//                    //组合完成 再次尝试出库
+//                    oldStocks = this.getOne(q -> q.eq(Stock::getProductId, productInfo.getId()).eq(Stock::getWarehouseId, warehouseId));
+//                    quantity = oldStocks.getQuantity().subtract(stock.getQuantity());
+//                    oldStocks.setQuantity(quantity);
+//                    if (quantity.compareTo(BigDecimal.ZERO) < 0) {
+//                        throw new ServiceException("以下商品库存不足,无法出库:" + productInfo.getName());
+//                    }
+//                }
+//                oldStocks.setQuantity(quantity);
+//            } else if (type == 3) {
+//                //维多利亚待入库增加冻结库存
+//                String victoriatouristJson = oldStocks.getVictoriatouristJson();
+//                JSONObject json = ObjectUtil.isEmpty(victoriatouristJson) ? new JSONObject() : JSONObject.parseObject(victoriatouristJson);
+//                BigDecimal frozenQuantity = json.getBigDecimal("frozenQuantity");
+//                frozenQuantity = frozenQuantity == null ? BigDecimal.ZERO : frozenQuantity;
+//                frozenQuantity = frozenQuantity.add(stock.getQuantity());
+//                json.put("frozenQuantity", frozenQuantity);
+//                oldStocks.setVictoriatouristJson(JSONObject.toJSONString(json, JSONWriter.Feature.WriteLongAsString));
+//            } else if (type == 4) {
+//                //维多利亚待出库操作次品库存
+//                String victoriatouristJson = oldStocks.getVictoriatouristJson();
+//                JSONObject json = ObjectUtil.isEmpty(victoriatouristJson) ? new JSONObject() : JSONObject.parseObject(victoriatouristJson);
+//                BigDecimal defectiveQuantity = json.getBigDecimal("defectiveQuantity");
+//                defectiveQuantity = defectiveQuantity == null ? BigDecimal.ZERO : defectiveQuantity;
+//                defectiveQuantity = defectiveQuantity.subtract(stock.getQuantity());
+//                if (defectiveQuantity.compareTo(BigDecimal.ZERO) < 0) {
+//                    ProductInfo productInfo = productInfoService.getById(stock.getProductId());
+//                    if (productInfo == null) {
+//                        throw new ServiceException("产品id:" + stock.getProductId() + "不存在");
+//                    }
+//                    throw new ServiceException("以下商品次品库存不足,无法出库:" + productInfo.getName());
+//                }
+//                json.put("defectiveQuantity", defectiveQuantity);
+//                oldStocks.setVictoriatouristJson(JSONObject.toJSONString(json, JSONWriter.Feature.WriteLongAsString));
+//            } else if (type == 5) {
+//                //直接修改库存数量
+//                oldStocks.setQuantity(stock.getQuantity());
+//            } else {
+//                throw new ServiceException("未知库存操作类型");
+//            }
+//            data.add(oldStocks);
+//            //创建出入库明细 忽略操作数量为0的记录 避免出现出入库记录为0的条目
+//            if (BigDecimal.ZERO.compareTo(stock.getQuantity()) != 0) {
+//                StockJournalDetails stockJournalDetails = new StockJournalDetailsDto();
+//                stockJournalDetails.setStockJournalId(stockJournalId);
+//                stockJournalDetails.setProductId(stock.getProductId());
+//                stockJournalDetails.setQuantity(stock.getQuantity().abs());
+//                stockJournalDetailsList.add(stockJournalDetails);
+//            }
+//        }
+//        //操作库存
+//        saveOrUpdateBatch(data);
+//
+//        //返回库存操作明细列表
+//        return stockJournalDetailsList;
     }
 
     @Override
@@ -744,7 +774,8 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
     public void inOut(List<? extends InOutBo> list, Long warehouseId, JournalType journalType, Long businessId) {
 
         // 改变库存数量
-        changeStock(list, warehouseId, journalType);
+//        changeStock(list, warehouseId, journalType);
+        changeStockComm(list, StockType.QUANTITY, journalType.getType(), warehouseId);
 
         // 增加出入库记录
         Long journalId = addJournal(warehouseId, journalType, businessId);
@@ -754,56 +785,56 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
 
     }
 
-    /**
-     * 改变库存数量
-     */
-    private synchronized void changeStock(List<? extends InOutBo> list, Long warehouseId, JournalType journalType) {
-
-        Map<Long, BigDecimal> map = list.stream().collect(Collectors.toMap(
-                InOutBo::getProductId,
-                InOutBo::getQuantity,
-                BigDecimal::add
-        ));
-
-        if (journalType.getType().equals(InOutType.IN)) {
-            map.forEach((productId, quantity) -> {
-                Stock stock = getOne(q -> q.eq(Stock::getProductId, productId).eq(Stock::getWarehouseId, warehouseId));
-
-                if (stock == null) {
-                    stock = new Stock();
-                    stock.setWarehouseId(warehouseId);
-                    stock.setProductId(productId);
-                    stock.setQuantity(quantity);
-                    save(stock);
-                } else {
-                    Long stockId = stock.getId();
-                    update(q -> q
-                            .eq(BaseIdPo::getId, stockId)
-                            .setSql("quantity = quantity + " + quantity)
-                    );
-                }
-            });
-        } else {
-            map.forEach((productId, quantity) -> {
-                boolean update = update(q -> q
-                        .setSql("quantity = quantity - '" + quantity + "'")
-                        .eq(Stock::getProductId, productId)
-                        .eq(Stock::getWarehouseId, warehouseId)
-                        .apply("quantity - {0} >= 0", quantity)
-                );
-
-                if (!update) {
-                    ProductInfo productInfo = productInfoService.getById(productId);
-                    if (productInfo == null) {
-                        throw new ServiceException("产品id:" + productId + "不存在");
-                    }
-
-                    String err = "产品 {} 库存不足,出库失败";
-                    throw new ServiceException(StrUtil.format(err, productInfo.getName()));
-                }
-            });
-        }
-    }
+//    /**
+//     * 改变库存数量
+//     */
+//    private synchronized void changeStock(List<? extends InOutBo> list, Long warehouseId, JournalType journalType) {
+//
+//        Map<Long, BigDecimal> map = list.stream().collect(Collectors.toMap(
+//                InOutBo::getProductId,
+//                InOutBo::getQuantity,
+//                BigDecimal::add
+//        ));
+//
+//        if (journalType.getType().equals(InOutType.IN)) {
+//            map.forEach((productId, quantity) -> {
+//                Stock stock = getOne(q -> q.eq(Stock::getProductId, productId).eq(Stock::getWarehouseId, warehouseId));
+//
+//                if (stock == null) {
+//                    stock = new Stock();
+//                    stock.setWarehouseId(warehouseId);
+//                    stock.setProductId(productId);
+//                    stock.setQuantity(quantity);
+//                    save(stock);
+//                } else {
+//                    Long stockId = stock.getId();
+//                    update(q -> q
+//                            .eq(BaseIdPo::getId, stockId)
+//                            .setSql("quantity = quantity + " + quantity)
+//                    );
+//                }
+//            });
+//        } else {
+//            map.forEach((productId, quantity) -> {
+//                boolean update = update(q -> q
+//                        .setSql("quantity = quantity - '" + quantity + "'")
+//                        .eq(Stock::getProductId, productId)
+//                        .eq(Stock::getWarehouseId, warehouseId)
+//                        .apply("quantity - {0} >= 0", quantity)
+//                );
+//
+//                if (!update) {
+//                    ProductInfo productInfo = productInfoService.getById(productId);
+//                    if (productInfo == null) {
+//                        throw new ServiceException("产品id:" + productId + "不存在");
+//                    }
+//
+//                    String err = "产品 {} 库存不足,出库失败";
+//                    throw new ServiceException(StrUtil.format(err, productInfo.getName()));
+//                }
+//            });
+//        }
+//    }
 
     /**
      * 添加出入库记录
@@ -1047,4 +1078,107 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
         return dictMap;
     }
 
+    @Override
+    public synchronized void changeStockComm(List<? extends InOutBo> inOutList, StockType stockType, InOutType inOutType, Long warehouseId) {
+        Assert.notEmpty(warehouseId, "仓库id不能为空!");
+
+        for (InOutBo inOutBo : inOutList) {
+            //获取产品信息
+            ProductInfo productInfo = productInfoService.getById(inOutBo.getProductId());
+            if (productInfo == null) {
+                throw new ServiceException("无法获取到产品信息:" + inOutBo.getProductId());
+            }
+
+            //检查库存是否存在
+            Stock oldStock = this.getOne(q -> q.eq(Stock::getProductId, inOutBo.getProductId()).eq(Stock::getWarehouseId, warehouseId));
+            if (oldStock == null) {
+                oldStock = new Stock();
+                oldStock.setProductId(inOutBo.getProductId());
+                oldStock.setWarehouseId(warehouseId);
+                oldStock.setQuantity(BigDecimal.ZERO);
+                oldStock.setVictoriatouristJson("{}");
+                this.save(oldStock);
+            }
+
+            if(ObjectUtil.isEmpty(oldStock.getVictoriatouristJson())){
+                oldStock.setVictoriatouristJson("{}");
+                this.updateById(oldStock);
+            }
+
+            //拼接操作方式
+            String opStr;
+            switch (inOutType) {
+                case IN:
+                    opStr = "+";
+                    break;
+                case OUT:
+                    opStr = "-";
+                    break;
+                case SET:
+                    opStr = "=";
+                    break;
+                default:
+                    throw new ServiceException("未知库存操作类型");
+            }
+
+            //操作普通库存
+            if (stockType.equals(StockType.QUANTITY)) {
+                boolean update = update(q -> q
+                        .eq(Stock::getProductId, inOutBo.getProductId())
+                        .eq(Stock::getWarehouseId, warehouseId)
+                        .setSql(String.format("quantity = quantity %s %s", opStr, inOutBo.getQuantity()))
+                        .apply(inOutType.equals(InOutType.OUT), "quantity - {0} >= 0", inOutBo.getQuantity())
+                );
+                if (!update) {
+                    if (inOutType.equals(InOutType.OUT)) {
+                        if (oldStock.getQuantity().subtract(inOutBo.getQuantity()).compareTo(BigDecimal.ZERO) < 0) {
+                            throw new ServiceException("产品库存不足无法出库:", productInfo.getName());
+                        }
+                    }
+                    throw new ServiceException("库存操作失败:" + productInfo.getName());
+                }
+            }
+            //操作冻结库存
+            if (stockType.equals(StockType.FROZEN_QUANTITY)) {
+                boolean update = update(q -> q
+                        .eq(Stock::getProductId, inOutBo.getProductId())
+                        .eq(Stock::getWarehouseId, warehouseId)
+                        .setSql(String.format("victoriatourist_json = JSON_SET(victoriatourist_json,'$.frozenQuantity',IFNULL(json_unquote(victoriatourist_json -> '$.frozenQuantity'), 0) %s %s)", opStr, inOutBo.getQuantity()))
+                        .apply(inOutType.equals(InOutType.OUT), "IFNULL(json_unquote(victoriatourist_json -> '$.frozenQuantity'), 0) - {0} >= 0", inOutBo.getQuantity())
+                );
+                if (!update) {
+                    if (inOutType.equals(InOutType.OUT)) {
+                        String jsonStr = oldStock.getVictoriatouristJson();
+                        JSONObject json = ObjectUtil.isEmpty(jsonStr) ? new JSONObject() : JSONObject.parseObject(jsonStr);
+
+                        if (json.getBigDecimal("frozenQuantity").subtract(inOutBo.getQuantity()).compareTo(BigDecimal.ZERO) < 0) {
+                            throw new ServiceException("产品冻结库存不足无法出库:", productInfo.getName());
+                        }
+                    }
+                    throw new ServiceException("冻结库存操作失败" + productInfo.getName());
+                }
+            }
+            //操作次品库存
+            if (stockType.equals(StockType.DEFECTIVE_QUANTITY)) {
+                boolean update = update(q -> q
+                        .eq(Stock::getProductId, inOutBo.getProductId())
+                        .eq(Stock::getWarehouseId, warehouseId)
+                        .setSql(String.format("victoriatourist_json = JSON_SET(victoriatourist_json,'$.defectiveQuantity',IFNULL(json_unquote(victoriatourist_json -> '$.defectiveQuantity'), 0) %s %s)", opStr, inOutBo.getQuantity()))
+                        .apply(inOutType.equals(InOutType.OUT), "IFNULL(json_unquote(victoriatourist_json -> '$.defectiveQuantity'), 0) - {0} >= 0", inOutBo.getQuantity())
+                );
+                if (!update) {
+                    if (inOutType.equals(InOutType.OUT)) {
+                        String jsonStr = oldStock.getVictoriatouristJson();
+                        JSONObject json = ObjectUtil.isEmpty(jsonStr) ? new JSONObject() : JSONObject.parseObject(jsonStr);
+
+                        if (json.getBigDecimal("defectiveQuantity").subtract(inOutBo.getQuantity()).compareTo(BigDecimal.ZERO) < 0) {
+                            throw new ServiceException("产品次品库存不足无法出库:", productInfo.getName());
+                        }
+                    }
+                    throw new ServiceException("次品库存操作失败" + productInfo.getName());
+                }
+            }
+        }
+    }
+
 }