From 9daeb6eac6e46710055e625bbbd56331b8890e21 Mon Sep 17 00:00:00 2001
From: xiaoyi <908147524@qq.com>
Date: 星期三, 04 十一月 2026 10:10:20 +0800
Subject: [PATCH] revert(energy): 撤销 energy 模块移植(与新高原有 em 模块重复)

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java |  162 ++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 144 insertions(+), 18 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
index b62bbec..11cfecd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
@@ -8,6 +8,7 @@
 import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockAdjustReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockMoveReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
@@ -16,6 +17,8 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseAreaMapper;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
@@ -51,6 +54,8 @@
 
     @Resource
     private MesWmMaterialStockMapper materialStockMapper;
+    @Resource
+    private MesWmWarehouseAreaMapper warehouseAreaMapper;
 
     @Resource
     private MesMdmItemService mdmItemService;
@@ -170,8 +175,9 @@
     @Override
     public MesWmMaterialStockDO getOrCreateMaterialStock(Long itemId, Long warehouseId, Long locationId, Long areaId,
                                                          Long batchId, String batchCode, Long vendorId, LocalDateTime receiptTime) {
-        // 1. 鏌ユ壘宸叉湁搴撳瓨璁板綍锛坴endorId 鍙備笌鍞竴閿級
-        MesWmMaterialStockDO stock = materialStockMapper.selectByCompositeKey(
+        // 鎵�鏈夊簱瀛樺垱寤哄叆鍙e叡鐢ㄥ簱浣嶉攣锛岄伩鍏嶄笌瀵煎叆骞跺彂鏃跺垱寤洪噸澶嶅彴璐︺��
+        lockAreaAndValidateMixing(areaId, itemId, batchId);
+        MesWmMaterialStockDO stock = materialStockMapper.selectByCompositeKeyForUpdate(
                 itemId, warehouseId, locationId, areaId, batchId, vendorId);
         if (stock != null) {
             return stock;
@@ -208,6 +214,23 @@
         }
     }
 
+    private void lockAreaAndValidateMixing(Long areaId, Long itemId, Long batchId) {
+        MesWmWarehouseAreaDO area = warehouseAreaMapper.selectOne(new LambdaQueryWrapperX<MesWmWarehouseAreaDO>()
+                .eq(MesWmWarehouseAreaDO::getId, areaId).last("FOR UPDATE"));
+        if (area == null) {
+            areaService.validateWarehouseAreaExists(areaId);
+            throw exception(WM_STOCK_IMPORT_INVALID, "搴撲綅涓嶅瓨鍦�");
+        }
+        List<MesWmMaterialStockDO> stocks = materialStockMapper.selectAreaStocksForUpdate(areaId);
+        if (Boolean.FALSE.equals(area.getAllowItemMixing()) && itemId != null
+                && CollUtil.anyMatch(stocks, stock -> ObjUtil.notEqual(itemId, stock.getItemId()))) {
+            throw exception(WM_MATERIAL_STOCK_AREA_ITEM_MIXING_NOT_ALLOWED, area.getName());
+        }
+        if (Boolean.FALSE.equals(area.getAllowBatchMixing()) && batchId != null
+                && CollUtil.anyMatch(stocks, stock -> ObjUtil.notEqual(batchId, stock.getBatchId()))) {
+            throw exception(WM_MATERIAL_STOCK_AREA_BATCH_MIXING_NOT_ALLOWED, area.getName());
+        }
+    }
     @Override
     public void checkAreaMixingRule(Long areaId, Long itemId, Long batchId) {
         // 1.1 鏍¢獙搴撲綅蹇呴』瀛樺湪
@@ -270,6 +293,11 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
+    public Long importMaterialStockIn(MesWmMaterialStockAdjustReqVO reqVO, Long importId, String reference) {
+        return doAdjustMaterialStock(reqVO, true, importId, reference);
+    }
+    @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long adjustMaterialStockOut(MesWmMaterialStockAdjustReqVO reqVO) {
         return doAdjustMaterialStock(reqVO, false);
     }
@@ -282,6 +310,10 @@
      * @return 搴撳瓨璁板綍ID
      */
     private Long doAdjustMaterialStock(MesWmMaterialStockAdjustReqVO reqVO, boolean isInbound) {
+        return doAdjustMaterialStock(reqVO, isInbound, null, null);
+    }
+
+    private Long doAdjustMaterialStock(MesWmMaterialStockAdjustReqVO reqVO, boolean isInbound, Long importId, String reference) {
         // 1. 鏍¢獙鐗╂枡瀛樺湪涓斿惎鐢�
         MesMdmItemDO item = mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
 
@@ -302,31 +334,46 @@
         }
 
         // 3. 鏍¢獙搴撲綅娣锋斁瑙勫垯
-        checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), batchId);
+        if (importId == null) {
+            checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), batchId);
+        }
 
         // 4. 鑾峰彇鎴栧垱寤哄簱瀛樿褰�
-        MesWmMaterialStockDO stock = getOrCreateMaterialStock(
-                reqVO.getItemId(),
-                reqVO.getWarehouseId(),
-                reqVO.getLocationId(),
-                reqVO.getAreaId(),
-                batchId,
-                batchCode,
-                reqVO.getVendorId(),
-                LocalDateTime.now()
-        );
-
+        MesWmMaterialStockDO stock;
+        if (importId != null) {
+            lockAreaAndValidateMixing(reqVO.getAreaId(), reqVO.getItemId(), batchId);
+            List<MesWmMaterialStockDO> matches = reqVO.getVendorId() == null
+                    ? materialStockMapper.selectImportBaseStocksForUpdate(reqVO.getItemId(), reqVO.getWarehouseId(),
+                            reqVO.getLocationId(), reqVO.getAreaId(), batchId)
+                    : materialStockMapper.selectImportStocksForUpdate(reqVO.getItemId(), reqVO.getWarehouseId(),
+                            reqVO.getLocationId(), reqVO.getAreaId(), batchId, reqVO.getVendorId());
+            if (matches.size() > 1) throw exception(WM_STOCK_IMPORT_INVALID,
+                    reqVO.getVendorId() == null ? "璇ュ簱瀛樼淮搴﹀瓨鍦ㄥ鏉¤褰曪紝璇峰~鍐欎緵搴斿晢缂栫爜骞跺鐞嗛噸澶嶅簱瀛�" : "搴撳瓨缁村害瀛樺湪閲嶅璁板綍锛岃鍏堝鐞嗗悗瀵煎叆");
+            if (reqVO.getVendorId() == null && matches.size() == 1) reqVO.setVendorId(matches.get(0).getVendorId());
+            if (matches.isEmpty()) {
+                stock = MesWmMaterialStockDO.builder().itemId(item.getId()).itemTypeId(item.getCategoryId())
+                        .warehouseId(reqVO.getWarehouseId()).locationId(reqVO.getLocationId()).areaId(reqVO.getAreaId())
+                        .batchId(batchId).batchCode(batchCode).vendorId(reqVO.getVendorId())
+                        .quantity(BigDecimal.ZERO).receiptTime(LocalDateTime.now()).frozen(false).build();
+                materialStockMapper.insert(stock);
+            } else {
+                stock = matches.get(0);
+            }
+        } else {
+            stock = getOrCreateMaterialStock(reqVO.getItemId(), reqVO.getWarehouseId(), reqVO.getLocationId(),
+                    reqVO.getAreaId(), batchId, batchCode, reqVO.getVendorId(), LocalDateTime.now());
+        }
         // 5. 璁$畻鍙樺姩鏁伴噺锛氬叆搴撲负姝o紝鍑哄簱涓鸿礋
         BigDecimal quantity = isInbound ? reqVO.getQuantity() : reqVO.getQuantity().negate();
 
         // 6. 鍒涘缓搴撳瓨浜嬪姟娴佹按锛堝唴閮ㄤ細鏇存柊搴撳瓨鏁伴噺锛�
-        int bizType = isInbound ? MesBizTypeConstants.WM_STOCK_ADJUST_IN : MesBizTypeConstants.WM_STOCK_ADJUST_OUT;
+        int bizType = importId != null ? MesBizTypeConstants.WM_STOCK_IMPORT_IN : (isInbound ? MesBizTypeConstants.WM_STOCK_ADJUST_IN : MesBizTypeConstants.WM_STOCK_ADJUST_OUT);
         MesWmTransactionSaveReqDTO transaction = new MesWmTransactionSaveReqDTO()
                 .setType(isInbound ? MesWmTransactionTypeEnum.IN.getType() : MesWmTransactionTypeEnum.OUT.getType())
                 .setBizType(bizType)
-                .setBizId(stock.getId())
-                .setBizCode("STOCK_ADJUST_" + stock.getId())
-                .setBizLineId(stock.getId())
+                .setBizId(importId != null ? importId : stock.getId())
+                .setBizCode(importId != null ? reference : "STOCK_ADJUST_" + stock.getId())
+                .setBizLineId(importId != null ? importId : stock.getId())
                 .setItemId(reqVO.getItemId())
                 .setQuantity(quantity)
                 .setBatchId(batchId)
@@ -336,6 +383,7 @@
                 .setAreaId(reqVO.getAreaId())
                 .setVendorId(reqVO.getVendorId())
                 .setReceiptTime(LocalDateTime.now())
+                .setMaterialStockId(importId != null ? stock.getId() : null)
                 .setCheckFlag(!isInbound);
         wmTransactionService.createTransaction(transaction);
 
@@ -415,4 +463,82 @@
         throw new IllegalArgumentException("鏃犳晥鐨勮川閲忕姸鎬佺被鍨�: " + qualityStatus.getClass().getName());
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void moveMaterialStock(MesWmMaterialStockMoveReqVO reqVO) {
+        // 1. 鏌ヨ鍘熷簱瀛樿褰�
+        MesWmMaterialStockDO sourceStock = validateMaterialStockExists(reqVO.getMaterialStockId());
+
+        // 2. 鏍¢獙搴撳瓨鏁伴噺鍏呰冻锛堝彲鐢ㄩ噺 = 鍦ㄥ簱鏁伴噺 - 鍐荤粨鏁伴噺 - 鍗犵敤閲忥級
+        BigDecimal availableQty = sourceStock.getQuantity() != null ? sourceStock.getQuantity() : BigDecimal.ZERO;
+        if (sourceStock.getFrozenQuantity() != null) {
+            availableQty = availableQty.subtract(sourceStock.getFrozenQuantity());
+        }
+        if (sourceStock.getReservedQuantity() != null) {
+            availableQty = availableQty.subtract(sourceStock.getReservedQuantity());
+        }
+        if (availableQty.compareTo(reqVO.getQuantity()) < 0) {
+            throw exception(WM_MATERIAL_STOCK_INSUFFICIENT);
+        }
+
+        // 3. 鏍¢獙搴撳瓨鏈喕缁�
+        if (Boolean.TRUE.equals(sourceStock.getFrozen())) {
+            throw exception(WM_MATERIAL_STOCK_FROZEN);
+        }
+
+        // 4. 鏍¢獙鐩爣搴撲綅娣锋斁瑙勫垯
+        checkAreaMixingRule(reqVO.getToAreaId(), sourceStock.getItemId(), sourceStock.getBatchId());
+
+        // 5. 鐢熸垚绉诲簱鍗曞彿
+        String moveCode = "MOVE_" + System.currentTimeMillis();
+
+        // 6. 鍒涘缓璋冩嫧绉诲嚭浜嬪姟锛堣礋鏁帮級
+        MesWmTransactionSaveReqDTO outTransaction = new MesWmTransactionSaveReqDTO()
+                .setType(MesWmTransactionTypeEnum.MOVE_OUT.getType())
+                .setBizType(MesBizTypeConstants.WM_TRANSFER_OUT)
+                .setBizId(sourceStock.getId())
+                .setBizCode(moveCode)
+                .setBizLineId(sourceStock.getId())
+                .setItemId(sourceStock.getItemId())
+                .setQuantity(reqVO.getQuantity().negate())
+                .setBatchId(sourceStock.getBatchId())
+                .setBatchCode(sourceStock.getBatchCode())
+                .setWarehouseId(sourceStock.getWarehouseId())
+                .setLocationId(sourceStock.getLocationId())
+                .setAreaId(sourceStock.getAreaId())
+                .setVendorId(sourceStock.getVendorId())
+                .setMaterialStockId(sourceStock.getId())
+                .setCheckFlag(true);
+        Long outTransactionId = wmTransactionService.createTransaction(outTransaction);
+
+        // 7. 鏌ユ壘鐩爣搴撲綅鐨勫簱瀛樿褰曪紙蹇界暐渚涘簲鍟嗭級锛岀敤浜庡悎骞跺簱瀛�
+        MesWmMaterialStockDO targetStock = materialStockMapper.selectByCompositeKeyIgnoreVendor(
+                sourceStock.getItemId(),
+                reqVO.getToWarehouseId(),
+                reqVO.getToLocationId(),
+                reqVO.getToAreaId(),
+                sourceStock.getBatchId()
+        );
+
+        // 8. 鍒涘缓璋冩嫧绉诲叆浜嬪姟锛堟鏁帮級锛屽叧鑱斿嚭搴撲簨鍔�
+        // 浣跨敤鐩爣搴撲綅宸叉湁搴撳瓨璁板綍鐨� vendorId锛堝鏋滄湁锛夛紝鍚﹀垯涓嶄紶
+        MesWmTransactionSaveReqDTO inTransaction = new MesWmTransactionSaveReqDTO()
+                .setType(MesWmTransactionTypeEnum.MOVE_IN.getType())
+                .setBizType(MesBizTypeConstants.WM_TRANSFER_IN)
+                .setBizId(sourceStock.getId())
+                .setBizCode(moveCode)
+                .setBizLineId(sourceStock.getId())
+                .setItemId(sourceStock.getItemId())
+                .setQuantity(reqVO.getQuantity())
+                .setBatchId(sourceStock.getBatchId())
+                .setBatchCode(sourceStock.getBatchCode())
+                .setWarehouseId(reqVO.getToWarehouseId())
+                .setLocationId(reqVO.getToLocationId())
+                .setAreaId(reqVO.getToAreaId())
+                .setVendorId(targetStock != null ? targetStock.getVendorId() : null)
+                .setRelatedTransactionId(outTransactionId)
+                .setCheckFlag(false);
+        wmTransactionService.createTransaction(inTransaction);
+    }
+
 }

--
Gitblit v1.9.3