| | |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.*; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | |
| | | import java.util.List; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | |
| | | @Validated |
| | | @lombok.extern.slf4j.Slf4j |
| | | public class MesProFeedbackServiceImpl implements MesProFeedbackService { |
| | | |
| | | private static final String FEEDBACK_APPROVE_CATEGORY_CODE = "mes_pro_feedback_audit"; |
| | | |
| | | @Resource |
| | | private MesProFeedbackEquipmentService equipmentService; |
| | |
| | | private MdmItemBatchConfigApi itemBatchConfigApi; |
| | | @Resource |
| | | private cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi processInstanceApi; |
| | | @Resource |
| | | private BpmProcessDefinitionService bpmProcessDefinitionService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | } |
| | | |
| | | MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(feedback.getWorkOrderId()); |
| | | if (workOrder != null && Boolean.TRUE.equals(workOrder.getFeedbackApprove()) |
| | | && StrUtil.isBlank(workOrder.getProcessDefinitionKey())) { |
| | | throw exception(PRO_FEEDBACK_APPROVAL_PROCESS_KEY_REQUIRED); |
| | | } |
| | | |
| | | // 1.2 报工与质检分离:提交报工不再自动生成过程检验单,质检由质检部门手工建单 |
| | | if (!processInstanceApi.isGlobalAutoApprove() && workOrder != null |
| | | && Boolean.TRUE.equals(workOrder.getFeedbackApprove()) |
| | | && cn.hutool.core.util.StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) { |
| | | && StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) { |
| | | ProcessDefinition processDefinition = bpmProcessDefinitionService |
| | | .getActiveProcessDefinition(workOrder.getProcessDefinitionKey()); |
| | | if (processDefinition == null || bpmProcessDefinitionService |
| | | .getProcessDefinitionInfoListByCategory(FEEDBACK_APPROVE_CATEGORY_CODE).stream() |
| | | .noneMatch(info -> Objects.equals(info.getProcessDefinitionId(), processDefinition.getId()))) { |
| | | throw exception(PRO_FEEDBACK_APPROVAL_PROCESS_KEY_INVALID); |
| | | } |
| | | // 2. 更新状态为审批中,并启动流程 |
| | | String processInstanceId = processInstanceApi.createProcessInstance(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(), |
| | | new cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO() |
| | | .setProcessDefinitionKey(workOrder.getProcessDefinitionKey()) |
| | | .setBusinessKey(String.valueOf(id))); |
| | | .setBusinessKey(String.valueOf(id)) |
| | | .setVariables(Map.of("businessNo", feedback.getCode()))); |
| | | |
| | | feedbackMapper.updateById(new MesProFeedbackDO().setId(id) |
| | | .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus()) |
| | |
| | | } |
| | | |
| | | // 3. 更新状态为审批中,然后直接通过审批 |
| | | feedbackMapper.updateById(new MesProFeedbackDO().setId(id) |
| | | .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus())); |
| | | feedbackMapper.update(null, new LambdaUpdateWrapper<MesProFeedbackDO>() |
| | | .eq(MesProFeedbackDO::getId, id) |
| | | .set(MesProFeedbackDO::getStatus, MesProFeedbackStatusEnum.APPROVING.getStatus()) |
| | | .set(MesProFeedbackDO::getProcessInstanceId, null) |
| | | .set(MesProFeedbackDO::getProcessDefinitionKey, null)); |
| | | MesProFeedbackApproveReqVO approveReqVO = cn.iocoder.yudao.framework.common.util.object.BeanUtils.toBean(reqVO, MesProFeedbackApproveReqVO.class); |
| | | // 自动审批:过程检验单刚生成尚未填写,不做质检工资前置校验(质量调整留空) |
| | | approveFeedback(approveReqVO, false); |
| | |
| | | reqVO.setLotNumber(reason); |
| | | } |
| | | } |
| | | approveFeedback(reqVO); |
| | | // BPM 回调时流程实例仍在运行,必须走内部方法,不能被「已发起流程」的校验拦住 |
| | | doApproveFeedback(reqVO, feedback, true); |
| | | } else if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(bpmResult) || |
| | | cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.CANCEL.getStatus().equals(bpmResult)) { |
| | | rejectFeedback(id); |
| | | doRejectFeedback(id); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void rejectFeedback(Long id) { |
| | | equipmentService.lock(); |
| | | // 1. 校验存在 + 审批中状态 |
| | | validateFeedbackStatusApproving(id); |
| | | MesProFeedbackDO feedback = validateFeedbackStatusApproving(id); |
| | | // 1.1 已发起审批流程的报工单只能由审批人通过「待办任务」处理,避免业务接口绕过流程 |
| | | if (StrUtil.isNotBlank(feedback.getProcessInstanceId())) { |
| | | throw exception(PRO_FEEDBACK_APPROVAL_HANDLE_IN_BPM); |
| | | } |
| | | doRejectFeedback(id); |
| | | } |
| | | |
| | | // 2. 更新状态为草稿 |
| | | private void doRejectFeedback(Long id) { |
| | | equipmentService.lock(); |
| | | // 1. 更新状态为草稿 |
| | | feedbackMapper.updateById(new MesProFeedbackDO().setId(id) |
| | | .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus())); |
| | | } |
| | |
| | | } |
| | | |
| | | private boolean approveFeedback(MesProFeedbackApproveReqVO reqVO, boolean enforceQualityGate) { |
| | | equipmentService.lock(); |
| | | // 1.1 校验存在 + 审批中状态 |
| | | MesProFeedbackDO feedback = validateFeedbackStatusApproving(reqVO.getId()); |
| | | // 1.2 已发起审批流程的报工单只能由审批人通过「待办任务」处理,避免业务接口绕过流程 |
| | | if (StrUtil.isNotBlank(feedback.getProcessInstanceId())) { |
| | | throw exception(PRO_FEEDBACK_APPROVAL_HANDLE_IN_BPM); |
| | | } |
| | | return doApproveFeedback(reqVO, feedback, enforceQualityGate); |
| | | } |
| | | |
| | | private boolean doApproveFeedback(MesProFeedbackApproveReqVO reqVO, MesProFeedbackDO feedback, |
| | | boolean enforceQualityGate) { |
| | | equipmentService.lock(); |
| | | equipmentService.validateApproval(feedback); |
| | | try (var equipmentScope = equipmentService.beginApproval(feedback)) { |
| | | return approveValidatedFeedback(reqVO, feedback, enforceQualityGate); |