From f02d0df2f1dfc7a8b775cf50d45375e57628a5ef Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 10 十一月 2026 11:26:22 +0800
Subject: [PATCH] feat(ncr): 完善NCR处置联动逻辑与关闭校验

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java |   33 +++++++++++++++++++++++++++++++--
 1 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java
index d95f758..b5b34b0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java
@@ -6,12 +6,17 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesMapper;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
 import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.List;
@@ -42,9 +47,15 @@
     private MesWmWarehouseAreaService warehouseAreaService;
     @Resource
     private MesWmSalesReelGuard salesReelGuard;
+    @Resource
+    private MesWmOqcConcessionGuard oqcConcessionGuard;
+    @Resource
+    private MesWmProductSalesMapper salesMapper;
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long createProductSalesDetail(MesWmProductSalesDetailSaveReqVO createReqVO) {
+        validateEditable(createReqVO.getSalesId(), createReqVO.getLineId());
         // 鏍¢獙鏁版嵁
         validateProductSalesDetailSaveData(createReqVO);
 
@@ -55,9 +66,14 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateProductSalesDetail(MesWmProductSalesDetailSaveReqVO updateReqVO) {
         // 鏍¢獙瀛樺湪
-        validateProductSalesDetailExists(updateReqVO.getId());
+        MesWmProductSalesDetailDO existing = validateProductSalesDetailExists(updateReqVO.getId());
+        if (!ObjUtil.equal(existing.getSalesId(), updateReqVO.getSalesId()) || !ObjUtil.equal(existing.getLineId(), updateReqVO.getLineId())) {
+            throw new ServiceException(400, "涓嶅厑璁告洿鏀瑰嚭搴撴槑缁嗘墍灞炲崟鎹垨琛�");
+        }
+        validateEditable(existing.getSalesId(), existing.getLineId());
         // 鏍¢獙鏁版嵁
         validateProductSalesDetailSaveData(updateReqVO);
 
@@ -67,11 +83,23 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void deleteProductSalesDetail(Long id) {
         // 鏍¢獙瀛樺湪
-        validateProductSalesDetailExists(id);
+        MesWmProductSalesDetailDO detail = validateProductSalesDetailExists(id);
+        validateEditable(detail.getSalesId(), detail.getLineId());
         // 鍒犻櫎
         productSalesDetailMapper.deleteById(id);
+    }
+
+    private void validateEditable(Long salesId, Long lineId) {
+        MesWmProductSalesDO sales = salesMapper.selectOne(new LambdaQueryWrapperX<MesWmProductSalesDO>()
+                .eq(MesWmProductSalesDO::getId, salesId).last("FOR UPDATE"));
+        MesWmProductSalesLineDO line = productSalesLineService.getProductSalesLine(lineId);
+        if (sales == null || line == null || !ObjUtil.equal(line.getSalesId(), salesId)) {
+            throw new ServiceException(400, "鍑哄簱鍗曟垨鍑哄簱琛屼笉瀛樺湪");
+        }
+        oqcConcessionGuard.validateEditable(line, sales.getStatus());
     }
 
     @Override
@@ -129,6 +157,7 @@
                 reqVO.getMaterialStockId(), reqVO.getItemId(), reqVO.getBatchId(), reqVO.getBatchCode(),
                 reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId(), reqVO.getQuantity());
         salesReelGuard.validate(line, reqVO.getBatchId());
+        oqcConcessionGuard.validate(line, reqVO.getMaterialStockId(), reqVO.getBatchCode(), reqVO.getQuantity());
     }
 
 }

--
Gitblit v1.9.3