From b3fe06c151dc8455649bf0a46e481ceb83e3ea2a Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期六, 07 十一月 2026 13:37:54 +0800
Subject: [PATCH] feat: 完成好水川 MOM 需求1/2/4/5/8(装箱、BOM成本、销售合同、劳动合同、留样)

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderServiceImpl.java |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderServiceImpl.java
index 948ebf5..cd5f14b 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderServiceImpl.java
@@ -7,8 +7,12 @@
 import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.MesProWorkOrderPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.MesProWorkOrderSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemBatchConfigDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.mps.MesProMpsDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.mps.MesProMpsMapper;
 import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.qc.retentionsample.MesQcRetentionSampleMapper;
+import cn.iocoder.yudao.module.mes.enums.pro.MesProMpsStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum;
 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemBatchConfigService;
@@ -55,6 +59,10 @@
 
     @Resource
     private MesProWorkOrderMapper workOrderMapper;
+    @Resource
+    private MesProMpsMapper mpsMapper;
+    @Resource
+    private MesQcRetentionSampleMapper retentionSampleMapper;
 
     @Resource
     private MesProWorkOrderBomService workOrderBomService;
@@ -74,6 +82,8 @@
     private MesMdWorkstationService workstationService;
     @Resource
     private CrmCustomerApi customerApi;
+    @Resource
+    private cn.iocoder.yudao.module.mes.service.pro.cost.MesProWorkOrderCostService workOrderCostService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -92,6 +102,8 @@
 
         // 3. 鑷姩鐢熸垚 BOM锛氭牴鎹骇鍝� BOM 鐢熸垚宸ュ崟 BOM
         workOrderBomService.generateWorkOrderBom(workOrder.getId(), createReqVO, false);
+        // 3.1 璁$畻鏍囧噯鐗╂枡鎴愭湰
+        workOrderCostService.recalculateWorkOrderCost(workOrder.getId());
 
         // 4. 宸ュ簭鐢卞墠绔�夋嫨浜у搧鍚庡甫鍏ワ紝涓嶅啀鑷姩鐢熸垚
 
@@ -123,6 +135,11 @@
         // 3. 鏇存柊
         MesProWorkOrderDO updateObj = BeanUtils.toBean(updateReqVO, MesProWorkOrderDO.class);
         workOrderMapper.updateById(updateObj);
+
+        // 4. 浜у搧鎴栨暟閲忓彉鍖栧悗閲嶇畻鏍囧噯鐗╂枡鎴愭湰
+        if (productChanged || quantityChanged) {
+            workOrderCostService.recalculateWorkOrderCost(updateReqVO.getId());
+        }
     }
 
     @Override
@@ -221,14 +238,53 @@
         if (ObjUtil.notEqual(workOrder.getStatus(), MesProWorkOrderStatusEnum.CONFIRMED.getStatus())) {
             throw exception(PRO_WORK_ORDER_NOT_CONFIRMED);
         }
+        // 2. 鏍¢獙宸茬敓浜ф暟閲忓繀椤诲ぇ浜� 0锛堟病鏈変骇鍑轰笉鍏佽瀹屾垚锛�
+        BigDecimal quantityProduced = ObjUtil.defaultIfNull(workOrder.getQuantityProduced(), BigDecimal.ZERO);
+        if (quantityProduced.compareTo(BigDecimal.ZERO) <= 0) {
+            throw exception(PRO_WORK_ORDER_NO_PRODUCED_QUANTITY, workOrder.getCode());
+        }
+        // 3. 鏍¢獙鐣欐牱璁板綍锛堟墍鏈夊伐鍗曞畬鎴愬墠蹇呴』鐧昏鐣欐牱锛�
+        if (retentionSampleMapper.selectByWorkOrderId(id) == null) {
+            throw exception(PRO_WORK_ORDER_RETENTION_SAMPLE_REQUIRED, workOrder.getCode());
+        }
 
-        // 2. 绾ц仈瀹屾垚鎵�鏈夊叧鑱斾换鍔�
+        // 4. 绾ц仈瀹屾垚鎵�鏈夊叧鑱斾换鍔�
         taskService.finishTaskByOrderId(id);
 
-        // 3. 鏇存柊宸ュ崟鐘舵�佷负宸插畬鎴�
+        // 5. 鏇存柊宸ュ崟鐘舵�佷负宸插畬鎴�
         workOrderMapper.updateById(new MesProWorkOrderDO().setId(id)
                 .setStatus(MesProWorkOrderStatusEnum.FINISHED.getStatus())
                 .setFinishDate(LocalDateTime.now()));
+
+        // 6. 鍚屾鍏宠仈 MPS 鐘舵��
+        finishRelatedMps(workOrder, quantityProduced);
+    }
+
+    /**
+     * 宸ュ崟瀹屾垚鏃跺悓姝� MPS锛氬凡涓嬪彂 鈫� 宸插畬鎴愶紝骞跺洖濉畬鎴愭椂闂淬��
+     * 鍚堝苟涓嬪彂鏃朵竴涓伐鍗曞搴斿鏉� MPS锛屽凡鐢熶骇鏁伴噺鐢卞悇 MPS 鑷韩缁存姢锛岃繖閲屼笉鍥炲~锛岄伩鍏嶉噸澶嶇疮璁°��
+     */
+    private void finishRelatedMps(MesProWorkOrderDO workOrder, BigDecimal quantityProduced) {
+        List<MesProMpsDO> mpsList = mpsMapper.selectListByWorkOrderId(workOrder.getId());
+        if (CollUtil.isEmpty(mpsList)) {
+            return;
+        }
+        boolean singleMps = mpsList.size() == 1;
+        LocalDateTime now = LocalDateTime.now();
+        for (MesProMpsDO mps : mpsList) {
+            // 宸插彇娑�/宸插畬鎴愮殑 MPS 涓嶅仛鐘舵�佸洖鍐�
+            if (!ObjUtil.equal(mps.getStatus(), MesProMpsStatusEnum.ISSUED.getStatus())) {
+                continue;
+            }
+            MesProMpsDO updateObj = new MesProMpsDO().setId(mps.getId())
+                    .setStatus(MesProMpsStatusEnum.FINISHED.getStatus())
+                    .setFinishDate(now);
+            if (singleMps) {
+                BigDecimal currentProduced = ObjUtil.defaultIfNull(mps.getQuantityProduced(), BigDecimal.ZERO);
+                updateObj.setQuantityProduced(quantityProduced.max(currentProduced));
+            }
+            mpsMapper.updateById(updateObj);
+        }
     }
 
     @Override

--
Gitblit v1.9.3