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/wm/packages/MesWmPackageLineServiceImpl.java | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 110 insertions(+), 7 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/packages/MesWmPackageLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/packages/MesWmPackageLineServiceImpl.java
index 295fc61..a670662 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/packages/MesWmPackageLineServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/packages/MesWmPackageLineServiceImpl.java
@@ -1,22 +1,38 @@
package cn.iocoder.yudao.module.mes.service.wm.packages;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.packages.vo.line.MesWmPackageLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.packages.vo.line.MesWmPackageLineSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.packages.MesWmPackageLineDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.packages.MesWmPackageLineMapper;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
+import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
+import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderProcessService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PACKAGE_LINE_NOT_EXISTS;
+import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
/**
* MES 瑁呯鏄庣粏 Service 瀹炵幇绫�
@@ -27,6 +43,9 @@
@Validated
public class MesWmPackageLineServiceImpl implements MesWmPackageLineService {
+ private static final String ASSEMBLY_PROCESS_CODE = "PRO-ASSEMBLY";
+ private static final String ASSEMBLY_PROCESS_NAME = "缁勮";
+
@Resource
private MesWmPackageLineMapper packageLineMapper;
@@ -36,15 +55,26 @@
@Resource
private MesMdmItemService mdmItemService;
@Resource
+ private MesMdItemService mdItemService;
+ @Resource
+ private MesMdItemTypeService itemTypeService;
+ @Resource
private MesProWorkOrderService workOrderService;
+ @Resource
+ private MesProWorkOrderProcessService workOrderProcessService;
+ @Resource
+ private MesProProcessService processService;
+ @Resource
+ private MesProFeedbackMapper feedbackMapper;
@Override
public Long createPackageLine(MesWmPackageLineSaveReqVO createReqVO) {
// 鏍¢獙鏁版嵁
- validateLineSaveData(createReqVO);
+ int boxCount = validateLineSaveData(createReqVO);
// 鎻掑叆
MesWmPackageLineDO line = BeanUtils.toBean(createReqVO, MesWmPackageLineDO.class);
+ line.setBoxCount(boxCount);
packageLineMapper.insert(line);
return line.getId();
}
@@ -55,10 +85,11 @@
MesWmPackageLineDO line = validatePackageLineExists(updateReqVO.getId());
// 鏍¢獙鏁版嵁
updateReqVO.setPackageId(line.getPackageId());
- validateLineSaveData(updateReqVO);
+ int boxCount = validateLineSaveData(updateReqVO);
// 鏇存柊
MesWmPackageLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmPackageLineDO.class);
+ updateObj.setBoxCount(boxCount);
packageLineMapper.updateById(updateObj);
}
@@ -95,15 +126,87 @@
// ========== 鏍¢獙鏂规硶 ==========
/**
- * 鏍¢獙淇濆瓨鏃剁殑鍏宠仈鏁版嵁
+ * 鏍¢獙淇濆瓨鏃剁殑鍏宠仈鏁版嵁锛屽苟杩斿洖鎸� 鏁伴噺 / 姣忕鏁伴噺 鍚戜笂鍙栨暣璁$畻鐨勭鏁�
*/
- private void validateLineSaveData(MesWmPackageLineSaveReqVO reqVO) {
+ private int validateLineSaveData(MesWmPackageLineSaveReqVO reqVO) {
// 鏍¢獙瑁呯鍗曠姸鎬佷负鑽夌
packageService.validatePackageStatusDraft(reqVO.getPackageId());
// 鏍¢獙浜у搧鐗╂枡瀛樺湪
mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
- // 鏍¢獙宸ュ崟宸茬‘璁�
- workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
+
+ // 鏍¢獙鐗╂枡妗f锛氬繀椤诲睘浜庢垚鍝佸垎绫伙紝涓斿凡缁存姢姣忕鏁伴噺
+ MesMdItemDO item = mdItemService.getItem(reqVO.getItemId());
+ if (item == null) {
+ throw exception(WM_PACKAGE_LINE_BOX_QUANTITY_NOT_CONFIGURED, "ID=" + reqVO.getItemId());
+ }
+ String itemName = StrUtil.isNotBlank(item.getName()) ? item.getName() : item.getCode();
+ MesMdItemTypeDO itemType = item.getItemTypeId() != null
+ ? itemTypeService.getItemTypeMap(Collections.singleton(item.getItemTypeId()))
+ .get(item.getItemTypeId())
+ : null;
+ if (itemType == null || !Boolean.TRUE.equals(itemType.getFinishedFlag())) {
+ throw exception(WM_PACKAGE_LINE_ITEM_NOT_FINISHED, itemName);
+ }
+ if (item.getBoxQuantity() == null || item.getBoxQuantity().compareTo(BigDecimal.ZERO) <= 0) {
+ throw exception(WM_PACKAGE_LINE_BOX_QUANTITY_NOT_CONFIGURED, itemName);
+ }
+
+ // 鏍¢獙宸ュ崟宸茬‘璁わ紝涓旇绠辩墿鏂欏繀椤讳负宸ュ崟鐨勪骇鍝�
+ MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
+ if (ObjUtil.notEqual(reqVO.getItemId(), workOrder.getProductId())) {
+ MesMdItemDO product = workOrder.getProductId() != null
+ ? mdItemService.getItem(workOrder.getProductId()) : null;
+ String productName = product != null
+ ? (StrUtil.isNotBlank(product.getName()) ? product.getName() : product.getCode())
+ : "ID=" + workOrder.getProductId();
+ throw exception(WM_PACKAGE_LINE_WORK_ORDER_PRODUCT_MISMATCH,
+ itemName, workOrder.getCode(), productName);
+ }
+
+ // 鏍¢獙鍚屼竴宸ュ崟绱瑁呯鏁伴噺涓嶈秴杩囧伐鍗曟暟閲忥紙鑽夌涓庡凡瀹屾垚鐨勮绠卞崟閮借鍏ワ級
+ BigDecimal plannedQuantity = packageLineMapper.selectListByWorkOrderId(workOrder.getId()).stream()
+ .filter(line -> ObjUtil.notEqual(line.getId(), reqVO.getId()))
+ .map(MesWmPackageLineDO::getQuantity)
+ .filter(Objects::nonNull)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ BigDecimal totalQuantity = plannedQuantity.add(reqVO.getQuantity());
+ if (workOrder.getQuantity() != null && totalQuantity.compareTo(workOrder.getQuantity()) > 0) {
+ throw exception(WM_PACKAGE_LINE_WORK_ORDER_QUANTITY_EXCEED,
+ workOrder.getCode(), workOrder.getQuantity(), plannedQuantity, reqVO.getQuantity());
+ }
+
+ // 鏍¢獙缁勮宸ュ簭宸插畬鎴愭姤宸ワ細缁勮鍚堟牸鏁伴噺蹇呴』瑕嗙洊绱瑁呯鏁伴噺
+ validateAssemblyCompleted(workOrder, plannedQuantity, reqVO.getQuantity(), totalQuantity);
+
+ // 绠辨暟 = 鏁伴噺 / 姣忕鏁伴噺锛屽悜涓婂彇鏁�
+ return reqVO.getQuantity().divide(item.getBoxQuantity(), 0, RoundingMode.CEILING).intValue();
+ }
+
+ /**
+ * 鏍¢獙宸ュ崟鐨勩�愮粍瑁呫�戝伐搴忓凡瀹屾垚鎶ュ伐锛屼笖鍚堟牸鏁伴噺涓嶅皯浜庣疮璁¤绠辨暟閲�
+ */
+ private void validateAssemblyCompleted(MesProWorkOrderDO workOrder, BigDecimal packedQuantity,
+ BigDecimal currentQuantity, BigDecimal totalQuantity) {
+ List<Long> processIds = workOrderProcessService.getWorkOrderProcessListByWorkOrderId(workOrder.getId())
+ .stream()
+ .map(MesProWorkOrderProcessDO::getProcessId)
+ .filter(Objects::nonNull)
+ .distinct()
+ .toList();
+ List<Long> assemblyProcessIds = processService.getProcessMap(processIds).values().stream()
+ .filter(process -> ASSEMBLY_PROCESS_CODE.equalsIgnoreCase(process.getCode())
+ || ASSEMBLY_PROCESS_NAME.equals(process.getName()))
+ .map(MesProProcessDO::getId)
+ .toList();
+ if (assemblyProcessIds.isEmpty()) {
+ throw exception(WM_PACKAGE_LINE_ASSEMBLY_PROCESS_NOT_FOUND, workOrder.getCode());
+ }
+ BigDecimal assembledQuantity = feedbackMapper.selectFinishedQualifiedQuantitySum(
+ workOrder.getId(), assemblyProcessIds);
+ if (assembledQuantity.compareTo(totalQuantity) < 0) {
+ throw exception(WM_PACKAGE_LINE_ASSEMBLY_NOT_COMPLETED,
+ workOrder.getCode(), assembledQuantity, totalQuantity, packedQuantity, currentQuantity);
+ }
}
private MesWmPackageLineDO validatePackageLineExists(Long id) {
--
Gitblit v1.9.3