From 3ce57820e618b704ce61487b7cdb38fdd6b0f44a Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 22 九月 2026 14:06:10 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_银川_九鸿化工' into dev_银川_九鸿化工

---
 yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java |  413 ++++++++++++++++++----------------------------------------
 1 files changed, 127 insertions(+), 286 deletions(-)

diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java
index b41b2ed..85bf379 100644
--- a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java
+++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java
@@ -3,30 +3,23 @@
 import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.qc.ipqc.MesQcIpqcMapper;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum;
+import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
 import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService;
-import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
-import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService;
-import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
-import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
 import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
+import cn.iocoder.yudao.module.mes.service.qc.ncr.MesQcNcrService;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
+import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateService;
 import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import jakarta.annotation.Resource;
 import org.junit.jupiter.api.Test;
@@ -34,17 +27,22 @@
 import org.springframework.test.context.bean.override.mockito.MockitoBean;
 
 import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.*;
 
 /**
  * {@link MesQcIpqcServiceImpl} 鐨勫崟鍏冩祴璇�
  *
- * @author 鑺嬮亾婧愮爜
+ * @author 瓒呯骇绠$悊鍛�
  */
 @Import(MesQcIpqcServiceImpl.class)
 public class MesQcIpqcServiceImplTest extends BaseDbUnitTest {
@@ -58,13 +56,9 @@
     @MockitoBean
     private MesQcTemplateItemService templateItemService;
     @MockitoBean
+    private MesQcTemplateService templateService;
+    @MockitoBean
     private MesQcIpqcLineService ipqcLineService;
-    @MockitoBean
-    private MesProWorkOrderService workOrderService;
-    @MockitoBean
-    private MesMdWorkstationService workstationService;
-    @MockitoBean
-    private MesMdItemService itemService;
     @MockitoBean
     private MesQcDefectRecordService defectRecordService;
     @MockitoBean
@@ -72,15 +66,15 @@
     @MockitoBean
     private MesProFeedbackService feedbackService;
     @MockitoBean
-    private MesProRouteProductService routeProductService;
-    @MockitoBean
-    private MesProRouteProcessService routeProcessService;
-    @MockitoBean
-    private MesProTaskService taskService;
-    @MockitoBean
     private MesQcIndicatorResultService indicatorResultService;
     @MockitoBean
     private MesWmProductProduceLineService productProduceLineService;
+    @MockitoBean
+    private MesQcNcrService ncrService;
+    @MockitoBean
+    private MdmItemApi mdmItemApi;
+
+    // ==================== finishIpqc 鍥炲啓鏉ユ簮鍗曟嵁 ====================
 
     @Test
     public void testFinishIpqc_writeBack_feedback() {
@@ -89,9 +83,6 @@
         Long sourceLineId = randomLongId();
         BigDecimal qualifiedQty = BigDecimal.valueOf(80);
         BigDecimal unqualifiedQty = BigDecimal.valueOf(20);
-        BigDecimal laborScrapQty = BigDecimal.valueOf(5);
-        BigDecimal materialScrapQty = BigDecimal.valueOf(10);
-        BigDecimal otherScrapQty = BigDecimal.valueOf(5);
 
         MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
             o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
@@ -101,9 +92,9 @@
             o.setSourceLineId(sourceLineId);
             o.setQualifiedQuantity(qualifiedQty);
             o.setUnqualifiedQuantity(unqualifiedQty);
-            o.setLaborScrapQuantity(laborScrapQty);
-            o.setMaterialScrapQuantity(materialScrapQty);
-            o.setOtherScrapQuantity(otherScrapQty);
+            o.setLaborScrapQuantity(BigDecimal.valueOf(5));
+            o.setMaterialScrapQuantity(BigDecimal.valueOf(10));
+            o.setOtherScrapQuantity(BigDecimal.valueOf(5));
         });
         ipqcMapper.insert(ipqc);
 
@@ -124,6 +115,8 @@
                 any(BigDecimal.class),
                 any(BigDecimal.class),
                 any(BigDecimal.class));
+        // 鏂█ 3锛氫笉鍚堟牸鏁伴噺 > 0锛岃嚜鍔ㄥ垱寤� NCR
+        verify(ncrService).createNcr(any());
     }
 
     @Test
@@ -161,13 +154,14 @@
 
     @Test
     public void testFinishIpqc_writeBack_noSourceDoc() {
-        // 鍑嗗鏁版嵁锛歴ourceDocType 涓虹┖锛屼笉闇�瑕佸洖鍐�
+        // 鍑嗗鏁版嵁锛氭棤鏉ユ簮鍗曟嵁锛堟墜宸ュ垱寤虹殑 IPQC锛夛紝鐩存帴瀹屾垚锛屼笉鍥炲啓
         MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
             o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
             o.setCheckResult(1);
             o.setSourceDocType(null);
             o.setSourceDocId(null);
             o.setSourceLineId(null);
+            o.setUnqualifiedQuantity(BigDecimal.ZERO);
         });
         ipqcMapper.insert(ipqc);
 
@@ -181,38 +175,6 @@
         // 鏂█ 2锛氫笉搴旇璋冪敤 feedbackService
         verify(feedbackService, never()).updateProFeedbackWhenIpqcFinish(
                 anyLong(), anyLong(), any(), any(), any(), any(), any());
-    }
-
-    @Test
-    public void testFinishIpqc_writeBack_sourceDocTypeDirtyData() {
-        // 鍑嗗鏁版嵁锛歴ourceDocType 闈炵┖浣� sourceDocId 涓虹┖锛屽簲璇ユ姏寮傚父
-        MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
-            o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
-            o.setCheckResult(1);
-            o.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
-            o.setSourceDocId(null); // 鑴忔暟鎹�
-            o.setSourceLineId(null);
-        });
-        ipqcMapper.insert(ipqc);
-
-        // 璋冪敤锛屽苟鏂█寮傚父
-        assertThrows(IllegalArgumentException.class, () -> ipqcService.finishIpqc(ipqc.getId()));
-    }
-
-    @Test
-    public void testFinishIpqc_writeBack_unknownSourceDocType() {
-        // 鍑嗗鏁版嵁锛歴ourceDocType 鏃犳硶璇嗗埆
-        MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
-            o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
-            o.setCheckResult(1);
-            o.setSourceDocType(99999); // 鏃犳硶璇嗗埆鐨勭被鍨�
-            o.setSourceDocId(randomLongId());
-            o.setSourceLineId(null);
-        });
-        ipqcMapper.insert(ipqc);
-
-        // 璋冪敤锛屽苟鏂█寮傚父
-        assertThrows(IllegalArgumentException.class, () -> ipqcService.finishIpqc(ipqc.getId()));
     }
 
     @Test
@@ -242,162 +204,61 @@
         assertThrows(Exception.class, () -> ipqcService.finishIpqc(ipqc.getId()));
     }
 
-    // ==================== processId 鎺ㄥ琛屼负娴嬭瘯 ====================
+    // ==================== createIpqc 鐗╂枡 / 鎵瑰彿 / 妯℃澘鍖归厤 ====================
 
     /**
-     * 宸ヤ綅鏈夊伐搴� + 璇ュ伐搴忓湪浜у搧宸ヨ壓璺嚎涓� 鈫� processId 搴旇琚缃负宸ヤ綅宸ュ簭
+     * 鎵嬪伐鍒涘缓锛氱墿鏂欐潵鑷� MDM锛屾ā鏉挎寜 MDM 鐗╂枡 ID 鍖归厤锛涙壒鍙枫�佺墿鏂欏潎钀藉簱
      */
     @Test
-    public void testCreateIpqc_processId_workstationHasProcess() {
+    public void testCreateIpqc_success() {
         // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
-        Long processId = randomLongId();
-        Long routeId = randomLongId();
+        Long itemId = randomLongId();
         Long templateId = randomLongId();
+        MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-TEST-001");
+        reqVO.setItemId(itemId);
+        reqVO.setBatchCode("BC20250101");
 
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-TEST-001");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
-
-        // mock 宸ヤ綅杩斿洖鏈夊伐搴�
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(processId);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        // mock 宸ュ崟
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        // mock 妯℃澘鍖归厤
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
-        // mock 宸ヨ壓璺嚎
-        MesProRouteProductDO routeProduct = new MesProRouteProductDO();
-        routeProduct.setRouteId(routeId);
-        when(routeProductService.getRouteProductByItemId(productId)).thenReturn(routeProduct);
-        // mock 宸ュ簭鍦ㄨ矾绾夸腑
-        when(routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId))
-                .thenReturn(new MesProRouteProcessDO());
+        // mock锛氭寜 MDM 鐗╂枡 ID 鍖归厤鍒拌川妫�鏂规
+        mockTemplate(templateId);
 
         // 璋冪敤
         Long ipqcId = ipqcService.createIpqc(reqVO);
 
-        // 鏂█锛歱rocessId 搴旇鏄伐浣嶅伐搴�
+        // 鏂█ 1锛氭壒鍙枫�佺墿鏂欍�佹柟妗堝潎钀藉簱
         MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
-        assertEquals(processId, ipqc.getProcessId());
+        assertNotNull(ipqc);
+        assertEquals("BC20250101", ipqc.getBatchCode());
+        assertEquals(itemId, ipqc.getItemId());
+        assertEquals(templateId, ipqc.getTemplateId());
+        assertEquals(MesQcStatusEnum.DRAFT.getStatus(), ipqc.getStatus());
+        assertNull(ipqc.getSourceDocCode());
+
+        // 鏂█ 2锛氭ā鏉挎寜 MDM 鐗╂枡 ID 鍖归厤锛屼笉鍐嶄緷璧栧伐鍗�/浠诲姟
+        verify(templateItemService).getTemplateItemList(
+                eq(itemId), eq(MesQcTypeEnum.IPQC.getType()), isNull(), isNull());
+        // 鏂█ 3锛氱墿鏂欏瓨鍦ㄦ�ф牎楠岃蛋 MDM
+        verify(mdmItemApi).validateItemExists(itemId);
     }
 
     /**
-     * 宸ヤ綅娌℃湁宸ュ簭锛坧rocessId=null锛夆啋 processId 搴旇鐣� null锛堜笉鍥為��鍒颁换鍔″伐搴忥級
+     * 鐗╂枡鏈尮閰嶅埌浠讳綍璐ㄦ鏂规 鈫� 鍒涘缓澶辫触
      */
     @Test
-    public void testCreateIpqc_processId_workstationNoProcess_shouldBeNull() {
+    public void testCreateIpqc_noTemplate() {
         // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
-        Long taskId = randomLongId();
-        Long templateId = randomLongId();
+        MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-TEST-002");
+        reqVO.setItemId(randomLongId());
 
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-TEST-002");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setTaskId(taskId); // 鏁呮剰浼犲叆 taskId锛岄獙璇佷笉浼氬洖閫�
-        reqVO.setInspectorUserId(randomLongId());
+        // mock锛氭棤鍖归厤鏂规
+        when(templateItemService.getTemplateItemList(any(), any(), any(), any()))
+                .thenReturn(Collections.emptyList());
 
-        // mock 宸ヤ綅娌℃湁宸ュ簭
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null); // 鏃犲伐搴�
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        // mock 宸ュ崟
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        // mock 浠诲姟
-        MesProTaskDO task = new MesProTaskDO();
-        task.setId(taskId);
-        task.setWorkOrderId(workOrderId);
-        task.setWorkstationId(workstationId);
-        task.setItemId(productId);
-        when(taskService.validateTaskNotFinished(taskId)).thenReturn(task);
-        // mock 妯℃澘鍖归厤
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
-
-        // 璋冪敤
-        Long ipqcId = ipqcService.createIpqc(reqVO);
-
-        // 鏂█锛歱rocessId 搴旇鏄� null锛屽嵆浣夸紶鍏ヤ簡 taskId 涔熶笉搴旇鍥為��
-        MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
-        assertNull(ipqc.getProcessId(),
-                "宸ヤ綅鏃犲伐搴忔椂 processId 搴斾负 null锛屼笉搴斿洖閫�鍒颁换鍔″伐搴�");
-        // 鏂█锛氫笉搴旇璇诲彇浠诲姟鐨� processId
-        verify(routeProductService, never()).getRouteProductByItemId(any());
+        // 璋冪敤锛屾柇瑷�寮傚父
+        ServiceException ex = assertThrows(ServiceException.class, () -> ipqcService.createIpqc(reqVO));
+        assertEquals(QC_NO_TEMPLATE.getCode(), ex.getCode());
     }
 
-    /**
-     * 宸ヤ綅鏈夊伐搴忎絾璇ュ伐搴忎笉鍦ㄤ骇鍝佸伐鑹鸿矾绾夸腑 鈫� processId 搴旇鐣� null
-     */
-    @Test
-    public void testCreateIpqc_processId_processNotInRoute() {
-        // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
-        Long processId = randomLongId();
-        Long routeId = randomLongId();
-        Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-TEST-003");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
-
-        // mock 宸ヤ綅鏈夊伐搴�
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(processId);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        // mock 宸ュ崟
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        // mock 妯℃澘鍖归厤
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
-        // mock 宸ヨ壓璺嚎瀛樺湪
-        MesProRouteProductDO routeProduct = new MesProRouteProductDO();
-        routeProduct.setRouteId(routeId);
-        when(routeProductService.getRouteProductByItemId(productId)).thenReturn(routeProduct);
-        // mock 宸ュ簭涓嶅湪璺嚎涓�
-        when(routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId))
-                .thenReturn(null);
-
-        // 璋冪敤
-        Long ipqcId = ipqcService.createIpqc(reqVO);
-
-        // 鏂█锛歱rocessId 搴旇鏄� null
-        MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
-        assertNull(ipqc.getProcessId());
-    }
-
-    // ==================== sourceLineId 鏍¢獙娴嬭瘯 ====================
+    // ==================== createIpqc sourceLineId 鏍¢獙 ====================
 
     /**
      * sourceDocType=PRO_FEEDBACK 鏃� sourceLineId 涓虹┖ 鈫� 鍒涘缓澶辫触
@@ -405,34 +266,15 @@
     @Test
     public void testCreateIpqc_sourceLineId_required() {
         // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
         Long feedbackId = randomLongId();
-        Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-SL-001");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
+        MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-001");
+        reqVO.setItemId(randomLongId());
         reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
         reqVO.setSourceDocId(feedbackId);
         reqVO.setSourceLineId(null); // 涓嶄紶 sourceLineId
 
         // mock
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        mockTemplate(randomLongId());
         when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
 
         // 璋冪敤锛屾柇瑷�寮傚父
@@ -446,35 +288,16 @@
     @Test
     public void testCreateIpqc_sourceLineId_notBelong() {
         // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
         Long feedbackId = randomLongId();
         Long sourceLineId = randomLongId();
-        Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-SL-002");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
+        MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-002");
+        reqVO.setItemId(randomLongId());
         reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
         reqVO.setSourceDocId(feedbackId);
         reqVO.setSourceLineId(sourceLineId);
 
         // mock
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        mockTemplate(randomLongId());
         when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
         // mock锛氫骇鍑鸿瀛樺湪浣� feedbackId 涓嶅尮閰�
         MesWmProductProduceLineDO line = new MesWmProductProduceLineDO();
@@ -494,35 +317,16 @@
     @Test
     public void testCreateIpqc_sourceLineId_notPending() {
         // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
         Long feedbackId = randomLongId();
         Long sourceLineId = randomLongId();
-        Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-SL-003");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
+        MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-003");
+        reqVO.setItemId(randomLongId());
         reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
         reqVO.setSourceDocId(feedbackId);
         reqVO.setSourceLineId(sourceLineId);
 
         // mock
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        mockTemplate(randomLongId());
         when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
         // mock锛氫骇鍑鸿瀛樺湪涓斿綊灞炴纭紝浣嗕笉鏄� PENDING 鐘舵��
         MesWmProductProduceLineDO line = new MesWmProductProduceLineDO();
@@ -537,40 +341,24 @@
     }
 
     /**
-     * sourceLineId 鏍¢獙鍏ㄩ儴閫氳繃 鈫� 鍒涘缓鎴愬姛
+     * sourceLineId 鏍¢獙鍏ㄩ儴閫氳繃 鈫� 鍒涘缓鎴愬姛锛屾潵婧愬崟鎹紪鍙峰洖鍐�
      */
     @Test
     public void testCreateIpqc_sourceLineId_success() {
         // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
+        Long itemId = randomLongId();
         Long feedbackId = randomLongId();
         Long sourceLineId = randomLongId();
         Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-SL-004");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
+        MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-004");
+        reqVO.setItemId(itemId);
+        reqVO.setBatchCode("BC20250101");
         reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
         reqVO.setSourceDocId(feedbackId);
         reqVO.setSourceLineId(sourceLineId);
 
         // mock
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        mockTemplate(templateId);
         MesProFeedbackDO feedback = new MesProFeedbackDO();
         feedback.setId(feedbackId);
         feedback.setCode("FB-001");
@@ -585,12 +373,65 @@
         // 璋冪敤
         Long ipqcId = ipqcService.createIpqc(reqVO);
 
-        // 鏂█锛氬垱寤烘垚鍔燂紝sourceDocCode 鍥炲啓
+        // 鏂█锛氬垱寤烘垚鍔燂紝鏉ユ簮鍗曟嵁瀛楁钀藉簱
         MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
         assertNotNull(ipqc);
         assertEquals(feedbackId, ipqc.getSourceDocId());
         assertEquals(sourceLineId, ipqc.getSourceLineId());
         assertEquals("FB-001", ipqc.getSourceDocCode());
+        assertEquals("BC20250101", ipqc.getBatchCode());
+        assertEquals(itemId, ipqc.getItemId());
+    }
+
+    /**
+     * 鏈煡鏉ユ簮鍗曟嵁绫诲瀷 鈫� 鍒涘缓澶辫触
+     */
+    @Test
+    public void testCreateIpqc_sourceDocTypeUnknown() {
+        // 鍑嗗鍙傛暟
+        MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-005");
+        reqVO.setItemId(randomLongId());
+        reqVO.setSourceDocType(99999); // 鏃犳硶璇嗗埆鐨勭被鍨�
+        reqVO.setSourceDocId(randomLongId());
+
+        // mock
+        mockTemplate(randomLongId());
+
+        // 璋冪敤锛屾柇瑷�寮傚父
+        ServiceException ex = assertThrows(ServiceException.class, () -> ipqcService.createIpqc(reqVO));
+        assertEquals(QC_IPQC_SOURCE_DOC_TYPE_UNKNOWN.getCode(), ex.getCode());
+    }
+
+    // ==================== 杈呭姪鏂规硶 ====================
+
+    /**
+     * 鏋勯�犱竴涓弧瓒冲繀濉」鐨勮繃绋嬫楠屽崟璇锋眰锛堜笉鍚潵婧愬崟鎹級
+     */
+    private MesQcIpqcSaveReqVO buildReqVO(String code) {
+        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
+        reqVO.setCode(code);
+        reqVO.setName(code + "-鍚嶇О");
+        reqVO.setType(1);
+        reqVO.setBatchCode("BC-" + code);
+        reqVO.setCheckQuantity(BigDecimal.valueOf(100));
+        reqVO.setQualifiedQuantity(BigDecimal.valueOf(95));
+        reqVO.setUnqualifiedQuantity(BigDecimal.valueOf(5));
+        reqVO.setLaborScrapQuantity(BigDecimal.ZERO);
+        reqVO.setMaterialScrapQuantity(BigDecimal.ZERO);
+        reqVO.setOtherScrapQuantity(BigDecimal.ZERO);
+        reqVO.setInspectorUserId(randomLongId());
+        return reqVO;
+    }
+
+    /**
+     * mock锛氭寜 MDM 鐗╂枡 ID + IPQC 绫诲瀷鍖归厤鍒版寚瀹氳川妫�鏂规
+     */
+    private void mockTemplate(Long templateId) {
+        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
+        templateItem.setTemplateId(templateId);
+        List<MesQcTemplateItemDO> templateItems = Collections.singletonList(templateItem);
+        when(templateItemService.getTemplateItemList(any(), eq(MesQcTypeEnum.IPQC.getType()), isNull(), isNull()))
+                .thenReturn(templateItems);
     }
 
 }

--
Gitblit v1.9.3