sql/mysql/20261107_item_receipt_approve_time.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,3 @@ -- éè´å ¥åºå®¡æ¹éè¿æ¶é´ï¼ç¨äºä¸å¡åæ®è¯¦æ ä¸å¯¼åºã ALTER TABLE mes_wm_item_receipt ADD COLUMN approve_time DATETIME NULL COMMENT '审æ¹éè¿æ¶é´' AFTER process_instance_id; sql/mysql/20261108_hrm_sales_process_cancel_permission.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,7 @@ -- éå®è§è²ç人äºç³è¯·äººå¯å¨âæçæµç¨âæ¤éæ¬äººåèµ·çå®ä¾ã -- BPM æ¤éæ¥å£ä»ææµç¨åèµ·äººæ ¡éªï¼ä¸è½æ¤éä»äººçå®ä¾ã INSERT INTO system_role_menu (role_id, menu_id, creator, create_time, updater, update_time, deleted, tenant_id) SELECT 165, 1220, '1', NOW(), '1', NOW(), b'0', 0 WHERE EXISTS (SELECT 1 FROM system_role WHERE id = 165 AND deleted = b'0') AND EXISTS (SELECT 1 FROM system_menu WHERE id = 1220 AND permission = 'bpm:process-instance:cancel' AND deleted = b'0') AND NOT EXISTS (SELECT 1 FROM system_role_menu WHERE role_id = 165 AND menu_id = 1220 AND deleted = b'0'); yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnVariableConstants.java
@@ -9,6 +9,9 @@ */ public class BpmnVariableConstants { /** ä¸å¡æµç¨çå¯è¯»åå·ï¼ç¨äºå¾ åæµç¨æ é¢ã */ public static final String PROCESS_INSTANCE_VARIABLE_BUSINESS_NO = "businessNo"; /** * æµç¨å®ä¾çåé - ç¶æ * yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java
@@ -175,8 +175,9 @@ * @return è¿æ»¤åç表å */ public static Map<String, Object> filterProcessInstanceFormVariable(Map<String, Object> processVariables) { processVariables.remove(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS); return processVariables; Map<String, Object> filteredVariables = new HashMap<>(processVariables); filteredVariables.remove(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS); return filteredVariables; } /** yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -5,6 +5,7 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.*; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; @@ -844,10 +845,8 @@ validateStartUserSelectAssignees(userId, definition, startUserSelectAssignees, variables); // 2. å建æµç¨å®ä¾ if (variables == null) { variables = new HashMap<>(); } FlowableUtils.filterProcessInstanceFormVariable(variables); // è¿æ»¤ä¸ä¸ï¼é¿å ProcessInstance ç³»ç»çº§çåé被å ç¨ variables = FlowableUtils.filterProcessInstanceFormVariable( variables == null ? new HashMap<>() : variables); // å¤å¶å¹¶è¿æ»¤ï¼é¿å ä¿®æ¹è°ç¨æ¹çåé variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, userId); // 设置æµç¨åéï¼å起人 ID variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // æµç¨å®ä¾ç¶æï¼å®¡æ¹ä¸ BpmProcessInstanceStatusEnum.RUNNING.getStatus()); @@ -914,6 +913,11 @@ } BpmModelMetaInfoVO.TitleSetting titleSetting = definitionInfo.getTitleSetting(); if (titleSetting == null || !BooleanUtil.isTrue(titleSetting.getEnable())) { String businessNo = MapUtil.getStr(variables, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_BUSINESS_NO); if (StrUtil.isNotBlank(businessNo)) { return definition.getName() + "-" + businessNo; } return definition.getName(); } AdminUserRespDTO user = adminUserApi.getUser(userId); yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationServiceImpl.java
@@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.hrm.service.approval; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; @@ -150,8 +151,12 @@ @Override public void updateResignationApplication(HrmResignationApplicationSaveReqVO updateReqVO) { HrmResignationApplicationDO application = validateResignationApplicationExists(updateReqVO.getId()); validateOperator(application, getCurrentUserId()); if (!isEditableResignationStatus(application.getStatus())) { throw exception(RESIGNATION_APPLICATION_UPDATE_FAIL_NOT_DRAFT); } if (updateReqVO.getUserId() != null && !Objects.equals(updateReqVO.getUserId(), application.getUserId())) { throw exception(RESIGNATION_APPLICATION_APPLICANT_IMMUTABLE); } HrmResignationApplicationDO updateObj = BeanUtils.toBean(updateReqVO, HrmResignationApplicationDO.class); // ä¸è¦çç³è¯·äººï¼äº¤æ¥äººç»ä¸è§£ææâåå·¥ID + ç¨æ·IDâ @@ -177,6 +182,7 @@ @Override public void deleteResignationApplication(Long id) { HrmResignationApplicationDO application = validateResignationApplicationExists(id); validateOperator(application, getCurrentUserId()); if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) { throw exception(RESIGNATION_APPLICATION_UPDATE_FAIL_NOT_DRAFT); } @@ -328,6 +334,7 @@ @Transactional(rollbackFor = Exception.class) public void submitResignationApplication(Long id, String processDefinitionKey, Long userId) { HrmResignationApplicationDO application = validateResignationApplicationExists(id); validateOperator(application, userId); if (!isEditableResignationStatus(application.getStatus())) { throw exception(RESIGNATION_APPLICATION_SUBMIT_FAIL_NOT_DRAFT); } @@ -339,9 +346,17 @@ } ProcessDefinition processDefinition = resolveActiveProcessDefinition(processDefinitionKey); String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(processDefinition.getKey()).setBusinessKey(String.valueOf(id))); String processInstanceId = bpmProcessInstanceApi.createProcessInstance(application.getUserId(), new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(processDefinition.getKey()).setBusinessKey(String.valueOf(id)) .setVariables(Map.of("businessNo", application.getNo()))); resignationApplicationMapper.startApproval(id, processInstanceId, HrmAuditStatusEnum.PROCESS.getStatus()); } private void validateOperator(HrmResignationApplicationDO application, Long operatorId) { if (!Objects.equals(application.getUserId(), operatorId) && !Objects.equals(application.getCreator(), String.valueOf(operatorId))) { throw exception(RESIGNATION_APPLICATION_OPERATOR_NOT_ALLOWED); } } private void validateApproveCategoryAndProcessDefinition() { @@ -436,11 +451,12 @@ log.error("[updateResignationApplicationAuditStatus][application({}) ä¸å¤äºå®¡æ¹ä¸ï¼æ æ³æ´æ°å®¡æ¹ç»æ({})]", id, status); throw exception(RESIGNATION_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS); } resignationApplicationMapper.updateById(HrmResignationApplicationDO.builder() .id(id) .status(status) .approveTime(java.time.LocalDateTime.now()) .build()); resignationApplicationMapper.update(null, new LambdaUpdateWrapper<HrmResignationApplicationDO>() .eq(HrmResignationApplicationDO::getId, id) .set(HrmResignationApplicationDO::getStatus, status) .set(HrmResignationApplicationDO::getApproveTime, Objects.equals(status, HrmAuditStatusEnum.APPROVE.getStatus()) ? LocalDateTime.now() : null)); } @Override yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationServiceImpl.java
@@ -2,6 +2,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; 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.common.util.object.BeanUtils; @@ -15,7 +16,9 @@ import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationSaveReqVO; import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmTransferApplicationDO; import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmTransferApplicationMapper; import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO; import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum; import cn.iocoder.yudao.module.hrm.enums.HrmTransferTypeEnum; @@ -60,6 +63,8 @@ @Resource private HrmTransferApplicationMapper transferApplicationMapper; @Resource private HrmEmployeeMapper employeeMapper; @Resource private HrmNoRedisDAO noRedisDAO; @Resource private DeptApi deptApi; @@ -87,6 +92,7 @@ if (Objects.equals(createReqVO.getTargetPostId(), createReqVO.getCurrentPostId())) { throw exception(TRANSFER_APPLICATION_SAME_POST); } validateTargetDeptAndPost(createReqVO.getTargetDeptId(), createReqVO.getTargetPostId()); // 3. ç¡®å®è¢«è°å²åå·¥ï¼æªæå®æ¶é»è®¤å½åç»å½ç¨æ·ï¼ Long userId = createReqVO.getUserId() != null ? createReqVO.getUserId() : getLoginUserId(); AdminUserRespDTO user = userId != null ? adminUserApi.getUser(userId) : null; @@ -99,6 +105,7 @@ throw new ServiceException(TRANSFER_APPLICATION_APPLICANT_DEPT_EMPTY.getCode(), String.format("è°å²ç³è¯·å¤±è´¥ï¼åå·¥[%s]æªè®¾ç½®é¨é¨ï¼æ æ³ç¡®å®åé¨é¨ã请å å°ãå工管çãç¼è¾è¯¥å工档æ¡è¡¥å ¨é¨é¨ï¼åéæ°åèµ·è°å²ç³è¯·ã", user.getNickname())); } validateCurrentDept(userId, createReqVO.getCurrentDeptId()); if (createReqVO.getCurrentPostId() == null) { throw new ServiceException(TRANSFER_APPLICATION_APPLICANT_POST_EMPTY.getCode(), String.format("è°å²ç³è¯·å¤±è´¥ï¼åå·¥[%s]æªè®¾ç½®å²ä½ï¼æ æ³ç¡®å®åå²ä½ã请å å°ãå工管çãç¼è¾è¯¥å工档æ¡è¡¥å ¨å²ä½ï¼åéæ°åèµ·è°å²ç³è¯·ã", user.getNickname())); @@ -131,9 +138,13 @@ @Override public void updateTransferApplication(HrmTransferApplicationSaveReqVO updateReqVO) { HrmTransferApplicationDO application = validateTransferApplicationExists(updateReqVO.getId()); validateOperator(application, getLoginUserId()); if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus()) && !Objects.equals(application.getStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) { throw exception(TRANSFER_APPLICATION_UPDATE_FAIL_NOT_DRAFT); && !Objects.equals(application.getStatus(), HrmAuditStatusEnum.REJECT.getStatus())) { throw exception(TRANSFER_APPLICATION_UPDATE_FAIL_NOT_EDITABLE); } if (updateReqVO.getUserId() != null && !Objects.equals(updateReqVO.getUserId(), application.getUserId())) { throw exception(TRANSFER_APPLICATION_APPLICANT_IMMUTABLE); } if (Objects.equals(updateReqVO.getTargetDeptId(), updateReqVO.getCurrentDeptId())) { throw exception(TRANSFER_APPLICATION_SAME_DEPT); @@ -141,7 +152,11 @@ if (Objects.equals(updateReqVO.getTargetPostId(), updateReqVO.getCurrentPostId())) { throw exception(TRANSFER_APPLICATION_SAME_POST); } validateTargetDeptAndPost(updateReqVO.getTargetDeptId(), updateReqVO.getTargetPostId()); validateCurrentDept(application.getUserId(), updateReqVO.getCurrentDeptId() != null ? updateReqVO.getCurrentDeptId() : application.getCurrentDeptId()); HrmTransferApplicationDO updateObj = BeanUtils.toBean(updateReqVO, HrmTransferApplicationDO.class); updateObj.setUserId(null); transferApplicationMapper.updateById(updateObj); storageAttachmentApi.updateAttachments("file", "hrm_transfer_application", updateReqVO.getId(), updateReqVO.getBlobIds()); } @@ -149,6 +164,7 @@ @Override public void deleteTransferApplication(Long id) { HrmTransferApplicationDO application = validateTransferApplicationExists(id); validateOperator(application, getLoginUserId()); if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) { throw exception(TRANSFER_APPLICATION_UPDATE_FAIL_NOT_DRAFT); } @@ -263,9 +279,13 @@ @Transactional(rollbackFor = Exception.class) public void submitTransferApplication(Long id, String processDefinitionKey, Long userId) { HrmTransferApplicationDO application = validateTransferApplicationExists(id); if (ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) { validateOperator(application, userId); if (ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus()) && ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.REJECT.getStatus())) { throw exception(TRANSFER_APPLICATION_SUBMIT_FAIL_NOT_DRAFT); } validateTargetDeptAndPost(application.getTargetDeptId(), application.getTargetPostId()); validateCurrentDept(application.getUserId(), application.getCurrentDeptId()); // å ¨å±å 审æ¹ï¼ä¸å¡æ ¡éªéè¿åç´æ¥æ§è¡å®¡æ¹éè¿é»è¾ï¼æ éæµç¨æ¨¡åã if (bpmProcessInstanceApi.isGlobalAutoApprove()) { transferApplicationMapper.updateById(HrmTransferApplicationDO.builder() @@ -278,17 +298,45 @@ } validateApproveCategoryAndProcessDefinition(); ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey); if (processDefinition == null) { if (processDefinitionKey == null || processDefinitionKey.isBlank()) { throw exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); } String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id))); transferApplicationMapper.updateById(HrmTransferApplicationDO.builder() .id(id) .processInstanceId(processInstanceId) .status(HrmAuditStatusEnum.PROCESS.getStatus()) .build()); ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey); if (processDefinition == null || bpmProcessDefinitionService .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE).stream() .noneMatch(info -> Objects.equals(info.getProcessDefinitionId(), processDefinition.getId()))) { throw exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); } String processInstanceId = bpmProcessInstanceApi.createProcessInstance(application.getUserId(), new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id)) .setVariables(Map.of("businessNo", application.getNo()))); transferApplicationMapper.update(null, new LambdaUpdateWrapper<HrmTransferApplicationDO>() .eq(HrmTransferApplicationDO::getId, id) .set(HrmTransferApplicationDO::getProcessInstanceId, processInstanceId) .set(HrmTransferApplicationDO::getStatus, HrmAuditStatusEnum.PROCESS.getStatus()) .set(HrmTransferApplicationDO::getApproveTime, null)); } private void validateTargetDeptAndPost(Long targetDeptId, Long targetPostId) { deptApi.validateDeptList(Collections.singletonList(targetDeptId)); postApi.validPostList(Collections.singletonList(targetPostId)); } private void validateOperator(HrmTransferApplicationDO application, Long operatorId) { if (!Objects.equals(application.getUserId(), operatorId) && !Objects.equals(application.getCreator(), String.valueOf(operatorId))) { throw exception(TRANSFER_APPLICATION_OPERATOR_NOT_ALLOWED); } } private void validateCurrentDept(Long userId, Long currentDeptId) { HrmEmployeeDO employee = employeeMapper.selectByUserId(userId); if (employee == null || employee.getDeptId() == null) { throw exception(TRANSFER_APPLICATION_EMPLOYEE_DEPT_NOT_FOUND); } if (!Objects.equals(employee.getDeptId(), currentDeptId)) { throw exception(TRANSFER_APPLICATION_CURRENT_DEPT_MISMATCH); } } private void validateApproveCategoryAndProcessDefinition() { @@ -344,11 +392,12 @@ log.error("[updateTransferApplicationAuditStatus][application({}) ä¸å¤äºå®¡æ¹ä¸ï¼æ æ³æ´æ°å®¡æ¹ç»æ({})]", id, status); throw exception(TRANSFER_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS); } transferApplicationMapper.updateById(HrmTransferApplicationDO.builder() .id(id) .status(status) .approveTime(java.time.LocalDateTime.now()) .build()); transferApplicationMapper.update(null, new LambdaUpdateWrapper<HrmTransferApplicationDO>() .eq(HrmTransferApplicationDO::getId, id) .set(HrmTransferApplicationDO::getStatus, status) .set(HrmTransferApplicationDO::getApproveTime, Objects.equals(status, HrmAuditStatusEnum.APPROVE.getStatus()) ? java.time.LocalDateTime.now() : null)); } @Override @@ -356,4 +405,4 @@ return transferApplicationMapper.selectByProcessInstanceId(processInstanceId); } } } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java
@@ -60,6 +60,10 @@ @Schema(description = "BPM æµç¨å®ä¾ç¼å·", example = "xxx") private String processInstanceId; @Schema(description = "审æ¹éè¿æ¶é´") @ExcelProperty("审æ¹éè¿æ¶é´") private LocalDateTime approveTime; @Schema(description = "夿³¨", example = "夿³¨") @ExcelProperty("夿³¨") private String remark; yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java
@@ -88,6 +88,8 @@ * BPM æµç¨å®ä¹ Key */ private String processDefinitionKey; /** 审æ¹éè¿æ¶é´ï¼é©³åææ¤éæ¶ä¸ºç©ºã */ private LocalDateTime approveTime; /** * 夿³¨ */ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -354,6 +354,10 @@ "å·¥åºã{}ãæè®¡æ¶è®¡èªï¼è¯·å¡«åæ¬æ¬¡æ¥å·¥å·¥æ¶ï¼å°æ¶ï¼ï¼å·¥æ¶å¿ é¡»å¤§äº 0ï¼è¥å®é ææ°é计èªï¼è¯·å æè¯¥å·¥åºçè®¡è´¹ç±»åæ¹ä¸ºè®¡ä»¶"); ErrorCode PRO_FEEDBACK_TIME_BILLING_QUICK_UNSUPPORTED = new ErrorCode(1_040_506_020, "å·¥åºã{}ãæè®¡æ¶è®¡èªï¼å¿«æ·æ¥å·¥æ æ³å½å ¥å·¥æ¶ï¼å°æ¶ï¼ï¼è¯·å°ãç产æ¥å·¥ã页颿°å¢æ¥å·¥å¹¶å¡«åå·¥æ¶"); ErrorCode PRO_FEEDBACK_APPROVAL_PROCESS_KEY_REQUIRED = new ErrorCode(1_040_506_021, "å·¥åå·²å¼å¯æ¥å·¥å®¡æ¹ï¼ä½æªé ç½®å®¡æ¹æµç¨ï¼è¯·å 为工åé ç½®æµç¨ååæäº¤æ¥å·¥"); ErrorCode PRO_FEEDBACK_APPROVAL_PROCESS_KEY_INVALID = new ErrorCode(1_040_506_022, "å·¥åé ç½®çæ¥å·¥å®¡æ¹æµç¨æªæ¿æ´»æä¸å±äºæ¥å·¥å®¡æ¹åç±»ï¼è¯·æ£æ¥å·¥å审æ¹é ç½®"); // ========== MES ç产管ç-è¾ å©å·¥æ¶é ç½®ï¼1-040-510-000ï¼ ========== ErrorCode PRO_WORKTIME_AUX_NOT_EXISTS = new ErrorCode(1_040_510_000, "è¾ å©å·¥æ¶é¡¹ç®ä¸åå¨"); @@ -590,6 +594,7 @@ ErrorCode WM_ITEM_RECEIPT_STATUS_ERROR = new ErrorCode(1_040_705_005, "å ¥åºåç¶æä¸æ£ç¡®"); ErrorCode WM_ITEM_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_705_006, "已宿æå·²åæ¶çå ¥åºåä¸å è®¸åæ¶"); ErrorCode WM_ITEM_RECEIPT_ALREADY_EXISTS = new ErrorCode(1_040_705_007, "该å°è´§éç¥åå·²çæå ¥åºåï¼ä¸è½éå¤çæ"); ErrorCode WM_ITEM_RECEIPT_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_040_705_008, "éè´å ¥åºå®¡æ¹æµç¨æªé ç½®ææéæµç¨ä¸å±äºéè´å ¥åºå®¡æ¹"); ErrorCode WM_PURCHASE_ORDER_NOT_EXISTS = new ErrorCode(1_040_705_008, "éè´è®¢åä¸åå¨"); ErrorCode WM_PURCHASE_ORDER_NO_ITEM = new ErrorCode(1_040_705_008, "éè´è®¢åæ æç»æ°æ®"); ErrorCode WM_ITEM_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_705_100, "éè´å ¥åºåè¡ä¸åå¨"); @@ -854,6 +859,7 @@ ErrorCode WM_SALES_NOTICE_SUBMIT_PROCESS_KEY_REQUIRED = new ErrorCode(1_040_720_020, "æäº¤å货审æ¹åå¿ é¡»éæ©å®¡æ¹æµç¨ï¼æªä¼ æµç¨å®ä¹ Key"); ErrorCode WM_SALES_NOTICE_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_040_720_021, "åè´§å®¡æ¹æµç¨æªé ç½®ï¼è¯·å å¨ãæµç¨ç®¡çãä¸è®¾è®¡å¹¶å¯ç¨ãå货审æ¹ãæµç¨ï¼åæäº¤åè´§å"); ErrorCode WM_SALES_NOTICE_UPDATE_AUDIT_STATUS_FAIL_NOT_APPROVING = new ErrorCode(1_040_720_022, "åè´§å({})å½åç¶æä¸º[{}]ï¼ä¸å¤äºå®¡æ¹ä¸ï¼æ æ³æ´æ°å®¡æ¹ç»æ"); ErrorCode WM_SALES_NOTICE_STATUS_NOT_ALLOW_SUBMIT = new ErrorCode(1_040_720_023, "åªæèç¨¿ç¶æçåè´§éç¥åæè½æäº¤å®¡æ¹"); // ========== MES ä»åºç®¡ç-æ¡ç é ç½®ï¼1-040-730-000ï¼ ========== ErrorCode WM_BARCODE_CONFIG_NOT_EXISTS = new ErrorCode(1_040_730_000, "æ¡ç é ç½®ä¸åå¨"); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
@@ -4,11 +4,14 @@ 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; @@ -76,6 +79,7 @@ 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; @@ -90,6 +94,8 @@ @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; @@ -147,6 +153,8 @@ private MdmItemBatchConfigApi itemBatchConfigApi; @Resource private cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi processInstanceApi; @Resource private BpmProcessDefinitionService bpmProcessDefinitionService; @Override @Transactional(rollbackFor = Exception.class) @@ -267,16 +275,28 @@ } 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()) @@ -292,8 +312,11 @@ } // 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); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
@@ -2,6 +2,8 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -25,26 +27,29 @@ import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi; import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.flowable.engine.repository.ProcessDefinition; import lombok.extern.slf4j.Slf4j; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; /** @@ -54,6 +59,8 @@ @Validated @Slf4j public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { private static final String ITEM_RECEIPT_APPROVE_CATEGORY_CODE = "item_receipt_approve"; @Resource private MesWmItemReceiptMapper itemReceiptMapper; @@ -79,6 +86,8 @@ @Resource private BpmProcessInstanceApi processInstanceApi; @Resource private BpmProcessDefinitionService bpmProcessDefinitionService; @Resource private ErpPurchaseOrderApi purchaseOrderApi; @@ -465,7 +474,12 @@ @Transactional(rollbackFor = Exception.class) public void submitItemReceiptApproval(Long id, String processDefinitionKey) { // 1. æ ¡éªåå¨ + èç¨¿ç¶æ validateItemReceiptExistsAndDraft(id); MesWmItemReceiptDO receipt = validateItemReceiptExistsAndDraft(id); // 审æ¹å ¥å£ä¸æ®éæäº¤å ¥å£ä¿æä¸è´ï¼ç©ºè¡åæ®ä¸è½è¿å ¥å®¡æ¹ã List<MesWmItemReceiptLineDO> lines = itemReceiptLineService.getItemReceiptLineListByReceiptId(id); if (CollUtil.isEmpty(lines)) { throw exception(WM_ITEM_RECEIPT_NO_LINE); } // 2. å建 BPM æµç¨å®ä¾ Long userId = getCurrentUserId(); @@ -479,10 +493,21 @@ return; } if (StrUtil.isBlank(processDefinitionKey)) { throw exception(WM_ITEM_RECEIPT_BPM_PROCESS_DEFINITION_NOT_EXISTS); } ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey); if (processDefinition == null || bpmProcessDefinitionService .getProcessDefinitionInfoListByCategory(ITEM_RECEIPT_APPROVE_CATEGORY_CODE).stream() .noneMatch(info -> Objects.equals(info.getProcessDefinitionId(), processDefinition.getId()))) { throw exception(WM_ITEM_RECEIPT_BPM_PROCESS_DEFINITION_NOT_EXISTS); } String processInstanceId = processInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(processDefinitionKey) .setBusinessKey(String.valueOf(id))); .setBusinessKey(String.valueOf(id)) .setVariables(Map.of("businessNo", receipt.getCode()))); // 3. æ´æ°å ¥åºåç¶æä¸ºå®¡æ¹ä¸ itemReceiptMapper.updateById(new MesWmItemReceiptDO() @@ -504,8 +529,11 @@ // 2. æ ¹æ®å®¡æ¹ç»ææ´æ°ç¶æ Integer newStatus = convertBpmResultToReceiptStatus(bpmResult); if (newStatus != null) { itemReceiptMapper.updateById(new MesWmItemReceiptDO() .setId(id).setStatus(newStatus)); itemReceiptMapper.update(null, new LambdaUpdateWrapper<MesWmItemReceiptDO>() .eq(MesWmItemReceiptDO::getId, id) .set(MesWmItemReceiptDO::getStatus, newStatus) .set(MesWmItemReceiptDO::getApproveTime, BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult) ? LocalDateTime.now() : null)); } } @@ -527,11 +555,7 @@ * è·åå½åç¨æ· ID */ private Long getCurrentUserId() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.getPrincipal() instanceof Long) { return (Long) authentication.getPrincipal(); } return 1L; // é»è®¤ç¨æ· return Objects.requireNonNull(getLoginUserId(), "éè´å ¥åºå®¡æ¹éè¦ç»å½ç¨æ·"); } /** yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java
@@ -44,6 +44,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -142,7 +143,10 @@ @Transactional(rollbackFor = Exception.class) public void submitSalesNotice(Long id, String processDefinitionKey, Long userId) { // 1.1 æ ¡éªåå¨ + èç¨¿ç¶æ MesWmSalesNoticeDO notice = validateSalesNoticeExistsAndDraft(id); MesWmSalesNoticeDO notice = validateSalesNoticeExists(id); if (ObjUtil.notEqual(PREPARE.getStatus(), notice.getStatus())) { throw exception(WM_SALES_NOTICE_STATUS_NOT_ALLOW_SUBMIT); } // 1.2 æ£æ¥æ¯å¦æè¡é¡¹ç® List<MesWmSalesNoticeLineDO> lines = salesNoticeLineService.getSalesNoticeLineListByNoticeId(id); if (CollUtil.isEmpty(lines)) { @@ -163,13 +167,16 @@ } validateSalesNoticeApproveCategoryAndProcessDefinition(); ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey); if (processDefinition == null) { if (processDefinition == null || bpmProcessDefinitionService .getProcessDefinitionInfoListByCategory(SALES_DELIVERY_APPROVE_CATEGORY_CODE).stream() .noneMatch(info -> Objects.equals(info.getProcessDefinitionId(), processDefinition.getId()))) { throw exception(WM_SALES_NOTICE_BPM_PROCESS_DEFINITION_NOT_EXISTS); } // 4. åå»ºå®¡æ¹æµç¨å®ä¾ï¼è¿å ¥å®¡æ¹ä¸ String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id))); .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id)) .setVariables(Map.of("businessNo", notice.getCode()))); salesNoticeMapper.updateById(new MesWmSalesNoticeDO() .setId(id).setProcessInstanceId(processInstanceId).setStatus(APPROVING.getStatus())); } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/scrap/MesWmScrapSaleService.java
@@ -46,7 +46,7 @@ saleMapper.updateById(update); String processId = processApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(PROCESS_KEY).setBusinessKey(String.valueOf(id)) .setVariables(Map.of("saleCode", sale.getCode(), "buyer", sale.getBuyer(), .setVariables(Map.of("businessNo", sale.getCode(), "saleCode", sale.getCode(), "buyer", sale.getBuyer(), "totalAmount", lines.stream().map(line -> line.getQuantity().multiply(line.getUnitPrice())) .reduce(BigDecimal.ZERO, BigDecimal::add)))); MesWmScrapSaleDO processUpdate = new MesWmScrapSaleDO();