| | |
| | | public class MesProFeedbackServiceImpl implements MesProFeedbackService { |
| | | |
| | | @Resource |
| | | private MesProFeedbackEquipmentService equipmentService; |
| | | |
| | | @Resource |
| | | private MesProFeedbackMapper feedbackMapper; |
| | | |
| | | @Resource |
| | |
| | | // 1. 校验 |
| | | MesProTaskDO task = validateFeedbackData(createReqVO); |
| | | |
| | | // 2. 插入(自动填充 itemId) |
| | | // 2. 插入(主键由数据库自增,忽略请求中可能残留的 id;自动填充 itemId) |
| | | MesProFeedbackDO feedback = BeanUtils.toBean(createReqVO, MesProFeedbackDO.class) |
| | | .setId(null) |
| | | .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus()) |
| | | .setItemId(task.getItemId()); |
| | | feedbackMapper.insert(feedback); |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateFeedback(MesProFeedbackSaveReqVO updateReqVO) { |
| | | equipmentService.lock(); |
| | | // 1.1 校验存在 + 草稿状态 |
| | | validateFeedbackStatusPrepare(updateReqVO.getId()); |
| | | // 1.2 校验业务数据 |
| | |
| | | MesProFeedbackDO updateObj = BeanUtils.toBean(updateReqVO, MesProFeedbackDO.class) |
| | | .setItemId(task.getItemId()); |
| | | feedbackMapper.updateById(updateObj); |
| | | equipmentService.resetSnapshot(updateReqVO.getId()); |
| | | // 3. 保存参数值;必填参数校验失败时整体回滚 |
| | | saveParamValues(task.getId(), updateReqVO.getParamValues()); |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteFeedback(Long id) { |
| | | equipmentService.lock(); |
| | | // 1. 校验存在 + 草稿状态 |
| | | validateFeedbackStatusPrepare(id); |
| | | |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void submitFeedback(MesProFeedbackSubmitReqVO reqVO) { |
| | | equipmentService.lock(); |
| | | Long id = reqVO.getId(); |
| | | // 1. 校验存在 + 草稿状态 |
| | | MesProFeedbackDO feedback = validateFeedbackStatusPrepare(id); |
| | | equipmentService.validateSubmission(feedback); |
| | | // 1.1 顺序报工校验:同一生产工单内,上一道工序必须已报工完成,否则不允许提交 |
| | | if (feedback.getTaskId() != null) { |
| | | MesProTaskDO submitTask = taskService.getTask(feedback.getTaskId()); |
| | |
| | | |
| | | MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(feedback.getWorkOrderId()); |
| | | |
| | | if (workOrder != null && Boolean.TRUE.equals(workOrder.getFeedbackApprove()) && cn.hutool.core.util.StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) { |
| | | if (!processInstanceApi.isGlobalAutoApprove() && workOrder != null |
| | | && Boolean.TRUE.equals(workOrder.getFeedbackApprove()) |
| | | && cn.hutool.core.util.StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) { |
| | | // 2. 更新状态为审批中,并启动流程 |
| | | String processInstanceId = processInstanceApi.createProcessInstance(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(), |
| | | new cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO() |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void rejectFeedback(Long id) { |
| | | equipmentService.lock(); |
| | | // 1. 校验存在 + 审批中状态 |
| | | validateFeedbackStatusApproving(id); |
| | | |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean approveFeedback(MesProFeedbackApproveReqVO reqVO) { |
| | | equipmentService.lock(); |
| | | // 1.1 校验存在 + 审批中状态 |
| | | MesProFeedbackDO feedback = validateFeedbackStatusApproving(reqVO.getId()); |
| | | equipmentService.validateApproval(feedback); |
| | | try (var equipmentScope = equipmentService.beginApproval(feedback)) { |
| | | return approveValidatedFeedback(reqVO, feedback); |
| | | } |
| | | } |
| | | |
| | | private boolean approveValidatedFeedback(MesProFeedbackApproveReqVO reqVO, MesProFeedbackDO feedback) { |
| | | // 1.2 校验报工数量 > 0 |
| | | if (feedback.getFeedbackQuantity() == null |
| | | || feedback.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) { |
| | |
| | | // 2.1 查询工序的关键工序标识 + 检验标识(需在 uncheckQuantity 校验之前,因为质检工序允许 uncheckQuantity > 0) |
| | | MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( |
| | | feedback.getRouteId(), feedback.getProcessId()); |
| | | boolean keyFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getKeyFlag()); |
| | | // 未配置工艺路线工序时,视为单工序生产,按最后一道工序更新工单产量 |
| | | boolean noProcessChain = routeProcess == null |
| | | && CollUtil.isEmpty(workOrderProcessService.getWorkOrderProcessListByWorkOrderId(feedback.getWorkOrderId())); |
| | | boolean keyFlag = routeProcess != null |
| | | ? Boolean.TRUE.equals(routeProcess.getKeyFlag()) |
| | | : noProcessChain; |
| | | boolean checkFlag = routeProcess != null && Boolean.TRUE.equals(routeProcess.getCheckFlag()); |
| | | // 2.2 非质检工序:合格品/不良品数量由质检确定;本工序不经过质检,报工未填写时默认全部为合格品 |
| | | if (!checkFlag |
| | |
| | | productProduceService.generateProductProduce(feedback, true, reqVO); |
| | | feedbackMapper.updateById(new MesProFeedbackDO().setId(reqVO.getId()) |
| | | .setStatus(MesProFeedbackStatusEnum.UNCHECK.getStatus())); |
| | | equipmentService.afterApproved(feedback); |
| | | return false; |
| | | } else { |
| | | // 6.2 无需检验:生成产出单(按合格/不合格拆行),直接完成入库 |
| | |
| | | |
| | | } |
| | | |
| | | equipmentService.afterApproved(feedback); |
| | | return true; // 已完成 |
| | | } |
| | | |
| | |
| | | // 3. 更新订单的已生产数量 |
| | | // 新增逻辑:只有在该笔订单最后一个工序才更新生产订单的已生产数量 |
| | | MesProWorkOrderProcessDO lastProcess = workOrderProcessService.getLastWorkOrderProcessByWorkOrderId(feedback.getWorkOrderId()); |
| | | if (lastProcess != null && ObjUtil.equal(lastProcess.getProcessId(), feedback.getProcessId())) { |
| | | // 未配置工序链路的单工序工单,报工即视为完成最后一道工序 |
| | | boolean noProcessChain = lastProcess == null && feedback.getRouteId() == null; |
| | | if (noProcessChain || (lastProcess != null && ObjUtil.equal(lastProcess.getProcessId(), feedback.getProcessId()))) { |
| | | workOrderService.updateProducedQuantity(feedback.getWorkOrderId(), |
| | | feedback.getFeedbackQuantity()); |
| | | // 4. 更新 MPS 的已生产数量(如果是销售订单来源) |
| | |
| | | reqVO.setItemId(task.getItemId()); |
| | | reqVO.setWorkstationId(task.getWorkstationId()); |
| | | |
| | | // 3. 校验工艺路线 + 工序配置有效 |
| | | MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( |
| | | task.getRouteId(), task.getProcessId()); |
| | | if (routeProcess == null) { |
| | | throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID); |
| | | } |
| | | // 3. 未配置工艺路线/工序时按单工序报工处理,不再强制校验路线工序配置 |
| | | // 4.1 校验数量:无论是否需要检验,报工只需填报工数量,且必须 > 0 |
| | | // 合格品/不良品数量由质检确定(非质检工序在审批时默认全部为合格品) |
| | | if (reqVO.getFeedbackQuantity() == null |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesProFeedbackQuickCreateRespVO quickCreateFeedback(MesProFeedbackQuickCreateReqVO reqVO) { |
| | | equipmentService.lock(); |
| | | // 1. 校验任务存在且非终态 |
| | | MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId()); |
| | | |
| | |
| | | // 1.1 顺序报工校验:同一生产工单内,上一道工序必须已报工完成,否则不允许报工 |
| | | validatePreviousProcessFinished(task); |
| | | |
| | | // 2. 校验工艺路线工序配置 |
| | | MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( |
| | | task.getRouteId(), task.getProcessId()); |
| | | if (routeProcess == null) { |
| | | throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID); |
| | | } |
| | | // 2. 未配置工艺路线/工序时按单工序报工处理,不再强制校验路线工序配置 |
| | | // 3. 校验数量:只填报工数量,且必须 > 0(合格品/不良品数量由质检确定) |
| | | if (reqVO.getFeedbackQuantity() == null |
| | | || reqVO.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) { |
| | |
| | | .setFeedbackTime(LocalDateTime.now()) |
| | | .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus()) |
| | | .setRemark(reqVO.getRemark()); |
| | | equipmentService.validateSubmission(feedback); |
| | | feedbackMapper.insert(feedback); |
| | | saveParamValues(task.getId(), reqVO.getParamValues()); |
| | | // 5. 返回结果 |