feat(hrm): 新增员工用工性质、班组归属字段及考勤异常处理优化
- 在 HrmEmployeeDO 中添加用工性质(employmentType)和所属班组(teamId)字段
- 重构考勤异常审批监听器,支持加班申请审批通过后回写加班时长功能
- 实现加班时长计算逻辑,基于规则下班时间与实际打卡时间差值计算
- 优化补卡和加班审批通过后的考勤记录更新机制
- 新增证书和合同到期提醒功能,集成懒触发机制
- 添加培训活动和转正申请编号生成功能
- 扩展绩效考核范围功能,支持按班组生成被考核人列表
- 优化员工列表展示,新增班组名称和用工性质名称显示
- 新增转正申请和培训管理相关错误码常量定义
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.api.workhour; |
| | | |
| | | import cn.iocoder.yudao.module.hrm.api.workhour.dto.HrmWorkHourSummaryRespDTO; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * HRM æåº¦å·¥æ¶æ±æ» API æ¥å£ |
| | | * <p> |
| | | * ä¾ææ¬æ ¸ç®ç模åè°ç¨ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface HrmWorkHourSummaryApi { |
| | | |
| | | /** |
| | | * è·åæå®å¨æçå
¨é¨åå·¥å·¥æ¶æ±æ» |
| | | * |
| | | * @param period æ ¸ç®å¨æï¼yyyy-MMï¼ |
| | | * @return åå·¥å·¥æ¶æ±æ» |
| | | */ |
| | | List<HrmWorkHourSummaryRespDTO> getSummaryByPeriod(String period); |
| | | |
| | | /** |
| | | * è·åæå®åå·¥æå®å¨æçå·¥æ¶æ±æ» |
| | | * |
| | | * @param employeeId åå·¥ID |
| | | * @param period æ ¸ç®å¨æï¼yyyy-MMï¼ |
| | | * @return åå·¥å·¥æ¶æ±æ» |
| | | */ |
| | | HrmWorkHourSummaryRespDTO getSummaryByEmployeeAndPeriod(Long employeeId, String period); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.api.workhour.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * HRM æåº¦å·¥æ¶æ±æ» Response DTO |
| | | * <p> |
| | | * ä¾ææ¬æ ¸ç®ç模åè°ç¨ï¼è·åæå®æ ¸ç®å¨æçåå·¥æåº¦å·¥æ¶ï¼èå¤å£å¾ï¼ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Data |
| | | public class HrmWorkHourSummaryRespDTO { |
| | | |
| | | /** |
| | | * åå·¥IDï¼HrmEmployeeDO#getId()ï¼ |
| | | */ |
| | | private Long employeeId; |
| | | |
| | | /** |
| | | * åå·¥ç¼å· |
| | | */ |
| | | private String employeeNo; |
| | | |
| | | /** |
| | | * åå·¥å§å |
| | | */ |
| | | private String employeeName; |
| | | |
| | | /** |
| | | * é¨é¨ID |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * é¨é¨åç§° |
| | | */ |
| | | private String deptName; |
| | | |
| | | /** |
| | | * æ ¸ç®å¨æï¼yyyy-MMï¼ |
| | | */ |
| | | private String period; |
| | | |
| | | /** |
| | | * åºå¤å¤©æ° |
| | | */ |
| | | private Integer workDays; |
| | | |
| | | /** |
| | | * æ£å¸¸å·¥æ¶ï¼å°æ¶ï¼ |
| | | */ |
| | | private BigDecimal workHours; |
| | | |
| | | /** |
| | | * å çå·¥æ¶ï¼å°æ¶ï¼ |
| | | */ |
| | | private BigDecimal overtimeHours; |
| | | |
| | | } |
| | |
| | | ErrorCode PERFORMANCE_APPRAISE_RESULT_NOT_EXISTS = new ErrorCode(1_030_008_007, "èæ ¸ç»æä¸åå¨"); |
| | | ErrorCode PERFORMANCE_APPRAISE_RESULT_ITEM_NOT_EXISTS = new ErrorCode(1_030_008_008, "èæ ¸ææ è¯åä¸åå¨"); |
| | | ErrorCode PERFORMANCE_APPRAISE_SCORE_FAIL_STATUS = new ErrorCode(1_030_008_009, "è¯å失败ï¼åå ï¼æ¹æ¡ä¸æ¯å·²åå¸/è¿è¡ä¸ç¶æ"); |
| | | ErrorCode PERFORMANCE_APPRAISE_SCOPE_TEAM_EMPTY = new ErrorCode(1_030_008_010, "æå®çç»ä¸ºç©ºï¼æ æ³çæè¢«èæ ¸äºº"); |
| | | |
| | | // ========== èªé
¬ç®¡ç 1-030-005-000 ========== |
| | | ErrorCode SALARY_STRUCTURE_NOT_EXISTS = new ErrorCode(1_030_005_000, "èªé
¬ç»æä¸åå¨"); |
| | |
| | | ErrorCode SALARY_PAYMENT_DELETE_FAIL = new ErrorCode(1_030_005_023, "å é¤å¤±è´¥ï¼åå ï¼ä»
å¾
åæ¾ç¶æå¯å é¤ï¼è¯·å
æ¤é已忾æç»"); |
| | | ErrorCode SALARY_PAYMENT_HAS_PAID_DETAIL = new ErrorCode(1_030_005_024, "å é¤å¤±è´¥ï¼åå ï¼åå¨å·²åæ¾æç»ï¼è¯·å
æ¤é"); |
| | | |
| | | // ========== 转æ£ç³è¯· 1-030-006-000 ========== |
| | | ErrorCode REGULARIZE_APPLICATION_NOT_EXISTS = new ErrorCode(1_030_006_000, "转æ£ç³è¯·ä¸åå¨"); |
| | | ErrorCode REGULARIZE_APPLICATION_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_030_006_001, "转æ£ç³è¯·æ´æ°å¤±è´¥ï¼åå ï¼ä¸æ¯èç¨¿ç¶æ"); |
| | | ErrorCode REGULARIZE_APPLICATION_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_030_006_002, "转æ£ç³è¯·æäº¤å¤±è´¥ï¼åå ï¼ä¸æ¯èç¨¿ç¶æ"); |
| | | ErrorCode REGULARIZE_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_006_003, "æ´æ°è½¬æ£ç³è¯·å®¡æ¹ç¶æå¤±è´¥ï¼åå ï¼ä¸æ¯å®¡æ¹ä¸ç¶æ"); |
| | | ErrorCode REGULARIZE_APPLICATION_NO_EXISTS = new ErrorCode(1_030_006_004, "çæè½¬æ£ç³è¯·åå·éå¤ï¼è¯·éè¯"); |
| | | ErrorCode REGULARIZE_APPLICATION_EXISTS = new ErrorCode(1_030_006_005, "该å工已åå¨è½¬æ£ç³è¯·ï¼è¯·å¿éå¤æäº¤"); |
| | | ErrorCode REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_006_006, "转æ£å®¡æ¹æµç¨ä¸åå¨"); |
| | | |
| | | // ========== å¹è®ç®¡ç 1-030-009-000 ========== |
| | | ErrorCode TRAINING_NOT_EXISTS = new ErrorCode(1_030_009_000, "å¹è®æ´»å¨ä¸åå¨"); |
| | | ErrorCode TRAINING_PARTICIPANT_NOT_EXISTS = new ErrorCode(1_030_009_001, "å¹è®åè®äººåä¸åå¨"); |
| | | ErrorCode TRAINING_EMPLOYEE_LIST_EMPTY = new ErrorCode(1_030_009_002, "è¯·éæ©åè®åå·¥"); |
| | | ErrorCode TRAINING_CERT_VALIDITY_REQUIRED = new ErrorCode(1_030_009_003, "å¯ç¨èªå¨åè¯æ¶å¿
须填åè¯ä¹¦æææï¼æï¼"); |
| | | ErrorCode TRAINING_CERT_TYPE_NOT_SUPPORT = new ErrorCode(1_030_009_004, "ä»
å®å
¨å¹è®/æè½å¹è®æ¯æèªå¨åè¯"); |
| | | ErrorCode TRAINING_LOCKED = new ErrorCode(1_030_009_005, "å¹è®å·²å®ææå·²åæ¶ï¼ä¸å¯ä¿®æ¹"); |
| | | ErrorCode TRAINING_COMPLETE_FAIL_STATUS = new ErrorCode(1_030_009_006, "å¹è®å®ææä½å¤±è´¥ï¼åå ï¼ä»
è稿/å¾
å¼å±ç¶æå¯å®æ"); |
| | | ErrorCode TRAINING_PARTICIPANT_EXISTS = new ErrorCode(1_030_009_007, "该å工已卿¬æ¬¡å¹è®åè®ååä¸ï¼è¯·å¿é夿·»å "); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.enums; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * ç¨å·¥æ§è´¨æä¸¾ |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Getter |
| | | public enum HrmEmploymentTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | FORMAL(1, "æ£å¼"), |
| | | LABOR(2, "å³å¡"), |
| | | OUTSOURCING(3, "å¤å
"), |
| | | INTERNSHIP(4, "å®ä¹ "), |
| | | RETIRED_REHIRE(5, "éä¼è¿è"), |
| | | OTHER(6, "å
¶ä»"); |
| | | |
| | | private final Integer type; |
| | | private final String name; |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(HrmEmploymentTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | public static String getNameByType(Integer type) { |
| | | return Arrays.stream(values()) |
| | | .filter(e -> e.getType().equals(type)) |
| | | .findFirst() |
| | | .map(HrmEmploymentTypeEnum::getName) |
| | | .orElse(""); |
| | | } |
| | | |
| | | } |
| | |
| | | <artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- 宿¶ä»»å¡ç¸å
³ï¼è¯ä¹¦/ååå°ææéæ¯æ¥ä»»å¡ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-spring-boot-starter-job</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Web ç¸å
³ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.api.workhour; |
| | | |
| | | import cn.iocoder.yudao.module.hrm.api.workhour.dto.HrmWorkHourSummaryRespDTO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.workhour.HrmWorkHourSummaryDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.workhour.HrmWorkHourSummaryMapper; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æåº¦å·¥æ¶æ±æ» API å®ç° |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | public class HrmWorkHourSummaryApiImpl implements HrmWorkHourSummaryApi { |
| | | |
| | | @Resource |
| | | private HrmWorkHourSummaryMapper workHourSummaryMapper; |
| | | @Resource |
| | | private HrmEmployeeService employeeService; |
| | | @Resource |
| | | private DeptApi deptApi; |
| | | |
| | | @Override |
| | | public List<HrmWorkHourSummaryRespDTO> getSummaryByPeriod(String period) { |
| | | return workHourSummaryMapper.selectListByPeriod(period).stream() |
| | | .map(this::convert) |
| | | .toList(); |
| | | } |
| | | |
| | | @Override |
| | | public HrmWorkHourSummaryRespDTO getSummaryByEmployeeAndPeriod(Long employeeId, String period) { |
| | | HrmWorkHourSummaryDO summary = workHourSummaryMapper.selectByEmployeeIdAndPeriod(employeeId, period); |
| | | return summary == null ? null : convert(summary); |
| | | } |
| | | |
| | | private HrmWorkHourSummaryRespDTO convert(HrmWorkHourSummaryDO summary) { |
| | | HrmWorkHourSummaryRespDTO dto = new HrmWorkHourSummaryRespDTO(); |
| | | dto.setEmployeeId(summary.getEmployeeId()); |
| | | dto.setDeptId(summary.getDeptId()); |
| | | dto.setPeriod(summary.getPeriod()); |
| | | dto.setWorkDays(summary.getWorkDays()); |
| | | dto.setWorkHours(summary.getWorkHours()); |
| | | dto.setOvertimeHours(summary.getOvertimeHours()); |
| | | HrmEmployeeDO employee = employeeService.getEmployee(summary.getEmployeeId()); |
| | | if (employee != null) { |
| | | dto.setEmployeeNo(employee.getEmployeeNo()); |
| | | dto.setEmployeeName(employee.getName()); |
| | | } |
| | | if (summary.getDeptId() != null) { |
| | | DeptRespDTO dept = deptApi.getDept(summary.getDeptId()); |
| | | if (dept != null) { |
| | | dto.setDeptName(dept.getName()); |
| | | } |
| | | } |
| | | return dto; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.approval; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.service.approval.HrmRegularizeApplicationService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | @Tag(name = "管çåå° - HRM 转æ£ç³è¯·") |
| | | @RestController |
| | | @RequestMapping("/hrm/regularize") |
| | | @Validated |
| | | public class HrmRegularizeApplicationController { |
| | | |
| | | @Resource |
| | | private HrmRegularizeApplicationService regularizeApplicationService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建转æ£ç³è¯·") |
| | | @PreAuthorize("@ss.hasPermission('hrm:regularize:create')") |
| | | public CommonResult<Long> createRegularizeApplication(@Valid @RequestBody HrmRegularizeApplicationSaveReqVO createReqVO) { |
| | | return success(regularizeApplicationService.createRegularizeApplication(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°è½¬æ£ç³è¯·") |
| | | @PreAuthorize("@ss.hasPermission('hrm:regularize:update')") |
| | | public CommonResult<Boolean> updateRegularizeApplication(@Valid @RequestBody HrmRegularizeApplicationSaveReqVO updateReqVO) { |
| | | regularizeApplicationService.updateRegularizeApplication(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤è½¬æ£ç³è¯·") |
| | | @Parameter(name = "id", description = "ç³è¯·ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:regularize:delete')") |
| | | public CommonResult<Boolean> deleteRegularizeApplication(@RequestParam("id") Long id) { |
| | | regularizeApplicationService.deleteRegularizeApplication(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾è½¬æ£ç³è¯·è¯¦æ
") |
| | | @Parameter(name = "id", description = "ç³è¯·ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:regularize:query')") |
| | | public CommonResult<HrmRegularizeApplicationRespVO> getRegularizeApplication(@RequestParam("id") Long id) { |
| | | return success(regularizeApplicationService.getRegularizeApplicationDetail(id)); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾è½¬æ£ç³è¯·å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:regularize:query')") |
| | | public CommonResult<PageResult<HrmRegularizeApplicationRespVO>> getRegularizeApplicationPage(@Valid HrmRegularizeApplicationPageReqVO pageReqVO) { |
| | | return success(regularizeApplicationService.getRegularizeApplicationPage(pageReqVO)); |
| | | } |
| | | |
| | | @PostMapping("/submit") |
| | | @Operation(summary = "æäº¤è½¬æ£ç³è¯·å®¡æ¹") |
| | | @Parameter(name = "id", description = "ç³è¯·ID", required = true) |
| | | @Parameter(name = "processDefinitionKey", description = "æµç¨å®ä¹Key", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:regularize:submit')") |
| | | public CommonResult<Boolean> submitRegularizeApplication(@RequestParam("id") Long id, |
| | | @RequestParam("processDefinitionKey") String processDefinitionKey) { |
| | | Long userId = SecurityFrameworkUtils.getLoginUserId(); |
| | | regularizeApplicationService.submitRegularizeApplication(id, processDefinitionKey, userId); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/approve-process-definition-list") |
| | | @Operation(summary = "è·åå¯ç¨çå®¡æ¹æµç¨å®ä¹å表") |
| | | @PreAuthorize("@ss.hasPermission('hrm:regularize:query')") |
| | | public CommonResult<List<Map<String, Object>>> getApproveProcessDefinitionList() { |
| | | return success(regularizeApplicationService.getApproveProcessDefinitionList()); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.approval.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - 转æ£ç³è¯·å页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class HrmRegularizeApplicationPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "ç³è¯·åå·", example = "ZZ202401001") |
| | | private String no; |
| | | |
| | | @Schema(description = "ç³è¯·äººID", example = "1") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "é¨é¨ID", example = "1") |
| | | private Long deptId; |
| | | |
| | | @Schema(description = "å½åç¨å·¥æ§è´¨", example = "2") |
| | | private Integer employmentType; |
| | | |
| | | @Schema(description = "审æ¹ç¶æ", example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.approval.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - 转æ£ç³è¯· Response VO") |
| | | @Data |
| | | public class HrmRegularizeApplicationRespVO { |
| | | |
| | | @Schema(description = "ç³è¯·ID", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ç³è¯·åå·", example = "ZZ202401001") |
| | | private String no; |
| | | |
| | | @Schema(description = "ç³è¯·äººID", example = "1") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "ç³è¯·äººå§å", example = "å¼ ä¸") |
| | | private String userName; |
| | | |
| | | @Schema(description = "é¨é¨ID", example = "1") |
| | | private Long deptId; |
| | | |
| | | @Schema(description = "é¨é¨åç§°", example = "ç åé¨") |
| | | private String deptName; |
| | | |
| | | @Schema(description = "å²ä½ID", example = "1") |
| | | private Long postId; |
| | | |
| | | @Schema(description = "å²ä½åç§°", example = "Java å·¥ç¨å¸") |
| | | private String postName; |
| | | |
| | | @Schema(description = "å½åç¨å·¥æ§è´¨", example = "2") |
| | | private Integer employmentType; |
| | | |
| | | @Schema(description = "å½åç¨å·¥æ§è´¨åç§°", example = "å³å¡") |
| | | private String employmentTypeName; |
| | | |
| | | @Schema(description = "æè½¬æ£æ¥æ", example = "2024-02-01") |
| | | private LocalDate expectedDate; |
| | | |
| | | @Schema(description = "转æ£åå ", example = "è¯ç¨æè¡¨ç°åæ ¼") |
| | | private String reason; |
| | | |
| | | @Schema(description = "审æ¹ç¶æ", example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "审æ¹ç¶æåç§°", example = "è稿") |
| | | private String statusName; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¾ID", example = "xxx") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "审æ¹å®ææ¶é´", example = "2024-01-01 10:00:00") |
| | | private LocalDateTime approveTime; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨ä¿¡æ¯") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´", example = "2024-01-01 09:00:00") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.approval.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDate; |
| | | |
| | | @Schema(description = "管çåå° - 转æ£ç³è¯·æ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class HrmRegularizeApplicationSaveReqVO { |
| | | |
| | | @Schema(description = "ç³è¯·ID", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ç³è¯·äººID", example = "1") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "é¨é¨ID", example = "1") |
| | | private Long deptId; |
| | | |
| | | @Schema(description = "å²ä½ID", example = "1") |
| | | private Long postId; |
| | | |
| | | @Schema(description = "å½åç¨å·¥æ§è´¨ï¼1-æ£å¼ï¼2-å³å¡ï¼3-å¤å
ï¼4-å®ä¹ ï¼5-éä¼è¿èï¼6-å
¶ä»", example = "2") |
| | | private Integer employmentType; |
| | | |
| | | @Schema(description = "æè½¬æ£æ¥æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-01") |
| | | @NotNull(message = "æè½¬æ£æ¥æä¸è½ä¸ºç©º") |
| | | private LocalDate expectedDate; |
| | | |
| | | @Schema(description = "转æ£åå ", requiredMode = Schema.RequiredMode.REQUIRED, example = "è¯ç¨æè¡¨ç°åæ ¼") |
| | | @NotEmpty(message = "转æ£åå ä¸è½ä¸ºç©º") |
| | | private String reason; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨ä¿¡æ¯") |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.service.certificate.HrmCertificateService; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.hrm.service.remind.HrmExpiryRemindService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | |
| | | private HrmCertificateService certificateService; |
| | | @Resource |
| | | private HrmEmployeeService employeeService; |
| | | @Resource |
| | | private HrmExpiryRemindService expiryRemindService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建è¯ä¹¦èµè´¨") |
| | |
| | | @Operation(summary = "è·å¾è¯ä¹¦èµè´¨å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:certificate:query')") |
| | | public CommonResult<PageResult<HrmCertificateRespVO>> getCertificatePage(@Valid HrmCertificatePageReqVO pageReqVO) { |
| | | // æè§¦åï¼æäººæå¼è¯ä¹¦å表æ¶é¡ºå¸¦è¡¥æ«å³å°å°æè¯ä¹¦å¹¶åéç«å
ä¿¡æéï¼best-effortï¼ |
| | | try { |
| | | expiryRemindService.sendCertificateExpireRemind(); |
| | | } catch (Exception ignored) { |
| | | } |
| | | PageResult<HrmCertificateDO> pageResult = certificateService.getCertificatePage(pageReqVO); |
| | | if (CollUtil.isEmpty(pageResult.getList())) { |
| | | return success(PageResult.empty(pageResult.getTotal())); |
| | |
| | | @Schema(description = "è¯ä¹¦åç§°", example = "é«åçµå·¥ç¹ç§ä½ä¸æä½è¯") |
| | | private String certName; |
| | | |
| | | @Schema(description = "å°æç±»åï¼1=å³å°å°æï¼2=å·²è¿æï¼ï¼é
ååè§å表çé", example = "1") |
| | | private Integer expiryType; |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractTerminateReqVO; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeContractService; |
| | | import cn.iocoder.yudao.module.hrm.service.remind.HrmExpiryRemindService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | |
| | | |
| | | @Resource |
| | | private HrmEmployeeContractService contractService; |
| | | @Resource |
| | | private HrmExpiryRemindService expiryRemindService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建åå·¥åå") |
| | |
| | | @Operation(summary = "è·å¾åå·¥ååå页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee-contract:query')") |
| | | public CommonResult<PageResult<HrmEmployeeContractRespVO>> getContractPage(@Valid HrmEmployeeContractPageReqVO pageReqVO) { |
| | | // æè§¦åï¼æäººæå¼ååå表æ¶é¡ºå¸¦è¡¥æ«å³å°å°æååå¹¶åéç«å
ä¿¡æéï¼best-effortï¼ |
| | | try { |
| | | expiryRemindService.sendContractExpireRemind(); |
| | | } catch (Exception ignored) { |
| | | } |
| | | return success(contractService.getContractPage(pageReqVO)); |
| | | } |
| | | |
| | |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeSimpleRespVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmEmploymentTypeEnum; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.mes.api.cal.MesCalTeamApi; |
| | | import cn.iocoder.yudao.module.mes.api.cal.dto.MesCalTeamRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.PostApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| | |
| | | private PostApi postApi; |
| | | @Resource |
| | | private RoleApi roleApi; |
| | | @Resource |
| | | private MesCalTeamApi mesCalTeamApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建åå·¥") |
| | |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, PostRespDTO> postMap = CollUtil.isEmpty(postIds) ? Collections.emptyMap() : postApi.getPostMap(postIds); |
| | | |
| | | // 3. æ¶éææè§è²ID |
| | | // 3. æ¹éè·åçç»ä¿¡æ¯ï¼æå±çç»ï¼ |
| | | Set<Long> teamIds = employeeList.stream() |
| | | .map(HrmEmployeeDO::getTeamId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, String> teamNameMap = CollUtil.isEmpty(teamIds) ? Collections.emptyMap() : mesCalTeamApi |
| | | .getTeamList(teamIds).stream() |
| | | .collect(Collectors.toMap(MesCalTeamRespDTO::getId, MesCalTeamRespDTO::getName, (v1, v2) -> v1)); |
| | | |
| | | // 4. æ¶éææè§è²ID |
| | | Set<Long> allRoleIds = new HashSet<>(); |
| | | for (HrmEmployeeDO employee : employeeList) { |
| | | if (StrUtil.isNotBlank(employee.getRoleIds())) { |
| | |
| | | respVO.setPostName(postMap.get(employee.getPostId()).getName()); |
| | | } |
| | | |
| | | // å¡«å
ç¨å·¥æ§è´¨åç§° |
| | | if (employee.getEmploymentType() != null) { |
| | | respVO.setEmploymentTypeName(HrmEmploymentTypeEnum.getNameByType(employee.getEmploymentType())); |
| | | } |
| | | |
| | | // å¡«å
æå±çç»åç§° |
| | | if (employee.getTeamId() != null && teamNameMap.containsKey(employee.getTeamId())) { |
| | | respVO.setTeamName(teamNameMap.get(employee.getTeamId())); |
| | | } |
| | | |
| | | // è§£æ roleIds å¹¶å¡«å
è§è²åç§° |
| | | if (StrUtil.isNotBlank(employee.getRoleIds())) { |
| | | List<Long> roleIds = JSONUtil.toList(employee.getRoleIds(), Long.class); |
| | |
| | | @ExcelProperty("å²ä½åç§°") |
| | | private String postName; |
| | | |
| | | @Schema(description = "ç¨å·¥æ§è´¨") |
| | | @ExcelProperty("ç¨å·¥æ§è´¨") |
| | | private Integer employmentType; |
| | | |
| | | @Schema(description = "ç¨å·¥æ§è´¨åç§°") |
| | | private String employmentTypeName; |
| | | |
| | | @Schema(description = "æå±çç»ID") |
| | | private Long teamId; |
| | | |
| | | @Schema(description = "æå±çç»åç§°") |
| | | @ExcelProperty("æå±çç»") |
| | | private String teamName; |
| | | |
| | | @Schema(description = "åå·¥å§å") |
| | | @ExcelProperty("åå·¥å§å") |
| | | private String name; |
| | |
| | | @NotNull(message = "å²ä½ä¸è½ä¸ºç©º") |
| | | private Long postId; |
| | | |
| | | @Schema(description = "ç¨å·¥æ§è´¨", example = "1") |
| | | private Integer employmentType; |
| | | |
| | | @Schema(description = "æå±çç»ID", example = "1") |
| | | private Long teamId; |
| | | |
| | | @Schema(description = "åå·¥å§å", requiredMode = Schema.RequiredMode.REQUIRED, example = "å¼ ä¸") |
| | | @NotEmpty(message = "åå·¥å§åä¸è½ä¸ºç©º") |
| | | private String name; |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.performanceappraise; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.json.JSONUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | |
| | | return success(buildResultRespVO(result, employeeService.getEmployee(employeeId))); |
| | | } |
| | | |
| | | @PostMapping("/generate-appraisees") |
| | | @Operation(summary = "çæè¢«èæ ¸äººï¼æèæ ¸èå´ï¼å¹çï¼") |
| | | @Parameter(name = "appraiseId", description = "æ¹æ¡ç¼å·", required = true, example = "1") |
| | | @PreAuthorize("@ss.hasPermission('hrm:performance-appraise:update')") |
| | | public CommonResult<Integer> generateAppraisees(@RequestParam("appraiseId") Long appraiseId) { |
| | | return success(appraiseService.generateAppraisees(appraiseId)); |
| | | } |
| | | |
| | | // ========== å
鍿¹æ³ï¼æ¼è£
VO ========== |
| | | |
| | | private HrmPerformanceAppraiseRespVO buildAppraiseRespVO(HrmPerformanceAppraiseDO appraise) { |
| | | HrmPerformanceAppraiseRespVO vo = BeanUtils.toBean(appraise, HrmPerformanceAppraiseRespVO.class); |
| | | if (StrUtil.isNotEmpty(appraise.getScopeTeamIds())) { |
| | | vo.setScopeTeamIds(JSONUtil.toList(appraise.getScopeTeamIds(), Long.class)); |
| | | } |
| | | vo.setStatusName(convertAppraiseStatusName(appraise.getStatus())); |
| | | vo.setAuditStatusName(HrmAuditStatusEnum.getNameByStatus(appraise.getAuditStatus())); |
| | | vo.setItemCount(appraiseService.getAppraiseItemList(appraise.getId()).size()); |
| | |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * HRM 绩æèæ ¸æ¹æ¡ Response VO |
| | |
| | | @DictFormat(cn.iocoder.yudao.module.hrm.enums.DictTypeConstants.HRM_PERFORMANCE_SCOPE_TYPE) |
| | | private Integer scopeType; |
| | | |
| | | @Schema(description = "æå®çç»ç¼å·éåï¼scopeType=2 æ¶çæï¼å
³è MES æçç»ï¼") |
| | | private List<Long> scopeTeamIds; |
| | | |
| | | @Schema(description = "æ¹æ¡ç¶æ", example = "0") |
| | | private Integer status; |
| | | |
| | |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * HRM 绩æèæ ¸æ¹æ¡ ä¿å Request VO |
| | | */ |
| | |
| | | @Schema(description = "èæ ¸èå´ç±»å: 1-å
¨é¨åå·¥ 2-æå®çç»", example = "1") |
| | | private Integer scopeType; |
| | | |
| | | @Schema(description = "æå®çç»ç¼å·éåï¼scopeType=2 æ¶å¿
å¡«ï¼å
³è MES æçç»ï¼") |
| | | private List<Long> scopeTeamIds; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.salary; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmEmployeeSalaryPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmEmployeeSalaryRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmEmployeeSalarySaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmEmployeeSalaryDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryStructureDO; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.hrm.service.salary.HrmEmployeeSalaryService; |
| | | import cn.iocoder.yudao.module.hrm.service.salary.HrmSalaryStructureService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.*; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | @Tag(name = "管çåå° - HRM åå·¥èªé
¬æ¡£æ¡") |
| | | @RestController |
| | | @RequestMapping("/hrm/employee-salary") |
| | | @Validated |
| | | public class HrmEmployeeSalaryController { |
| | | |
| | | @Resource |
| | | private HrmEmployeeSalaryService employeeSalaryService; |
| | | @Resource |
| | | private HrmEmployeeService employeeService; |
| | | @Resource |
| | | private HrmSalaryStructureService structureService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建åå·¥èªé
¬æ¡£æ¡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:create')") |
| | | public CommonResult<Long> createEmployeeSalary(@Valid @RequestBody HrmEmployeeSalarySaveReqVO createReqVO) { |
| | | HrmEmployeeSalaryDO salary = BeanUtils.toBean(createReqVO, HrmEmployeeSalaryDO.class); |
| | | return success(employeeSalaryService.createEmployeeSalary(salary)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°åå·¥èªé
¬æ¡£æ¡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:update')") |
| | | public CommonResult<Boolean> updateEmployeeSalary(@Valid @RequestBody HrmEmployeeSalarySaveReqVO updateReqVO) { |
| | | HrmEmployeeSalaryDO salary = BeanUtils.toBean(updateReqVO, HrmEmployeeSalaryDO.class); |
| | | employeeSalaryService.updateEmployeeSalary(salary); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤åå·¥èªé
¬æ¡£æ¡") |
| | | @Parameter(name = "id", description = "æ¡£æ¡ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:delete')") |
| | | public CommonResult<Boolean> deleteEmployeeSalary(@RequestParam("id") Long id) { |
| | | employeeSalaryService.deleteEmployeeSalary(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·ååå·¥èªé
¬æ¡£æ¡") |
| | | @Parameter(name = "id", description = "æ¡£æ¡ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | public CommonResult<HrmEmployeeSalaryRespVO> getEmployeeSalary(@RequestParam("id") Long id) { |
| | | HrmEmployeeSalaryDO salary = employeeSalaryService.getEmployeeSalary(id); |
| | | if (salary == null) { |
| | | return success(null); |
| | | } |
| | | HrmEmployeeSalaryRespVO respVO = BeanUtils.toBean(salary, HrmEmployeeSalaryRespVO.class); |
| | | fillEmployeeInfo(respVO, salary.getUserId()); |
| | | fillStructureInfo(respVO, salary.getSalaryStructureId()); |
| | | return success(respVO); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·ååå·¥èªé
¬æ¡£æ¡å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | public CommonResult<PageResult<HrmEmployeeSalaryRespVO>> getEmployeeSalaryPage( |
| | | @Valid HrmEmployeeSalaryPageReqVO pageReqVO) { |
| | | PageResult<HrmEmployeeSalaryDO> pageResult = employeeSalaryService.getEmployeeSalaryPage(pageReqVO); |
| | | List<HrmEmployeeSalaryDO> recordList = pageResult.getList(); |
| | | if (CollUtil.isEmpty(recordList)) { |
| | | return success(new PageResult<>(Collections.emptyList(), pageResult.getTotal())); |
| | | } |
| | | // æ¹éè·ååå·¥ä¿¡æ¯ |
| | | Set<Long> employeeIds = new HashSet<>(); |
| | | Set<Long> structureIds = new HashSet<>(); |
| | | for (HrmEmployeeSalaryDO record : recordList) { |
| | | if (record.getUserId() != null) { |
| | | employeeIds.add(record.getUserId()); |
| | | } |
| | | if (record.getSalaryStructureId() != null) { |
| | | structureIds.add(record.getSalaryStructureId()); |
| | | } |
| | | } |
| | | Map<Long, HrmEmployeeDO> employeeMap = new HashMap<>(); |
| | | for (Long employeeId : employeeIds) { |
| | | HrmEmployeeDO employee = employeeService.getEmployee(employeeId); |
| | | if (employee != null) { |
| | | employeeMap.put(employeeId, employee); |
| | | } |
| | | } |
| | | Map<Long, HrmSalaryStructureDO> structureMap = new HashMap<>(); |
| | | for (Long structureId : structureIds) { |
| | | HrmSalaryStructureDO structure = structureService.getStructure(structureId); |
| | | if (structure != null) { |
| | | structureMap.put(structureId, structure); |
| | | } |
| | | } |
| | | List<HrmEmployeeSalaryRespVO> list = recordList.stream() |
| | | .map(salary -> { |
| | | HrmEmployeeSalaryRespVO respVO = BeanUtils.toBean(salary, HrmEmployeeSalaryRespVO.class); |
| | | HrmEmployeeDO employee = employeeMap.get(salary.getUserId()); |
| | | if (employee != null) { |
| | | respVO.setEmployeeNo(employee.getEmployeeNo()); |
| | | respVO.setEmployeeName(employee.getName()); |
| | | } |
| | | if (salary.getSalaryStructureId() != null) { |
| | | HrmSalaryStructureDO structure = structureMap.get(salary.getSalaryStructureId()); |
| | | if (structure != null) { |
| | | respVO.setSalaryStructureName(structure.getName()); |
| | | } |
| | | } |
| | | return respVO; |
| | | }) |
| | | .toList(); |
| | | return success(new PageResult<>(list, pageResult.getTotal())); |
| | | } |
| | | |
| | | @GetMapping("/list-by-user") |
| | | @Operation(summary = "è·ååå·¥èªé
¬æ¡£æ¡åå²å表") |
| | | @Parameter(name = "userId", description = "åå·¥ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | public CommonResult<List<HrmEmployeeSalaryRespVO>> getEmployeeSalaryList( |
| | | @RequestParam("userId") Long userId) { |
| | | List<HrmEmployeeSalaryDO> list = employeeSalaryService.getEmployeeSalaryList(userId); |
| | | return success(list.stream() |
| | | .map(salary -> { |
| | | HrmEmployeeSalaryRespVO respVO = BeanUtils.toBean(salary, HrmEmployeeSalaryRespVO.class); |
| | | fillEmployeeInfo(respVO, salary.getUserId()); |
| | | fillStructureInfo(respVO, salary.getSalaryStructureId()); |
| | | return respVO; |
| | | }) |
| | | .toList()); |
| | | } |
| | | |
| | | @GetMapping("/get-latest") |
| | | @Operation(summary = "è·ååå·¥ææ°çæçèªé
¬æ¡£æ¡") |
| | | @Parameter(name = "userId", description = "åå·¥ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | public CommonResult<HrmEmployeeSalaryRespVO> getLatestEmployeeSalary( |
| | | @RequestParam("userId") Long userId) { |
| | | HrmEmployeeSalaryDO salary = employeeSalaryService.getLatestEmployeeSalary(userId); |
| | | if (salary == null) { |
| | | return success(null); |
| | | } |
| | | HrmEmployeeSalaryRespVO respVO = BeanUtils.toBean(salary, HrmEmployeeSalaryRespVO.class); |
| | | fillEmployeeInfo(respVO, salary.getUserId()); |
| | | fillStructureInfo(respVO, salary.getSalaryStructureId()); |
| | | return success(respVO); |
| | | } |
| | | |
| | | private void fillEmployeeInfo(HrmEmployeeSalaryRespVO respVO, Long userId) { |
| | | HrmEmployeeDO employee = employeeService.getEmployee(userId); |
| | | if (employee != null) { |
| | | respVO.setEmployeeNo(employee.getEmployeeNo()); |
| | | respVO.setEmployeeName(employee.getName()); |
| | | } |
| | | } |
| | | |
| | | private void fillStructureInfo(HrmEmployeeSalaryRespVO respVO, Long structureId) { |
| | | if (structureId != null) { |
| | | HrmSalaryStructureDO structure = structureService.getStructure(structureId); |
| | | if (structure != null) { |
| | | respVO.setSalaryStructureName(structure.getName()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.salary; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmSalaryStructurePageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmSalaryStructureRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmSalaryStructureSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryStructureDO; |
| | | import cn.iocoder.yudao.module.hrm.service.salary.HrmSalaryStructureService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | @Tag(name = "管çåå° - HRM èªé
Ⱦ") |
| | | @RestController |
| | | @RequestMapping("/hrm/salary/structure") |
| | | @Validated |
| | | public class HrmSalaryStructureController { |
| | | |
| | | @Resource |
| | | private HrmSalaryStructureService structureService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建èªé
Ⱦ") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:create')") |
| | | public CommonResult<Long> createStructure(@Valid @RequestBody HrmSalaryStructureSaveReqVO createReqVO) { |
| | | HrmSalaryStructureDO structure = BeanUtils.toBean(createReqVO, HrmSalaryStructureDO.class); |
| | | return success(structureService.createStructure(structure)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°èªé
Ⱦ") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:update')") |
| | | public CommonResult<Boolean> updateStructure(@Valid @RequestBody HrmSalaryStructureSaveReqVO updateReqVO) { |
| | | HrmSalaryStructureDO structure = BeanUtils.toBean(updateReqVO, HrmSalaryStructureDO.class); |
| | | structureService.updateStructure(structure); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤èªé
Ⱦ") |
| | | @Parameter(name = "id", description = "ç»æID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:delete')") |
| | | public CommonResult<Boolean> deleteStructure(@RequestParam("id") Long id) { |
| | | structureService.deleteStructure(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·åèªé
Ⱦ") |
| | | @Parameter(name = "id", description = "ç»æID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | public CommonResult<HrmSalaryStructureRespVO> getStructure(@RequestParam("id") Long id) { |
| | | HrmSalaryStructureDO structure = structureService.getStructure(id); |
| | | return success(BeanUtils.toBean(structure, HrmSalaryStructureRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·åèªé
¬ç»æå页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | public CommonResult<PageResult<HrmSalaryStructureRespVO>> getStructurePage(HrmSalaryStructurePageReqVO pageReqVO) { |
| | | PageResult<HrmSalaryStructureDO> pageResult = structureService.getStructurePage(pageReqVO); |
| | | return success(BeanUtils.toBean(pageResult, HrmSalaryStructureRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "è·åèªé
¬ç»æå表") |
| | | @Parameter(name = "status", description = "ç¶æ") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | public CommonResult<List<HrmSalaryStructureRespVO>> getStructureList( |
| | | @RequestParam(value = "status", required = false) Integer status) { |
| | | List<HrmSalaryStructureDO> list = structureService.getStructureList(status); |
| | | return success(BeanUtils.toBean(list, HrmSalaryStructureRespVO.class)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.salary.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | @Schema(description = "管çåå° - åå·¥èªé
¬æ¡£æ¡å页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class HrmEmployeeSalaryPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "åå·¥ID", example = "1024") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "èªé
ȾID", example = "1") |
| | | private Long salaryStructureId; |
| | | |
| | | @Schema(description = "ç¶æï¼0-å¯ç¨ï¼1-ç¦ç¨", example = "0") |
| | | private Integer status; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.salary.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - åå·¥èªé
¬æ¡£æ¡ Response VO") |
| | | @Data |
| | | public class HrmEmployeeSalaryRespVO { |
| | | |
| | | @Schema(description = "æ¡£æ¡ID", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private Long id; |
| | | |
| | | @Schema(description = "åå·¥ID") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "åå·¥ç¼å·") |
| | | private String employeeNo; |
| | | |
| | | @Schema(description = "åå·¥å§å") |
| | | private String employeeName; |
| | | |
| | | @Schema(description = "èªé
ȾID") |
| | | private Long salaryStructureId; |
| | | |
| | | @Schema(description = "èªé
¬ç»æåç§°") |
| | | private String salaryStructureName; |
| | | |
| | | @Schema(description = "åºæ¬å·¥èµ") |
| | | private BigDecimal baseSalary; |
| | | |
| | | @Schema(description = "绩æå·¥èµ") |
| | | private BigDecimal performanceSalary; |
| | | |
| | | @Schema(description = "é¤è¡¥") |
| | | private BigDecimal mealAllowance; |
| | | |
| | | @Schema(description = "交é补贴") |
| | | private BigDecimal transportAllowance; |
| | | |
| | | @Schema(description = "å
¶ä»è¡¥è´´") |
| | | private BigDecimal otherAllowance; |
| | | |
| | | @Schema(description = "çææ¥æ") |
| | | private LocalDate effectiveDate; |
| | | |
| | | @Schema(description = "ç¶æï¼0-å¯ç¨ï¼1-ç¦ç¨") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.salary.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | |
| | | @Schema(description = "管çåå° - åå·¥èªé
¬æ¡£æ¡ æ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class HrmEmployeeSalarySaveReqVO { |
| | | |
| | | @Schema(description = "æ¡£æ¡ID", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "åå·¥ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | @NotNull(message = "åå·¥ä¸è½ä¸ºç©º") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "èªé
ȾID", example = "1") |
| | | private Long salaryStructureId; |
| | | |
| | | @Schema(description = "åºæ¬å·¥èµ", example = "8000.00") |
| | | private BigDecimal baseSalary; |
| | | |
| | | @Schema(description = "绩æå·¥èµ", example = "2000.00") |
| | | private BigDecimal performanceSalary; |
| | | |
| | | @Schema(description = "é¤è¡¥", example = "300.00") |
| | | private BigDecimal mealAllowance; |
| | | |
| | | @Schema(description = "交é补贴", example = "200.00") |
| | | private BigDecimal transportAllowance; |
| | | |
| | | @Schema(description = "å
¶ä»è¡¥è´´", example = "100.00") |
| | | private BigDecimal otherAllowance; |
| | | |
| | | @Schema(description = "çææ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "çææ¥æä¸è½ä¸ºç©º") |
| | | private LocalDate effectiveDate; |
| | | |
| | | @Schema(description = "ç¶æï¼0-å¯ç¨ï¼1-ç¦ç¨", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| | | @NotNull(message = "ç¶æä¸è½ä¸ºç©º") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨ä¿¡æ¯") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.salary.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | @Schema(description = "管çåå° - èªé
¬ç»æå页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class HrmSalaryStructurePageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "ç»æåç§°", example = "ç产å²") |
| | | private String name; |
| | | |
| | | @Schema(description = "ç¶æï¼0-å¯ç¨ï¼1-ç¦ç¨", example = "0") |
| | | private Integer status; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.salary.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - èªé
Ⱦ Response VO") |
| | | @Data |
| | | public class HrmSalaryStructureRespVO { |
| | | |
| | | @Schema(description = "ç»æID", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private Long id; |
| | | |
| | | @Schema(description = "ç»æåç§°") |
| | | private String name; |
| | | |
| | | @Schema(description = "åºæ¬å·¥èµ") |
| | | private BigDecimal baseSalary; |
| | | |
| | | @Schema(description = "绩æå·¥èµå æ¯ï¼%ï¼") |
| | | private BigDecimal performanceRatio; |
| | | |
| | | @Schema(description = "å çå·¥èµåç") |
| | | private BigDecimal overtimePayRatio; |
| | | |
| | | @Schema(description = "社ä¿åºæ°") |
| | | private BigDecimal socialSecurityBase; |
| | | |
| | | @Schema(description = "å
¬ç§¯éåºæ°") |
| | | private BigDecimal housingFundBase; |
| | | |
| | | @Schema(description = "ç¶æï¼0-å¯ç¨ï¼1-ç¦ç¨") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.salary.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Schema(description = "管çåå° - èªé
¬ç»æ æ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class HrmSalaryStructureSaveReqVO { |
| | | |
| | | @Schema(description = "ç»æID", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ç»æåç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "ç产å²èªé
Ⱦ") |
| | | @NotEmpty(message = "ç»æåç§°ä¸è½ä¸ºç©º") |
| | | private String name; |
| | | |
| | | @Schema(description = "åºæ¬å·¥èµ", example = "8000.00") |
| | | private BigDecimal baseSalary; |
| | | |
| | | @Schema(description = "绩æå·¥èµå æ¯ï¼%ï¼", example = "20") |
| | | private BigDecimal performanceRatio; |
| | | |
| | | @Schema(description = "å çå·¥èµåç", example = "1.5") |
| | | private BigDecimal overtimePayRatio; |
| | | |
| | | @Schema(description = "社ä¿åºæ°", example = "8000.00") |
| | | private BigDecimal socialSecurityBase; |
| | | |
| | | @Schema(description = "å
¬ç§¯éåºæ°", example = "8000.00") |
| | | private BigDecimal housingFundBase; |
| | | |
| | | @Schema(description = "ç¶æï¼0-å¯ç¨ï¼1-ç¦ç¨", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| | | @NotNull(message = "ç¶æä¸è½ä¸ºç©º") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨ä¿¡æ¯") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.training; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingParticipantRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingParticipantDO; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.hrm.service.training.HrmTrainingService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingDO.*; |
| | | |
| | | @Tag(name = "管çåå° - HRM å¹è®æ´»å¨") |
| | | @RestController |
| | | @RequestMapping("/hrm/training") |
| | | @Validated |
| | | public class HrmTrainingController { |
| | | |
| | | @Resource |
| | | private HrmTrainingService trainingService; |
| | | @Resource |
| | | private HrmEmployeeService employeeService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建å¹è®æ´»å¨ï¼åå§ä¸ºèç¨¿ç¶æï¼") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:create')") |
| | | public CommonResult<Long> createTraining(@Valid @RequestBody HrmTrainingSaveReqVO createReqVO) { |
| | | return success(trainingService.createTraining(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°å¹è®æ´»å¨ï¼ä»
è稿/å¾
å¼å±å¯æ¹ï¼ç¶æèµ° start/complete/cancel æµè½¬ï¼") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:update')") |
| | | public CommonResult<Boolean> updateTraining(@Valid @RequestBody HrmTrainingSaveReqVO updateReqVO) { |
| | | trainingService.updateTraining(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤å¹è®æ´»å¨ï¼çº§èå é¤åè®äººåï¼å·²å®æ/已忶ä¸å¯å ï¼") |
| | | @Parameter(name = "ids", description = "ç¼å·æ°ç»", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:delete')") |
| | | public CommonResult<Boolean> deleteTraining(@RequestParam("ids") List<Long> ids) { |
| | | trainingService.deleteTraining(ids); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾å¹è®æ´»å¨è¯¦æ
ï¼å«åè®äººåå表ï¼") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:query')") |
| | | public CommonResult<HrmTrainingRespVO> getTraining(@RequestParam("id") Long id) { |
| | | HrmTrainingDO training = trainingService.getTraining(id); |
| | | if (training == null) { |
| | | return success(null); |
| | | } |
| | | HrmTrainingRespVO respVO = BeanUtils.toBean(training, HrmTrainingRespVO.class); |
| | | fillDisplayNames(respVO); |
| | | respVO.setParticipants(buildParticipantList(trainingService.getParticipantsByTrainingId(id))); |
| | | return success(respVO); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾å¹è®æ´»å¨å页ï¼å«åè®äººæ°ï¼") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:query')") |
| | | public CommonResult<PageResult<HrmTrainingRespVO>> getTrainingPage(@Valid HrmTrainingPageReqVO pageReqVO) { |
| | | PageResult<HrmTrainingDO> pageResult = trainingService.getTrainingPage(pageReqVO); |
| | | if (CollUtil.isEmpty(pageResult.getList())) { |
| | | return success(PageResult.empty(pageResult.getTotal())); |
| | | } |
| | | Map<Long, Integer> participantCountMap = trainingService.getParticipantCountMap( |
| | | convertSet(pageResult.getList(), HrmTrainingDO::getId)); |
| | | return success(BeanUtils.toBean(pageResult, HrmTrainingRespVO.class, vo -> { |
| | | fillDisplayNames(vo); |
| | | vo.setParticipantCount(participantCountMap.getOrDefault(vo.getId(), 0)); |
| | | })); |
| | | } |
| | | |
| | | @PostMapping("/start") |
| | | @Operation(summary = "å¼å§å¹è®ï¼è稿 â å¾
å¼å±ï¼") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:update')") |
| | | public CommonResult<Boolean> startTraining(@RequestParam("id") Long id) { |
| | | trainingService.startTraining(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @PostMapping("/complete") |
| | | @Operation(summary = "宿å¹è®ï¼è稿/å¾
å¼å± â 已宿ï¼å¼å¯èªå¨åè¯æ¶å¯¹åæ ¼äººåèå¨åæ¾è¯ä¹¦ï¼") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:update')") |
| | | public CommonResult<Boolean> completeTraining(@RequestParam("id") Long id) { |
| | | trainingService.completeTraining(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @PostMapping("/cancel") |
| | | @Operation(summary = "åæ¶å¹è®ï¼è稿/å¾
å¼å± â 已忶ï¼") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:update')") |
| | | public CommonResult<Boolean> cancelTraining(@RequestParam("id") Long id) { |
| | | trainingService.cancelTraining(id); |
| | | return success(true); |
| | | } |
| | | |
| | | // ========== ç§ææ¹æ³ ========== |
| | | |
| | | private void fillDisplayNames(HrmTrainingRespVO respVO) { |
| | | respVO.setTrainingTypeName(convertTrainingTypeName(respVO.getTrainingType())); |
| | | respVO.setStatusName(convertStatusName(respVO.getStatus())); |
| | | } |
| | | |
| | | private List<HrmTrainingParticipantRespVO> buildParticipantList(List<HrmTrainingParticipantDO> participants) { |
| | | if (CollUtil.isEmpty(participants)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | Map<Long, HrmEmployeeDO> employeeMap = employeeService.getEmployeeList( |
| | | convertSet(participants, HrmTrainingParticipantDO::getEmployeeId)).stream() |
| | | .collect(java.util.stream.Collectors.toMap(HrmEmployeeDO::getId, e -> e, (a, b) -> a)); |
| | | List<HrmTrainingParticipantRespVO> voList = BeanUtils.toBean(participants, HrmTrainingParticipantRespVO.class); |
| | | for (HrmTrainingParticipantRespVO vo : voList) { |
| | | HrmEmployeeDO employee = employeeMap.get(vo.getEmployeeId()); |
| | | if (employee != null) { |
| | | vo.setEmployeeName(employee.getName()); |
| | | vo.setEmployeeNo(employee.getEmployeeNo()); |
| | | } |
| | | } |
| | | return voList; |
| | | } |
| | | |
| | | private String convertTrainingTypeName(Integer trainingType) { |
| | | return switch (trainingType == null ? 0 : trainingType) { |
| | | case TYPE_SAFETY -> "å®å
¨å¹è®"; |
| | | case TYPE_SKILL -> "æè½å¹è®"; |
| | | case TYPE_MANAGE -> "管çå¹è®"; |
| | | case TYPE_OTHER -> "å
¶ä»"; |
| | | default -> ""; |
| | | }; |
| | | } |
| | | |
| | | private String convertStatusName(Integer status) { |
| | | return switch (status == null ? -1 : status) { |
| | | case STATUS_DRAFT -> "è稿"; |
| | | case STATUS_PLANNED -> "å¾
å¼å±"; |
| | | case STATUS_COMPLETED -> "已宿"; |
| | | case STATUS_CANCELED -> "已忶"; |
| | | default -> ""; |
| | | }; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.training; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingParticipantAddReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingParticipantRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingParticipantUpdateReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingParticipantDO; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.hrm.service.training.HrmTrainingService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | |
| | | @Tag(name = "管çåå° - HRM å¹è®åè®äººå") |
| | | @RestController |
| | | @RequestMapping("/hrm/training-participant") |
| | | @Validated |
| | | public class HrmTrainingParticipantController { |
| | | |
| | | @Resource |
| | | private HrmTrainingService trainingService; |
| | | @Resource |
| | | private HrmEmployeeService employeeService; |
| | | |
| | | @PostMapping("/add") |
| | | @Operation(summary = "æ¹éæ·»å åè®åå·¥ï¼èªå¨è·³è¿å·²å¨ååä¸çåå·¥ï¼") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:update')") |
| | | public CommonResult<Integer> addParticipants(@Valid @RequestBody HrmTrainingParticipantAddReqVO addReqVO) { |
| | | return success(trainingService.addParticipants(addReqVO.getTrainingId(), addReqVO.getEmployeeIds())); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°åè®è®°å½ï¼åå æ
åµ/èæ ¸æç»©/æ¯å¦åæ ¼ï¼") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:update')") |
| | | public CommonResult<Boolean> updateParticipant(@Valid @RequestBody HrmTrainingParticipantUpdateReqVO updateReqVO) { |
| | | trainingService.updateParticipant(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤åè®è®°å½") |
| | | @Parameter(name = "ids", description = "åè®è®°å½ç¼å·æ°ç»", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:update')") |
| | | public CommonResult<Boolean> deleteParticipants(@RequestParam("ids") List<Long> ids) { |
| | | trainingService.deleteParticipants(ids); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "è·å¾ææ¬¡å¹è®çåè®äººåå表") |
| | | @Parameter(name = "trainingId", description = "å¹è®æ´»å¨ç¼å·", required = true, example = "1024") |
| | | @PreAuthorize("@ss.hasPermission('hrm:training:query')") |
| | | public CommonResult<List<HrmTrainingParticipantRespVO>> getParticipantsByTrainingId( |
| | | @RequestParam("trainingId") Long trainingId) { |
| | | List<HrmTrainingParticipantDO> participants = trainingService.getParticipantsByTrainingId(trainingId); |
| | | return success(buildParticipantList(participants)); |
| | | } |
| | | |
| | | private List<HrmTrainingParticipantRespVO> buildParticipantList(List<HrmTrainingParticipantDO> participants) { |
| | | if (CollUtil.isEmpty(participants)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | Map<Long, HrmEmployeeDO> employeeMap = employeeService.getEmployeeList( |
| | | convertSet(participants, HrmTrainingParticipantDO::getEmployeeId)).stream() |
| | | .collect(java.util.stream.Collectors.toMap(HrmEmployeeDO::getId, e -> e, (a, b) -> a)); |
| | | List<HrmTrainingParticipantRespVO> voList = BeanUtils.toBean(participants, HrmTrainingParticipantRespVO.class); |
| | | for (HrmTrainingParticipantRespVO vo : voList) { |
| | | HrmEmployeeDO employee = employeeMap.get(vo.getEmployeeId()); |
| | | if (employee != null) { |
| | | vo.setEmployeeName(employee.getName()); |
| | | vo.setEmployeeNo(employee.getEmployeeNo()); |
| | | } |
| | | } |
| | | return voList; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.training.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | @Schema(description = "管çåå° - HRM å¹è®æ´»å¨å页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class HrmTrainingPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "å¹è®ç¼å·", example = "PX202409080001") |
| | | private String trainingNo; |
| | | |
| | | @Schema(description = "å¹è®åç§°", example = "2026年度çµåå®å
¨å¹è®") |
| | | private String name; |
| | | |
| | | @Schema(description = "å¹è®ç±»åï¼1=å®å
¨å¹è®ï¼2=æè½å¹è®ï¼3=管çå¹è®ï¼4=å
¶ä»ï¼", example = "1") |
| | | private Integer trainingType; |
| | | |
| | | @Schema(description = "ç¶æï¼0=è稿ï¼10=å¾
å¼å±ï¼20=已宿ï¼30=已忶ï¼", example = "10") |
| | | private Integer status; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.training.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - HRM å¹è®åè®äººåï¼æ¹éæ·»å ï¼ Request VO") |
| | | @Data |
| | | public class HrmTrainingParticipantAddReqVO { |
| | | |
| | | @Schema(description = "å¹è®æ´»å¨ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "å¹è®æ´»å¨ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long trainingId; |
| | | |
| | | @Schema(description = "åè®åå·¥ç¼å·éå", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotEmpty(message = "è¯·éæ©åè®åå·¥") |
| | | private List<Long> employeeIds; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.training.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - HRM å¹è®åè®äººå Response VO") |
| | | @Data |
| | | public class HrmTrainingParticipantRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å¹è®æ´»å¨ç¼å·", example = "1") |
| | | private Long trainingId; |
| | | |
| | | @Schema(description = "åå·¥ç¼å·", example = "1") |
| | | private Long employeeId; |
| | | |
| | | @Schema(description = "å工工å·", example = "EMP202401010001") |
| | | private String employeeNo; |
| | | |
| | | @Schema(description = "åå·¥å§å", example = "å¼ ä¸") |
| | | private String employeeName; |
| | | |
| | | @Schema(description = "æ¯å¦å®é
åå ï¼0=æªåå ï¼1=åå ï¼", example = "true") |
| | | private Boolean attended; |
| | | |
| | | @Schema(description = "èæ ¸æç»©", example = "90") |
| | | private BigDecimal score; |
| | | |
| | | @Schema(description = "æ¯å¦åæ ¼ï¼0=ä¸åæ ¼ï¼1=åæ ¼ï¼", example = "true") |
| | | private Boolean isPass; |
| | | |
| | | @Schema(description = "èå¨çæçè¯ä¹¦ç¼å·ï¼ä¸ºç©ºè¡¨ç¤ºå°æªåè¯ï¼", example = "1") |
| | | private Long certificateId; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.training.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Schema(description = "管çåå° - HRM å¹è®åè®äººåï¼åå /æç»©/åæ ¼ï¼æ´æ° Request VO") |
| | | @Data |
| | | public class HrmTrainingParticipantUpdateReqVO { |
| | | |
| | | @Schema(description = "åè®è®°å½ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "åè®è®°å½ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | @Schema(description = "æ¯å¦å®é
åå ï¼0=æªåå ï¼1=åå ï¼", example = "true") |
| | | private Boolean attended; |
| | | |
| | | @Schema(description = "èæ ¸æç»©", example = "90") |
| | | private BigDecimal score; |
| | | |
| | | @Schema(description = "æ¯å¦åæ ¼ï¼0=ä¸åæ ¼ï¼1=åæ ¼ï¼", example = "true") |
| | | private Boolean isPass; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.training.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - HRM å¹è®æ´»å¨ Response VO") |
| | | @Data |
| | | public class HrmTrainingRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å¹è®ç¼å·", example = "PX202409080001") |
| | | private String trainingNo; |
| | | |
| | | @Schema(description = "å¹è®åç§°", example = "2026年度çµåå®å
¨å¹è®") |
| | | private String name; |
| | | |
| | | @Schema(description = "å¹è®ç±»åï¼1=å®å
¨å¹è®ï¼2=æè½å¹è®ï¼3=管çå¹è®ï¼4=å
¶ä»ï¼", example = "1") |
| | | private Integer trainingType; |
| | | |
| | | @Schema(description = "å¹è®ç±»ååç§°", example = "å®å
¨å¹è®") |
| | | private String trainingTypeName; |
| | | |
| | | @Schema(description = "讲å¸", example = "å¼ å·¥") |
| | | private String trainer; |
| | | |
| | | @Schema(description = "å¹è®å°ç¹", example = "å®å
¨å¹è®å®¤") |
| | | private String location; |
| | | |
| | | @Schema(description = "å¹è®å¦æ¶", example = "8") |
| | | private BigDecimal hours; |
| | | |
| | | @Schema(description = "å¼å§æ¥æ") |
| | | private LocalDate startDate; |
| | | |
| | | @Schema(description = "ç»ææ¥æ") |
| | | private LocalDate endDate; |
| | | |
| | | @Schema(description = "æ¯å¦èªå¨åè¯ï¼0=å¦ï¼1=æ¯ï¼", example = "true") |
| | | private Boolean issueCertificate; |
| | | |
| | | @Schema(description = "è¯ä¹¦æææï¼æï¼", example = "12") |
| | | private Integer certValidityMonths; |
| | | |
| | | @Schema(description = "ç¶æï¼0=è稿ï¼10=å¾
å¼å±ï¼20=已宿ï¼30=已忶ï¼", example = "10") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "ç¶æåç§°", example = "å¾
å¼å±") |
| | | private String statusName; |
| | | |
| | | @Schema(description = "åè®äººæ°", example = "5") |
| | | private Integer participantCount; |
| | | |
| | | @Schema(description = "åè®äººåå表ï¼è¯¦æ
æ¥å£è¿åï¼") |
| | | private List<HrmTrainingParticipantRespVO> participants; |
| | | |
| | | @Schema(description = "夿³¨", example = "年度ä¾è¡å¹è®") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.training.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | |
| | | @Schema(description = "管çåå° - HRM å¹è®æ´»å¨æ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class HrmTrainingSaveReqVO { |
| | | |
| | | @Schema(description = "ç¼å·ï¼ä¿®æ¹æ¶å¿
å¡«ï¼", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å¹è®åç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026年度çµåå®å
¨å¹è®") |
| | | @NotEmpty(message = "å¹è®åç§°ä¸è½ä¸ºç©º") |
| | | private String name; |
| | | |
| | | @Schema(description = "å¹è®ç±»åï¼1=å®å
¨å¹è®ï¼2=æè½å¹è®ï¼3=管çå¹è®ï¼4=å
¶ä»ï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "å¹è®ç±»åä¸è½ä¸ºç©º") |
| | | private Integer trainingType; |
| | | |
| | | @Schema(description = "讲å¸", example = "å¼ å·¥") |
| | | private String trainer; |
| | | |
| | | @Schema(description = "å¹è®å°ç¹", example = "å®å
¨å¹è®å®¤") |
| | | private String location; |
| | | |
| | | @Schema(description = "å¹è®å¦æ¶", example = "8") |
| | | private BigDecimal hours; |
| | | |
| | | @Schema(description = "å¼å§æ¥æ") |
| | | private LocalDate startDate; |
| | | |
| | | @Schema(description = "ç»ææ¥æ") |
| | | private LocalDate endDate; |
| | | |
| | | @Schema(description = "æ¯å¦èªå¨åè¯ï¼0=å¦ï¼1=æ¯ï¼ä»
å®å
¨/æè½å¹è®æ¯æï¼", example = "true") |
| | | private Boolean issueCertificate; |
| | | |
| | | @Schema(description = "è¯ä¹¦æææï¼æï¼ï¼èªå¨åè¯æ¶å¿
å¡«ï¼ç¨äºè®¡ç®è¯ä¹¦å°ææ¥", example = "12") |
| | | private Integer certValidityMonths; |
| | | |
| | | @Schema(description = "夿³¨", example = "年度ä¾è¡å¹è®") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.workhour; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo.HrmWorkHourSummaryPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo.HrmWorkHourSummaryRespVO; |
| | | import cn.iocoder.yudao.module.hrm.service.workhour.HrmWorkHourSummaryService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | @Tag(name = "管çåå° - HRM æåº¦å·¥æ¶æ±æ»") |
| | | @RestController |
| | | @RequestMapping("/hrm/work-hour-summary") |
| | | @Validated |
| | | public class HrmWorkHourSummaryController { |
| | | |
| | | @Resource |
| | | private HrmWorkHourSummaryService workHourSummaryService; |
| | | |
| | | @PostMapping("/generate-monthly") |
| | | @Operation(summary = "çææåº¦å·¥æ¶æ±æ»") |
| | | @Parameter(name = "period", description = "æ ¸ç®å¨æï¼æ ¼å¼ yyyy-MM", required = true, example = "2026-08") |
| | | @PreAuthorize("@ss.hasPermission('hrm:work-hour:generate')") |
| | | public CommonResult<Boolean> generateMonthly(@RequestParam("period") String period) { |
| | | workHourSummaryService.generateMonthly(period); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾æåº¦å·¥æ¶æ±æ»å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:work-hour:query')") |
| | | public CommonResult<PageResult<HrmWorkHourSummaryRespVO>> getPage( |
| | | @Valid HrmWorkHourSummaryPageReqVO pageReqVO) { |
| | | return success(workHourSummaryService.getWorkHourSummaryPage(pageReqVO)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | @Schema(description = "管çåå° - æåº¦å·¥æ¶æ±æ»å页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class HrmWorkHourSummaryPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "æ ¸ç®å¨æï¼yyyy-MMï¼", example = "2026-08") |
| | | private String period; |
| | | |
| | | @Schema(description = "åå·¥ID", example = "1024") |
| | | private Long employeeId; |
| | | |
| | | @Schema(description = "é¨é¨ID", example = "1") |
| | | private Long deptId; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - æåº¦å·¥æ¶æ±æ» Response VO") |
| | | @Data |
| | | public class HrmWorkHourSummaryRespVO { |
| | | |
| | | @Schema(description = "æ±æ»ID") |
| | | private Long id; |
| | | |
| | | @Schema(description = "åå·¥ID") |
| | | private Long employeeId; |
| | | |
| | | @Schema(description = "åå·¥ç¼å·") |
| | | private String employeeNo; |
| | | |
| | | @Schema(description = "åå·¥å§å") |
| | | private String employeeName; |
| | | |
| | | @Schema(description = "é¨é¨ID") |
| | | private Long deptId; |
| | | |
| | | @Schema(description = "é¨é¨åç§°") |
| | | private String deptName; |
| | | |
| | | @Schema(description = "æ ¸ç®å¨æï¼yyyy-MMï¼") |
| | | private String period; |
| | | |
| | | @Schema(description = "åºå¤å¤©æ°") |
| | | private Integer workDays; |
| | | |
| | | @Schema(description = "æ£å¸¸å·¥æ¶ï¼å°æ¶ï¼") |
| | | private BigDecimal workHours; |
| | | |
| | | @Schema(description = "å çå·¥æ¶ï¼å°æ¶ï¼") |
| | | private BigDecimal overtimeHours; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.dataobject.approval; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.time.LocalDate; |
| | | |
| | | /** |
| | | * 转æ£ç³è¯· DO |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @TableName("hrm_regularize_application") |
| | | @KeySequence("hrm_regularize_application_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class HrmRegularizeApplicationDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç³è¯·ID |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç³è¯·åå· |
| | | */ |
| | | private String no; |
| | | |
| | | /** |
| | | * ç³è¯·äººID |
| | | * |
| | | * å
³è AdminUserDO#getId() |
| | | */ |
| | | private Long userId; |
| | | |
| | | /** |
| | | * é¨é¨ID |
| | | * |
| | | * å
³è DeptDO#getId() |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * å²ä½ID |
| | | * |
| | | * å
³è PostDO#getId() |
| | | */ |
| | | private Long postId; |
| | | |
| | | /** |
| | | * å½åç¨å·¥æ§è´¨ |
| | | * |
| | | * 1-æ£å¼ï¼2-å³å¡ï¼3-å¤å
ï¼4-å®ä¹ ï¼5-éä¼è¿èï¼6-å
¶ä» |
| | | */ |
| | | private Integer employmentType; |
| | | |
| | | /** |
| | | * æè½¬æ£æ¥æ |
| | | */ |
| | | private LocalDate expectedDate; |
| | | |
| | | /** |
| | | * 转æ£åå |
| | | */ |
| | | private String reason; |
| | | |
| | | /** |
| | | * 审æ¹ç¶æ |
| | | * |
| | | * æä¸¾ {@link cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum} |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * BPM æµç¨å®ä¾ID |
| | | */ |
| | | private String processInstanceId; |
| | | |
| | | /** |
| | | * 审æ¹å®ææ¶é´ |
| | | */ |
| | | private java.time.LocalDateTime approveTime; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | private Long postId; |
| | | |
| | | /** |
| | | * ç¨å·¥æ§è´¨ |
| | | * |
| | | * 1-æ£å¼ï¼2-å³å¡ï¼3-å¤å
ï¼4-å®ä¹ ï¼5-éä¼è¿èï¼6-å
¶ä» |
| | | */ |
| | | private Integer employmentType; |
| | | |
| | | /** |
| | | * æå±çç»ID |
| | | * |
| | | * å
³è MesCalTeamDO#getId()ï¼MES æçç»ï¼çç»/æç/绩æåæºï¼ |
| | | */ |
| | | private Long teamId; |
| | | |
| | | /** |
| | | * åå·¥ç¼å· |
| | | */ |
| | | private String employeeNo; |
| | |
| | | private Integer scopeType; |
| | | |
| | | /** |
| | | * æå®çç»ç¼å·éåï¼JSON æ°ç»ï¼scopeType=2 æ¶çæï¼å
³è MES æçç»ï¼ |
| | | */ |
| | | private String scopeTeamIds; |
| | | |
| | | /** |
| | | * æ¹æ¡ç¶æ: 0-è稿 10-å·²åå¸ 20-è¿è¡ä¸ 30-已宿 |
| | | */ |
| | | private Integer status; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.dataobject.training; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | |
| | | /** |
| | | * HRM å¹è®æ´»å¨ DO |
| | | * |
| | | * <p>管çå®å
¨å¹è®ãæè½å¹è®çå¹è®è®¡å/æ´»å¨ï¼é
å hrm_training_participant è®°å½åè®ä¸èæ ¸ç»æï¼ |
| | | * å¹è®å®æï¼status=å·²å®æï¼æ¶å¯¹åæ ¼äººåèå¨çæå¯¹åºè¯ä¹¦èµè´¨ï¼æé"å¹è®âè¯ä¹¦âå°ææé"åè§é¾è·¯ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @TableName("hrm_training") |
| | | @KeySequence("hrm_training_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class HrmTrainingDO extends BaseDO { |
| | | |
| | | /** |
| | | * å¹è®ç±»åï¼å®å
¨å¹è® |
| | | */ |
| | | public static final int TYPE_SAFETY = 1; |
| | | /** |
| | | * å¹è®ç±»åï¼æè½å¹è® |
| | | */ |
| | | public static final int TYPE_SKILL = 2; |
| | | /** |
| | | * å¹è®ç±»åï¼ç®¡çå¹è® |
| | | */ |
| | | public static final int TYPE_MANAGE = 3; |
| | | /** |
| | | * å¹è®ç±»åï¼å
¶ä» |
| | | */ |
| | | public static final int TYPE_OTHER = 4; |
| | | |
| | | /** |
| | | * ç¶æï¼è稿 |
| | | */ |
| | | public static final int STATUS_DRAFT = 0; |
| | | /** |
| | | * ç¶æï¼å¾
å¼å± |
| | | */ |
| | | public static final int STATUS_PLANNED = 10; |
| | | /** |
| | | * ç¶æï¼å·²å®æ |
| | | */ |
| | | public static final int STATUS_COMPLETED = 20; |
| | | /** |
| | | * ç¶æï¼å·²åæ¶ |
| | | */ |
| | | public static final int STATUS_CANCELED = 30; |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | |
| | | /** |
| | | * å¹è®ç¼å· |
| | | */ |
| | | private String trainingNo; |
| | | |
| | | /** |
| | | * å¹è®åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * å¹è®ç±»åï¼1=å®å
¨å¹è®ï¼2=æè½å¹è®ï¼3=管çå¹è®ï¼4=å
¶ä»ï¼ |
| | | */ |
| | | private Integer trainingType; |
| | | |
| | | /** |
| | | * è®²å¸ |
| | | */ |
| | | private String trainer; |
| | | |
| | | /** |
| | | * å¹è®å°ç¹ |
| | | */ |
| | | private String location; |
| | | |
| | | /** |
| | | * å¹è®å¦æ¶ |
| | | */ |
| | | private BigDecimal hours; |
| | | |
| | | /** |
| | | * å¼å§æ¥æ |
| | | */ |
| | | private LocalDate startDate; |
| | | |
| | | /** |
| | | * ç»ææ¥æ |
| | | */ |
| | | private LocalDate endDate; |
| | | |
| | | /** |
| | | * æ¯å¦èªå¨åè¯ï¼0=å¦ï¼1=æ¯ï¼ä»
å®å
¨/æè½å¹è®æ¯æï¼ |
| | | */ |
| | | private Boolean issueCertificate; |
| | | |
| | | /** |
| | | * è¯ä¹¦æææï¼æï¼ï¼èªå¨åè¯æ¶ç¨äºè®¡ç®è¯ä¹¦å°ææ¥ |
| | | */ |
| | | private Integer certValidityMonths; |
| | | |
| | | /** |
| | | * ç¶æï¼0=è稿ï¼10=å¾
å¼å±ï¼20=已宿ï¼30=å·²åæ¶ï¼ |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.dataobject.training; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * HRM å¹è®åè®äººå DO |
| | | * |
| | | * <p>è®°å½ææ¬¡å¹è®çåè®åå·¥ãæ¯å¦åå ãèæ ¸æç»©ä¸æ¯å¦åæ ¼ï¼å¹è®èå¨åè¯ååå certificateIdï¼é¿å
éå¤åè¯ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @TableName("hrm_training_participant") |
| | | @KeySequence("hrm_training_participant_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class HrmTrainingParticipantDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | |
| | | /** |
| | | * å¹è®æ´»å¨ç¼å· |
| | | * |
| | | * å
³è {@link HrmTrainingDO#getId()} |
| | | */ |
| | | private Long trainingId; |
| | | |
| | | /** |
| | | * åå·¥ç¼å· |
| | | * |
| | | * å
³è {@link cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO#getId()} |
| | | */ |
| | | private Long employeeId; |
| | | |
| | | /** |
| | | * æ¯å¦å®é
åå ï¼0=æªåå ï¼1=åå ï¼ |
| | | */ |
| | | private Boolean attended; |
| | | |
| | | /** |
| | | * èæ ¸æç»© |
| | | */ |
| | | private BigDecimal score; |
| | | |
| | | /** |
| | | * æ¯å¦åæ ¼ï¼0=ä¸åæ ¼ï¼1=åæ ¼ï¼ |
| | | */ |
| | | private Boolean isPass; |
| | | |
| | | /** |
| | | * èå¨çæè¯ä¹¦èµè´¨ç¼å· |
| | | * |
| | | * å
³è {@link cn.iocoder.yudao.module.hrm.dal.dataobject.certificate.HrmCertificateDO#getId()}ï¼ |
| | | * ç¨äºå¹çï¼åä¸åè®äººåä¸å¹è®åªå䏿¬¡è¯ï¼ |
| | | */ |
| | | private Long certificateId; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.dataobject.workhour; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * æåº¦å·¥æ¶æ±æ» DO |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @TableName("hrm_workhour_summary") |
| | | @KeySequence("hrm_workhour_summary_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class HrmWorkHourSummaryDO extends BaseDO { |
| | | |
| | | /** |
| | | * æ±æ»ID |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | |
| | | /** |
| | | * åå·¥ID |
| | | * |
| | | * å
³è HrmEmployeeDO#getId() |
| | | */ |
| | | private Long employeeId; |
| | | |
| | | /** |
| | | * é¨é¨ID |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * æ ¸ç®å¨æï¼yyyy-MMï¼ |
| | | */ |
| | | private String period; |
| | | |
| | | /** |
| | | * åºå¤å¤©æ° |
| | | */ |
| | | private Integer workDays; |
| | | |
| | | /** |
| | | * æ£å¸¸å·¥æ¶ï¼å°æ¶ï¼ |
| | | */ |
| | | private BigDecimal workHours; |
| | | |
| | | /** |
| | | * å çå·¥æ¶ï¼å°æ¶ï¼ |
| | | */ |
| | | private BigDecimal overtimeHours; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.mysql.approval; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmRegularizeApplicationDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * 转æ£ç³è¯· Mapper |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Mapper |
| | | public interface HrmRegularizeApplicationMapper extends BaseMapperX<HrmRegularizeApplicationDO> { |
| | | |
| | | default PageResult<HrmRegularizeApplicationDO> selectPage(HrmRegularizeApplicationPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<HrmRegularizeApplicationDO>() |
| | | .likeIfPresent(HrmRegularizeApplicationDO::getNo, reqVO.getNo()) |
| | | .eqIfPresent(HrmRegularizeApplicationDO::getUserId, reqVO.getUserId()) |
| | | .eqIfPresent(HrmRegularizeApplicationDO::getDeptId, reqVO.getDeptId()) |
| | | .eqIfPresent(HrmRegularizeApplicationDO::getEmploymentType, reqVO.getEmploymentType()) |
| | | .eqIfPresent(HrmRegularizeApplicationDO::getStatus, reqVO.getStatus()) |
| | | .betweenIfPresent(HrmRegularizeApplicationDO::getCreateTime, reqVO.getCreateTime()) |
| | | .orderByDesc(HrmRegularizeApplicationDO::getId)); |
| | | } |
| | | |
| | | default HrmRegularizeApplicationDO selectByNo(String no) { |
| | | return selectOne(HrmRegularizeApplicationDO::getNo, no); |
| | | } |
| | | |
| | | default HrmRegularizeApplicationDO selectByProcessInstanceId(String processInstanceId) { |
| | | return selectOne(HrmRegularizeApplicationDO::getProcessInstanceId, processInstanceId); |
| | | } |
| | | |
| | | default HrmRegularizeApplicationDO selectByUserIdAndStatusNot(Long userId, Integer status) { |
| | | return selectOne(new LambdaQueryWrapperX<HrmRegularizeApplicationDO>() |
| | | .eq(HrmRegularizeApplicationDO::getUserId, userId) |
| | | .ne(HrmRegularizeApplicationDO::getStatus, status) |
| | | .orderByDesc(HrmRegularizeApplicationDO::getId) |
| | | .last("LIMIT 1")); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.certificate.HrmCertificateDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * HRM è¯ä¹¦èµè´¨ Mapper |
| | | * |
| | |
| | | @Mapper |
| | | public interface HrmCertificateMapper extends BaseMapperX<HrmCertificateDO> { |
| | | |
| | | /** |
| | | * å°ææéå¤©æ° |
| | | */ |
| | | int REMIND_DAYS = 30; |
| | | |
| | | default PageResult<HrmCertificateDO> selectPage(HrmCertificatePageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<HrmCertificateDO>() |
| | | LambdaQueryWrapperX<HrmCertificateDO> query = new LambdaQueryWrapperX<HrmCertificateDO>() |
| | | .eqIfPresent(HrmCertificateDO::getEmployeeId, reqVO.getEmployeeId()) |
| | | .eqIfPresent(HrmCertificateDO::getCertType, reqVO.getCertType()) |
| | | .likeIfPresent(HrmCertificateDO::getCertName, reqVO.getCertName()) |
| | | .orderByDesc(HrmCertificateDO::getId)); |
| | | .likeIfPresent(HrmCertificateDO::getCertName, reqVO.getCertName()); |
| | | // å°æç±»åçéï¼é
ååè§å表/å¾
åæéï¼ï¼1=å³å°å°æï¼2=å·²è¿æ |
| | | if (reqVO.getExpiryType() != null) { |
| | | LocalDate today = LocalDate.now(); |
| | | if (reqVO.getExpiryType() == 1) { // å³å°å°æ |
| | | query.between(HrmCertificateDO::getExpireDate, today, today.plusDays(REMIND_DAYS)); |
| | | } else if (reqVO.getExpiryType() == 2) { // å·²è¿æ |
| | | query.isNotNull(HrmCertificateDO::getExpireDate) |
| | | .lt(HrmCertificateDO::getExpireDate, today); |
| | | } |
| | | } |
| | | return selectPage(reqVO, query.orderByDesc(HrmCertificateDO::getId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æææè½å¨ [start, end] ä¹é´çè¯ä¹¦ï¼å°ææéç¨ï¼ |
| | | * |
| | | * @param start èµ·å§æ¥æ |
| | | * @param end æªæ¢æ¥æ |
| | | * @return å³å°å°æè¯ä¹¦å表 |
| | | */ |
| | | default List<HrmCertificateDO> selectListByExpireDateBetween(LocalDate start, LocalDate end) { |
| | | return selectList(new LambdaQueryWrapperX<HrmCertificateDO>() |
| | | .isNotNull(HrmCertificateDO::getExpireDate) |
| | | .between(HrmCertificateDO::getExpireDate, start, end)); |
| | | } |
| | | |
| | | } |
| | |
| | | .orderByDesc(HrmEmployeeContractDO::getId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åçæãå°å¨ [start, end] ä¹é´å°æçåºå®æéååï¼å°ææéç¨ï¼ |
| | | * |
| | | * @param start èµ·å§æ¥æ |
| | | * @param end æªæ¢æ¥æ |
| | | * @return å³å°å°æååå表 |
| | | */ |
| | | default List<HrmEmployeeContractDO> selectListExpiringBetween(LocalDate start, LocalDate end) { |
| | | return selectList(new LambdaQueryWrapperX<HrmEmployeeContractDO>() |
| | | .eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL) |
| | | .eq(HrmEmployeeContractDO::getIsCurrent, true) |
| | | .le(HrmEmployeeContractDO::getStartDate, start) |
| | | .isNotNull(HrmEmployeeContractDO::getEndDate) |
| | | .between(HrmEmployeeContractDO::getEndDate, start, end)); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.mysql.employee; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | .orderByAsc(HrmEmployeeDO::getName)); |
| | | } |
| | | |
| | | default List<HrmEmployeeDO> selectListByTeamIds(Collection<Long> teamIds) { |
| | | return selectList(new LambdaQueryWrapperX<HrmEmployeeDO>() |
| | | .inIfPresent(HrmEmployeeDO::getTeamId, CollUtil.isNotEmpty(teamIds) ? teamIds : null) |
| | | .orderByAsc(HrmEmployeeDO::getName)); |
| | | } |
| | | |
| | | } |
| | |
| | | .orderByDesc(HrmPerformanceAppraiseDO::getId)); |
| | | } |
| | | |
| | | default HrmPerformanceAppraiseDO selectMonthlyCompletedByPeriod(String period) { |
| | | return selectOne(new LambdaQueryWrapperX<HrmPerformanceAppraiseDO>() |
| | | .eq(HrmPerformanceAppraiseDO::getPeriodType, 1) |
| | | .eq(HrmPerformanceAppraiseDO::getPeriod, period) |
| | | .eq(HrmPerformanceAppraiseDO::getStatus, 30) |
| | | .orderByDesc(HrmPerformanceAppraiseDO::getId) |
| | | .last("LIMIT 1")); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.mysql.salary; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmEmployeeSalaryPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmEmployeeSalaryDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | |
| | | .orderByDesc(HrmEmployeeSalaryDO::getEffectiveDate)); |
| | | } |
| | | |
| | | default PageResult<HrmEmployeeSalaryDO> selectPage(HrmEmployeeSalaryPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<HrmEmployeeSalaryDO>() |
| | | .eqIfPresent(HrmEmployeeSalaryDO::getUserId, reqVO.getUserId()) |
| | | .eqIfPresent(HrmEmployeeSalaryDO::getSalaryStructureId, reqVO.getSalaryStructureId()) |
| | | .eqIfPresent(HrmEmployeeSalaryDO::getStatus, reqVO.getStatus()) |
| | | .orderByDesc(HrmEmployeeSalaryDO::getId)); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.mysql.salary; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmSalaryStructurePageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryStructureDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | |
| | | .orderByAsc(HrmSalaryStructureDO::getName)); |
| | | } |
| | | |
| | | default PageResult<HrmSalaryStructureDO> selectPage(HrmSalaryStructurePageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<HrmSalaryStructureDO>() |
| | | .likeIfPresent(HrmSalaryStructureDO::getName, reqVO.getName()) |
| | | .eqIfPresent(HrmSalaryStructureDO::getStatus, reqVO.getStatus()) |
| | | .orderByDesc(HrmSalaryStructureDO::getId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.mysql.training; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * HRM å¹è®æ´»å¨ Mapper |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Mapper |
| | | public interface HrmTrainingMapper extends BaseMapperX<HrmTrainingDO> { |
| | | |
| | | default PageResult<HrmTrainingDO> selectPage(HrmTrainingPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<HrmTrainingDO>() |
| | | .likeIfPresent(HrmTrainingDO::getName, reqVO.getName()) |
| | | .eqIfPresent(HrmTrainingDO::getTrainingNo, reqVO.getTrainingNo()) |
| | | .eqIfPresent(HrmTrainingDO::getTrainingType, reqVO.getTrainingType()) |
| | | .eqIfPresent(HrmTrainingDO::getStatus, reqVO.getStatus()) |
| | | .orderByDesc(HrmTrainingDO::getId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.mysql.training; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingParticipantDO; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * HRM å¹è®åè®äººå Mapper |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Mapper |
| | | public interface HrmTrainingParticipantMapper extends BaseMapperX<HrmTrainingParticipantDO> { |
| | | |
| | | /** |
| | | * æ¥è¯¢ææ¬¡å¹è®çå
¨é¨åè®äººå |
| | | * |
| | | * @param trainingId å¹è®æ´»å¨ç¼å· |
| | | * @return åè®äººåå表 |
| | | */ |
| | | default List<HrmTrainingParticipantDO> selectListByTrainingId(Long trainingId) { |
| | | return selectList(new LambdaQueryWrapperX<HrmTrainingParticipantDO>() |
| | | .eq(HrmTrainingParticipantDO::getTrainingId, trainingId) |
| | | .orderByAsc(HrmTrainingParticipantDO::getId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éæ¥è¯¢æå®å¹è®çåè®äººåï¼å页ç»è®¡åè®äººæ°ç¨ï¼ |
| | | * |
| | | * @param trainingIds å¹è®æ´»å¨ç¼å·éå |
| | | * @return åè®äººåå表 |
| | | */ |
| | | default List<HrmTrainingParticipantDO> selectListByTrainingIds(Collection<Long> trainingIds) { |
| | | return selectList(new LambdaQueryWrapperX<HrmTrainingParticipantDO>() |
| | | .in(HrmTrainingParticipantDO::getTrainingId, trainingIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ææ¬¡å¹è®ä¸æä½åå·¥çåè®è®°å½ï¼é²é夿·»å ç¨ï¼ |
| | | * |
| | | * @param trainingId å¹è®æ´»å¨ç¼å· |
| | | * @param employeeId åå·¥ç¼å· |
| | | * @return åè®è®°å½ï¼æ åè¿å null |
| | | */ |
| | | default HrmTrainingParticipantDO selectByTrainingIdAndEmployeeId(Long trainingId, Long employeeId) { |
| | | return selectOne(new LambdaQueryWrapperX<HrmTrainingParticipantDO>() |
| | | .eq(HrmTrainingParticipantDO::getTrainingId, trainingId) |
| | | .eq(HrmTrainingParticipantDO::getEmployeeId, employeeId)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ææ¬¡å¹è®çå
¨é¨åè®äººåï¼å¹è®å 餿¶çº§èï¼ |
| | | * |
| | | * @param trainingId å¹è®æ´»å¨ç¼å· |
| | | */ |
| | | default void deleteByTrainingId(Long trainingId) { |
| | | delete(new LambdaQueryWrapperX<HrmTrainingParticipantDO>() |
| | | .eq(HrmTrainingParticipantDO::getTrainingId, trainingId)); |
| | | } |
| | | |
| | | /** |
| | | * ååèå¨çæçè¯ä¹¦ç¼å· |
| | | * |
| | | * @param id åè®äººåç¼å· |
| | | * @param certificateId è¯ä¹¦èµè´¨ç¼å· |
| | | */ |
| | | default void updateCertificateId(Long id, Long certificateId) { |
| | | update(null, new LambdaUpdateWrapper<HrmTrainingParticipantDO>() |
| | | .eq(HrmTrainingParticipantDO::getId, id) |
| | | .set(HrmTrainingParticipantDO::getCertificateId, certificateId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.mysql.workhour; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo.HrmWorkHourSummaryPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.workhour.HrmWorkHourSummaryDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æåº¦å·¥æ¶æ±æ» Mapper |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Mapper |
| | | public interface HrmWorkHourSummaryMapper extends BaseMapperX<HrmWorkHourSummaryDO> { |
| | | |
| | | default PageResult<HrmWorkHourSummaryDO> selectPage(HrmWorkHourSummaryPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<HrmWorkHourSummaryDO>() |
| | | .eqIfPresent(HrmWorkHourSummaryDO::getEmployeeId, reqVO.getEmployeeId()) |
| | | .eqIfPresent(HrmWorkHourSummaryDO::getDeptId, reqVO.getDeptId()) |
| | | .eqIfPresent(HrmWorkHourSummaryDO::getPeriod, reqVO.getPeriod()) |
| | | .orderByDesc(HrmWorkHourSummaryDO::getId)); |
| | | } |
| | | |
| | | default HrmWorkHourSummaryDO selectByEmployeeIdAndPeriod(Long employeeId, String period) { |
| | | return selectOne(new LambdaQueryWrapperX<HrmWorkHourSummaryDO>() |
| | | .eq(HrmWorkHourSummaryDO::getEmployeeId, employeeId) |
| | | .eq(HrmWorkHourSummaryDO::getPeriod, period) |
| | | .last("LIMIT 1")); |
| | | } |
| | | |
| | | default List<HrmWorkHourSummaryDO> selectListByPeriod(String period) { |
| | | return selectList(new LambdaQueryWrapperX<HrmWorkHourSummaryDO>() |
| | | .eq(HrmWorkHourSummaryDO::getPeriod, period) |
| | | .orderByAsc(HrmWorkHourSummaryDO::getEmployeeId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.dal.redis; |
| | | |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.time.Duration; |
| | | import java.time.LocalDate; |
| | | |
| | | /** |
| | | * HRM è¯ä¹¦/ååå°ææé Redis DAO |
| | | * |
| | | * <p>ç¨äºå°æç«å
ä¿¡çå»éï¼åä¸ä¸å¡åä¸å°ææ¥åªæé䏿¬¡ï¼ä¸å½å¤©æ«æé¨é©ï¼é¿å
å¤å®ä¾/夿¬¡å¹¶åé夿«æï¼ï¼ |
| | | * æè·¯åç
§ MES 计éå¨å
·å°ææéã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Repository |
| | | public class HrmExpiryRemindRedisDAO { |
| | | |
| | | /** |
| | | * æéå»é KEY çè¿ææ¶é´ï¼60 天ï¼ï¼åä¸ä¸å¡è®°å½åä¸å°ææ¥ 60 天å
åªæé䏿¬¡ |
| | | */ |
| | | private static final Duration REMIND_TIMEOUT = Duration.ofDays(60); |
| | | /** |
| | | * æ«æé¨é©çè¿ææ¶é´ï¼30 åéï¼ï¼é¿å
å¤å®ä¾/夿¬¡å¹¶åé夿«æ |
| | | */ |
| | | private static final Duration SCAN_LOCK_TIMEOUT = Duration.ofMinutes(30); |
| | | |
| | | @Resource |
| | | private StringRedisTemplate stringRedisTemplate; |
| | | |
| | | /** |
| | | * å°è¯æ è®°å·²æéï¼åä¸ä¸å¡è®°å½åä¸å°ææ¥ 60 天å
åªæé䏿¬¡ï¼ |
| | | * |
| | | * @param biz ä¸å¡æ è¯ï¼å¦ cert=è¯ä¹¦èµè´¨ãcontract=åå·¥ååï¼ |
| | | * @param bizId ä¸å¡è®°å½ç¼å· |
| | | * @param expireDate å°ææ¥ |
| | | * @return true è¡¨ç¤ºé¦æ¬¡æ è®°æåï¼éè¦åéæé |
| | | */ |
| | | public boolean tryMarkReminded(String biz, Long bizId, LocalDate expireDate) { |
| | | String key = HrmRedisKeyConstants.EXPIRE_REMIND + biz + ":" + bizId + ":" + expireDate; |
| | | return Boolean.TRUE.equals(stringRedisTemplate.opsForValue().setIfAbsent(key, "1", REMIND_TIMEOUT)); |
| | | } |
| | | |
| | | /** |
| | | * å°è¯è·åå½å¤©çæ«æé¨é©ï¼é¿å
å¤å®ä¾å¹¶åé夿«æ |
| | | * |
| | | * @param biz ä¸å¡æ è¯ï¼å¦ cert=è¯ä¹¦èµè´¨ãcontract=åå·¥ååï¼ |
| | | * @param today å½å¤©æ¥æ |
| | | * @return true 表示è·åæåï¼å¯ä»¥æ§è¡æ«æï¼ |
| | | */ |
| | | public boolean tryAcquireScanLock(String biz, LocalDate today) { |
| | | String key = HrmRedisKeyConstants.EXPIRE_REMIND_SCAN + biz + ":" + today; |
| | | return Boolean.TRUE.equals(stringRedisTemplate.opsForValue().setIfAbsent(key, "1", SCAN_LOCK_TIMEOUT)); |
| | | } |
| | | |
| | | } |
| | |
| | | */ |
| | | public static final String EMPLOYEE_CONTRACT_NO_PREFIX = "HT"; |
| | | |
| | | /** |
| | | * å¹è®æ´»å¨ç¼å·åç¼ |
| | | */ |
| | | public static final String TRAINING_NO_PREFIX = "PX"; |
| | | |
| | | /** |
| | | * 转æ£ç³è¯·ç¼å·åç¼ |
| | | */ |
| | | public static final String REGULARIZE_APPLICATION_NO_PREFIX = "ZZ"; |
| | | |
| | | @Resource |
| | | private StringRedisTemplate stringRedisTemplate; |
| | | |
| | | /** |
| | | * çæå¹è®æ´»å¨ç¼å·ï¼æ ¼å¼ï¼PX + yyyyMMdd + 4ä½èªå¢ |
| | | * ä¾å¦ï¼PX202401010001 |
| | | * |
| | | * @return å¹è®æ´»å¨ç¼å· |
| | | */ |
| | | public String generateTrainingNo() { |
| | | return generate(TRAINING_NO_PREFIX, 4); |
| | | } |
| | | |
| | | /** |
| | | * çæè½¬æ£ç³è¯·ç¼å·ï¼æ ¼å¼ï¼ZZ + yyyyMMdd + 4ä½èªå¢ |
| | | * ä¾å¦ï¼ZZ202401010001 |
| | | * |
| | | * @return 转æ£ç³è¯·ç¼å· |
| | | */ |
| | | public String generateRegularizeApplicationNo() { |
| | | return generate(REGULARIZE_APPLICATION_NO_PREFIX, 4); |
| | | } |
| | | |
| | | /** |
| | | * çæåå·¥ç¼å·ï¼æ ¼å¼ï¼EMP + yyyyMMdd + 4ä½èªå¢ |
| | | * ä¾å¦ï¼EMP202401010001 |
| | | * |
| | |
| | | */ |
| | | String NO = "hrm:no:"; |
| | | |
| | | /** |
| | | * å°ææéå»é KEY åç¼ï¼åæ¥ ä¸å¡æ è¯:id:å°ææ¥æï¼ |
| | | */ |
| | | String EXPIRE_REMIND = "hrm:remind:item:"; |
| | | |
| | | /** |
| | | * å°ææéæ«æé¨é© KEY åç¼ï¼åæ¥ ä¸å¡æ è¯:å½å¤©æ¥æï¼ |
| | | */ |
| | | String EXPIRE_REMIND_SCAN = "hrm:remind:scan:"; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.job; |
| | | |
| | | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; |
| | | import cn.iocoder.yudao.module.hrm.service.remind.HrmExpiryRemindService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * HRM è¯ä¹¦/ååå°ææé宿¶ä»»å¡ |
| | | * |
| | | * <p>æ¯æ¥æ«æå³å°å°æï¼é»è®¤ 30 天å
ï¼å¯å¨ infra_config è°æ´ï¼çè¯ä¹¦èµè´¨ä¸å³å¨ååï¼ |
| | | * åå¨å²å工系ç»è´¦å·åéç«å
ä¿¡æéãå¨ãåºç¡è®¾æ½ â 宿¶ä»»å¡ãä¸ä»¥ handlerName=hrmExpiryRemindJob å¯ç¨ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Component |
| | | public class HrmExpiryRemindJob implements JobHandler { |
| | | |
| | | @Resource |
| | | private HrmExpiryRemindService expiryRemindService; |
| | | |
| | | @Override |
| | | public String execute(String param) { |
| | | expiryRemindService.sendAll(); |
| | | return "HRM è¯ä¹¦/ååå°ææéæ§è¡å®æ"; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.approval; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmRegularizeApplicationDO; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 转æ£ç³è¯· Service æ¥å£ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface HrmRegularizeApplicationService { |
| | | |
| | | /** |
| | | * 审æ¹åç±»ç¼ç ï¼è½¬æ£å®¡æ¹ |
| | | */ |
| | | String APPROVE_CATEGORY_CODE = "hrm_regularize_approve"; |
| | | |
| | | /** |
| | | * å建转æ£ç³è¯· |
| | | * |
| | | * @param createReqVO åå»ºä¿¡æ¯ |
| | | * @return ç³è¯·ID |
| | | */ |
| | | Long createRegularizeApplication(HrmRegularizeApplicationSaveReqVO createReqVO); |
| | | |
| | | /** |
| | | * æ´æ°è½¬æ£ç³è¯· |
| | | * |
| | | * @param updateReqVO æ´æ°ä¿¡æ¯ |
| | | */ |
| | | void updateRegularizeApplication(HrmRegularizeApplicationSaveReqVO updateReqVO); |
| | | |
| | | /** |
| | | * å é¤è½¬æ£ç³è¯· |
| | | * |
| | | * @param id ç³è¯·ID |
| | | */ |
| | | void deleteRegularizeApplication(Long id); |
| | | |
| | | /** |
| | | * è·å转æ£ç³è¯· |
| | | * |
| | | * @param id ç³è¯·ID |
| | | * @return ç³è¯·ä¿¡æ¯ |
| | | */ |
| | | HrmRegularizeApplicationDO getRegularizeApplication(Long id); |
| | | |
| | | /** |
| | | * è·å转æ£ç³è¯·è¯¦æ
|
| | | * |
| | | * @param id ç³è¯·ID |
| | | * @return ç³è¯·è¯¦æ
|
| | | */ |
| | | HrmRegularizeApplicationRespVO getRegularizeApplicationDetail(Long id); |
| | | |
| | | /** |
| | | * è·å转æ£ç³è¯·å页 |
| | | * |
| | | * @param pageReqVO åé¡µè¯·æ± |
| | | * @return åé¡µç»æ |
| | | */ |
| | | PageResult<HrmRegularizeApplicationRespVO> getRegularizeApplicationPage(HrmRegularizeApplicationPageReqVO pageReqVO); |
| | | |
| | | /** |
| | | * æäº¤è½¬æ£ç³è¯·å®¡æ¹ |
| | | * |
| | | * @param id ç³è¯·ID |
| | | * @param processDefinitionKey æµç¨å®ä¹Key |
| | | * @param userId å起人ID |
| | | */ |
| | | void submitRegularizeApplication(Long id, String processDefinitionKey, Long userId); |
| | | |
| | | /** |
| | | * æ´æ°è½¬æ£ç³è¯·å®¡æ¹ç¶æ |
| | | * |
| | | * @param id ç³è¯·ID |
| | | * @param status 审æ¹ç¶æ |
| | | */ |
| | | void updateRegularizeApplicationAuditStatus(Long id, Integer status); |
| | | |
| | | /** |
| | | * æ ¹æ®æµç¨å®ä¾IDè·å转æ£ç³è¯· |
| | | * |
| | | * @param processInstanceId æµç¨å®ä¾ID |
| | | * @return ç³è¯·ä¿¡æ¯ |
| | | */ |
| | | HrmRegularizeApplicationDO getRegularizeApplicationByProcessInstanceId(String processInstanceId); |
| | | |
| | | /** |
| | | * è·å转æ£å®¡æ¹æµç¨å®ä¹å表 |
| | | * |
| | | * @return æµç¨å®ä¹å表 |
| | | */ |
| | | List<Map<String, Object>> getApproveProcessDefinitionList(); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.approval; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; |
| | | 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.dal.dataobject.definition.BpmProcessDefinitionInfoDO; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmRegularizeApplicationDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmRegularizeApplicationMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmEmploymentTypeEnum; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.PostApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.Stream; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * 转æ£ç³è¯· Service å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class HrmRegularizeApplicationServiceImpl implements HrmRegularizeApplicationService { |
| | | |
| | | @Resource |
| | | private HrmRegularizeApplicationMapper regularizeApplicationMapper; |
| | | @Resource |
| | | private HrmNoRedisDAO noRedisDAO; |
| | | @Resource |
| | | private DeptApi deptApi; |
| | | @Resource |
| | | private PostApi postApi; |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | @Resource |
| | | private BpmProcessInstanceApi bpmProcessInstanceApi; |
| | | @Resource |
| | | private BpmCategoryService bpmCategoryService; |
| | | @Resource |
| | | private BpmProcessDefinitionService bpmProcessDefinitionService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createRegularizeApplication(HrmRegularizeApplicationSaveReqVO createReqVO) { |
| | | Long userId = createReqVO.getUserId(); |
| | | if (userId == null) { |
| | | userId = getCurrentUserId(); |
| | | } |
| | | HrmRegularizeApplicationDO existing = regularizeApplicationMapper.selectByUserIdAndStatusNot(userId, |
| | | HrmAuditStatusEnum.CANCEL.getStatus()); |
| | | if (existing != null) { |
| | | throw exception(REGULARIZE_APPLICATION_EXISTS); |
| | | } |
| | | String no = generateUniqueNo(); |
| | | AdminUserRespDTO user = adminUserApi.getUser(userId); |
| | | if (user == null) { |
| | | userId = getCurrentUserId(); |
| | | user = adminUserApi.getUser(userId); |
| | | } |
| | | HrmRegularizeApplicationDO application = BeanUtils.toBean(createReqVO, HrmRegularizeApplicationDO.class); |
| | | application.setNo(no); |
| | | application.setUserId(userId); |
| | | application.setDeptId(createReqVO.getDeptId() != null ? createReqVO.getDeptId() |
| | | : (user != null ? user.getDeptId() : null)); |
| | | application.setStatus(HrmAuditStatusEnum.DRAFT.getStatus()); |
| | | regularizeApplicationMapper.insert(application); |
| | | return application.getId(); |
| | | } |
| | | |
| | | private Long getCurrentUserId() { |
| | | return SecurityFrameworkUtils.getLoginUserId(); |
| | | } |
| | | |
| | | private String generateUniqueNo() { |
| | | String no = noRedisDAO.generateRegularizeApplicationNo(); |
| | | if (regularizeApplicationMapper.selectByNo(no) != null) { |
| | | return generateUniqueNo(); |
| | | } |
| | | return no; |
| | | } |
| | | |
| | | @Override |
| | | public void updateRegularizeApplication(HrmRegularizeApplicationSaveReqVO updateReqVO) { |
| | | HrmRegularizeApplicationDO application = validateRegularizeApplicationExists(updateReqVO.getId()); |
| | | if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) { |
| | | throw exception(REGULARIZE_APPLICATION_UPDATE_FAIL_NOT_DRAFT); |
| | | } |
| | | HrmRegularizeApplicationDO updateObj = BeanUtils.toBean(updateReqVO, HrmRegularizeApplicationDO.class); |
| | | regularizeApplicationMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteRegularizeApplication(Long id) { |
| | | HrmRegularizeApplicationDO application = validateRegularizeApplicationExists(id); |
| | | if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) { |
| | | throw exception(REGULARIZE_APPLICATION_UPDATE_FAIL_NOT_DRAFT); |
| | | } |
| | | regularizeApplicationMapper.deleteById(id); |
| | | } |
| | | |
| | | private HrmRegularizeApplicationDO validateRegularizeApplicationExists(Long id) { |
| | | HrmRegularizeApplicationDO application = regularizeApplicationMapper.selectById(id); |
| | | if (application == null) { |
| | | throw exception(REGULARIZE_APPLICATION_NOT_EXISTS); |
| | | } |
| | | return application; |
| | | } |
| | | |
| | | @Override |
| | | public HrmRegularizeApplicationDO getRegularizeApplication(Long id) { |
| | | return regularizeApplicationMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public HrmRegularizeApplicationRespVO getRegularizeApplicationDetail(Long id) { |
| | | HrmRegularizeApplicationDO application = getRegularizeApplication(id); |
| | | if (application == null) { |
| | | return null; |
| | | } |
| | | HrmRegularizeApplicationRespVO respVO = BeanUtils.toBean(application, HrmRegularizeApplicationRespVO.class); |
| | | fillUserNames(respVO, application); |
| | | if (application.getDeptId() != null) { |
| | | DeptRespDTO dept = deptApi.getDept(application.getDeptId()); |
| | | if (dept != null) { |
| | | respVO.setDeptName(dept.getName()); |
| | | } |
| | | } |
| | | if (application.getPostId() != null) { |
| | | Map<Long, PostRespDTO> postMap = postApi.getPostMap(Collections.singleton(application.getPostId())); |
| | | PostRespDTO post = postMap.get(application.getPostId()); |
| | | if (post != null) { |
| | | respVO.setPostName(post.getName()); |
| | | } |
| | | } |
| | | respVO.setEmploymentTypeName(HrmEmploymentTypeEnum.getNameByType(application.getEmploymentType())); |
| | | respVO.setStatusName(HrmAuditStatusEnum.getNameByStatus(application.getStatus())); |
| | | return respVO; |
| | | } |
| | | |
| | | private void fillUserNames(HrmRegularizeApplicationRespVO respVO, HrmRegularizeApplicationDO application) { |
| | | if (application.getUserId() != null) { |
| | | AdminUserRespDTO user = adminUserApi.getUser(application.getUserId()); |
| | | if (user != null) { |
| | | respVO.setUserName(user.getNickname()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<HrmRegularizeApplicationRespVO> getRegularizeApplicationPage(HrmRegularizeApplicationPageReqVO pageReqVO) { |
| | | PageResult<HrmRegularizeApplicationDO> pageResult = regularizeApplicationMapper.selectPage(pageReqVO); |
| | | if (pageResult.getList().isEmpty()) { |
| | | return new PageResult<>(Collections.emptyList(), pageResult.getTotal()); |
| | | } |
| | | Set<Long> userIds = pageResult.getList().stream() |
| | | .map(HrmRegularizeApplicationDO::getUserId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); |
| | | Set<Long> deptIds = pageResult.getList().stream() |
| | | .map(HrmRegularizeApplicationDO::getDeptId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(deptIds); |
| | | Set<Long> postIds = pageResult.getList().stream() |
| | | .map(HrmRegularizeApplicationDO::getPostId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds); |
| | | List<HrmRegularizeApplicationRespVO> list = pageResult.getList().stream().map(app -> { |
| | | HrmRegularizeApplicationRespVO vo = BeanUtils.toBean(app, HrmRegularizeApplicationRespVO.class); |
| | | if (app.getUserId() != null && userMap.containsKey(app.getUserId())) { |
| | | vo.setUserName(userMap.get(app.getUserId()).getNickname()); |
| | | } |
| | | if (app.getDeptId() != null && deptMap.containsKey(app.getDeptId())) { |
| | | vo.setDeptName(deptMap.get(app.getDeptId()).getName()); |
| | | } |
| | | if (app.getPostId() != null && postMap.containsKey(app.getPostId())) { |
| | | vo.setPostName(postMap.get(app.getPostId()).getName()); |
| | | } |
| | | vo.setEmploymentTypeName(HrmEmploymentTypeEnum.getNameByType(app.getEmploymentType())); |
| | | vo.setStatusName(HrmAuditStatusEnum.getNameByStatus(app.getStatus())); |
| | | return vo; |
| | | }).collect(Collectors.toList()); |
| | | return new PageResult<>(list, pageResult.getTotal()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void submitRegularizeApplication(Long id, String processDefinitionKey, Long userId) { |
| | | HrmRegularizeApplicationDO application = validateRegularizeApplicationExists(id); |
| | | if (ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) { |
| | | throw exception(REGULARIZE_APPLICATION_SUBMIT_FAIL_NOT_DRAFT); |
| | | } |
| | | validateApproveCategoryAndProcessDefinition(); |
| | | ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey); |
| | | if (processDefinition == null) { |
| | | throw exception(REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() |
| | | .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id))); |
| | | regularizeApplicationMapper.updateById(HrmRegularizeApplicationDO.builder() |
| | | .id(id) |
| | | .processInstanceId(processInstanceId) |
| | | .status(HrmAuditStatusEnum.PROCESS.getStatus()) |
| | | .build()); |
| | | } |
| | | |
| | | private void validateApproveCategoryAndProcessDefinition() { |
| | | List<String> codes = Collections.singletonList(APPROVE_CATEGORY_CODE); |
| | | Map<String, ?> categoryMap = bpmCategoryService.getCategoryMap(codes); |
| | | if (!categoryMap.containsKey(APPROVE_CATEGORY_CODE)) { |
| | | throw exception(REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService |
| | | .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE); |
| | | if (CollUtil.isEmpty(definitionInfoList)) { |
| | | throw exception(REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId); |
| | | List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds); |
| | | boolean hasActiveDefinition = processDefinitions.stream().anyMatch(pd -> !pd.isSuspended()); |
| | | if (!hasActiveDefinition) { |
| | | throw exception(REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> getApproveProcessDefinitionList() { |
| | | validateApproveCategoryAndProcessDefinition(); |
| | | List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService |
| | | .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE); |
| | | Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId); |
| | | List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds); |
| | | Map<String, ProcessDefinition> latestVersionMap = new HashMap<>(); |
| | | for (ProcessDefinition pd : processDefinitions) { |
| | | if (pd.isSuspended()) continue; |
| | | ProcessDefinition existing = latestVersionMap.get(pd.getKey()); |
| | | if (existing == null || pd.getVersion() > existing.getVersion()) { |
| | | latestVersionMap.put(pd.getKey(), pd); |
| | | } |
| | | } |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (ProcessDefinition pd : latestVersionMap.values()) { |
| | | Map<String, Object> item = new HashMap<>(); |
| | | item.put("id", pd.getId()); |
| | | item.put("key", pd.getKey()); |
| | | item.put("name", pd.getName()); |
| | | item.put("version", pd.getVersion()); |
| | | result.add(item); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public void updateRegularizeApplicationAuditStatus(Long id, Integer status) { |
| | | HrmRegularizeApplicationDO application = validateRegularizeApplicationExists(id); |
| | | if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) { |
| | | log.error("[updateRegularizeApplicationAuditStatus][application({}) ä¸å¤äºå®¡æ¹ä¸ï¼æ æ³æ´æ°å®¡æ¹ç»æ({})]", id, status); |
| | | throw exception(REGULARIZE_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS); |
| | | } |
| | | regularizeApplicationMapper.updateById(HrmRegularizeApplicationDO.builder() |
| | | .id(id) |
| | | .status(status) |
| | | .approveTime(java.time.LocalDateTime.now()) |
| | | .build()); |
| | | } |
| | | |
| | | @Override |
| | | public HrmRegularizeApplicationDO getRegularizeApplicationByProcessInstanceId(String processInstanceId) { |
| | | return regularizeApplicationMapper.selectByProcessInstanceId(processInstanceId); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.approval.listener; |
| | | |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmRegularizeApplicationDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmRegularizeApplicationMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum; |
| | | import cn.iocoder.yudao.module.hrm.service.approval.HrmRegularizeApplicationService; |
| | | import cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.ApplicationListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.time.LocalDate; |
| | | |
| | | /** |
| | | * 转æ£ç³è¯·å®¡æ¹çç»æçå¬å¨å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class HrmRegularizeApplicationStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> { |
| | | |
| | | /** |
| | | * åå·¥ç¶æï¼å¨è |
| | | */ |
| | | private static final Integer EMPLOYEE_STATUS_ACTIVE = 1; |
| | | |
| | | /** |
| | | * ç¨å·¥æ§è´¨ï¼æ£å¼ |
| | | */ |
| | | private static final Integer EMPLOYMENT_TYPE_FORMAL = 1; |
| | | |
| | | @Resource |
| | | private HrmRegularizeApplicationService regularizeApplicationService; |
| | | @Resource |
| | | private HrmRegularizeApplicationMapper regularizeApplicationMapper; |
| | | @Resource |
| | | private HrmEmployeeMapper employeeMapper; |
| | | |
| | | @Override |
| | | public void onApplicationEvent(BpmProcessInstanceStatusEvent event) { |
| | | // éè¿ businessKey æ¥è¯¢è½¬æ£ç³è¯· |
| | | Long applicationId; |
| | | try { |
| | | applicationId = Long.parseLong(event.getBusinessKey()); |
| | | } catch (NumberFormatException e) { |
| | | return; |
| | | } |
| | | |
| | | HrmRegularizeApplicationDO application = regularizeApplicationMapper.selectById(applicationId); |
| | | if (application == null) { |
| | | return; |
| | | } |
| | | |
| | | // åªæå®¡æ¹ä¸ç¶æç转æ£ç³è¯·æå¤ç |
| | | if (!HrmAuditStatusEnum.PROCESS.getStatus().equals(application.getStatus())) { |
| | | log.warn("[onApplicationEvent] 转æ£ç³è¯·({}) ä¸å¤äºå®¡æ¹ä¸ç¶æï¼å½åç¶æ: {}", applicationId, application.getStatus()); |
| | | return; |
| | | } |
| | | |
| | | log.info("[onApplicationEvent] 转æ£ç³è¯·({}) 审æ¹ç¶ææ´æ°: {}", applicationId, event.getStatus()); |
| | | // æ´æ°å®¡æ¹ç¶æ |
| | | Integer auditStatus = HrmAuditStatusUtils.convertBpmResultToAuditStatus(event.getStatus()); |
| | | regularizeApplicationService.updateRegularizeApplicationAuditStatus(applicationId, auditStatus); |
| | | // 审æ¹éè¿ï¼ååå工主档ï¼ç¶æ=å¨èï¼ç¨å·¥æ§è´¨=æ£å¼ï¼è½¬æ£æ¥æ = æè½¬æ£æ¥ææå½å¤©ï¼ |
| | | if (HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) { |
| | | writeBackEmployee(application); |
| | | } |
| | | } |
| | | |
| | | private void writeBackEmployee(HrmRegularizeApplicationDO application) { |
| | | HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId()); |
| | | if (employee == null) { |
| | | log.warn("[writeBackEmployee] 转æ£ç³è¯·({}) ç¨æ·({}) æªæ¾å°å工档æ¡ï¼è·³è¿åå", application.getId(), application.getUserId()); |
| | | return; |
| | | } |
| | | LocalDate regularDate = application.getExpectedDate() != null ? application.getExpectedDate() : LocalDate.now(); |
| | | employeeMapper.updateById(HrmEmployeeDO.builder() |
| | | .id(employee.getId()) |
| | | .employeeStatus(EMPLOYEE_STATUS_ACTIVE) |
| | | .employmentType(EMPLOYMENT_TYPE_FORMAL) |
| | | .regularDate(regularDate) |
| | | .build()); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmResignationApplicationDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmResignationApplicationMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum; |
| | | import cn.iocoder.yudao.module.hrm.service.approval.HrmResignationApplicationService; |
| | | import cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils; |
| | |
| | | @Slf4j |
| | | public class HrmResignationApplicationStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> { |
| | | |
| | | /** |
| | | * åå·¥ç¶æï¼ç¦»è |
| | | */ |
| | | private static final Integer EMPLOYEE_STATUS_RESIGNED = 3; |
| | | |
| | | @Resource |
| | | private HrmResignationApplicationService resignationApplicationService; |
| | | @Resource |
| | | private HrmResignationApplicationMapper resignationApplicationMapper; |
| | | @Resource |
| | | private HrmEmployeeMapper employeeMapper; |
| | | |
| | | @Override |
| | | public void onApplicationEvent(BpmProcessInstanceStatusEvent event) { |
| | |
| | | // æ´æ°å®¡æ¹ç¶æ |
| | | Integer auditStatus = HrmAuditStatusUtils.convertBpmResultToAuditStatus(event.getStatus()); |
| | | resignationApplicationService.updateResignationApplicationAuditStatus(applicationId, auditStatus); |
| | | // 审æ¹éè¿ï¼ååå工主档ï¼ç¶æ=离èï¼ç¦»èæ¥æ = å®é
ç¦»èæ¥ææé¢è®¡ç¦»èæ¥æï¼ |
| | | if (HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) { |
| | | writeBackEmployee(application); |
| | | } |
| | | } |
| | | |
| | | private void writeBackEmployee(HrmResignationApplicationDO application) { |
| | | HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId()); |
| | | if (employee == null) { |
| | | log.warn("[writeBackEmployee] 离èç³è¯·({}) ç¨æ·({}) æªæ¾å°å工档æ¡ï¼è·³è¿åå", application.getId(), application.getUserId()); |
| | | return; |
| | | } |
| | | java.time.LocalDate leaveDate = application.getActualDate() != null |
| | | ? application.getActualDate() : application.getExpectedDate(); |
| | | employeeMapper.updateById(HrmEmployeeDO.builder() |
| | | .id(employee.getId()) |
| | | .employeeStatus(EMPLOYEE_STATUS_RESIGNED) |
| | | .leaveDate(leaveDate) |
| | | .build()); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; |
| | | 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.enums.HrmAuditStatusEnum; |
| | | import cn.iocoder.yudao.module.hrm.service.approval.HrmTransferApplicationService; |
| | | import cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils; |
| | |
| | | private HrmTransferApplicationService transferApplicationService; |
| | | @Resource |
| | | private HrmTransferApplicationMapper transferApplicationMapper; |
| | | @Resource |
| | | private HrmEmployeeMapper employeeMapper; |
| | | |
| | | @Override |
| | | public void onApplicationEvent(BpmProcessInstanceStatusEvent event) { |
| | |
| | | // æ´æ°å®¡æ¹ç¶æ |
| | | Integer auditStatus = HrmAuditStatusUtils.convertBpmResultToAuditStatus(event.getStatus()); |
| | | transferApplicationService.updateTransferApplicationAuditStatus(applicationId, auditStatus); |
| | | // 审æ¹éè¿ï¼ååå工主档ï¼é¨é¨ = ç®æ é¨é¨ï¼å²ä½ = ç®æ å²ä½ï¼ |
| | | if (HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) { |
| | | writeBackEmployee(application); |
| | | } |
| | | } |
| | | |
| | | private void writeBackEmployee(HrmTransferApplicationDO application) { |
| | | HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId()); |
| | | if (employee == null) { |
| | | log.warn("[writeBackEmployee] è°å²ç³è¯·({}) ç¨æ·({}) æªæ¾å°å工档æ¡ï¼è·³è¿åå", application.getId(), application.getUserId()); |
| | | return; |
| | | } |
| | | employeeMapper.updateById(HrmEmployeeDO.builder() |
| | | .id(employee.getId()) |
| | | .deptId(application.getTargetDeptId()) |
| | | .postId(application.getTargetPostId()) |
| | | .build()); |
| | | } |
| | | |
| | | } |
| | |
| | | */ |
| | | void supplementClockIn(HrmAttendanceExceptionDO exception); |
| | | |
| | | /** |
| | | * å çå¼å¸¸å®¡æ¹éè¿ååå彿¥èå¤è®°å½çå çæ¶é¿ |
| | | * |
| | | * @param exception èå¤å¼å¸¸ç³è¯·ï¼type=å çï¼ |
| | | */ |
| | | void recordOvertime(HrmAttendanceExceptionDO exception); |
| | | |
| | | } |
| | |
| | | .divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP); |
| | | record.setWorkHours(workHours); |
| | | } |
| | | // 7. 计ç®å çæ¶é¿ï¼è¶
è¿è§åä¸çæ¶é´çé¨å |
| | | record.setOvertimeHours(computeOvertimeHours(rule.getWorkEndTime(), clockTimeOnly)); |
| | | attendanceRecordMapper.updateById(record); |
| | | return record; |
| | | } |
| | | |
| | | /** |
| | | * 计ç®å çæ¶é¿ï¼å°æ¶ï¼ï¼clockTimeOnly æäº workEndTime çé¨åï¼å¦å为 0 |
| | | */ |
| | | private BigDecimal computeOvertimeHours(LocalTime workEndTime, LocalTime clockTimeOnly) { |
| | | if (workEndTime == null || clockTimeOnly == null || !clockTimeOnly.isAfter(workEndTime)) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | return BigDecimal.valueOf(Duration.between(workEndTime, clockTimeOnly).toMinutes()) |
| | | .divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void recordOvertime(HrmAttendanceExceptionDO exception) { |
| | | // ä»
å¤çå çç±»å |
| | | if (!HrmAttendanceExceptionTypeEnum.OVERTIME.getType().equals(exception.getType()) |
| | | || exception.getExceptionTime() == null) { |
| | | return; |
| | | } |
| | | // 1. ååå·¥èå¤è§åï¼ç¨è§åä¸çæ¶é´å°å¼å¸¸æ¶é´(å®é
ä¸çç¹)æç®å çæ¶é¿ï¼æ è§ååæ æ³æç®ï¼è·³è¿ |
| | | BigDecimal overtimeHours = BigDecimal.ZERO; |
| | | HrmEmployeeDO employee = employeeService.getEmployee(exception.getUserId()); |
| | | HrmAttendanceRuleDO rule = employee == null ? null |
| | | : attendanceRuleService.getAttendanceRuleByDeptId(employee.getDeptId()); |
| | | if (rule != null) { |
| | | overtimeHours = computeOvertimeHours(rule.getWorkEndTime(), exception.getExceptionTime().toLocalTime()); |
| | | } |
| | | if (overtimeHours.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return; |
| | | } |
| | | // 2. æ¥è¯¢å½æ¥èå¤è®°å½ï¼ä¸åå¨å补建 |
| | | HrmAttendanceRecordDO record = attendanceRecordMapper.selectByUserIdAndDate(exception.getUserId(), exception.getExceptionDate()); |
| | | if (record == null) { |
| | | record = HrmAttendanceRecordDO.builder() |
| | | .userId(exception.getUserId()) |
| | | .deptId(employee != null ? employee.getDeptId() : exception.getDeptId()) |
| | | .date(exception.getExceptionDate()) |
| | | .dataSource(HrmAttendanceDataSourceEnum.SUPPLEMENT.getType()) |
| | | .build(); |
| | | record.setOvertimeHours(overtimeHours); |
| | | attendanceRecordMapper.insert(record); |
| | | return; |
| | | } |
| | | // 3. å·²æè®°å½åç´¯å å çæ¶é¿ |
| | | BigDecimal existed = record.getOvertimeHours() != null ? record.getOvertimeHours() : BigDecimal.ZERO; |
| | | record.setOvertimeHours(existed.add(overtimeHours)); |
| | | attendanceRecordMapper.updateById(record); |
| | | } |
| | | |
| | | @Override |
| | |
| | | LocalDate exceptionDate = exception.getExceptionDate(); |
| | | LocalDateTime exceptionTime = exception.getExceptionTime(); |
| | | Long userId = exception.getUserId(); |
| | | HrmEmployeeDO employee = employeeService.getEmployee(userId); |
| | | HrmAttendanceRuleDO rule = employee == null ? null |
| | | : attendanceRuleService.getAttendanceRuleByDeptId(employee.getDeptId()); |
| | | // æ¥è¯¢èå¤è®°å½ |
| | | HrmAttendanceRecordDO record = attendanceRecordMapper.selectByUserIdAndDate(userId, exceptionDate); |
| | | if (record == null) { |
| | | // å¦ææ²¡æè®°å½ï¼åå»ºä¸æ¡ |
| | | HrmEmployeeDO employee = employeeService.getEmployee(userId); |
| | | record = HrmAttendanceRecordDO.builder() |
| | | .userId(userId) |
| | | .deptId(employee != null ? employee.getDeptId() : exception.getDeptId()) |
| | |
| | | // ä¸çè¡¥å¡ |
| | | record.setClockOutTime(exceptionTime); |
| | | record.setClockOutType(HrmAttendanceClockTypeEnum.NORMAL.getType()); |
| | | // ä¸çè¡¥å¡åæ¶æç®å çæ¶é¿ï¼è¶
è¿è§åä¸çæ¶é´é¨åï¼ |
| | | record.setOvertimeHours(computeOvertimeHours(rule == null ? null : rule.getWorkEndTime(), time)); |
| | | } |
| | | // æ´æ°æ°æ®æ¥æºä¸ºè¡¥å¡å®¡æ¹ |
| | | record.setDataSource(HrmAttendanceDataSourceEnum.SUPPLEMENT.getType()); |
| | |
| | | // æ´æ°å®¡æ¹ç¶æ |
| | | attendanceExceptionService.updateAttendanceExceptionAuditStatus(exceptionId, auditStatus); |
| | | |
| | | // è¡¥å¡å®¡æ¹éè¿åï¼æ´æ°èå¤è®°å½ |
| | | if (HrmAttendanceExceptionTypeEnum.SUPPLEMENT.getType().equals(exception.getType()) |
| | | && HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) { |
| | | // è¡¥å¡/å ç审æ¹éè¿åï¼æ´æ°èå¤è®°å½ï¼è¡¥å¡åå¡«ä¸ä¸çæ¶é´ï¼å çååå çæ¶é¿ï¼ |
| | | if (HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) { |
| | | if (HrmAttendanceExceptionTypeEnum.SUPPLEMENT.getType().equals(exception.getType())) { |
| | | log.info("[onApplicationEvent] è¡¥å¡ç³è¯·({}) 审æ¹éè¿ï¼å¼å§æ´æ°èå¤è®°å½", exceptionId); |
| | | attendanceRecordService.supplementClockIn(exception); |
| | | } else if (HrmAttendanceExceptionTypeEnum.OVERTIME.getType().equals(exception.getType())) { |
| | | log.info("[onApplicationEvent] å çç³è¯·({}) 审æ¹éè¿ï¼å¼å§ååå çæ¶é¿", exceptionId); |
| | | attendanceRecordService.recordOvertime(exception); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | 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; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmEmploymentTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.api.cal.MesCalTeamApi; |
| | | import cn.iocoder.yudao.module.mes.api.cal.dto.MesCalTeamRespDTO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeEducationSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeEmergencyContactSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeImportExcelVO; |
| | |
| | | private AdminUserApi adminUserApi; |
| | | @Resource |
| | | private RoleApi roleApi; |
| | | @Resource |
| | | private MesCalTeamApi mesCalTeamApi; |
| | | @Resource |
| | | @Lazy // èªæ³¨å
¥éå»¶è¿å è½½ï¼å¦å bean 被代çå
è£
åæ³¨å
¥åå§çæ¬å¯¼è´å¯å¨å¤±è´¥ |
| | | private HrmEmployeeService self; |
| | |
| | | respVO.setRoleNames(roles.stream().map(RoleRespDTO::getName).collect(Collectors.joining(","))); |
| | | } |
| | | } |
| | | // å¡«å
ç¨å·¥æ§è´¨åç§° |
| | | if (employee.getEmploymentType() != null) { |
| | | respVO.setEmploymentTypeName(HrmEmploymentTypeEnum.getNameByType(employee.getEmploymentType())); |
| | | } |
| | | // å¡«å
æå±çç»åç§° |
| | | if (employee.getTeamId() != null) { |
| | | List<MesCalTeamRespDTO> teams = mesCalTeamApi.getTeamList(Collections.singleton(employee.getTeamId())); |
| | | if (CollUtil.isNotEmpty(teams)) { |
| | | respVO.setTeamName(teams.get(0).getName()); |
| | | } |
| | | } |
| | | return respVO; |
| | | } |
| | | |
| | |
| | | */ |
| | | List<HrmPerformanceAppraiseResultItemDO> getAppraiseResultItems(Long resultId); |
| | | |
| | | /** |
| | | * çæè¢«èæ ¸äººï¼æèæ ¸èå´ï¼å
¨é¨å¨èåå·¥ / æå®çç»åå·¥ï¼ï¼å·²åå¨ç»æçä¸éå¤çæ |
| | | * |
| | | * @param appraiseId èæ ¸æ¹æ¡ç¼å· |
| | | * @return æ¬æ¬¡æ°çæçè¢«èæ ¸äººæ° |
| | | */ |
| | | Integer generateAppraisees(Long appraiseId); |
| | | |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.json.JSONUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.performanceappraise.vo.*; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.performanceappraise.*; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.performanceappraise.*; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum; |
| | | import cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants; |
| | |
| | | private static final Integer SCORER_SUPERIOR = 2; |
| | | |
| | | /** |
| | | * èæ ¸èå´ç±»åï¼1 å
¨é¨åå·¥ / 2 æå®çç» |
| | | */ |
| | | private static final Integer SCOPE_ALL = 1; |
| | | private static final Integer SCOPE_TEAM = 2; |
| | | |
| | | /** |
| | | * å¨èåå·¥ç¶æ |
| | | */ |
| | | private static final Integer EMPLOYEE_STATUS_ACTIVE = 1; |
| | | |
| | | /** |
| | | * BPM 绩æèæ ¸å®¡æ¹åç±»ç¼ç |
| | | */ |
| | | private static final String APPRAISE_APPROVE_CATEGORY_CODE = "performance_appraise_approve"; |
| | |
| | | @Resource |
| | | private HrmPerformanceAppraiseResultItemMapper resultItemMapper; |
| | | @Resource |
| | | private HrmEmployeeMapper employeeMapper; |
| | | @Resource |
| | | private BpmProcessInstanceApi bpmProcessInstanceApi; |
| | | @Resource |
| | | private BpmCategoryService bpmCategoryService; |
| | |
| | | HrmPerformanceAppraiseDO appraise = BeanUtils.toBean(createReqVO, HrmPerformanceAppraiseDO.class, req -> req |
| | | .setStatus(STATUS_DRAFT) |
| | | .setAuditStatus(HrmAuditStatusEnum.DRAFT.getStatus())); |
| | | appraise.setScopeTeamIds(CollUtil.isEmpty(createReqVO.getScopeTeamIds()) |
| | | ? null : JSONUtil.toJsonStr(createReqVO.getScopeTeamIds())); |
| | | appraiseMapper.insert(appraise); |
| | | return appraise.getId(); |
| | | } |
| | |
| | | .setStatus(oldAppraise.getStatus()) |
| | | .setAuditStatus(oldAppraise.getAuditStatus()) |
| | | .setProcessInstanceId(oldAppraise.getProcessInstanceId())); |
| | | updateObj.setScopeTeamIds(CollUtil.isEmpty(updateReqVO.getScopeTeamIds()) |
| | | ? null : JSONUtil.toJsonStr(updateReqVO.getScopeTeamIds())); |
| | | appraiseMapper.updateById(updateObj); |
| | | } |
| | | |
| | |
| | | return resultItemMapper.selectListByResultId(resultId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Integer generateAppraisees(Long appraiseId) { |
| | | HrmPerformanceAppraiseDO appraise = validateAppraiseExists(appraiseId); |
| | | // 1. æèæ ¸èå´çéåå·¥ |
| | | List<HrmEmployeeDO> employees; |
| | | if (Objects.equals(appraise.getScopeType(), SCOPE_TEAM)) { |
| | | List<Long> teamIds = StrUtil.isEmpty(appraise.getScopeTeamIds()) |
| | | ? Collections.emptyList() : JSONUtil.toList(appraise.getScopeTeamIds(), Long.class); |
| | | if (CollUtil.isEmpty(teamIds)) { |
| | | throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_SCOPE_TEAM_EMPTY); |
| | | } |
| | | employees = employeeMapper.selectListByTeamIds(teamIds); |
| | | } else { |
| | | employees = employeeMapper.selectListByStatus(EMPLOYEE_STATUS_ACTIVE); |
| | | } |
| | | if (CollUtil.isEmpty(employees)) { |
| | | return 0; |
| | | } |
| | | // 2. å·²åå¨ç»æçä¸åçæï¼å¹çï¼ |
| | | List<HrmPerformanceAppraiseResultDO> existing = resultMapper.selectList( |
| | | new LambdaQueryWrapperX<HrmPerformanceAppraiseResultDO>() |
| | | .eq(HrmPerformanceAppraiseResultDO::getAppraiseId, appraiseId)); |
| | | Set<Long> existingEmployeeIds = convertSet(existing, HrmPerformanceAppraiseResultDO::getEmployeeId); |
| | | // 3. çæç©ºç½ç»æè¡ |
| | | int count = 0; |
| | | for (HrmEmployeeDO employee : employees) { |
| | | if (existingEmployeeIds.contains(employee.getId())) { |
| | | continue; |
| | | } |
| | | resultMapper.insert(new HrmPerformanceAppraiseResultDO() |
| | | .setAppraiseId(appraiseId) |
| | | .setEmployeeId(employee.getId())); |
| | | count++; |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | // ========== ç§ææ¹æ³ ========== |
| | | |
| | | private Integer calcGrade(BigDecimal finalScore) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.remind; |
| | | |
| | | /** |
| | | * HRM è¯ä¹¦/ååå°ææé Service æ¥å£ |
| | | * |
| | | * <p>对å³å°å°æçè¯ä¹¦èµè´¨ãå³å¨åååæè¯/å¨å²åå·¥åéç«å
ä¿¡æéï¼ |
| | | * 满足çµåè¡ä¸å®å
¨å¹è®åæ ¼è¯ãç¹ç§ä½ä¸è¯ä¹¦ãä»ä¸èµè´¨çåè§ç»æè¦æ±ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface HrmExpiryRemindService { |
| | | |
| | | /** |
| | | * åéè¯ä¹¦èµè´¨å°ææéï¼å³å°å°æ [today, today+N]ï¼ |
| | | */ |
| | | void sendCertificateExpireRemind(); |
| | | |
| | | /** |
| | | * åéå³å¨ååå°ææéï¼å³å°å°æ [today, today+N]ï¼ |
| | | */ |
| | | void sendContractExpireRemind(); |
| | | |
| | | /** |
| | | * åéå
¨é¨å°ææéï¼å
è¯ä¹¦åååï¼ï¼ä¾æ¯æ¥å®æ¶ä»»å¡è°ç¨ |
| | | */ |
| | | void sendAll(); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.remind; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.certificate.HrmCertificateDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeContractDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.certificate.HrmCertificateMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeContractMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.redis.HrmExpiryRemindRedisDAO; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmEmployeeStatusEnum; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.infra.api.config.ConfigApi; |
| | | import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; |
| | | import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | |
| | | /** |
| | | * HRM è¯ä¹¦/ååå°ææé Service å®ç°ç±» |
| | | * |
| | | * <p>åç
§ MES 计éå¨å
·å°ææéå®ç°ï¼Redis æ¥éé²å¤å®ä¾å¹¶åé夿«æãæä¸å¡è®°å½+å°ææ¥å»éï¼ |
| | | * åå工系ç»è´¦å·ï¼hrm_employee.userIdï¼åéç«å
ä¿¡ï¼æé天æ°ä» infra_config 读åï¼é»è®¤ 30 天ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class HrmExpiryRemindServiceImpl implements HrmExpiryRemindService { |
| | | |
| | | /** |
| | | * ä¸å¡æ è¯ï¼è¯ä¹¦èµè´¨ |
| | | */ |
| | | private static final String BIZ_CERT = "cert"; |
| | | /** |
| | | * ä¸å¡æ è¯ï¼åå·¥åå |
| | | */ |
| | | private static final String BIZ_CONTRACT = "contract"; |
| | | |
| | | /** |
| | | * è¯ä¹¦å°ææé天æ°é
ç½® KEYï¼infra_configï¼ |
| | | */ |
| | | private static final String CERT_REMIND_DAYS_KEY = "hrm.certificate.remind-days"; |
| | | /** |
| | | * ååå°ææé天æ°é
ç½® KEYï¼infra_configï¼ |
| | | */ |
| | | private static final String CONTRACT_REMIND_DAYS_KEY = "hrm.contract.remind-days"; |
| | | /** |
| | | * æé天æ°é»è®¤å¼ |
| | | */ |
| | | private static final int DEFAULT_REMIND_DAYS = 30; |
| | | |
| | | /** |
| | | * è¯ä¹¦å°ææéç«å
信模æ¿ç¼å· |
| | | */ |
| | | private static final String CERT_REMIND_TEMPLATE = "hrm_certificate_expire_remind"; |
| | | /** |
| | | * ååå°ææéç«å
信模æ¿ç¼å· |
| | | */ |
| | | private static final String CONTRACT_REMIND_TEMPLATE = "hrm_contract_expire_remind"; |
| | | |
| | | @Resource |
| | | private HrmCertificateMapper certificateMapper; |
| | | @Resource |
| | | private HrmEmployeeContractMapper contractMapper; |
| | | @Resource |
| | | private HrmExpiryRemindRedisDAO expiryRemindRedisDAO; |
| | | @Resource |
| | | private ConfigApi configApi; |
| | | @Resource |
| | | private NotifyMessageSendApi notifyMessageSendApi; |
| | | @Resource |
| | | private HrmEmployeeService employeeService; |
| | | |
| | | @Override |
| | | public void sendAll() { |
| | | sendCertificateExpireRemind(); |
| | | sendContractExpireRemind(); |
| | | } |
| | | |
| | | @Override |
| | | public void sendCertificateExpireRemind() { |
| | | try { |
| | | LocalDate today = LocalDate.now(); |
| | | if (!expiryRemindRedisDAO.tryAcquireScanLock(BIZ_CERT, today)) { |
| | | return; |
| | | } |
| | | int remindDays = getRemindDays(CERT_REMIND_DAYS_KEY); |
| | | List<HrmCertificateDO> list = certificateMapper.selectListByExpireDateBetween( |
| | | today, today.plusDays(remindDays)); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return; |
| | | } |
| | | Map<Long, HrmEmployeeDO> employeeMap = buildEmployeeMap( |
| | | convertSet(list, HrmCertificateDO::getEmployeeId)); |
| | | for (HrmCertificateDO certificate : list) { |
| | | if (certificate.getExpireDate() == null) { |
| | | continue; |
| | | } |
| | | HrmEmployeeDO employee = employeeMap.get(certificate.getEmployeeId()); |
| | | if (!canNotify(employee)) { |
| | | continue; |
| | | } |
| | | if (!expiryRemindRedisDAO.tryMarkReminded(BIZ_CERT, certificate.getId(), certificate.getExpireDate())) { |
| | | continue; |
| | | } |
| | | sendCertificateRemind(certificate, employee); |
| | | } |
| | | } catch (Exception ex) { |
| | | // best-effortï¼æé失败ä¸å½±åå表æ¥è¯¢/宿¶ä»»å¡æ´ä½ |
| | | log.error("[sendCertificateExpireRemind][åéè¯ä¹¦å°ææé失败]", ex); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void sendContractExpireRemind() { |
| | | try { |
| | | LocalDate today = LocalDate.now(); |
| | | if (!expiryRemindRedisDAO.tryAcquireScanLock(BIZ_CONTRACT, today)) { |
| | | return; |
| | | } |
| | | int remindDays = getRemindDays(CONTRACT_REMIND_DAYS_KEY); |
| | | List<HrmEmployeeContractDO> list = contractMapper.selectListExpiringBetween( |
| | | today, today.plusDays(remindDays)); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return; |
| | | } |
| | | Map<Long, HrmEmployeeDO> employeeMap = buildEmployeeMap( |
| | | convertSet(list, HrmEmployeeContractDO::getEmployeeId)); |
| | | for (HrmEmployeeContractDO contract : list) { |
| | | if (contract.getEndDate() == null) { |
| | | continue; |
| | | } |
| | | HrmEmployeeDO employee = employeeMap.get(contract.getEmployeeId()); |
| | | if (!canNotify(employee)) { |
| | | continue; |
| | | } |
| | | if (!expiryRemindRedisDAO.tryMarkReminded(BIZ_CONTRACT, contract.getId(), contract.getEndDate())) { |
| | | continue; |
| | | } |
| | | sendContractRemind(contract, employee); |
| | | } |
| | | } catch (Exception ex) { |
| | | // best-effortï¼æé失败ä¸å½±åå表æ¥è¯¢/宿¶ä»»å¡æ´ä½ |
| | | log.error("[sendContractExpireRemind][åéååå°ææé失败]", ex); |
| | | } |
| | | } |
| | | |
| | | private boolean canNotify(HrmEmployeeDO employee) { |
| | | // ä»
åæç³»ç»è´¦å·ä¸å¨å²/è¯ç¨åå·¥åéæéï¼ç¦»èåå·¥ï¼è´¦å·å¤å·²åç¨ï¼ä¸ææ° |
| | | return employee != null && employee.getUserId() != null |
| | | && !HrmEmployeeStatusEnum.LEAVE.getStatus().equals(employee.getEmployeeStatus()); |
| | | } |
| | | |
| | | private void sendCertificateRemind(HrmCertificateDO certificate, HrmEmployeeDO employee) { |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("employeeName", StrUtil.nullToEmpty(employee.getName())); |
| | | params.put("certTypeName", StrUtil.nullToEmpty(convertCertTypeName(certificate.getCertType()))); |
| | | params.put("certName", StrUtil.nullToEmpty(certificate.getCertName())); |
| | | params.put("expireDate", StrUtil.nullToEmpty(certificate.getExpireDate() == null ? null : certificate.getExpireDate().toString())); |
| | | notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO() |
| | | .setUserId(employee.getUserId()) |
| | | .setTemplateCode(CERT_REMIND_TEMPLATE) |
| | | .setTemplateParams(params)); |
| | | } |
| | | |
| | | private void sendContractRemind(HrmEmployeeContractDO contract, HrmEmployeeDO employee) { |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("employeeName", StrUtil.nullToEmpty(employee.getName())); |
| | | params.put("contractNo", StrUtil.nullToEmpty(contract.getContractNo())); |
| | | params.put("endDate", StrUtil.nullToEmpty(contract.getEndDate() == null ? null : contract.getEndDate().toString())); |
| | | notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO() |
| | | .setUserId(employee.getUserId()) |
| | | .setTemplateCode(CONTRACT_REMIND_TEMPLATE) |
| | | .setTemplateParams(params)); |
| | | } |
| | | |
| | | private Map<Long, HrmEmployeeDO> buildEmployeeMap(java.util.Collection<Long> employeeIds) { |
| | | if (CollUtil.isEmpty(employeeIds)) { |
| | | return Map.of(); |
| | | } |
| | | return employeeService.getEmployeeList(employeeIds).stream() |
| | | .collect(java.util.stream.Collectors.toMap(HrmEmployeeDO::getId, e -> e, (a, b) -> a)); |
| | | } |
| | | |
| | | private int getRemindDays(String configKey) { |
| | | String value = configApi.getConfigValueByKey(configKey); |
| | | if (StrUtil.isBlank(value)) { |
| | | return DEFAULT_REMIND_DAYS; |
| | | } |
| | | try { |
| | | return Integer.parseInt(value.trim()); |
| | | } catch (NumberFormatException ex) { |
| | | log.warn("[getRemindDays][é
ç½® {} çå¼ {} éæ³ï¼ä½¿ç¨é»è®¤å¼ {}]", configKey, value, DEFAULT_REMIND_DAYS); |
| | | return DEFAULT_REMIND_DAYS; |
| | | } |
| | | } |
| | | |
| | | private String convertCertTypeName(Integer certType) { |
| | | return switch (certType == null ? 0 : certType) { |
| | | case 1 -> "ç¹ç§ä½ä¸è¯ä¹¦"; |
| | | case 2 -> "ä»ä¸èµè´¨"; |
| | | case 3 -> "æè½ç级è¯ä¹¦"; |
| | | case 4 -> "å®å
¨å¹è®åæ ¼è¯"; |
| | | default -> "è¯ä¹¦"; |
| | | }; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.salary; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmEmployeeSalaryPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmEmployeeSalaryDO; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * åå·¥èªé
¬æ¡£æ¡ Service æ¥å£ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface HrmEmployeeSalaryService { |
| | | |
| | | /** |
| | | * å建åå·¥èªé
¬æ¡£æ¡ |
| | | * |
| | | * @param salary æ¡£æ¡ä¿¡æ¯ |
| | | * @return æ¡£æ¡ID |
| | | */ |
| | | Long createEmployeeSalary(HrmEmployeeSalaryDO salary); |
| | | |
| | | /** |
| | | * æ´æ°åå·¥èªé
¬æ¡£æ¡ |
| | | * |
| | | * @param salary æ¡£æ¡ä¿¡æ¯ |
| | | */ |
| | | void updateEmployeeSalary(HrmEmployeeSalaryDO salary); |
| | | |
| | | /** |
| | | * å é¤åå·¥èªé
¬æ¡£æ¡ |
| | | * |
| | | * @param id æ¡£æ¡ID |
| | | */ |
| | | void deleteEmployeeSalary(Long id); |
| | | |
| | | /** |
| | | * è·ååå·¥èªé
¬æ¡£æ¡ |
| | | * |
| | | * @param id æ¡£æ¡ID |
| | | * @return æ¡£æ¡ä¿¡æ¯ |
| | | */ |
| | | HrmEmployeeSalaryDO getEmployeeSalary(Long id); |
| | | |
| | | /** |
| | | * è·ååå·¥èªé
¬æ¡£æ¡å页 |
| | | * |
| | | * @param pageReqVO åé¡µè¯·æ± |
| | | * @return åé¡µç»æ |
| | | */ |
| | | PageResult<HrmEmployeeSalaryDO> getEmployeeSalaryPage(HrmEmployeeSalaryPageReqVO pageReqVO); |
| | | |
| | | /** |
| | | * è·ååå·¥èªé
¬æ¡£æ¡åå²å表 |
| | | * |
| | | * @param userId åå·¥ID |
| | | * @return æ¡£æ¡å表 |
| | | */ |
| | | List<HrmEmployeeSalaryDO> getEmployeeSalaryList(Long userId); |
| | | |
| | | /** |
| | | * è·ååå·¥ææ°çæçèªé
¬æ¡£æ¡ |
| | | * |
| | | * @param userId åå·¥ID |
| | | * @return æ¡£æ¡ä¿¡æ¯ |
| | | */ |
| | | HrmEmployeeSalaryDO getLatestEmployeeSalary(Long userId); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.salary; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmEmployeeSalaryPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmEmployeeSalaryDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmEmployeeSalaryMapper; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.EMPLOYEE_SALARY_NOT_EXISTS; |
| | | |
| | | /** |
| | | * åå·¥èªé
¬æ¡£æ¡ Service å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class HrmEmployeeSalaryServiceImpl implements HrmEmployeeSalaryService { |
| | | |
| | | @Resource |
| | | private HrmEmployeeSalaryMapper employeeSalaryMapper; |
| | | |
| | | @Override |
| | | public Long createEmployeeSalary(HrmEmployeeSalaryDO salary) { |
| | | employeeSalaryMapper.insert(salary); |
| | | return salary.getId(); |
| | | } |
| | | |
| | | @Override |
| | | public void updateEmployeeSalary(HrmEmployeeSalaryDO salary) { |
| | | validateEmployeeSalaryExists(salary.getId()); |
| | | employeeSalaryMapper.updateById(salary); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteEmployeeSalary(Long id) { |
| | | validateEmployeeSalaryExists(id); |
| | | employeeSalaryMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | | public HrmEmployeeSalaryDO getEmployeeSalary(Long id) { |
| | | return employeeSalaryMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<HrmEmployeeSalaryDO> getEmployeeSalaryPage(HrmEmployeeSalaryPageReqVO pageReqVO) { |
| | | return employeeSalaryMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | @Override |
| | | public List<HrmEmployeeSalaryDO> getEmployeeSalaryList(Long userId) { |
| | | return employeeSalaryMapper.selectListByUserId(userId); |
| | | } |
| | | |
| | | @Override |
| | | public HrmEmployeeSalaryDO getLatestEmployeeSalary(Long userId) { |
| | | return employeeSalaryMapper.selectLatestByUserId(userId); |
| | | } |
| | | |
| | | private void validateEmployeeSalaryExists(Long id) { |
| | | if (employeeSalaryMapper.selectById(id) == null) { |
| | | throw exception(EMPLOYEE_SALARY_NOT_EXISTS); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmSalaryCalculationPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmLeaveApplicationDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceSummaryDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.performanceappraise.HrmPerformanceAppraiseDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.performanceappraise.HrmPerformanceAppraiseResultDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmEmployeeSalaryDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmEmployeeSocialSecurityDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmLeaveTypeConfigDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryCalculationDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryPaymentDetailDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryPaymentDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryStructureDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSocialSecuritySchemeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmLeaveApplicationMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmAttendanceSummaryMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.performanceappraise.HrmPerformanceAppraiseMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.performanceappraise.HrmPerformanceAppraiseResultMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmEmployeeSalaryMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmEmployeeSocialSecurityMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmLeaveTypeConfigMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmSalaryCalculationMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmSalaryPaymentDetailMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmSalaryPaymentMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmSalaryStructureMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmSocialSecuritySchemeMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | |
| | | private static final BigDecimal DEFAULT_UNEMPLOYMENT_PERSONAL_RATIO = new BigDecimal("0.005"); |
| | | private static final BigDecimal DEFAULT_HOUSING_FUND_PERSONAL_RATIO = new BigDecimal("0.12"); |
| | | |
| | | /** |
| | | * å çå·¥èµåçé»è®¤å¼ï¼èªé
¬ç»ææªé
ç½®æ¶ä½¿ç¨ï¼ |
| | | */ |
| | | private static final BigDecimal DEFAULT_OVERTIME_PAY_RATIO = new BigDecimal("1.5"); |
| | | |
| | | /** |
| | | * é»è®¤åºåºå¤å¤©æ°ï¼æ è夿±æ»æ¶çå
åºå¼ï¼ |
| | | */ |
| | | private static final int DEFAULT_WORK_DAYS = 22; |
| | | |
| | | /** |
| | | * 绩æå·¥èµæ¡£çº§ç³»æ°ï¼1-ä¼ç§ 2-è¯å¥½ 3-åæ ¼ 4-å¾
æ¹è¿ |
| | | */ |
| | | private static final BigDecimal PERFORMANCE_GRADE_FACTOR_EXCELLENT = new BigDecimal("1.2"); |
| | | private static final BigDecimal PERFORMANCE_GRADE_FACTOR_GOOD = new BigDecimal("1.0"); |
| | | private static final BigDecimal PERFORMANCE_GRADE_FACTOR_PASS = new BigDecimal("0.8"); |
| | | private static final BigDecimal PERFORMANCE_GRADE_FACTOR_IMPROVE = new BigDecimal("0.6"); |
| | | |
| | | @Resource |
| | | private HrmSalaryCalculationMapper salaryCalculationMapper; |
| | | @Resource |
| | |
| | | private HrmSalaryPaymentMapper salaryPaymentMapper; |
| | | @Resource |
| | | private HrmSalaryPaymentDetailMapper salaryPaymentDetailMapper; |
| | | @Resource |
| | | private HrmAttendanceSummaryMapper attendanceSummaryMapper; |
| | | @Resource |
| | | private HrmPerformanceAppraiseMapper performanceAppraiseMapper; |
| | | @Resource |
| | | private HrmPerformanceAppraiseResultMapper performanceAppraiseResultMapper; |
| | | @Resource |
| | | private HrmSalaryStructureMapper salaryStructureMapper; |
| | | |
| | | @Override |
| | | public PageResult<HrmSalaryCalculationDO> getSalaryCalculationPage(HrmSalaryCalculationPageReqVO pageReqVO) { |
| | |
| | | BigDecimal mealAllowance = employeeSalary.getMealAllowance() != null ? employeeSalary.getMealAllowance() : BigDecimal.ZERO; |
| | | BigDecimal transportAllowance = employeeSalary.getTransportAllowance() != null ? employeeSalary.getTransportAllowance() : BigDecimal.ZERO; |
| | | BigDecimal otherAllowance = employeeSalary.getOtherAllowance() != null ? employeeSalary.getOtherAllowance() : BigDecimal.ZERO; |
| | | // ===== èå¤é¾è·¯ï¼åºåºå¤å¤©æ° / å çæ¶é¿ / ç¼ºå¤æ£æ¬¾ ===== |
| | | HrmAttendanceSummaryDO attendanceSummary = attendanceSummaryMapper.selectByUserIdAndYearMonth(employeeId, period); |
| | | int workDays = attendanceSummary != null && attendanceSummary.getWorkDays() != null |
| | | ? attendanceSummary.getWorkDays() : DEFAULT_WORK_DAYS; |
| | | BigDecimal overtimeHours = attendanceSummary != null && attendanceSummary.getOvertimeHours() != null |
| | | ? attendanceSummary.getOvertimeHours() : BigDecimal.ZERO; |
| | | // ===== å çå·¥èµ = æ¶èª à å çæ¶é¿ Ã åçï¼æ¶èª = åºæ¬å·¥èµ ÷ (åºåºå¤å¤© à 8)ï¼ ===== |
| | | BigDecimal overtimePay = BigDecimal.ZERO; |
| | | if (overtimeHours.compareTo(BigDecimal.ZERO) > 0 && workDays > 0) { |
| | | BigDecimal hourlyRate = baseSalary.divide(BigDecimal.valueOf(workDays * 8L), 4, RoundingMode.HALF_UP); |
| | | overtimePay = hourlyRate.multiply(overtimeHours).multiply(getOvertimePayRatio(employeeSalary, employee)) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | // ===== 绩æå·¥èµï¼æå½æç»©æç»ææ¡£çº§ç³»æ°æç®ï¼æ ç»ææå
¨é¢ï¼ ===== |
| | | performanceSalary = calculatePerformanceSalary(performanceSalary, employeeId, period); |
| | | |
| | | // åºåå·¥èµæ»é¢ |
| | | BigDecimal totalIncome = baseSalary.add(performanceSalary).add(mealAllowance) |
| | |
| | | // å
¬ç§¯éæ£é¤ = åºæ° à å
¬ç§¯é个人æ¯ä¾ |
| | | BigDecimal housingFundDeduction = housingFundBase.multiply(housingFundPersonalRatio).setScale(2, RoundingMode.HALF_UP); |
| | | |
| | | // 计ç®è¯·åæ£æ¬¾ |
| | | BigDecimal leaveDeduction = calculateLeaveDeduction(employee, period, baseSalary); |
| | | // 计ç®ç¼ºå¤æ£æ¬¾ï¼èå¤å£å¾ï¼ç¼ºå¤å¤©æ° = åºåºå¤ â å®é
åºå¤ï¼æ è夿±æ»æ¶åéå°è¯·åç³è¯·å£å¾ï¼ |
| | | BigDecimal leaveDeduction = calculateDeduction(attendanceSummary, baseSalary, workDays, employee, period); |
| | | |
| | | // 计ç®ä¸ªç¨æ£é¤ |
| | | // åºçº³ç¨æå¾é¢ = åºåå·¥èµ - ç¤¾ä¿æ£é¤ - å
¬ç§¯éæ£é¤ - èµ·å¾ç¹(5000) |
| | |
| | | .otherDeduction(otherDeduction) |
| | | .leaveDeduction(leaveDeduction) |
| | | .actualSalary(actualSalary) |
| | | .workDays(22) // é»è®¤å·¥ä½æ¥ |
| | | .overtimeHours(BigDecimal.ZERO) |
| | | .workDays(workDays) // 卿åºåºå¤å¤©æ°ï¼æ¥èªè夿±æ»ï¼ |
| | | .overtimeHours(overtimeHours) // å çæ¶é¿ï¼æ¥èªè夿±æ»ï¼ |
| | | .status(0) // å¾
确认 |
| | | .build(); |
| | | } |
| | | |
| | | /** |
| | | * 计ç®ç¼ºå¤æ£æ¬¾ï¼ä¼å
æè夿±æ»ï¼ç¼ºå¤å¤©æ° = åºåºå¤ â å®é
åºå¤ï¼ï¼æ æ±æ»æ¶åéå°è¯·åç³è¯·å£å¾ |
| | | */ |
| | | private BigDecimal calculateDeduction(HrmAttendanceSummaryDO attendanceSummary, BigDecimal baseSalary, |
| | | int workDays, HrmEmployeeDO employee, String period) { |
| | | if (attendanceSummary != null && workDays > 0 && attendanceSummary.getActualDays() != null) { |
| | | int absentDays = Math.max(0, workDays - attendanceSummary.getActualDays()); |
| | | if (absentDays == 0) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | BigDecimal daySalary = baseSalary.divide(BigDecimal.valueOf(workDays), 4, RoundingMode.HALF_UP); |
| | | return daySalary.multiply(BigDecimal.valueOf(absentDays)).setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | return calculateLeaveDeduction(employee, period, baseSalary); |
| | | } |
| | | |
| | | /** |
| | | * 计ç®ç»©æå·¥èµï¼æå½æå·²å®æä¸å¹é
æ ¸ç®å¨æçæåº¦ç»©æèæ ¸ç»æçæ¡£çº§ç³»æ°æç® |
| | | */ |
| | | private BigDecimal calculatePerformanceSalary(BigDecimal performanceSalary, Long employeeId, String period) { |
| | | HrmPerformanceAppraiseDO appraise = performanceAppraiseMapper.selectMonthlyCompletedByPeriod(period); |
| | | if (appraise == null) { |
| | | return performanceSalary; |
| | | } |
| | | HrmPerformanceAppraiseResultDO result = performanceAppraiseResultMapper |
| | | .selectByAppraiseIdAndEmployeeId(appraise.getId(), employeeId); |
| | | if (result == null || result.getGrade() == null) { |
| | | return performanceSalary; |
| | | } |
| | | BigDecimal factor = switch (result.getGrade()) { |
| | | case 1 -> PERFORMANCE_GRADE_FACTOR_EXCELLENT; |
| | | case 2 -> PERFORMANCE_GRADE_FACTOR_GOOD; |
| | | case 3 -> PERFORMANCE_GRADE_FACTOR_PASS; |
| | | case 4 -> PERFORMANCE_GRADE_FACTOR_IMPROVE; |
| | | default -> BigDecimal.ONE; |
| | | }; |
| | | return performanceSalary.multiply(factor).setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | /** |
| | | * è·åå çå·¥èµåçï¼èªé
¬ç»ææªé
ç½®æ¶é»è®¤ 1.5ï¼ |
| | | */ |
| | | private BigDecimal getOvertimePayRatio(HrmEmployeeSalaryDO employeeSalary, HrmEmployeeDO employee) { |
| | | Long structureId = employeeSalary.getSalaryStructureId() != null |
| | | ? employeeSalary.getSalaryStructureId() : employee.getSalaryStructureId(); |
| | | if (structureId == null) { |
| | | return DEFAULT_OVERTIME_PAY_RATIO; |
| | | } |
| | | HrmSalaryStructureDO structure = salaryStructureMapper.selectById(structureId); |
| | | return structure != null && structure.getOvertimePayRatio() != null |
| | | ? structure.getOvertimePayRatio() : DEFAULT_OVERTIME_PAY_RATIO; |
| | | } |
| | | |
| | | /** |
| | | * 计ç®è¯·åæ£æ¬¾ |
| | | * |
| | | * @param employee åå·¥ä¿¡æ¯ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.salary; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmSalaryStructurePageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryStructureDO; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * èªé
¬ç»æ Service æ¥å£ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface HrmSalaryStructureService { |
| | | |
| | | /** |
| | | * å建èªé
Ⱦ |
| | | * |
| | | * @param structure ç»æä¿¡æ¯ |
| | | * @return ç»æID |
| | | */ |
| | | Long createStructure(HrmSalaryStructureDO structure); |
| | | |
| | | /** |
| | | * æ´æ°èªé
Ⱦ |
| | | * |
| | | * @param structure ç»æä¿¡æ¯ |
| | | */ |
| | | void updateStructure(HrmSalaryStructureDO structure); |
| | | |
| | | /** |
| | | * å é¤èªé
Ⱦ |
| | | * |
| | | * @param id ç»æID |
| | | */ |
| | | void deleteStructure(Long id); |
| | | |
| | | /** |
| | | * è·åèªé
Ⱦ |
| | | * |
| | | * @param id ç»æID |
| | | * @return ç»æä¿¡æ¯ |
| | | */ |
| | | HrmSalaryStructureDO getStructure(Long id); |
| | | |
| | | /** |
| | | * è·åèªé
¬ç»æå表 |
| | | * |
| | | * @param status ç¶æï¼å¯éï¼ |
| | | * @return ç»æå表 |
| | | */ |
| | | List<HrmSalaryStructureDO> getStructureList(Integer status); |
| | | |
| | | /** |
| | | * è·åèªé
¬ç»æå页 |
| | | * |
| | | * @param pageReqVO åé¡µè¯·æ± |
| | | * @return åé¡µç»æ |
| | | */ |
| | | PageResult<HrmSalaryStructureDO> getStructurePage(HrmSalaryStructurePageReqVO pageReqVO); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.salary; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.salary.vo.HrmSalaryStructurePageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryStructureDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmSalaryStructureMapper; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.SALARY_STRUCTURE_NOT_EXISTS; |
| | | |
| | | /** |
| | | * èªé
¬ç»æ Service å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class HrmSalaryStructureServiceImpl implements HrmSalaryStructureService { |
| | | |
| | | @Resource |
| | | private HrmSalaryStructureMapper structureMapper; |
| | | |
| | | @Override |
| | | public Long createStructure(HrmSalaryStructureDO structure) { |
| | | structureMapper.insert(structure); |
| | | return structure.getId(); |
| | | } |
| | | |
| | | @Override |
| | | public void updateStructure(HrmSalaryStructureDO structure) { |
| | | validateStructureExists(structure.getId()); |
| | | structureMapper.updateById(structure); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteStructure(Long id) { |
| | | validateStructureExists(id); |
| | | structureMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | | public HrmSalaryStructureDO getStructure(Long id) { |
| | | return structureMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public List<HrmSalaryStructureDO> getStructureList(Integer status) { |
| | | return structureMapper.selectListByStatus(status); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<HrmSalaryStructureDO> getStructurePage(HrmSalaryStructurePageReqVO pageReqVO) { |
| | | return structureMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | private void validateStructureExists(Long id) { |
| | | if (structureMapper.selectById(id) == null) { |
| | | throw exception(SALARY_STRUCTURE_NOT_EXISTS); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.training; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingParticipantUpdateReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingParticipantDO; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * HRM å¹è®æ´»å¨ Service æ¥å£ |
| | | * |
| | | * <p>管çå®å
¨å¹è®ãæè½å¹è®çå¹è®è®¡åä¸åè®/èæ ¸ç»æï¼å¹è®å®ææ¶å¯¹åæ ¼äººåèå¨çæè¯ä¹¦èµè´¨ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface HrmTrainingService { |
| | | |
| | | /** |
| | | * å建å¹è®æ´»å¨ |
| | | * |
| | | * @param createReqVO åå»ºä¿¡æ¯ |
| | | * @return å¹è®æ´»å¨ID |
| | | */ |
| | | Long createTraining(HrmTrainingSaveReqVO createReqVO); |
| | | |
| | | /** |
| | | * æ´æ°å¹è®æ´»å¨ï¼ä»
è稿/å¾
å¼å±å¯æ¹ï¼ä¸ä¸æ¹ç¶æï¼ |
| | | * |
| | | * @param updateReqVO æ´æ°ä¿¡æ¯ |
| | | */ |
| | | void updateTraining(HrmTrainingSaveReqVO updateReqVO); |
| | | |
| | | /** |
| | | * å é¤å¹è®æ´»å¨ï¼çº§èå é¤åè®äººåï¼å·²å®æ/已忶ä¸å¯å ï¼ |
| | | * |
| | | * @param ids å¹è®æ´»å¨IDéå |
| | | */ |
| | | void deleteTraining(Collection<Long> ids); |
| | | |
| | | /** |
| | | * è·å¾å¹è®æ´»å¨ |
| | | * |
| | | * @param id å¹è®æ´»å¨ID |
| | | * @return å¹è®æ´»å¨ |
| | | */ |
| | | HrmTrainingDO getTraining(Long id); |
| | | |
| | | /** |
| | | * è·å¾å¹è®æ´»å¨å页 |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | | * @return å¹è®æ´»å¨å页 |
| | | */ |
| | | PageResult<HrmTrainingDO> getTrainingPage(HrmTrainingPageReqVO pageReqVO); |
| | | |
| | | /** |
| | | * å¼å§å¹è®ï¼è稿 â å¾
å¼å±ï¼ |
| | | * |
| | | * @param id å¹è®æ´»å¨ID |
| | | */ |
| | | void startTraining(Long id); |
| | | |
| | | /** |
| | | * 宿å¹è®ï¼å¾
å¼å±/è稿 â 已宿ï¼ï¼å®ææ¶å¯¹åæ ¼äººåèå¨èªå¨åè¯ |
| | | * |
| | | * @param id å¹è®æ´»å¨ID |
| | | */ |
| | | void completeTraining(Long id); |
| | | |
| | | /** |
| | | * åæ¶å¹è®ï¼è稿/å¾
å¼å± â å·²åæ¶ï¼ |
| | | * |
| | | * @param id å¹è®æ´»å¨ID |
| | | */ |
| | | void cancelTraining(Long id); |
| | | |
| | | /** |
| | | * æ·»å åè®åå·¥ï¼èªå¨è·³è¿å·²å¨ååä¸çåå·¥ï¼ |
| | | * |
| | | * @param trainingId å¹è®æ´»å¨ID |
| | | * @param employeeIds åå·¥IDéå |
| | | * @return å®é
æ°å¢æ°é |
| | | */ |
| | | int addParticipants(Long trainingId, Collection<Long> employeeIds); |
| | | |
| | | /** |
| | | * æ´æ°åè®è®°å½ï¼åå æ
åµ/æç»©/æ¯å¦åæ ¼ï¼ |
| | | * |
| | | * @param updateReqVO æ´æ°ä¿¡æ¯ |
| | | */ |
| | | void updateParticipant(HrmTrainingParticipantUpdateReqVO updateReqVO); |
| | | |
| | | /** |
| | | * å é¤åè®è®°å½ |
| | | * |
| | | * @param ids åè®è®°å½IDéå |
| | | */ |
| | | void deleteParticipants(Collection<Long> ids); |
| | | |
| | | /** |
| | | * è·å¾ææ¬¡å¹è®çå
¨é¨åè®è®°å½ |
| | | * |
| | | * @param trainingId å¹è®æ´»å¨ID |
| | | * @return åè®è®°å½å表 |
| | | */ |
| | | List<HrmTrainingParticipantDO> getParticipantsByTrainingId(Long trainingId); |
| | | |
| | | /** |
| | | * æ¹éç»è®¡åå¹è®æ´»å¨çåè®äººæ°ï¼å页å表å±ç¤ºç¨ï¼ |
| | | * |
| | | * @param trainingIds å¹è®æ´»å¨IDéå |
| | | * @return å¹è®æ´»å¨ID â åè®äººæ° |
| | | */ |
| | | Map<Long, Integer> getParticipantCountMap(Collection<Long> trainingIds); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.training; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingParticipantUpdateReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.training.vo.HrmTrainingSaveReqVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.certificate.HrmCertificateDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingParticipantDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.certificate.HrmCertificateMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.training.HrmTrainingMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.training.HrmTrainingParticipantMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.hrm.dal.dataobject.training.HrmTrainingDO.*; |
| | | import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * HRM å¹è®æ´»å¨ Service å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class HrmTrainingServiceImpl implements HrmTrainingService { |
| | | |
| | | @Resource |
| | | private HrmTrainingMapper trainingMapper; |
| | | @Resource |
| | | private HrmTrainingParticipantMapper participantMapper; |
| | | @Resource |
| | | private HrmCertificateMapper certificateMapper; |
| | | @Resource |
| | | private HrmNoRedisDAO noRedisDAO; |
| | | |
| | | @Override |
| | | public Long createTraining(HrmTrainingSaveReqVO createReqVO) { |
| | | validateIssueCertificate(createReqVO.getTrainingType(), createReqVO.getIssueCertificate(), |
| | | createReqVO.getCertValidityMonths()); |
| | | HrmTrainingDO training = BeanUtils.toBean(createReqVO, HrmTrainingDO.class); |
| | | training.setId(null); |
| | | training.setTrainingNo(noRedisDAO.generateTrainingNo()); |
| | | training.setStatus(STATUS_DRAFT); |
| | | trainingMapper.insert(training); |
| | | return training.getId(); |
| | | } |
| | | |
| | | @Override |
| | | public void updateTraining(HrmTrainingSaveReqVO updateReqVO) { |
| | | HrmTrainingDO training = validateTrainingExists(updateReqVO.getId()); |
| | | ensureMutable(training); |
| | | validateIssueCertificate(updateReqVO.getTrainingType(), updateReqVO.getIssueCertificate(), |
| | | updateReqVO.getCertValidityMonths()); |
| | | HrmTrainingDO update = BeanUtils.toBean(updateReqVO, HrmTrainingDO.class); |
| | | update.setTrainingNo(training.getTrainingNo()); // ç¼å·ä¸å¯æ¹ |
| | | update.setStatus(null); // ç¶æèµ° start/complete/cancel æµè½¬ï¼ä¸å¨æ¤ä¿®æ¹ |
| | | trainingMapper.updateById(update); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteTraining(Collection<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return; |
| | | } |
| | | for (Long id : ids) { |
| | | HrmTrainingDO training = validateTrainingExists(id); |
| | | ensureMutable(training); |
| | | participantMapper.deleteByTrainingId(id); |
| | | trainingMapper.deleteById(id); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public HrmTrainingDO getTraining(Long id) { |
| | | return trainingMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<HrmTrainingDO> getTrainingPage(HrmTrainingPageReqVO pageReqVO) { |
| | | return trainingMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | @Override |
| | | public void startTraining(Long id) { |
| | | HrmTrainingDO training = validateTrainingExists(id); |
| | | if (training.getStatus() != null && !training.getStatus().equals(STATUS_DRAFT)) { |
| | | throw exception(TRAINING_COMPLETE_FAIL_STATUS); // ä»
è稿å¯å¼å§ |
| | | } |
| | | trainingMapper.updateById(HrmTrainingDO.builder().id(id).status(STATUS_PLANNED).build()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void completeTraining(Long id) { |
| | | HrmTrainingDO training = validateTrainingExists(id); |
| | | if (training.getStatus() == null |
| | | || (!training.getStatus().equals(STATUS_DRAFT) && !training.getStatus().equals(STATUS_PLANNED))) { |
| | | throw exception(TRAINING_COMPLETE_FAIL_STATUS); |
| | | } |
| | | trainingMapper.updateById(HrmTrainingDO.builder().id(id).status(STATUS_COMPLETED).build()); |
| | | // èå¨åè¯ï¼å¹è®å®æåå¯¹åæ ¼äººåèªå¨çæè¯ä¹¦ï¼å¹çï¼äºæ¬¡å®æä¸éå¤åï¼ |
| | | if (Boolean.TRUE.equals(training.getIssueCertificate())) { |
| | | issueCertificatesForPassed(training); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void cancelTraining(Long id) { |
| | | HrmTrainingDO training = validateTrainingExists(id); |
| | | if (training.getStatus() == null || training.getStatus().equals(STATUS_COMPLETED) |
| | | || training.getStatus().equals(STATUS_CANCELED)) { |
| | | throw exception(TRAINING_LOCKED); |
| | | } |
| | | trainingMapper.updateById(HrmTrainingDO.builder().id(id).status(STATUS_CANCELED).build()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int addParticipants(Long trainingId, Collection<Long> employeeIds) { |
| | | HrmTrainingDO training = validateTrainingExists(trainingId); |
| | | ensureMutable(training); |
| | | if (CollUtil.isEmpty(employeeIds)) { |
| | | return 0; |
| | | } |
| | | int count = 0; |
| | | for (Long employeeId : employeeIds) { |
| | | if (participantMapper.selectByTrainingIdAndEmployeeId(trainingId, employeeId) != null) { |
| | | continue; // å·²å¨ååä¸ï¼è·³è¿ä¸é夿·»å |
| | | } |
| | | HrmTrainingParticipantDO participant = HrmTrainingParticipantDO.builder() |
| | | .trainingId(trainingId) |
| | | .employeeId(employeeId) |
| | | .attended(false) |
| | | .isPass(false) |
| | | .build(); |
| | | participantMapper.insert(participant); |
| | | count++; |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateParticipant(HrmTrainingParticipantUpdateReqVO updateReqVO) { |
| | | HrmTrainingParticipantDO participant = validateParticipantExists(updateReqVO.getId()); |
| | | HrmTrainingDO training = validateTrainingExists(participant.getTrainingId()); |
| | | ensureMutable(training); |
| | | HrmTrainingParticipantDO update = HrmTrainingParticipantDO.builder() |
| | | .id(participant.getId()) |
| | | .attended(updateReqVO.getAttended()) |
| | | .score(updateReqVO.getScore()) |
| | | .isPass(updateReqVO.getIsPass()) |
| | | .remark(updateReqVO.getRemark()) |
| | | .build(); |
| | | participantMapper.updateById(update); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteParticipants(Collection<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return; |
| | | } |
| | | for (Long id : ids) { |
| | | HrmTrainingParticipantDO participant = validateParticipantExists(id); |
| | | HrmTrainingDO training = validateTrainingExists(participant.getTrainingId()); |
| | | ensureMutable(training); |
| | | participantMapper.deleteById(id); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public List<HrmTrainingParticipantDO> getParticipantsByTrainingId(Long trainingId) { |
| | | return participantMapper.selectListByTrainingId(trainingId); |
| | | } |
| | | |
| | | @Override |
| | | public Map<Long, Integer> getParticipantCountMap(Collection<Long> trainingIds) { |
| | | if (CollUtil.isEmpty(trainingIds)) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | return participantMapper.selectListByTrainingIds(trainingIds).stream() |
| | | .collect(Collectors.groupingBy(HrmTrainingParticipantDO::getTrainingId, Collectors.summingInt(p -> 1))); |
| | | } |
| | | |
| | | // ========== ç§ææ¹æ³ ========== |
| | | |
| | | private void issueCertificatesForPassed(HrmTrainingDO training) { |
| | | if (training.getCertValidityMonths() == null || training.getCertValidityMonths() <= 0) { |
| | | throw exception(TRAINING_CERT_VALIDITY_REQUIRED); |
| | | } |
| | | List<HrmTrainingParticipantDO> participants = participantMapper.selectListByTrainingId(training.getId()); |
| | | if (CollUtil.isEmpty(participants)) { |
| | | return; |
| | | } |
| | | Integer certType = convertToCertificateType(training.getTrainingType()); |
| | | LocalDate issueDate = LocalDate.now(); |
| | | LocalDate expireDate = issueDate.plusMonths(training.getCertValidityMonths()); |
| | | for (HrmTrainingParticipantDO participant : participants) { |
| | | if (!Boolean.TRUE.equals(participant.getIsPass()) || participant.getCertificateId() != null) { |
| | | continue; |
| | | } |
| | | HrmCertificateDO certificate = HrmCertificateDO.builder() |
| | | .employeeId(participant.getEmployeeId()) |
| | | .certType(certType) |
| | | .certName(training.getName()) |
| | | .issueDate(issueDate) |
| | | .expireDate(expireDate) |
| | | .remark("ç±å¹è®ã" + training.getTrainingNo() + "ã" + training.getName() + "宿èªå¨åæ¾") |
| | | .build(); |
| | | certificateMapper.insert(certificate); |
| | | participantMapper.updateCertificateId(participant.getId(), certificate.getId()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¹è®ç±»å â è¯ä¹¦èµè´¨ç±»åæ å°ï¼å®å
¨å¹è®â4 å®å
¨å¹è®åæ ¼è¯ï¼æè½å¹è®â3 æè½ç级è¯ä¹¦ |
| | | */ |
| | | private Integer convertToCertificateType(Integer trainingType) { |
| | | return switch (trainingType == null ? 0 : trainingType) { |
| | | case TYPE_SAFETY -> 4; |
| | | case TYPE_SKILL -> 3; |
| | | default -> null; |
| | | }; |
| | | } |
| | | |
| | | private void validateIssueCertificate(Integer trainingType, Boolean issueCertificate, Integer certValidityMonths) { |
| | | if (Boolean.TRUE.equals(issueCertificate)) { |
| | | if (trainingType == null |
| | | || (!trainingType.equals(TYPE_SAFETY) && !trainingType.equals(TYPE_SKILL))) { |
| | | throw exception(TRAINING_CERT_TYPE_NOT_SUPPORT); |
| | | } |
| | | if (certValidityMonths == null || certValidityMonths <= 0) { |
| | | throw exception(TRAINING_CERT_VALIDITY_REQUIRED); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private HrmTrainingDO validateTrainingExists(Long id) { |
| | | HrmTrainingDO training = trainingMapper.selectById(id); |
| | | if (training == null) { |
| | | throw exception(TRAINING_NOT_EXISTS); |
| | | } |
| | | return training; |
| | | } |
| | | |
| | | private HrmTrainingParticipantDO validateParticipantExists(Long id) { |
| | | HrmTrainingParticipantDO participant = participantMapper.selectById(id); |
| | | if (participant == null) { |
| | | throw exception(TRAINING_PARTICIPANT_NOT_EXISTS); |
| | | } |
| | | return participant; |
| | | } |
| | | |
| | | /** |
| | | * 已宿/已忶çå¹è®ä¸å
许åä¿®æ¹ |
| | | */ |
| | | private void ensureMutable(HrmTrainingDO training) { |
| | | if (training.getStatus() != null |
| | | && (training.getStatus().equals(STATUS_COMPLETED) || training.getStatus().equals(STATUS_CANCELED))) { |
| | | throw exception(TRAINING_LOCKED); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.workhour; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo.HrmWorkHourSummaryPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo.HrmWorkHourSummaryRespVO; |
| | | |
| | | /** |
| | | * æåº¦å·¥æ¶æ±æ» Service æ¥å£ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface HrmWorkHourSummaryService { |
| | | |
| | | /** |
| | | * çææå®å¨æçæåº¦å·¥æ¶æ±æ»ï¼èå¤å£å¾ï¼æåå·¥ upsertï¼ |
| | | * |
| | | * @param period æ ¸ç®å¨æï¼yyyy-MMï¼ |
| | | */ |
| | | void generateMonthly(String period); |
| | | |
| | | /** |
| | | * è·åæåº¦å·¥æ¶æ±æ»å页 |
| | | * |
| | | * @param pageReqVO åé¡µè¯·æ± |
| | | * @return åé¡µç»æ |
| | | */ |
| | | PageResult<HrmWorkHourSummaryRespVO> getWorkHourSummaryPage(HrmWorkHourSummaryPageReqVO pageReqVO); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.hrm.service.workhour; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo.HrmEmployeeWorkHourReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo.HrmWorkHourSummaryPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.workhour.vo.HrmWorkHourSummaryRespVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.workhour.HrmWorkHourSummaryDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmAttendanceRecordMapper; |
| | | import cn.iocoder.yudao.module.hrm.dal.mysql.workhour.HrmWorkHourSummaryMapper; |
| | | import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.YearMonth; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æåº¦å·¥æ¶æ±æ» Service å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class HrmWorkHourSummaryServiceImpl implements HrmWorkHourSummaryService { |
| | | |
| | | @Resource |
| | | private HrmWorkHourSummaryMapper workHourSummaryMapper; |
| | | @Resource |
| | | private HrmAttendanceRecordMapper attendanceRecordMapper; |
| | | @Resource |
| | | private HrmEmployeeService employeeService; |
| | | @Resource |
| | | private DeptApi deptApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void generateMonthly(String period) { |
| | | YearMonth yearMonth = YearMonth.parse(period); |
| | | HrmEmployeeWorkHourReqVO reqVO = new HrmEmployeeWorkHourReqVO(); |
| | | reqVO.setStartDate(yearMonth.atDay(1)); |
| | | reqVO.setEndDate(yearMonth.atEndOfMonth()); |
| | | for (Map<String, Object> row : attendanceRecordMapper.selectWorkHourSummary(reqVO)) { |
| | | Long employeeId = toLong(row.get("user_id")); |
| | | if (employeeId == null) { |
| | | continue; |
| | | } |
| | | HrmEmployeeDO employee = employeeService.getEmployee(employeeId); |
| | | HrmWorkHourSummaryDO summary = workHourSummaryMapper.selectByEmployeeIdAndPeriod(employeeId, period); |
| | | if (summary == null) { |
| | | summary = new HrmWorkHourSummaryDO(); |
| | | summary.setEmployeeId(employeeId); |
| | | summary.setPeriod(period); |
| | | } |
| | | summary.setDeptId(employee != null ? employee.getDeptId() : null); |
| | | summary.setWorkDays(toInteger(row.get("work_days"))); |
| | | summary.setWorkHours(toDecimal(row.get("work_hours"))); |
| | | summary.setOvertimeHours(toDecimal(row.get("overtime_hours"))); |
| | | if (summary.getId() == null) { |
| | | workHourSummaryMapper.insert(summary); |
| | | } else { |
| | | workHourSummaryMapper.updateById(summary); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<HrmWorkHourSummaryRespVO> getWorkHourSummaryPage(HrmWorkHourSummaryPageReqVO pageReqVO) { |
| | | PageResult<HrmWorkHourSummaryDO> pageResult = workHourSummaryMapper.selectPage(pageReqVO); |
| | | if (CollUtil.isEmpty(pageResult.getList())) { |
| | | return new PageResult<>(Collections.emptyList(), pageResult.getTotal()); |
| | | } |
| | | List<HrmWorkHourSummaryRespVO> list = pageResult.getList().stream() |
| | | .map(this::convert) |
| | | .toList(); |
| | | return new PageResult<>(list, pageResult.getTotal()); |
| | | } |
| | | |
| | | private HrmWorkHourSummaryRespVO convert(HrmWorkHourSummaryDO summary) { |
| | | HrmWorkHourSummaryRespVO respVO = new HrmWorkHourSummaryRespVO(); |
| | | respVO.setId(summary.getId()); |
| | | respVO.setEmployeeId(summary.getEmployeeId()); |
| | | respVO.setDeptId(summary.getDeptId()); |
| | | respVO.setPeriod(summary.getPeriod()); |
| | | respVO.setWorkDays(summary.getWorkDays()); |
| | | respVO.setWorkHours(summary.getWorkHours()); |
| | | respVO.setOvertimeHours(summary.getOvertimeHours()); |
| | | respVO.setRemark(summary.getRemark()); |
| | | respVO.setCreateTime(summary.getCreateTime()); |
| | | HrmEmployeeDO employee = employeeService.getEmployee(summary.getEmployeeId()); |
| | | if (employee != null) { |
| | | respVO.setEmployeeNo(employee.getEmployeeNo()); |
| | | respVO.setEmployeeName(employee.getName()); |
| | | } |
| | | if (summary.getDeptId() != null) { |
| | | DeptRespDTO dept = deptApi.getDept(summary.getDeptId()); |
| | | if (dept != null) { |
| | | respVO.setDeptName(dept.getName()); |
| | | } |
| | | } |
| | | return respVO; |
| | | } |
| | | |
| | | private Long toLong(Object value) { |
| | | return value instanceof Number ? ((Number) value).longValue() : null; |
| | | } |
| | | |
| | | private Integer toInteger(Object value) { |
| | | return value instanceof Number ? ((Number) value).intValue() : 0; |
| | | } |
| | | |
| | | private BigDecimal toDecimal(Object value) { |
| | | return value instanceof Number ? new BigDecimal(value.toString()) : BigDecimal.ZERO; |
| | | } |
| | | |
| | | } |
| | |
| | | @Schema(description = "æ¯å¦æ¹æ¬¡ç®¡ç", example = "false") |
| | | private Boolean isBatchManaged; |
| | | |
| | | @Schema(description = "æ¯å¦åºåå·ç®¡ç", example = "false") |
| | | private Boolean isSerialManaged; |
| | | |
| | | @Schema(description = "éé(kg)", example = "0.5") |
| | | private BigDecimal weight; |
| | | |
| | |
| | | @Schema(description = "æ¯å¦æ¹æ¬¡ç®¡ç", example = "false") |
| | | private Boolean isBatchManaged; |
| | | |
| | | @Schema(description = "æ¯å¦åºåå·ç®¡ç", example = "false") |
| | | private Boolean isSerialManaged; |
| | | |
| | | @Schema(description = "æ¯å¦é«å¼ç©æ", example = "false") |
| | | private Boolean highValue; |
| | | |
| | |
| | | @Schema(description = "æ¯å¦æ¹æ¬¡ç®¡ç", example = "false") |
| | | private Boolean isBatchManaged; |
| | | |
| | | @Schema(description = "æ¯å¦åºåå·ç®¡ç", example = "false") |
| | | private Boolean isSerialManaged; |
| | | |
| | | @Schema(description = "éé(kg)", example = "0.5") |
| | | private BigDecimal weight; |
| | | |
| | |
| | | |
| | | MATERIAL(1, "ç©æ"), |
| | | PRODUCT(2, "产å"), |
| | | SEMI_FINISHED(3, "åæå"); |
| | | SEMI_FINISHED(3, "åæå"), |
| | | EQUIPMENT(4, "设å¤"); |
| | | |
| | | /** |
| | | * ç±»åç¼ç |
| | |
| | | @Schema(description = "æ¯å¦æ¹æ¬¡ç®¡ç", example = "false") |
| | | private Boolean isBatchManaged; |
| | | |
| | | @Schema(description = "æ¯å¦åºåå·ç®¡ç", example = "false") |
| | | private Boolean isSerialManaged; |
| | | |
| | | @Schema(description = "æ¯å¦é«å¼ç©æ", example = "false") |
| | | private Boolean isHighValue; |
| | | |
| | |
| | | |
| | | MATERIAL(1, "ç©æ"), |
| | | PRODUCT(2, "产å"), |
| | | SEMI_FINISHED(3, "åæå"); |
| | | SEMI_FINISHED(3, "åæå"), |
| | | EQUIPMENT(4, "设å¤"); |
| | | |
| | | /** |
| | | * ç±»åç¼ç |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.cal; |
| | | |
| | | import cn.iocoder.yudao.module.mes.api.cal.dto.MesCalTeamRespDTO; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES çç» API æ¥å£ |
| | | * |
| | | * <p>ä¾ HRM çæ¨¡åå¼ç¨ï¼æçç» ID æ¹éæ¥è¯¢çç»ç¼ç /åç§°ï¼ç¨äºå工主档ãæå±çç»ãåæ¾ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface MesCalTeamApi { |
| | | |
| | | /** |
| | | * æçç» ID éåæ¥è¯¢çç»å表 |
| | | * |
| | | * @param teamIds çç» ID éåï¼ä¸ºç©ºè¿å空åè¡¨ï¼ |
| | | * @return çç»å表 |
| | | */ |
| | | List<MesCalTeamRespDTO> getTeamList(Collection<Long> teamIds); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.cal.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * MES çç» Response DTO |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Data |
| | | public class MesCalTeamRespDTO { |
| | | |
| | | /** |
| | | * çç»ç¼å· |
| | | */ |
| | | private Long id; |
| | | |
| | | /** |
| | | * çç»ç¼ç |
| | | */ |
| | | private String code; |
| | | |
| | | /** |
| | | * çç»åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | } |
| | |
| | | <artifactId>yudao-spring-boot-starter-excel</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- æ¡ç /äºç»´ç çæï¼zxingï¼ --> |
| | | <dependency> |
| | | <groupId>com.google.zxing</groupId> |
| | | <artifactId>core</artifactId> |
| | | <version>3.3.3</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.google.zxing</groupId> |
| | | <artifactId>javase</artifactId> |
| | | <version>3.3.3</version> |
| | | </dependency> |
| | | |
| | | <!-- Test æµè¯ç¸å
³ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.cal; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.module.mes.api.cal.dto.MesCalTeamRespDTO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.cal.team.MesCalTeamMapper; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES çç» API å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class MesCalTeamApiImpl implements MesCalTeamApi { |
| | | |
| | | @Resource |
| | | private MesCalTeamMapper teamMapper; |
| | | |
| | | @Override |
| | | public List<MesCalTeamRespDTO> getTeamList(Collection<Long> teamIds) { |
| | | if (CollUtil.isEmpty(teamIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<MesCalTeamDO> teams = teamMapper.selectByIds(teamIds); |
| | | List<MesCalTeamRespDTO> list = new ArrayList<>(teams.size()); |
| | | for (MesCalTeamDO team : teams) { |
| | | MesCalTeamRespDTO dto = new MesCalTeamRespDTO(); |
| | | dto.setId(team.getId()); |
| | | dto.setCode(team.getCode()); |
| | | dto.setName(team.getName()); |
| | | list.add(dto); |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.cal.schedule; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | 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.cal.schedule.vo.*; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.schedule.MesCalScheduleDetailDO; |
| | | import cn.iocoder.yudao.module.mes.service.cal.schedule.MesCalScheduleDetailService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | @Tag(name = "管çåå° - MES å工级æçæç»") |
| | | @RestController |
| | | @RequestMapping("/mes/cal/schedule-detail") |
| | | @Validated |
| | | public class MesCalScheduleDetailController { |
| | | |
| | | @Resource |
| | | private MesCalScheduleDetailService scheduleDetailService; |
| | | |
| | | @PostMapping("/generate") |
| | | @Operation(summary = "æçç»æççæå工级æçæç»") |
| | | @Parameter(name = "planId", description = "æç计åç¼å·", required = true, example = "1") |
| | | @PreAuthorize("@ss.hasPermission('mes:cal-schedule-detail:generate')") |
| | | public CommonResult<Boolean> generateDetails(@RequestParam("planId") Long planId) { |
| | | scheduleDetailService.generateDetails(planId); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°å工级æçæç»ï¼äººå·¥å¾®è°ï¼") |
| | | @PreAuthorize("@ss.hasPermission('mes:cal-schedule-detail:update')") |
| | | public CommonResult<Boolean> updateDetail(@Valid @RequestBody MesCalScheduleDetailSaveReqVO updateReqVO) { |
| | | scheduleDetailService.updateDetail(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾å工级æçæç»å页") |
| | | @PreAuthorize("@ss.hasPermission('mes:cal-schedule-detail:query')") |
| | | public CommonResult<PageResult<MesCalScheduleDetailRespVO>> getDetailPage( |
| | | @Valid MesCalScheduleDetailPageReqVO pageReqVO) { |
| | | PageResult<MesCalScheduleDetailDO> pageResult = scheduleDetailService.getDetailPage(pageReqVO); |
| | | List<MesCalScheduleDetailRespVO> list = BeanUtils.toBean(pageResult.getList(), MesCalScheduleDetailRespVO.class); |
| | | return success(new PageResult<>(list, pageResult.getTotal())); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "è·å¾å工级æçæç»å表") |
| | | @PreAuthorize("@ss.hasPermission('mes:cal-schedule-detail:query')") |
| | | public CommonResult<List<MesCalScheduleDetailRespVO>> getDetailList( |
| | | @Valid MesCalScheduleDetailPageReqVO pageReqVO) { |
| | | return success(BeanUtils.toBean(scheduleDetailService.getDetailList(pageReqVO), MesCalScheduleDetailRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/check") |
| | | @Operation(summary = "åå·¥æçåè§æ ¡éªï¼è¿ç»å·¥æ¶/伿¯é´éï¼") |
| | | @PreAuthorize("@ss.hasPermission('mes:cal-schedule-detail:query')") |
| | | public CommonResult<List<MesCalScheduleDetailCheckRespVO>> checkCompliance( |
| | | @Valid MesCalScheduleDetailCheckReqVO checkReqVO) { |
| | | return success(scheduleDetailService.checkCompliance(checkReqVO)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - MES å工级æçæç» åè§æ ¡éª Request VO") |
| | | @Data |
| | | public class MesCalScheduleDetailCheckReqVO { |
| | | |
| | | @NotNull(message = "çç»æåç¨æ·ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "èµ·å§æ¥æ") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime startDay; |
| | | |
| | | @Schema(description = "ç»ææ¥æ") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime endDay; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - MES å工级æçæç» åè§æ ¡éªç»æé¡¹ VO") |
| | | @Data |
| | | public class MesCalScheduleDetailCheckRespVO { |
| | | |
| | | @Schema(description = "æ¥æ") |
| | | private LocalDateTime day; |
| | | |
| | | @Schema(description = "çæ¬¡åç§°") |
| | | private String shiftName; |
| | | |
| | | @Schema(description = "å¼å§æ¶é´ï¼HH:mmï¼") |
| | | private String startTime; |
| | | |
| | | @Schema(description = "ç»ææ¶é´ï¼HH:mmï¼") |
| | | private String endTime; |
| | | |
| | | @Schema(description = "è¿è§ç±»å: 1-忥çä¼¼è¿ç»å·¥æ¶è¶
é¿ 2-ç¸é»ç次é´ä¼æ¯ä¸è¶³", example = "1") |
| | | private Integer issueType; |
| | | |
| | | @Schema(description = "åè§æ ¡éªé®é¢æè¿°ï¼ä¸ºç©ºè¡¨ç¤ºè¯¥ç次åè§") |
| | | private String issue; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.SortablePageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - MES å工级æçæç» å页/å表 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class MesCalScheduleDetailPageReqVO extends SortablePageParam { |
| | | |
| | | @Schema(description = "æç计åç¼å·", example = "1") |
| | | private Long planId; |
| | | |
| | | @Schema(description = "çç»ç¼å·", example = "1") |
| | | private Long teamId; |
| | | |
| | | @Schema(description = "çç»æåç¨æ·ç¼å·", example = "1") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "å¼å§æ¥æ") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime startDay; |
| | | |
| | | @Schema(description = "ç»ææ¥æ") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime endDay; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - MES å工级æçæç» Response VO") |
| | | @Data |
| | | public class MesCalScheduleDetailRespVO { |
| | | |
| | | @Schema(description = "ç¼å·") |
| | | private Long id; |
| | | |
| | | @Schema(description = "æç计åç¼å·") |
| | | private Long planId; |
| | | |
| | | @Schema(description = "çç»ç¼å·") |
| | | private Long teamId; |
| | | |
| | | @Schema(description = "çç»æåç¨æ·ç¼å·") |
| | | private Long userId; |
| | | |
| | | @Schema(description = "æ¥æ") |
| | | private LocalDateTime day; |
| | | |
| | | @Schema(description = "çæ¬¡ç¼å·") |
| | | private Long shiftId; |
| | | |
| | | @Schema(description = "çæ¬¡åç§°") |
| | | private String shiftName; |
| | | |
| | | @Schema(description = "å¼å§æ¶é´ï¼HH:mmï¼") |
| | | private String startTime; |
| | | |
| | | @Schema(description = "ç»ææ¶é´ï¼HH:mmï¼") |
| | | private String endTime; |
| | | |
| | | @Schema(description = "æ¥æº: 1-èªå¨çæ 2-äººå·¥è°æ´") |
| | | private Integer source; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管çåå° - MES å工级æçæç» äººå·¥è°æ´ Request VO") |
| | | @Data |
| | | public class MesCalScheduleDetailSaveReqVO { |
| | | |
| | | @NotNull(message = "æç»ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | @Schema(description = "çæ¬¡ç¼å·") |
| | | private Long shiftId; |
| | | |
| | | @Schema(description = "çæ¬¡åç§°") |
| | | private String shiftName; |
| | | |
| | | @Schema(description = "å¼å§æ¶é´ï¼HH:mmï¼") |
| | | private String startTime; |
| | | |
| | | @Schema(description = "ç»ææ¶é´ï¼HH:mmï¼") |
| | | private String endTime; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | @ExcelProperty("å·¥ä½ç«") |
| | | private String workstationName; |
| | | |
| | | @Schema(description = "对åºç©æç¼å·", example = "1000") |
| | | @ExcelProperty("ç©æç¼å·") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | |
| | | @Schema(description = "å·¥ä½ç«ç¼å·", example = "300") |
| | | private Long workstationId; |
| | | |
| | | @Schema(description = "对åºç©æç¼å·ï¼ç±ç³»ç»å¨åå»ºè®¾å¤æ¶èªå¨çæï¼æ éåç«¯ä¼ å
¥ï¼", example = "1000") |
| | | private Long itemId; |
| | | |
| | | } |
| | |
| | | |
| | | import java.io.IOException; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | |
| | | @Operation(summary = "çææ¡ç å
容") |
| | | @Parameter(name = "bizType", description = "ä¸å¡ç±»å", required = true, example = "1") |
| | | @Parameter(name = "bizCode", description = "ä¸å¡ç¼ç ", required = true, example = "WO202403070001") |
| | | @Parameter(name = "bizName", description = "ä¸å¡åç§°", required = false, example = "ä¸å·è½¦é´") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-barcode:query')") |
| | | public CommonResult<String> generateBarcodeContent(@RequestParam("bizType") @NotNull(message = "ä¸å¡ç±»åä¸è½ä¸ºç©º") Integer bizType, |
| | | @RequestParam("bizCode") @NotBlank(message = "ä¸å¡ç¼ç ä¸è½ä¸ºç©º") String bizCode) { |
| | | String content = barcodeService.generateBarcodeContent(bizType, bizCode); |
| | | @RequestParam("bizCode") @NotBlank(message = "ä¸å¡ç¼ç ä¸è½ä¸ºç©º") String bizCode, |
| | | @RequestParam(value = "bizName", required = false) String bizName) { |
| | | String content = barcodeService.generateBarcodeContent(bizType, bizCode, bizName); |
| | | return success(content); |
| | | } |
| | | |
| | | @PostMapping("/render") |
| | | @Operation(summary = "çææ¡ç /äºç»´ç å¾ç", description = "æå¡ç«¯ zxing æå¾ï¼è¿å PNG Base64 ä¾å³æ¶é¢è§ï¼ä¸è½åº") |
| | | @Parameter(name = "content", description = "æ¡ç å
容", required = true) |
| | | @Parameter(name = "format", description = "æ¡ç æ ¼å¼ï¼1 äºç»´ç / 2 EAN13 / 3 CODE39 / 4 UPC-A / 空é»è®¤ CODE128ï¼", required = false) |
| | | @Parameter(name = "width", description = "å¾ç宽度", required = false) |
| | | @Parameter(name = "height", description = "å¾çé«åº¦", required = false) |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-barcode:query')") |
| | | public CommonResult<String> renderBarcodeImage(@RequestParam("content") @NotBlank(message = "æ¡ç å
容ä¸è½ä¸ºç©º") String content, |
| | | @RequestParam(value = "format", required = false) Integer format, |
| | | @RequestParam(value = "width", required = false) Integer width, |
| | | @RequestParam(value = "height", required = false) Integer height) { |
| | | return success(barcodeService.renderBarcodeImage(content, format, width, height)); |
| | | } |
| | | |
| | | @PostMapping("/parse") |
| | | @Operation(summary = "è§£ææ¡ç å
容", description = "ææ¡ç å
容精确å½ä¸ææ¨¡æ¿åè§£ï¼è¿åä¸å¡å段") |
| | | @Parameter(name = "content", description = "æ«æå°çæ¡ç å
容", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-barcode:query')") |
| | | public CommonResult<Map<String, Object>> parseBarcodeContent(@RequestParam("content") @NotBlank(message = "æ¡ç å
容ä¸è½ä¸ºç©º") String content) { |
| | | return success(barcodeService.parseBarcodeContent(content)); |
| | | } |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "å¯¼åºæ¡ç æ¸
å Excel") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-barcode:export')") |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | 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.equipmentreceipt.vo.*; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptDO; |
| | | import cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt.MesWmEquipmentReceiptService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | @Tag(name = "管çåå° - MES 设å¤å
¥åºå") |
| | | @RestController |
| | | @RequestMapping("/mes/wm/equipment-receipt") |
| | | @Validated |
| | | public class MesWmEquipmentReceiptController { |
| | | |
| | | @Resource |
| | | private MesWmEquipmentReceiptService equipmentReceiptService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建设å¤å
¥åºå") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:create')") |
| | | public CommonResult<Long> create(@Valid @RequestBody MesWmEquipmentReceiptSaveReqVO reqVO) { |
| | | return success(equipmentReceiptService.createEquipmentReceipt(reqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "ä¿®æ¹è®¾å¤å
¥åºå") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:update')") |
| | | public CommonResult<Boolean> update(@Valid @RequestBody MesWmEquipmentReceiptSaveReqVO reqVO) { |
| | | equipmentReceiptService.updateEquipmentReceipt(reqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤è®¾å¤å
¥åºå") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:delete')") |
| | | public CommonResult<Boolean> delete(@RequestParam("id") Long id) { |
| | | equipmentReceiptService.deleteEquipmentReceipt(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾è®¾å¤å
¥åºå") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:query')") |
| | | public CommonResult<MesWmEquipmentReceiptRespVO> get(@RequestParam("id") Long id) { |
| | | return success(BeanUtils.toBean(equipmentReceiptService.getEquipmentReceipt(id), MesWmEquipmentReceiptRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾è®¾å¤å
¥åºåå页") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:query')") |
| | | public CommonResult<PageResult<MesWmEquipmentReceiptRespVO>> page(@Valid MesWmEquipmentReceiptPageReqVO reqVO) { |
| | | return success(BeanUtils.toBean(equipmentReceiptService.getEquipmentReceiptPage(reqVO), MesWmEquipmentReceiptRespVO.class)); |
| | | } |
| | | |
| | | @PutMapping("/submit-approval") |
| | | @Operation(summary = "æäº¤è®¾å¤å
¥åºå审æ¹") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:submit')") |
| | | public CommonResult<Boolean> submitApproval(@RequestParam("id") Long id, |
| | | @RequestParam("processDefinitionKey") String processDefinitionKey) { |
| | | equipmentReceiptService.submitEquipmentReceiptApproval(id, processDefinitionKey); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/approval-process-list") |
| | | @Operation(summary = "è·å¾è®¾å¤å
¥åºå®¡æ¹æµç¨å®ä¹å表") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:query')") |
| | | public CommonResult<List<Map<String, Object>>> approvalProcessList() { |
| | | return success(equipmentReceiptService.getEquipmentReceiptApprovalProcessDefinitionList()); |
| | | } |
| | | |
| | | @PutMapping("/finish") |
| | | @Operation(summary = "æ§è¡è®¾å¤å
¥åº") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:finish')") |
| | | public CommonResult<Boolean> finish(@RequestParam("id") Long id) { |
| | | equipmentReceiptService.finishEquipmentReceipt(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/cancel") |
| | | @Operation(summary = "åæ¶è®¾å¤å
¥åºå") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:cancel')") |
| | | public CommonResult<Boolean> cancel(@RequestParam("id") Long id) { |
| | | equipmentReceiptService.cancelEquipmentReceipt(id); |
| | | return success(true); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line.*; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptLineDO; |
| | | import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt.MesWmEquipmentReceiptLineService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | |
| | | @Tag(name = "管çåå° - MES 设å¤å
¥åºåè¡") |
| | | @RestController |
| | | @RequestMapping("/mes/wm/equipment-receipt-line") |
| | | @Validated |
| | | public class MesWmEquipmentReceiptLineController { |
| | | |
| | | @Resource |
| | | private MesWmEquipmentReceiptLineService lineService; |
| | | @Resource |
| | | private MesDvMachineryService machineryService; |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建设å¤å
¥åºåè¡") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:create')") |
| | | public CommonResult<Long> create(@Valid @RequestBody MesWmEquipmentReceiptLineSaveReqVO reqVO) { |
| | | return success(lineService.createEquipmentReceiptLine(reqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "ä¿®æ¹è®¾å¤å
¥åºåè¡") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:update')") |
| | | public CommonResult<Boolean> update(@Valid @RequestBody MesWmEquipmentReceiptLineSaveReqVO reqVO) { |
| | | lineService.updateEquipmentReceiptLine(reqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤è®¾å¤å
¥åºåè¡") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:delete')") |
| | | public CommonResult<Boolean> delete(@RequestParam("id") Long id) { |
| | | lineService.deleteEquipmentReceiptLine(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾è®¾å¤å
¥åºåè¡") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:query')") |
| | | public CommonResult<MesWmEquipmentReceiptLineRespVO> get(@RequestParam("id") Long id) { |
| | | MesWmEquipmentReceiptLineDO line = lineService.getEquipmentReceiptLine(id); |
| | | return success(buildResp(Collections.singletonList(line)).get(0)); |
| | | } |
| | | |
| | | @GetMapping("/list-by-receipt-id") |
| | | @Operation(summary = "è·å¾è®¾å¤å
¥åºåè¡å表") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:query')") |
| | | public CommonResult<List<MesWmEquipmentReceiptLineRespVO>> listByReceiptId(@RequestParam("receiptId") Long receiptId) { |
| | | return success(buildResp(lineService.getEquipmentReceiptLineListByReceiptId(receiptId))); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾è®¾å¤å
¥åºåè¡å页") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:query')") |
| | | public CommonResult<PageResult<MesWmEquipmentReceiptLineRespVO>> page(@Valid MesWmEquipmentReceiptLinePageReqVO reqVO) { |
| | | PageResult<MesWmEquipmentReceiptLineDO> result = lineService.getEquipmentReceiptLinePage(reqVO); |
| | | return success(new PageResult<>(buildResp(result.getList()), result.getTotal())); |
| | | } |
| | | |
| | | private List<MesWmEquipmentReceiptLineRespVO> buildResp(List<MesWmEquipmentReceiptLineDO> list) { |
| | | if (CollUtil.isEmpty(list)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | Map<Long, MesDvMachineryDO> machineryMap = machineryService.getMachineryMap(convertSet(list, MesWmEquipmentReceiptLineDO::getMachineryId)); |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(convertSet(list, MesWmEquipmentReceiptLineDO::getItemId)); |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureList( |
| | | convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData() |
| | | .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e)); |
| | | return BeanUtils.toBean(list, MesWmEquipmentReceiptLineRespVO.class, vo -> { |
| | | MesDvMachineryDO machinery = machineryMap.get(vo.getMachineryId()); |
| | | if (machinery != null) { |
| | | vo.setMachineryCode(machinery.getCode()).setMachineryName(machinery.getName()); |
| | | } |
| | | MdmItemRespDTO item = itemMap.get(vo.getItemId()); |
| | | if (item != null) { |
| | | vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); |
| | | MdmUnitMeasureRespDTO unit = unitMap.get(item.getUnitMeasureId()); |
| | | if (unit != null) { |
| | | vo.setUnitMeasureName(unit.getName()); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - MES 设å¤å
¥åºåå页 Request VO") |
| | | @Data |
| | | public class MesWmEquipmentReceiptPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "åæ®ç¼ç ", example = "ER20260908001") |
| | | private String code; |
| | | |
| | | @Schema(description = "åæ®åç§°", example = "设å¤å
¥åº") |
| | | private String name; |
| | | |
| | | @Schema(description = "å
¥åºæ¥æº", example = "å¤è´") |
| | | private String source; |
| | | |
| | | @Schema(description = "ç¶æ", example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å
¥åºæ¥æ") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] receiptDate; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo; |
| | | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line.MesWmEquipmentReceiptLineRespVO; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - MES 设å¤å
¥åºå Response VO") |
| | | @Data |
| | | public class MesWmEquipmentReceiptRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "åæ®ç¼ç ", requiredMode = Schema.RequiredMode.REQUIRED, example = "ER20260908001") |
| | | private String code; |
| | | |
| | | @Schema(description = "åæ®åç§°", example = "设å¤å
¥åº") |
| | | private String name; |
| | | |
| | | @Schema(description = "å
¥åºæ¥æ") |
| | | private LocalDateTime receiptDate; |
| | | |
| | | @Schema(description = "å
¥åºæ¥æº", example = "å¤è´") |
| | | private String source; |
| | | |
| | | @Schema(description = "ç¶æ", example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¾ç¼å·") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨ä¿¡æ¯") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "æç»è¡") |
| | | private List<MesWmEquipmentReceiptLineRespVO> lines; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import jakarta.validation.constraints.NotNull; |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - MES 设å¤å
¥åºåæ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class MesWmEquipmentReceiptSaveReqVO { |
| | | |
| | | @Schema(description = "ç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "åæ®ç¼ç ", requiredMode = Schema.RequiredMode.REQUIRED, example = "ER20260908001") |
| | | @NotEmpty(message = "åæ®ç¼ç ä¸è½ä¸ºç©º") |
| | | private String code; |
| | | |
| | | @Schema(description = "åæ®åç§°", example = "设å¤å
¥åº") |
| | | private String name; |
| | | |
| | | @Schema(description = "å
¥åºæ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "å
¥åºæ¥æä¸è½ä¸ºç©º") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime receiptDate; |
| | | |
| | | @Schema(description = "å
¥åºæ¥æº", example = "å¤è´") |
| | | private String source; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨ä¿¡æ¯") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管çåå° - MES 设å¤å
¥åºåè¡å页 Request VO") |
| | | @Data |
| | | public class MesWmEquipmentReceiptLinePageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "å
¥åºåç¼å·", example = "1") |
| | | private Long receiptId; |
| | | |
| | | @Schema(description = "设å¤å°è´¦ç¼å·", example = "1") |
| | | private Long machineryId; |
| | | |
| | | @Schema(description = "设å¤ç©æç¼å·", example = "1") |
| | | private Long itemId; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - MES 设å¤å
¥åºåè¡ Response VO") |
| | | @Data |
| | | public class MesWmEquipmentReceiptLineRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å
¥åºåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long receiptId; |
| | | |
| | | @Schema(description = "设å¤å°è´¦ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long machineryId; |
| | | |
| | | @Schema(description = "设å¤ç¼ç ") |
| | | private String machineryCode; |
| | | |
| | | @Schema(description = "设å¤åç§°") |
| | | private String machineryName; |
| | | |
| | | @Schema(description = "设å¤ç©æç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "ç©æç¼ç ") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "ç©æåç§°") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "è§æ ¼åå·") |
| | | private String specification; |
| | | |
| | | @Schema(description = "计éåä½åç§°") |
| | | private String unitMeasureName; |
| | | |
| | | @Schema(description = "å
¥åºæ°é", example = "1.00") |
| | | private BigDecimal quantity; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.DecimalMin; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Schema(description = "管çåå° - MES 设å¤å
¥åºåè¡æ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class MesWmEquipmentReceiptLineSaveReqVO { |
| | | |
| | | @Schema(description = "ç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å
¥åºåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "å
¥åºåç¼å·ä¸è½ä¸ºç©º") |
| | | private Long receiptId; |
| | | |
| | | @Schema(description = "设å¤å°è´¦ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "设å¤ä¸è½ä¸ºç©º") |
| | | private Long machineryId; |
| | | |
| | | @Schema(description = "设å¤ç©æç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "设å¤ç©æä¸è½ä¸ºç©º") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "å
¥åºæ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.00") |
| | | @NotNull(message = "å
¥åºæ°éä¸è½ä¸ºç©º") |
| | | @DecimalMin(value = "0.01", message = "å
¥åºæ°éä¸è½å°äº 0.01") |
| | | private BigDecimal quantity; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnDetailRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnInStockPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnInStockReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnOutStockReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnRespVO; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | @PostMapping("/in-stock") |
| | | @Operation(summary = "å
¥åºç»è®° SN", description = "æ SN 建ç«åä»¶å
¥åºäºå¡å¹¶å
¥å°ï¼éç©æå·²å¯ç¨åºåå·ç®¡ç") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-sn:update')") |
| | | public CommonResult<Boolean> registerSnInStock(@Valid @RequestBody MesWmSnInStockReqVO reqVO) { |
| | | snService.registerSnInStock(reqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @PostMapping("/out-stock") |
| | | @Operation(summary = "åºåºæ ¸é SN", description = "æ SN 建ç«åä»¶åºåºäºå¡å¹¶æ ¸é") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-sn:update')") |
| | | public CommonResult<Boolean> outboundSn(@Valid @RequestBody MesWmSnOutStockReqVO reqVO) { |
| | | snService.outboundSn(reqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/detail") |
| | | @Operation(summary = "è·å¾ SN åä»¶æç»", description = "è¿åç¶æãå¨åºä½ç½®åæè¿ä¸ç¬åºåäºå¡") |
| | | @Parameter(name = "code", description = "SN ç ", required = true, example = "SN20260305000001") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-sn:query')") |
| | | public CommonResult<MesWmSnDetailRespVO> getSnDetail(@RequestParam("code") @NotBlank(message = "SN ç ä¸è½ä¸ºç©º") String code) { |
| | | return success(snService.getSnDetail(code)); |
| | | } |
| | | |
| | | @GetMapping("/in-stock-page") |
| | | @Operation(summary = "SN ç ç¶æå页", description = "æç¶æ/ç©æ/åºä½ç维度å页æ¥è¯¢ SNï¼æ¯æçç¹æ ¸å¯¹ï¼") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-sn:query')") |
| | | public CommonResult<PageResult<MesWmSnRespVO>> getSnInStockPage(@Valid MesWmSnInStockPageReqVO reqVO) { |
| | | PageResult<MesWmSnRespVO> pageResult = BeanUtils.toBean(snService.getSnInStockPage(reqVO), MesWmSnRespVO.class); |
| | | buildSnItemVO(pageResult.getList()); |
| | | return success(pageResult); |
| | | } |
| | | |
| | | @GetMapping("/group-export-excel") |
| | | @Operation(summary = "å¯¼åº SN ç åç» Excel") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-sn:export')") |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - SN ç åä»¶æç» Response VO") |
| | | @Data |
| | | public class MesWmSnDetailRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "SN ç ", example = "SN20260305000001") |
| | | private String code; |
| | | |
| | | @Schema(description = "ç©æç¼å·", example = "1") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "æ¹æ¬¡å·", example = "BATCH001") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "ç¶æï¼1-å¨åº 2-å·²åºåºï¼", example = "1") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å¨åºä»åº ID", example = "5") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "å¨åºåºåº ID", example = "11") |
| | | private Long locationId; |
| | | |
| | | @Schema(description = "å¨åºåºä½ ID", example = "10") |
| | | private Long areaId; |
| | | |
| | | // ==================== æè¿ä¸ç¬åºåäºå¡ï¼å»å/ä½ç½®æ¥æºï¼ ==================== |
| | | |
| | | @Schema(description = "æè¿äºå¡ç±»åï¼1-å
¥åº 2-åºåºï¼", example = "1") |
| | | private Integer lastTransactionType; |
| | | |
| | | @Schema(description = "æè¿äºå¡ç±»ååç§°", example = "å
¥åº") |
| | | private String lastTransactionTypeName; |
| | | |
| | | @Schema(description = "æè¿äºå¡å卿°é", example = "1") |
| | | private BigDecimal lastTransactionQuantity; |
| | | |
| | | @Schema(description = "æè¿äºå¡ä¸å¡ç±»å", example = "109") |
| | | private Integer lastTransactionBizType; |
| | | |
| | | @Schema(description = "æè¿äºå¡ä¸å¡åå·", example = "SN20260305000001") |
| | | private String lastTransactionBizCode; |
| | | |
| | | @Schema(description = "æè¿äºå¡åçæ¶é´", example = "2026-09-08 10:00:00") |
| | | private LocalDateTime lastTransactionTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | @Schema(description = "管çåå° - SN ç å¨åº/ç¶æå页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class MesWmSnInStockPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "SN ç ", example = "SN20260305000001") |
| | | private String code; |
| | | |
| | | @Schema(description = "ç©æç¼å·", example = "1") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "æ¹æ¬¡å·", example = "BATCH001") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "ä»åº ID", example = "5") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "åºåº ID", example = "11") |
| | | private Long locationId; |
| | | |
| | | @Schema(description = "åºä½ ID", example = "10") |
| | | private Long areaId; |
| | | |
| | | @Schema(description = "ç¶æï¼1-å¨åº 2-å·²åºåºï¼", example = "1") |
| | | private Integer status; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管çåå° - SN ç å
¥åºç»è®° Request VO") |
| | | @Data |
| | | public class MesWmSnInStockReqVO { |
| | | |
| | | @Schema(description = "SN ç ", requiredMode = Schema.RequiredMode.REQUIRED, example = "SN20260305000001") |
| | | @NotBlank(message = "SN ç ä¸è½ä¸ºç©º") |
| | | private String code; |
| | | |
| | | @Schema(description = "ç©æç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "ç©æç¼å·ä¸è½ä¸ºç©º") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "ä»åº ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") |
| | | @NotNull(message = "ä»åºä¸è½ä¸ºç©º") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "åºåº ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11") |
| | | @NotNull(message = "åºåºä¸è½ä¸ºç©º") |
| | | private Long locationId; |
| | | |
| | | @Schema(description = "åºä½ ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| | | @NotNull(message = "åºä½ä¸è½ä¸ºç©º") |
| | | private Long areaId; |
| | | |
| | | @Schema(description = "æ¹æ¬¡å·", example = "BATCH001") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "夿³¨", example = "æ«ç å
¥åº") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管çåå° - SN ç åºåºæ ¸é Request VO") |
| | | @Data |
| | | public class MesWmSnOutStockReqVO { |
| | | |
| | | @Schema(description = "SN ç ", requiredMode = Schema.RequiredMode.REQUIRED, example = "SN20260305000001") |
| | | @NotBlank(message = "SN ç ä¸è½ä¸ºç©º") |
| | | private String code; |
| | | |
| | | @Schema(description = "ç©æç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "ç©æç¼å·ä¸è½ä¸ºç©º") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "夿³¨", example = "æ«ç åºåº") |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | @Schema(description = "ç产工åç¼å·", example = "1") |
| | | private Long workOrderId; |
| | | |
| | | @Schema(description = "ç¶æï¼1-å¨åº 2-å·²åºåºï¼", example = "1") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å¨åºä»åº ID", example = "5") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "å¨åºåºåº ID", example = "11") |
| | | private Long locationId; |
| | | |
| | | @Schema(description = "å¨åºåºä½ ID", example = "10") |
| | | private Long areaId; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | @ExcelProperty("çææ¶é´") |
| | | private LocalDateTime createTime; |
| | |
| | | @ExcelProperty("æ¯å¦å»ç»åºå") |
| | | private Boolean frozen; |
| | | |
| | | @Schema(description = "æ¯å¦å®æèªå¨çæçç¹ä»»å¡", example = "false") |
| | | @ExcelProperty("æ¯å¦å®æèªå¨çæ") |
| | | private Boolean autoGenerate; |
| | | |
| | | @Schema(description = "èªå¨çæå¨æ cron 表达å¼", example = "0 0 8 * * ?") |
| | | @ExcelProperty("èªå¨çæå¨æ") |
| | | private String generateCron; |
| | | |
| | | @Schema(description = "䏿¬¡èªå¨çææ¶é´") |
| | | @ExcelProperty("䏿¬¡èªå¨çææ¶é´") |
| | | private LocalDateTime lastGenerateTime; |
| | | |
| | | @Schema(description = "ç¶æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| | | @ExcelProperty("ç¶æ") |
| | | private Integer status; |
| | |
| | | @NotNull(message = "æ¯å¦å»ç»åºåä¸è½ä¸ºç©º") |
| | | private Boolean frozen; |
| | | |
| | | @Schema(description = "æ¯å¦å®æèªå¨çæçç¹ä»»å¡", example = "false") |
| | | private Boolean autoGenerate; |
| | | |
| | | @Schema(description = "èªå¨çæå¨æ cron 表达å¼ï¼å¼å¯èªå¨çææ¶å¿
å¡«ï¼å¦ 0 0 8 * * ?", example = "0 0 8 * * ?") |
| | | private String generateCron; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | |
| | | buildTaskRespVOList(pageResult.getList())); |
| | | } |
| | | |
| | | @PutMapping("/finish") |
| | | @Operation(summary = "宿çç¹ä»»å¡") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:finish')") |
| | | public CommonResult<Boolean> finishStockTakingTask(@Valid @RequestBody MesWmStockTakingTaskFinishReqVO reqVO) { |
| | | stockTakingTaskService.finishStockTakingTask(reqVO.getId()); |
| | | @PutMapping("/submit-approval") |
| | | @Operation(summary = "æäº¤çç¹ç»æå®¡æ¹") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @Parameter(name = "processDefinitionKey", description = "æµç¨å®ä¹ Key", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:update')") |
| | | public CommonResult<Boolean> submitStockTakingTaskResultApproval(@RequestParam("id") Long id, |
| | | @RequestParam("processDefinitionKey") String processDefinitionKey) { |
| | | stockTakingTaskService.submitStockTakingResultApproval(id, processDefinitionKey); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/approval-process-list") |
| | | @Operation(summary = "è·å¾çç¹ç»æå®¡æ¹æµç¨å®ä¹å表") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:query')") |
| | | public CommonResult<List<Map<String, Object>>> getStockTakingTaskResultApprovalProcessDefinitionList() { |
| | | return success(stockTakingTaskService.getStockTakingTaskResultApprovalProcessDefinitionList()); |
| | | } |
| | | |
| | | @PutMapping("/cancel") |
| | | @Operation(summary = "åæ¶çç¹ä»»å¡") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | |
| | | @ExcelProperty("ç¶æ") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¾ç¼å·ï¼é空表示çç¹ç»æå·²æäº¤å®¡æ¹", example = "xxx") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | @ExcelProperty("夿³¨") |
| | | private String remark; |
| | |
| | | return "å¤ååæ"; |
| | | case MesBizTypeConstants.WM_OUTSOURCE_RECPT: |
| | | return "å¤åå
¥åº"; |
| | | case MesBizTypeConstants.WM_STOCK_TAKING: |
| | | return "çç¹è°æ´"; |
| | | case MesBizTypeConstants.WM_SN: |
| | | return "SN åºå
¥åº"; |
| | | case MesBizTypeConstants.WM_ITEM_RECEIPT_CANCEL: |
| | | return "éè´å
¥åºçº¢å²"; |
| | | case MesBizTypeConstants.DV_MACHINERY: |
| | | return "设å¤å°è´¦å
¥åº"; |
| | | case MesBizTypeConstants.DV_EQUIPMENT_RECEIPT: |
| | | return "设å¤å
¥åº"; |
| | | default: |
| | | return "æªç¥ç±»å(" + bizType + ")"; |
| | | } |
| | |
| | | @Schema(description = "åºåè®°å½ID", example = "1") |
| | | private Long materialStockId; |
| | | |
| | | @Schema(description = "SN ç ", example = "SN20260305000001") |
| | | private String snCode; |
| | | |
| | | @Schema(description = "å¼å§æ¶é´") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime startTime; |
| | |
| | | @Schema(description = "æ¹æ¬¡å·", example = "BATCH001") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "SN ç ", example = "SN20260305000001") |
| | | private String snCode; |
| | | |
| | | // ========== åºåä½ç½® ========== |
| | | |
| | | @Schema(description = "ä»åºID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.cal.schedule; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanShiftDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * MES å工级æçæç» DO |
| | | * |
| | | * ç±çç»æçï¼mes_cal_team_shiftï¼+ çç»æåï¼mes_cal_team_memberï¼å±å¼å°"åå·¥Ãæ¥Ãçæ¬¡"ï¼ |
| | | * ä½ä¸ºå·¥æ¶ç»è®¡ä¸å¼å®åè§çåºåã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @TableName("mes_cal_schedule_detail") |
| | | @KeySequence("mes_cal_schedule_detail_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class MesCalScheduleDetailDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * æç计åç¼å· |
| | | */ |
| | | private Long planId; |
| | | /** |
| | | * çç»ç¼å· |
| | | * |
| | | * å
³è {@link MesCalTeamDO#getId()} |
| | | */ |
| | | private Long teamId; |
| | | /** |
| | | * çç»æåç¨æ·ç¼å· |
| | | * |
| | | * å
³è system_users.idï¼mes_cal_team_member.userIdï¼ |
| | | */ |
| | | private Long userId; |
| | | /** |
| | | * æ¥æ |
| | | */ |
| | | private LocalDateTime day; |
| | | /** |
| | | * çæ¬¡ç¼å· |
| | | * |
| | | * å
³è {@link MesCalPlanShiftDO#getId()} |
| | | */ |
| | | private Long shiftId; |
| | | /** |
| | | * çæ¬¡åç§°ï¼åä½ï¼ |
| | | */ |
| | | private String shiftName; |
| | | /** |
| | | * å¼å§æ¶é´ï¼HH:mm æ ¼å¼ï¼åä½ï¼ |
| | | */ |
| | | private String startTime; |
| | | /** |
| | | * ç»ææ¶é´ï¼HH:mm æ ¼å¼ï¼åä½ï¼ |
| | | */ |
| | | private String endTime; |
| | | /** |
| | | * æ¥æº: 1-èªå¨çæ 2-äººå·¥è°æ´ |
| | | */ |
| | | private Integer source; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | * å
³è {@link cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO#getId()} |
| | | */ |
| | | private Long workstationId; |
| | | /** |
| | | * 对åºç©æç¼å· |
| | | * |
| | | * å
³è MDM ç©æ {@link cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO#getId()} |
| | | * 设å¤å建æ¶èªå¨å建对åºç©æï¼å¹¶ä»¥æ¤å
³è设å¤ä»åºå |
| | | */ |
| | | private Long itemId; |
| | | |
| | | } |
| | |
| | | * å
å®¹æ ¼å¼æ¨¡æ¿å ä½ç¬¦ |
| | | */ |
| | | public static final String PLACEHOLDER_BUSINESS_CODE = "{BUSINESSCODE}"; |
| | | /** |
| | | * å
å®¹æ ¼å¼æ¨¡æ¿å ä½ç¬¦ |
| | | */ |
| | | public static final String PLACEHOLDER_BUSINESS_NAME = "{BUSINESSNAME}"; |
| | | |
| | | /** |
| | | * ç¼å· |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * MES 设å¤å
¥åºå DO |
| | | */ |
| | | @TableName("mes_wm_equipment_receipt") |
| | | @KeySequence("mes_wm_equipment_receipt_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class MesWmEquipmentReceiptDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * åæ®ç¼ç |
| | | */ |
| | | private String code; |
| | | /** |
| | | * åæ®åç§° |
| | | */ |
| | | private String name; |
| | | /** |
| | | * å
¥åºæ¥æ |
| | | */ |
| | | private LocalDateTime receiptDate; |
| | | /** |
| | | * å
¥åºæ¥æº |
| | | */ |
| | | private String source; |
| | | /** |
| | | * ç¶æ |
| | | * |
| | | * æä¸¾ {@link cn.iocoder.yudao.module.mes.enums.wm.MesWmEquipmentReceiptStatusEnum} |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * BPM æµç¨å®ä¾ç¼å· |
| | | */ |
| | | private String processInstanceId; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * MES 设å¤å
¥åºåè¡ DO |
| | | */ |
| | | @TableName("mes_wm_equipment_receipt_line") |
| | | @KeySequence("mes_wm_equipment_receipt_line_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class MesWmEquipmentReceiptLineDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * å
¥åºåç¼å· |
| | | * |
| | | * å
³è {@link MesWmEquipmentReceiptDO#getId()} |
| | | */ |
| | | private Long receiptId; |
| | | /** |
| | | * 设å¤å°è´¦ç¼å· |
| | | * |
| | | * å
³è {@link cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO#getId()} |
| | | */ |
| | | private Long machineryId; |
| | | /** |
| | | * 设å¤ç©æç¼å·ï¼è®¾å¤å°è´¦å¯¹åºç MDM ç©æï¼mdm_item.idï¼ |
| | | */ |
| | | private Long itemId; |
| | | /** |
| | | * å
¥åºæ°é |
| | | */ |
| | | private BigDecimal quantity; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmSnStatusEnum; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | |
| | | * å
³è {@link MesProWorkOrderDO#getId()} |
| | | */ |
| | | private Long workOrderId; |
| | | /** |
| | | * æ¹æ¬¡ ID |
| | | * |
| | | * å
³è {@link MesWmBatchDO#getId()} |
| | | */ |
| | | private Long batchId; |
| | | /** |
| | | * ç¶æ |
| | | * |
| | | * æä¸¾ {@link MesWmSnStatusEnum} |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * å¨åºä»åº ID |
| | | * |
| | | * å
³è {@link MesWmWarehouseDO#getId()} |
| | | */ |
| | | private Long warehouseId; |
| | | /** |
| | | * å¨åºåºåº ID |
| | | * |
| | | * å
³è {@link MesWmWarehouseLocationDO#getId()} |
| | | */ |
| | | private Long locationId; |
| | | /** |
| | | * å¨åºåºä½ ID |
| | | * |
| | | * å
³è {@link MesWmWarehouseAreaDO#getId()} |
| | | */ |
| | | private Long areaId; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | private Boolean frozen; |
| | | |
| | | /** |
| | | * æ¯å¦å®æèªå¨çæçç¹ä»»å¡ |
| | | * |
| | | * 为 true æ¶ç±åå°å®æ¶ä»»å¡æ {@link #generateCron} 卿èªå¨å建çç¹ä»»å¡ |
| | | */ |
| | | private Boolean autoGenerate; |
| | | /** |
| | | * èªå¨çæå¨æ cron è¡¨è¾¾å¼ |
| | | * |
| | | * autoGenerate 为 true æ¶å¿
å¡«ï¼Quartz 6 段 cronï¼å¦ {@code 0 0 8 * * ?} 表示æ¯å¤© 8 ç¹ |
| | | */ |
| | | private String generateCron; |
| | | /** |
| | | * 䏿¬¡èªå¨çææ¶é´ |
| | | * |
| | | * 宿¶ä»»å¡æ®æ¤å¤æå¨ææ¯å¦å°æï¼é¿å
åä¸å¨æéå¤çæ |
| | | */ |
| | | private LocalDateTime lastGenerateTime; |
| | | |
| | | /** |
| | | * ç¶æ |
| | | * |
| | | * æä¸¾ {@link CommonStatusEnum} |
| | |
| | | private Integer status; |
| | | |
| | | /** |
| | | * BPM æµç¨å®ä¾ç¼å· |
| | | * |
| | | * é空表示çç¹ç»æå·²æäº¤ BPM 审æ¹ï¼æ£å¨çå¾
审æ¹ç»æ |
| | | */ |
| | | private String processInstanceId; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | |
| | | * å
³è {@link MesWmBatchDO#getCode()} |
| | | */ |
| | | private String batchCode; |
| | | /** |
| | | * SN ç ï¼åºåå·ç®¡çç©æååè¿åºï¼ |
| | | */ |
| | | private String snCode; |
| | | |
| | | // ==================== åºåä½ç½® ==================== |
| | | |
| | |
| | | public static final String WIP_VIRTUAL_AREA = "WIP_VIRTUAL_AREA"; |
| | | |
| | | /** |
| | | * 设å¤ä»é»è®¤åºä½ç¼ç ï¼é
å {@link MesWmWarehouseDO#EQUIPMENT_WAREHOUSE} 使ç¨ï¼ |
| | | */ |
| | | public static final String EQUIPMENT_AREA = "SYS-EQUIP-BIN-01"; |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | |
| | | public static final String WIP_VIRTUAL_WAREHOUSE = "WIP_VIRTUAL_WAREHOUSE"; |
| | | |
| | | /** |
| | | * 设å¤ä»ç¼ç |
| | | * |
| | | * 设å¤å建æ¶èªå¨å
¥åºçä¸ç¨ä»åºï¼å¯¹åºåºåäºå¡ä»åºç»´åº¦ã |
| | | */ |
| | | public static final String EQUIPMENT_WAREHOUSE = "SYS-EQUIPMENT"; |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | |
| | | public static final String WIP_VIRTUAL_LOCATION = "WIP_VIRTUAL_LOCATION"; |
| | | |
| | | /** |
| | | * 设å¤ä»éç¨åºåºç¼ç ï¼é
å {@link MesWmWarehouseDO#EQUIPMENT_WAREHOUSE} 使ç¨ï¼ |
| | | */ |
| | | public static final String EQUIPMENT_LOCATION = "SYS-EQUIP-LOC-01"; |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.cal.schedule; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.schedule.MesCalScheduleDetailDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES å工级æçæç» Mapper |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Mapper |
| | | public interface MesCalScheduleDetailMapper extends BaseMapperX<MesCalScheduleDetailDO> { |
| | | |
| | | default PageResult<MesCalScheduleDetailDO> selectPage(MesCalScheduleDetailPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesCalScheduleDetailDO>() |
| | | .eqIfPresent(MesCalScheduleDetailDO::getPlanId, reqVO.getPlanId()) |
| | | .eqIfPresent(MesCalScheduleDetailDO::getTeamId, reqVO.getTeamId()) |
| | | .eqIfPresent(MesCalScheduleDetailDO::getUserId, reqVO.getUserId()) |
| | | .geIfPresent(MesCalScheduleDetailDO::getDay, reqVO.getStartDay()) |
| | | .leIfPresent(MesCalScheduleDetailDO::getDay, reqVO.getEndDay()) |
| | | .orderByAsc(MesCalScheduleDetailDO::getDay)); |
| | | } |
| | | |
| | | default List<MesCalScheduleDetailDO> selectList(MesCalScheduleDetailPageReqVO reqVO) { |
| | | return selectList(new LambdaQueryWrapperX<MesCalScheduleDetailDO>() |
| | | .eqIfPresent(MesCalScheduleDetailDO::getPlanId, reqVO.getPlanId()) |
| | | .eqIfPresent(MesCalScheduleDetailDO::getTeamId, reqVO.getTeamId()) |
| | | .eqIfPresent(MesCalScheduleDetailDO::getUserId, reqVO.getUserId()) |
| | | .geIfPresent(MesCalScheduleDetailDO::getDay, reqVO.getStartDay()) |
| | | .leIfPresent(MesCalScheduleDetailDO::getDay, reqVO.getEndDay()) |
| | | .orderByAsc(MesCalScheduleDetailDO::getDay)); |
| | | } |
| | | |
| | | default List<MesCalScheduleDetailDO> selectListByPlanId(Long planId) { |
| | | return selectList(MesCalScheduleDetailDO::getPlanId, planId); |
| | | } |
| | | |
| | | default List<MesCalScheduleDetailDO> selectListByUserIdBetween(Long userId, |
| | | java.time.LocalDateTime startDay, |
| | | java.time.LocalDateTime endDay) { |
| | | return selectList(new LambdaQueryWrapperX<MesCalScheduleDetailDO>() |
| | | .eq(MesCalScheduleDetailDO::getUserId, userId) |
| | | .geIfPresent(MesCalScheduleDetailDO::getDay, startDay) |
| | | .leIfPresent(MesCalScheduleDetailDO::getDay, endDay) |
| | | .orderByAsc(MesCalScheduleDetailDO::getDay)); |
| | | } |
| | | |
| | | default void deleteByPlanId(Long planId) { |
| | | delete(MesCalScheduleDetailDO::getPlanId, planId); |
| | | } |
| | | |
| | | default void deleteByTeamId(Long teamId) { |
| | | delete(MesCalScheduleDetailDO::getTeamId, teamId); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.wm.barcode; |
| | | |
| | | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.barcode.vo.config.MesWmBarcodeConfigPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.barcode.MesWmBarcodeConfigDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES æ¡ç é
ç½® Mapper |
| | |
| | | return selectOne(MesWmBarcodeConfigDO::getBizType, bizType); |
| | | } |
| | | |
| | | default List<MesWmBarcodeConfigDO> selectEnableList() { |
| | | return selectList(new LambdaQueryWrapperX<MesWmBarcodeConfigDO>() |
| | | .eq(MesWmBarcodeConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) |
| | | .orderByAsc(MesWmBarcodeConfigDO::getId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.wm.equipmentreceipt; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line.MesWmEquipmentReceiptLinePageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptLineDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES 设å¤å
¥åºåè¡ Mapper |
| | | */ |
| | | @Mapper |
| | | public interface MesWmEquipmentReceiptLineMapper extends BaseMapperX<MesWmEquipmentReceiptLineDO> { |
| | | |
| | | default PageResult<MesWmEquipmentReceiptLineDO> selectPage(MesWmEquipmentReceiptLinePageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesWmEquipmentReceiptLineDO>() |
| | | .eqIfPresent(MesWmEquipmentReceiptLineDO::getReceiptId, reqVO.getReceiptId()) |
| | | .eqIfPresent(MesWmEquipmentReceiptLineDO::getMachineryId, reqVO.getMachineryId()) |
| | | .eqIfPresent(MesWmEquipmentReceiptLineDO::getItemId, reqVO.getItemId()) |
| | | .orderByDesc(MesWmEquipmentReceiptLineDO::getId)); |
| | | } |
| | | |
| | | default List<MesWmEquipmentReceiptLineDO> selectListByReceiptId(Long receiptId) { |
| | | return selectList(MesWmEquipmentReceiptLineDO::getReceiptId, receiptId); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.wm.equipmentreceipt; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.MesWmEquipmentReceiptPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * MES 设å¤å
¥åºå Mapper |
| | | */ |
| | | @Mapper |
| | | public interface MesWmEquipmentReceiptMapper extends BaseMapperX<MesWmEquipmentReceiptDO> { |
| | | |
| | | default PageResult<MesWmEquipmentReceiptDO> selectPage(MesWmEquipmentReceiptPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesWmEquipmentReceiptDO>() |
| | | .likeIfPresent(MesWmEquipmentReceiptDO::getCode, reqVO.getCode()) |
| | | .likeIfPresent(MesWmEquipmentReceiptDO::getName, reqVO.getName()) |
| | | .likeIfPresent(MesWmEquipmentReceiptDO::getSource, reqVO.getSource()) |
| | | .eqIfPresent(MesWmEquipmentReceiptDO::getStatus, reqVO.getStatus()) |
| | | .betweenIfPresent(MesWmEquipmentReceiptDO::getReceiptDate, reqVO.getReceiptDate()) |
| | | .orderByDesc(MesWmEquipmentReceiptDO::getId)); |
| | | } |
| | | |
| | | default MesWmEquipmentReceiptDO selectByCode(String code) { |
| | | return selectOne(MesWmEquipmentReceiptDO::getCode, code); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnInStockPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.sn.MesWmSnDO; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmSnStatusEnum; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | |
| | | .eq(MesWmSnDO::getUuid, uuid)); |
| | | } |
| | | |
| | | default MesWmSnDO selectByCode(String code) { |
| | | return selectOne(MesWmSnDO::getCode, code); |
| | | } |
| | | |
| | | /** |
| | | * åºåºæ ¸éï¼ç½®ä¸ºå·²åºåºå¹¶æ¸
空å¨åºåºä½ |
| | | */ |
| | | default void markOutStockAndClearLocation(Long id) { |
| | | update(null, new LambdaUpdateWrapper<MesWmSnDO>() |
| | | .eq(MesWmSnDO::getId, id) |
| | | .set(MesWmSnDO::getStatus, MesWmSnStatusEnum.OUT_STOCK.getStatus()) |
| | | .set(MesWmSnDO::getWarehouseId, null) |
| | | .set(MesWmSnDO::getLocationId, null) |
| | | .set(MesWmSnDO::getAreaId, null)); |
| | | } |
| | | |
| | | /** |
| | | * æ SN ç¶æ/åºä½/ç©æç维度å页æ¥è¯¢ |
| | | */ |
| | | default PageResult<MesWmSnDO> selectStatusPage(MesWmSnInStockPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesWmSnDO>() |
| | | .likeIfPresent(MesWmSnDO::getCode, reqVO.getCode()) |
| | | .eqIfPresent(MesWmSnDO::getItemId, reqVO.getItemId()) |
| | | .likeIfPresent(MesWmSnDO::getBatchCode, reqVO.getBatchCode()) |
| | | .eqIfPresent(MesWmSnDO::getWarehouseId, reqVO.getWarehouseId()) |
| | | .eqIfPresent(MesWmSnDO::getLocationId, reqVO.getLocationId()) |
| | | .eqIfPresent(MesWmSnDO::getAreaId, reqVO.getAreaId()) |
| | | .eqIfPresent(MesWmSnDO::getStatus, reqVO.getStatus()) |
| | | .orderByDesc(MesWmSnDO::getId)); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.plan; |
| | | |
| | | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.plan.vo.MesWmStockTakingPlanPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.plan.MesWmStockTakingPlanDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | |
| | | return selectOne(MesWmStockTakingPlanDO::getCode, code); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å¯ç¨ä¸å¼å¯å®æèªå¨çæççç¹æ¹æ¡ |
| | | * |
| | | * @return çç¹æ¹æ¡å表 |
| | | */ |
| | | default List<MesWmStockTakingPlanDO> selectEnableAutoGenerateList() { |
| | | return selectList(new LambdaQueryWrapperX<MesWmStockTakingPlanDO>() |
| | | .eq(MesWmStockTakingPlanDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) |
| | | .eq(MesWmStockTakingPlanDO::getAutoGenerate, Boolean.TRUE) |
| | | .isNotNull(MesWmStockTakingPlanDO::getGenerateCron) |
| | | .orderByAsc(MesWmStockTakingPlanDO::getId)); |
| | | } |
| | | |
| | | default PageResult<MesWmStockTakingPlanDO> selectPage(MesWmStockTakingPlanPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesWmStockTakingPlanDO>() |
| | | .likeIfPresent(MesWmStockTakingPlanDO::getCode, reqVO.getCode()) |
| | |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.MesWmStockTakingTaskPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | |
| | | return selectOne(MesWmStockTakingTaskDO::getCode, code); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
空 BPM æµç¨å®ä¾ç¼å· |
| | | * |
| | | * ç¨äºçç¹ç»æå®¡æ¹è¢«é©³å/åæ¶å置空ï¼ä»»å¡åå°å¯éæ°æäº¤ç»æå®¡æ¹çç¶æ |
| | | * |
| | | * @param id çç¹ä»»å¡ç¼å· |
| | | */ |
| | | default void clearProcessInstanceId(Long id) { |
| | | update(null, new LambdaUpdateWrapper<MesWmStockTakingTaskDO>() |
| | | .eq(MesWmStockTakingTaskDO::getId, id) |
| | | .set(MesWmStockTakingTaskDO::getProcessInstanceId, null)); |
| | | } |
| | | |
| | | default PageResult<MesWmStockTakingTaskDO> selectPage(MesWmStockTakingTaskPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesWmStockTakingTaskDO>() |
| | | .likeIfPresent(MesWmStockTakingTaskDO::getCode, reqVO.getCode()) |
| | |
| | | .eqIfPresent(MesWmTransactionDO::getBizType, reqVO.getBizType()) |
| | | .likeIfPresent(MesWmTransactionDO::getBizCode, reqVO.getBizCode()) |
| | | .eqIfPresent(MesWmTransactionDO::getMaterialStockId, reqVO.getMaterialStockId()) |
| | | .eqIfPresent(MesWmTransactionDO::getSnCode, reqVO.getSnCode()) |
| | | .geIfPresent(MesWmTransactionDO::getTransactionTime, reqVO.getStartTime()) |
| | | .leIfPresent(MesWmTransactionDO::getTransactionTime, reqVO.getEndTime()) |
| | | .orderByDesc(MesWmTransactionDO::getTransactionTime)); |
| | | } |
| | | |
| | | /** |
| | | * æ SN ç æ¥è¯¢æè¿ä¸ç¬åºåäºå¡ |
| | | * |
| | | * @param snCode SN ç |
| | | * @return æè¿ä¸ç¬äºå¡ï¼ä¸åå¨è¿å null |
| | | */ |
| | | default MesWmTransactionDO selectLatestBySnCode(String snCode) { |
| | | return selectOne(new LambdaQueryWrapperX<MesWmTransactionDO>() |
| | | .eq(MesWmTransactionDO::getSnCode, snCode) |
| | | .orderByDesc(MesWmTransactionDO::getTransactionTime) |
| | | .orderByDesc(MesWmTransactionDO::getId) |
| | | .last("LIMIT 1")); |
| | | } |
| | | |
| | | /** |
| | | * æ¥æ¾èæçº¿è¾¹åºåºåè®°å½å¯¹åºçåå§åºåºä»åºä¿¡æ¯ |
| | | * <p> |
| | | * éè¿èæçº¿è¾¹åºç materialStockIdï¼æ¾å°é¦æ¬¡å
¥åºäºå¡ï¼INï¼ï¼ |
| | |
| | | ErrorCode CAL_TEAM_SHIFT_NOT_EXISTS = new ErrorCode(1_040_201_200, "çç»æçè®°å½ä¸åå¨"); |
| | | ErrorCode CAL_TEAM_SHIFT_GENERATE_TEAM_NOT_ENOUGH = new ErrorCode(1_040_201_201, "çç»æ°é䏿»¡è¶³è½®çæ¹å¼è¦æ±"); |
| | | ErrorCode CAL_TEAM_SHIFT_GENERATE_SHIFT_NOT_ENOUGH = new ErrorCode(1_040_201_202, "çæ¬¡æ°é䏿»¡è¶³è½®çæ¹å¼è¦æ±"); |
| | | // ========== MES æ¥åæç-å工级æçæç»ï¼1-040-201-300ï¼ ========== |
| | | ErrorCode CAL_SCHEDULE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_201_300, "åå·¥æçæç»ä¸åå¨"); |
| | | ErrorCode CAL_SCHEDULE_DETAIL_GENERATE_TEAM_MEMBER_EMPTY = new ErrorCode(1_040_201_301, "该计ååä¸ççç»åæ çç»æåï¼æ æ³çæåå·¥æçæç»"); |
| | | |
| | | // ========== MES æ¥åæç-æç计åï¼1-040-202-000ï¼ ========== |
| | | ErrorCode CAL_PLAN_NOT_EXISTS = new ErrorCode(1_040_202_000, "æç计åä¸åå¨"); |
| | |
| | | ErrorCode DV_MACHINERY_HAS_MAINTEN_RECORD = new ErrorCode(1_040_301_005, "设å¤å·²å
³èä¿å
»è®°å½ï¼æ æ³å é¤"); |
| | | ErrorCode DV_MACHINERY_HAS_REPAIR = new ErrorCode(1_040_301_006, "设å¤å·²å
³è维修工åï¼æ æ³å é¤"); |
| | | ErrorCode DV_MACHINERY_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_301_008, "å·¥ä½ç«ç¼ç ä¸åå¨"); |
| | | ErrorCode DV_MACHINERY_HAS_ITEM = new ErrorCode(1_040_301_009, "设å¤å·²èªå¨çæç©æå¹¶å
¥è®¾å¤ä»ï¼ç¦æ¢å é¤ï¼å¦éç§»é¤è¯·éè¿åºåè°æ´å
å¤çåºå"); |
| | | ErrorCode DV_MACHINERY_EQUIP_MASTER_MISSING = new ErrorCode(1_040_301_010, "设å¤å
¥åºè卿éä¸»æ°æ®æªåå§åï¼è®¾å¤ä»æâ设å¤âåç±»/âå°â计éåä½ç¼ºå¤±ï¼ï¼è¯·è系管çååå§å"); |
| | | |
| | | // ========== MES 设å¤ç®¡ç-è®¾å¤æ°éï¼1-040-308-000ï¼ ========== |
| | | ErrorCode DV_TELEMETRY_NOT_EXISTS = new ErrorCode(1_040_308_000, "æ°é饿µæ°æ®ä¸åå¨"); |
| | |
| | | ErrorCode WM_STOCK_TAKING_PLAN_PARAM_NOT_EXISTS = new ErrorCode(1_040_714_104, "çç¹æ¹æ¡åæ°ä¸åå¨"); |
| | | ErrorCode WM_STOCK_TAKING_PLAN_PARAM_EMPTY = new ErrorCode(1_040_714_105, "çç¹æ¹æ¡åæ°ä¸è½ä¸ºç©ºï¼è¯·å
é
ç½®çç¹åæ°"); |
| | | ErrorCode WM_STOCK_TAKING_PLAN_DYNAMIC_TIME_INVALID = new ErrorCode(1_040_714_106, "卿çç¹æ¹æ¡å¿
须设置å¼å§æ¶é´åç»ææ¶é´ï¼ä¸ç»ææ¶é´å¿
é¡»æäºå¼å§æ¶é´"); |
| | | ErrorCode WM_STOCK_TAKING_PLAN_AUTO_GENERATE_CRON_REQUIRED = new ErrorCode(1_040_714_107, "å¼å¯å®æèªå¨çææ¶å¿
é¡»é
ç½®çæå¨æ cron 表达å¼"); |
| | | ErrorCode WM_STOCK_TAKING_PLAN_AUTO_GENERATE_CRON_INVALID = new ErrorCode(1_040_714_108, "çæå¨æ cron 表达å¼ä¸åæ³"); |
| | | ErrorCode WM_STOCK_TAKING_PLAN_NOT_AUTO_GENERATE = new ErrorCode(1_040_714_109, "该çç¹æ¹æ¡æªå¼å¯å®æèªå¨çæ"); |
| | | ErrorCode WM_STOCK_TAKING_TASK_NOT_EXISTS = new ErrorCode(1_040_714_110, "çç¹ä»»å¡ä¸åå¨"); |
| | | ErrorCode WM_STOCK_TAKING_TASK_CODE_DUPLICATE = new ErrorCode(1_040_714_111, "çç¹ä»»å¡ç¼ç å·²åå¨"); |
| | | ErrorCode WM_STOCK_TAKING_TASK_NOT_PREPARE = new ErrorCode(1_040_714_112, "åªæèç¨¿ç¶æççç¹ä»»å¡æå
è®¸æ¤æä½"); |
| | |
| | | ErrorCode WM_STOCK_TAKING_TASK_RESULT_NOT_EXISTS = new ErrorCode(1_040_714_119, "çç¹ç»æä¸åå¨"); |
| | | ErrorCode WM_STOCK_TAKING_TASK_LINE_ALREADY_TAKEN = new ErrorCode(1_040_714_120, "该çç¹æ¸
åè¡å·²æçç¹è®°å½ï¼ä¸è½éå¤çç¹"); |
| | | ErrorCode WM_STOCK_TAKING_TASK_NOT_FINISHED = new ErrorCode(1_040_714_121, "åªæå·²å®æç¶æççç¹ä»»å¡æè½å¤çå·®å¼"); |
| | | ErrorCode WM_STOCK_TAKING_TASK_NO_RESULT = new ErrorCode(1_040_714_122, "çç¹ä»»å¡è³å°éè¦ä¸æ¡çç¹ç»ææå
许æäº¤ç»æå®¡æ¹"); |
| | | ErrorCode WM_STOCK_TAKING_TASK_ALREADY_SUBMIT_APPROVAL = new ErrorCode(1_040_714_123, "çç¹ç»æå®¡æ¹å·²æäº¤ï¼è¯·å¿éå¤æäº¤"); |
| | | |
| | | // ========== MES ä»åºç®¡ç-éå®åºåºåï¼1-040-714-000ï¼ ========== |
| | | ErrorCode WM_PRODUCT_SALES_NOT_EXISTS = new ErrorCode(1_040_714_000, "éå®åºåºåä¸åå¨"); |
| | |
| | | ErrorCode BARCODE_BIZ_TYPE_NOT_EXISTS = new ErrorCode(1_040_731_003, "ä¸å¡ç±»åä¸è½ä¸ºç©º"); |
| | | ErrorCode BARCODE_BIZ_CODE_NOT_EXISTS = new ErrorCode(1_040_731_004, "ä¸å¡ç¼ç ä¸è½ä¸ºç©º"); |
| | | ErrorCode BARCODE_CONFIG_NOT_EXISTS = new ErrorCode(1_040_731_005, "æ¡ç é
ç½®ä¸åå¨"); |
| | | ErrorCode BARCODE_FORMAT_INVALID = new ErrorCode(1_040_731_006, "æ¡ç æ ¼å¼ä¸æ¯ææ¸²æ"); |
| | | ErrorCode BARCODE_CONTENT_EMPTY = new ErrorCode(1_040_731_007, "æ¡ç å
容ä¸è½ä¸ºç©º"); |
| | | |
| | | // ========== MES ä»åºç®¡ç-SN ç ï¼1-040-732-000ï¼ ========== |
| | | ErrorCode WM_SN_NOT_EXISTS = new ErrorCode(1_040_732_000, "SN ç ä¸åå¨"); |
| | | ErrorCode WM_SN_ITEM_NOT_SERIAL = new ErrorCode(1_040_732_001, "ç©ææªå¯ç¨åºåå·ç®¡çï¼æ æ³ç»è®° SN"); |
| | | ErrorCode WM_SN_ALREADY_IN_STOCK = new ErrorCode(1_040_732_002, "SN å·²å¨åºï¼è¯·å
åºåºåç»è®°å
¥åº"); |
| | | ErrorCode WM_SN_NOT_IN_STOCK = new ErrorCode(1_040_732_003, "SN ä¸å¨åºï¼æ æ³åºåº"); |
| | | ErrorCode WM_SN_ITEM_MISMATCH = new ErrorCode(1_040_732_004, "SN ä¸ç©æä¸å¹é
"); |
| | | ErrorCode WM_SN_LOCATION_MISMATCH = new ErrorCode(1_040_732_005, "SN ä¸å¨æå®åºä½å¨åºï¼æ æ³åºåº"); |
| | | |
| | | // ========== MES 设å¤å
¥åºåï¼1-040-733-000ï¼ ========== |
| | | ErrorCode WM_EQUIP_RECEIPT_NOT_EXISTS = new ErrorCode(1_040_733_000, "设å¤å
¥åºåä¸åå¨"); |
| | | ErrorCode WM_EQUIP_RECEIPT_CODE_DUPLICATE = new ErrorCode(1_040_733_001, "设å¤å
¥åºåç¼ç å·²åå¨"); |
| | | ErrorCode WM_EQUIP_RECEIPT_STATUS_NOT_PREPARE = new ErrorCode(1_040_733_002, "åªæèç¨¿ç¶ææå
è®¸æ¤æä½"); |
| | | ErrorCode WM_EQUIP_RECEIPT_STATUS_NOT_APPROVED = new ErrorCode(1_040_733_003, "åªæå·²å®¡æ¹ç¶ææå
许æ§è¡å
¥åº"); |
| | | ErrorCode WM_EQUIP_RECEIPT_NO_LINE = new ErrorCode(1_040_733_004, "è³å°éè¦ä¸æ¡è¡é¡¹ç®"); |
| | | ErrorCode WM_EQUIP_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_733_005, "已宿æå·²åæ¶çå
¥åºåä¸å
è®¸åæ¶"); |
| | | ErrorCode WM_EQUIP_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_733_100, "设å¤å
¥åºåè¡ä¸åå¨"); |
| | | ErrorCode WM_EQUIP_RECEIPT_MACHINERY_NOT_VALID = new ErrorCode(1_040_733_101, "æéè®¾å¤æªå
³èç©æï¼æ æ³å
¥åº"); |
| | | ErrorCode WM_EQUIP_RECEIPT_QUANTITY_INVALID = new ErrorCode(1_040_733_102, "å
¥åºæ°éå¿
é¡»å¤§äº 0"); |
| | | |
| | | // ========== MES ä»åºç®¡ç-è£
ç®±åï¼1-040-740-000ï¼ ========== |
| | | ErrorCode WM_PACKAGE_NOT_EXISTS = new ErrorCode(1_040_740_000, "è£
ç®±åä¸åå¨"); |
| | |
| | | // ========== DV è®¾å¤æ¨¡å [400, 500) ========== |
| | | |
| | | public static final int DV_MACHINERY = 400; // 设å¤ï¼MesDvMachineryDO |
| | | public static final int DV_EQUIPMENT_RECEIPT = 401; // 设å¤å
¥åºåï¼MesWmEquipmentReceiptDO |
| | | |
| | | // ========== TM å·¥è£
夹å
·æ¨¡å [500, 600) ========== |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.enums.cal; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * MES åå·¥æçæç»æ¥æºæä¸¾ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum MesCalScheduleDetailSourceEnum implements ArrayValuable<Integer> { |
| | | |
| | | AUTO(1, "èªå¨çæ"), |
| | | MANUAL(2, "äººå·¥è°æ´"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesCalScheduleDetailSourceEnum::getSource).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * æ¥æºå¼ |
| | | */ |
| | | private final Integer source; |
| | | /** |
| | | * æ¥æºå |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| | |
| | | WM_SALES_NOTICE_CODE("WM_SALES_NOTICE_CODE", "åè´§éç¥åç¼ç "), |
| | | WM_RETURN_SALES_CODE("WM_RETURN_SALES_CODE", "éå®éè´§åç¼ç "), |
| | | WM_MISC_ISSUE_CODE("WM_MISC_ISSUE_CODE", "æé¡¹åºåºåç¼ç "), |
| | | WM_EQUIP_RECEIPT_CODE("WM_EQUIP_RECEIPT_CODE", "设å¤å
¥åºåç¼ç "), |
| | | PRO_ROUTE_CODE("PRO_ROUTE_CODE", "å·¥èºè·¯çº¿ç¼ç "), |
| | | PRO_FEEDBACK_CODE("PRO_FEEDBACK_CODE", "ç产æ¥å·¥åç¼ç "), |
| | | PRO_WORK_ORDER_CODE("PRO_WORK_ORDER_CODE", "ç产工åç¼ç "), |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.enums.wm; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * MES 设å¤å
¥åºåç¶ææä¸¾ |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum MesWmEquipmentReceiptStatusEnum implements ArrayValuable<Integer> { |
| | | |
| | | /** |
| | | * è稿 |
| | | */ |
| | | PREPARE(MesOrderStatusConstants.PREPARE, "è稿"), |
| | | /** |
| | | * 审æ¹ä¸ |
| | | */ |
| | | APPROVING(MesOrderStatusConstants.APPROVING, "审æ¹ä¸"), |
| | | /** |
| | | * å·²å®¡æ¹ |
| | | */ |
| | | APPROVED(MesOrderStatusConstants.APPROVED, "已审æ¹"), |
| | | /** |
| | | * 已宿 |
| | | */ |
| | | FINISHED(MesOrderStatusConstants.FINISHED, "已宿"), |
| | | /** |
| | | * 已忶 |
| | | */ |
| | | CANCELED(MesOrderStatusConstants.CANCELLED, "已忶"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(MesWmEquipmentReceiptStatusEnum::getStatus).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * ç¶æå¼ |
| | | */ |
| | | private final Integer status; |
| | | /** |
| | | * ç¶æå |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.enums.wm; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * MES SN ç ç¶ææä¸¾ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum MesWmSnStatusEnum implements ArrayValuable<Integer> { |
| | | |
| | | IN_STOCK(1, "å¨åº"), |
| | | OUT_STOCK(2, "å·²åºåº"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmSnStatusEnum::getStatus).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * ç¶æå¼ |
| | | */ |
| | | private final Integer status; |
| | | /** |
| | | * ç¶æå |
| | | */ |
| | | private final String label; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| | |
| | | */ |
| | | PREPARE(MesOrderStatusConstants.PREPARE, "è稿"), |
| | | /** |
| | | * 审æ¹ä¸ |
| | | * çç¹ä¸ï¼å«çç¹ç»æå®¡æ¹ä¸ï¼ |
| | | * |
| | | * å¯¹åº MesWmStockTakingTaskService#submitStockTakingTask æ¹æ³ |
| | | * å¯¹åº MesWmStockTakingTaskService#submitStockTakingTask å¼å§çç¹ã |
| | | * #submitStockTakingResultApproval æäº¤ç»æå®¡æ¹ |
| | | */ |
| | | APPROVING(MesOrderStatusConstants.APPROVING, "审æ¹ä¸"), |
| | | APPROVING(MesOrderStatusConstants.APPROVING, "çç¹ä¸"), |
| | | /** |
| | | * 已宿 |
| | | * |
| | | * å¯¹åº MesWmStockTakingTaskService#finishStockTakingTask æ¹æ³ |
| | | * çç¹ç»æå®¡æ¹éè¿åï¼ç±ç»æå®¡æ¹åè°ç½®ä¸ºå·²å®æå¹¶èªå¨æ ¸éå·®å¼ |
| | | */ |
| | | FINISHED(MesOrderStatusConstants.FINISHED, "已宿"), |
| | | /** |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.job.wm; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; |
| | | import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.plan.MesWmStockTakingPlanDO; |
| | | import cn.iocoder.yudao.module.mes.service.wm.stocktaking.plan.MesWmStockTakingPlanService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.quartz.CronExpression; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneId; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES 宿çç¹èªå¨çæ Job |
| | | * |
| | | * <p>æ«æå¯ç¨ä¸å¼å¯å®æèªå¨çæççç¹æ¹æ¡ï¼æåæ¹æ¡é
ç½®ççæå¨æ cron 夿æ¯å¦å°æï¼ |
| | | * å°æåææ¹æ¡èªå¨å建çç¹ä»»å¡ï¼é¿å
人工éæå»ºåãåå°è°åº¦ cron 建议é
置为æ¯åéæ§è¡ä¸æ¬¡ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class MesWmStockTakingPlanAutoJob implements JobHandler { |
| | | |
| | | @Resource |
| | | private MesWmStockTakingPlanService stockTakingPlanService; |
| | | @Resource |
| | | private MesWmStockTakingTaskService stockTakingTaskService; |
| | | |
| | | @Override |
| | | @TenantJob |
| | | public String execute(String param) { |
| | | // 1. è·åå¯ç¨ä¸å¼å¯å®æèªå¨çæçæ¹æ¡ |
| | | List<MesWmStockTakingPlanDO> plans = stockTakingPlanService.getEnableAutoGeneratePlanList(); |
| | | if (CollUtil.isEmpty(plans)) { |
| | | return "宿çç¹ï¼æ å¯ç¨çèªå¨çææ¹æ¡ï¼è·³è¿"; |
| | | } |
| | | |
| | | // 2. éä¸ªæ¹æ¡å¤æå¨ææ¯å¦å°æï¼å°æåèªå¨çæä»»å¡ |
| | | Date now = new Date(); |
| | | int successCount = 0; |
| | | List<String> errors = new ArrayList<>(); |
| | | for (MesWmStockTakingPlanDO plan : plans) { |
| | | try { |
| | | if (shouldGenerate(plan, now)) { |
| | | Long taskId = stockTakingTaskService.createStockTakingTaskFromPlan(plan.getId()); |
| | | successCount++; |
| | | log.info("[execute] æ¹æ¡({}) èªå¨çæçç¹ä»»å¡({}) æå", plan.getId(), taskId); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("[execute] æ¹æ¡({}) èªå¨çæçç¹ä»»å¡å¤±è´¥", plan.getId(), e); |
| | | errors.add(String.format("æ¹æ¡[%s]ï¼%s", plan.getName(), e.toString())); |
| | | } |
| | | } |
| | | |
| | | // 3. æ±æ»æ§è¡ç»æ |
| | | String msg = String.format("宿çç¹ï¼æ«æ %s ä¸ªæ¹æ¡ï¼æ¬æ¬¡çæ %s 个任å¡", plans.size(), successCount); |
| | | if (CollUtil.isNotEmpty(errors)) { |
| | | msg += "ï¼å¤±è´¥æç»ï¼" + String.join("ï¼", errors); |
| | | } |
| | | return msg; |
| | | } |
| | | |
| | | /** |
| | | * å¤ææ¹æ¡å½å卿æ¯å¦å°æ |
| | | * |
| | | * <p>仿ªçæè¿åä»
è®°å½åºçº¿æ¶é´å¹¶ä»ä¸ä¸å¨æå¼å§è§¦åï¼åå¯ç¨ä¸ç«å³çæï¼ï¼ |
| | | * å¦åæã䏿¬¡çææ¶é´ + cronã计ç®ä¸ä¸æ¬¡è§¦åæ¶é´ï¼è½å¨å½åæ¶é´ä¹åå³ä¸ºå°æã |
| | | * |
| | | * @param plan çç¹æ¹æ¡ |
| | | * @param now å½åæ¶é´ |
| | | * @return æ¯å¦å°æ |
| | | */ |
| | | private boolean shouldGenerate(MesWmStockTakingPlanDO plan, Date now) { |
| | | CronExpression cron; |
| | | try { |
| | | cron = new CronExpression(plan.getGenerateCron()); |
| | | } catch (Exception e) { |
| | | log.warn("[shouldGenerate] æ¹æ¡({}) cron 表达å¼({}) ä¸åæ³ï¼è·³è¿", |
| | | plan.getId(), plan.getGenerateCron()); |
| | | return false; |
| | | } |
| | | LocalDateTime lastTime = plan.getLastGenerateTime(); |
| | | if (lastTime == null) { |
| | | // 馿¬¡æ«æï¼ä»
è®°å½åºçº¿æ¶é´ï¼ä¸ç«å³çæ |
| | | stockTakingPlanService.updateStockTakingPlanLastGenerateTime(plan.getId(), LocalDateTime.now()); |
| | | return false; |
| | | } |
| | | Date last = Date.from(lastTime.atZone(ZoneId.systemDefault()).toInstant()); |
| | | Date next = cron.getNextValidTimeAfter(last); |
| | | return next != null && !next.after(now); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.cal.schedule; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailCheckReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailCheckRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.schedule.MesCalScheduleDetailDO; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES å工级æçæç» Service æ¥å£ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface MesCalScheduleDetailService { |
| | | |
| | | /** |
| | | * æçç»æççæå工级æçæç»ï¼å¹çï¼å
æ¸
çè¯¥è®¡åæ§æç»åå±å¼çç»æåï¼ |
| | | * |
| | | * @param planId æç计åç¼å· |
| | | */ |
| | | void generateDetails(Long planId); |
| | | |
| | | /** |
| | | * è·å¾å工级æçæç»å页 |
| | | * |
| | | * @param reqVO æ¥è¯¢æ¡ä»¶ |
| | | * @return åé¡µç»æ |
| | | */ |
| | | PageResult<MesCalScheduleDetailDO> getDetailPage(MesCalScheduleDetailPageReqVO reqVO); |
| | | |
| | | /** |
| | | * è·å¾å工级æçæç»å表 |
| | | * |
| | | * @param reqVO æ¥è¯¢æ¡ä»¶ |
| | | * @return æç»å表 |
| | | */ |
| | | List<MesCalScheduleDetailDO> getDetailList(MesCalScheduleDetailPageReqVO reqVO); |
| | | |
| | | /** |
| | | * æ´æ°å工级æçæç»ï¼äººå·¥å¾®è°ï¼source 置为 2-äººå·¥è°æ´ï¼ |
| | | * |
| | | * @param updateReqVO æ´æ°ä¿¡æ¯ |
| | | */ |
| | | void updateDetail(MesCalScheduleDetailSaveReqVO updateReqVO); |
| | | |
| | | /** |
| | | * åå·¥æçåè§æ ¡éªï¼åæ¥è¿ç»å·¥æ¶è¶
é¿ãç¸é»ç次é´ä¼æ¯ä¸è¶³ï¼ |
| | | * |
| | | * @param reqVO æ ¡éªæ¡ä»¶ |
| | | * @return æ ¡éªç»æå表ï¼item.issue ä¸ºç©ºè¡¨ç¤ºè¯¥çæ¬¡åè§ |
| | | */ |
| | | List<MesCalScheduleDetailCheckRespVO> checkCompliance(MesCalScheduleDetailCheckReqVO reqVO); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.cal.schedule; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailCheckReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailCheckRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.cal.schedule.vo.MesCalScheduleDetailSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanShiftDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.schedule.MesCalScheduleDetailDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamMemberDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamShiftDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.cal.plan.MesCalPlanShiftMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.cal.schedule.MesCalScheduleDetailMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.cal.team.MesCalTeamMemberMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.cal.team.MesCalTeamShiftMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.cal.MesCalScheduleDetailSourceEnum; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.CAL_SCHEDULE_DETAIL_GENERATE_TEAM_MEMBER_EMPTY; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.CAL_SCHEDULE_DETAIL_NOT_EXISTS; |
| | | |
| | | /** |
| | | * MES å工级æçæç» Service å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class MesCalScheduleDetailServiceImpl implements MesCalScheduleDetailService { |
| | | |
| | | /** |
| | | * åè§æ ¡éªéå¼ï¼åççä¼¼è¿ç»å·¥æ¶ä¸éï¼å°æ¶ï¼ |
| | | */ |
| | | private static final long MAX_CONTINUOUS_WORK_HOURS = 12; |
| | | /** |
| | | * åè§æ ¡éªéå¼ï¼ç¸é»ç次æå°ä¼æ¯é´éï¼å°æ¶ï¼ |
| | | */ |
| | | private static final long MIN_REST_HOURS = 8; |
| | | private static final int MINUTES_PER_DAY = 24 * 60; |
| | | |
| | | @Resource |
| | | private MesCalScheduleDetailMapper scheduleDetailMapper; |
| | | @Resource |
| | | private MesCalTeamShiftMapper teamShiftMapper; |
| | | @Resource |
| | | private MesCalTeamMemberMapper teamMemberMapper; |
| | | @Resource |
| | | private MesCalPlanShiftMapper planShiftMapper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void generateDetails(Long planId) { |
| | | // 1. æ¥è¯¢è¯¥è®¡åä¸ççç»æçï¼çç» Ã æ¥æ Ã çæ¬¡ï¼ |
| | | List<MesCalTeamShiftDO> teamShifts = teamShiftMapper.selectListByPlanId(planId); |
| | | if (teamShifts.isEmpty()) { |
| | | scheduleDetailMapper.deleteByPlanId(planId); |
| | | throw exception(CAL_SCHEDULE_DETAIL_GENERATE_TEAM_MEMBER_EMPTY); |
| | | } |
| | | Set<Long> teamIds = teamShifts.stream().map(MesCalTeamShiftDO::getTeamId).collect(Collectors.toSet()); |
| | | // 2. å è½½çæ¬¡å®ä¹ï¼ç次åç§°/èµ·æ¢æ¶é´ï¼ä¸çç»æå |
| | | Map<Long, MesCalPlanShiftDO> shiftMap = planShiftMapper.selectListByPlanId(planId).stream() |
| | | .collect(Collectors.toMap(MesCalPlanShiftDO::getId, shift -> shift, (a, b) -> a)); |
| | | List<MesCalTeamMemberDO> members = teamMemberMapper.selectListByTeamIds(teamIds); |
| | | if (members.isEmpty()) { |
| | | scheduleDetailMapper.deleteByPlanId(planId); |
| | | throw exception(CAL_SCHEDULE_DETAIL_GENERATE_TEAM_MEMBER_EMPTY); |
| | | } |
| | | Map<Long, List<MesCalTeamMemberDO>> memberMap = members.stream() |
| | | .collect(Collectors.groupingBy(MesCalTeamMemberDO::getTeamId)); |
| | | // 3. å±å¼ä¸ºå工级æç»ï¼åå·¥ Ã æ¥æ Ã çæ¬¡ï¼ï¼å
æ¸
çæ§æ°æ®ä¿è¯å¹ç |
| | | scheduleDetailMapper.deleteByPlanId(planId); |
| | | List<MesCalScheduleDetailDO> details = new ArrayList<>(); |
| | | for (MesCalTeamShiftDO teamShift : teamShifts) { |
| | | MesCalPlanShiftDO shift = shiftMap.get(teamShift.getShiftId()); |
| | | if (shift == null) { |
| | | continue; |
| | | } |
| | | for (MesCalTeamMemberDO member : memberMap.getOrDefault(teamShift.getTeamId(), Collections.emptyList())) { |
| | | details.add(MesCalScheduleDetailDO.builder() |
| | | .planId(planId) |
| | | .teamId(teamShift.getTeamId()) |
| | | .userId(member.getUserId()) |
| | | .day(teamShift.getDay()) |
| | | .shiftId(teamShift.getShiftId()) |
| | | .shiftName(shift.getName()) |
| | | .startTime(shift.getStartTime()) |
| | | .endTime(shift.getEndTime()) |
| | | .source(MesCalScheduleDetailSourceEnum.AUTO.getSource()) |
| | | .build()); |
| | | } |
| | | } |
| | | if (!details.isEmpty()) { |
| | | scheduleDetailMapper.insertBatch(details); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<MesCalScheduleDetailDO> getDetailPage(MesCalScheduleDetailPageReqVO reqVO) { |
| | | return scheduleDetailMapper.selectPage(reqVO); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesCalScheduleDetailDO> getDetailList(MesCalScheduleDetailPageReqVO reqVO) { |
| | | return scheduleDetailMapper.selectList(reqVO); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateDetail(MesCalScheduleDetailSaveReqVO updateReqVO) { |
| | | MesCalScheduleDetailDO detail = scheduleDetailMapper.selectById(updateReqVO.getId()); |
| | | if (detail == null) { |
| | | throw exception(CAL_SCHEDULE_DETAIL_NOT_EXISTS); |
| | | } |
| | | MesCalScheduleDetailDO updateObj = MesCalScheduleDetailDO.builder() |
| | | .id(updateReqVO.getId()) |
| | | .shiftId(updateReqVO.getShiftId()) |
| | | .shiftName(updateReqVO.getShiftName()) |
| | | .startTime(updateReqVO.getStartTime()) |
| | | .endTime(updateReqVO.getEndTime()) |
| | | .remark(updateReqVO.getRemark()) |
| | | .source(MesCalScheduleDetailSourceEnum.MANUAL.getSource()) |
| | | .build(); |
| | | scheduleDetailMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesCalScheduleDetailCheckRespVO> checkCompliance(MesCalScheduleDetailCheckReqVO reqVO) { |
| | | List<MesCalScheduleDetailDO> details = |
| | | scheduleDetailMapper.selectListByUserIdBetween(reqVO.getUserId(), reqVO.getStartDay(), reqVO.getEndDay()); |
| | | List<MesCalScheduleDetailCheckRespVO> result = new ArrayList<>(); |
| | | for (int i = 0; i < details.size(); i++) { |
| | | MesCalScheduleDetailDO detail = details.get(i); |
| | | MesCalScheduleDetailCheckRespVO respVO = new MesCalScheduleDetailCheckRespVO(); |
| | | respVO.setDay(detail.getDay()); |
| | | respVO.setShiftName(detail.getShiftName()); |
| | | respVO.setStartTime(detail.getStartTime()); |
| | | respVO.setEndTime(detail.getEndTime()); |
| | | // æ ¡éª 1ï¼åççä¼¼è¿ç»å·¥æ¶è¶
é¿ |
| | | Long duration = shiftDurationMinutes(detail.getStartTime(), detail.getEndTime()); |
| | | if (duration != null && duration > MAX_CONTINUOUS_WORK_HOURS * 60) { |
| | | respVO.setIssueType(1); |
| | | respVO.setIssue("åççä¼¼è¿ç»å·¥æ¶è¶
é¿ï¼" + formatMinutes(duration) + "ï¼ï¼å¯è½è¿åè¿ç»å·¥æ¶ä¸é"); |
| | | } |
| | | // æ ¡éª 2ï¼ä¸åä¸ç次é´é伿¯ä¸è¶³ï¼ä»
å¨åä¸å¤©æç¸é»å¤©ææ¯è¾ï¼ |
| | | if (i > 0) { |
| | | MesCalScheduleDetailDO prev = details.get(i - 1); |
| | | Long rest = restMinutesBetween(prev, detail); |
| | | if (rest != null && rest < MIN_REST_HOURS * 60) { |
| | | respVO.setIssueType(2); |
| | | respVO.setIssue("ä¸åä¸ä¸ªç次é´éä»
" + formatMinutes(rest) + "ï¼ä¼æ¯æ¶é´ä¸è¶³"); |
| | | } |
| | | } |
| | | result.add(respVO); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 计ç®åçå·¥æ¶ï¼åéï¼ï¼è·¨åå¤ç次èªå¨+24hï¼æ¶é´æ ¼å¼éæ³æ¶è¿å null |
| | | */ |
| | | private Long shiftDurationMinutes(String startTime, String endTime) { |
| | | Integer start = toMinutes(startTime); |
| | | Integer end = toMinutes(endTime); |
| | | if (start == null || end == null) { |
| | | return null; |
| | | } |
| | | int duration = end - start; |
| | | if (duration < 0) { |
| | | duration += MINUTES_PER_DAY; |
| | | } |
| | | return (long) duration; |
| | | } |
| | | |
| | | /** |
| | | * 计ç®ç¸é»ä¸¤å¤©ç次ä¹é´ç伿¯é´éï¼åéï¼ï¼ |
| | | * çæ¬¡è¥è·¨åå¤ï¼ç»æåéæ°æè¶
è¿ MINUTES_PER_DAY 计ï¼å³ day + çæ¬¡æ¶é¿ï¼ï¼ |
| | | * ä¸ä¸ç次å¼å§åéææ°çä¸å¤©ï¼+MINUTES_PER_DAYï¼è®¡ã |
| | | */ |
| | | private Long restMinutesBetween(MesCalScheduleDetailDO prev, MesCalScheduleDetailDO next) { |
| | | Integer prevStart = toMinutes(prev.getStartTime()); |
| | | Integer prevEnd = toMinutes(prev.getEndTime()); |
| | | Integer nextStart = toMinutes(next.getStartTime()); |
| | | if (prevStart == null || prevEnd == null || nextStart == null) { |
| | | return null; |
| | | } |
| | | int prevDuration = prevEnd - prevStart; |
| | | if (prevDuration < 0) { |
| | | prevDuration += MINUTES_PER_DAY; |
| | | } |
| | | int prevEndMinutes = prevStart + prevDuration; // ç¸å¯¹ prev.day é¶ç¹ï¼å¯è½è¶
è¿ä¸å¤© |
| | | int nextStartMinutes = MINUTES_PER_DAY + nextStart; // ä¸ä¸çæ¬¡å¨æ°çä¸å¤© |
| | | return (long) (nextStartMinutes - prevEndMinutes); |
| | | } |
| | | |
| | | private Integer toMinutes(String time) { |
| | | if (time == null) { |
| | | return null; |
| | | } |
| | | String[] parts = time.split(":"); |
| | | if (parts.length != 2) { |
| | | return null; |
| | | } |
| | | try { |
| | | return Integer.parseInt(parts[0].trim()) * 60 + Integer.parseInt(parts[1].trim()); |
| | | } catch (NumberFormatException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | private String formatMinutes(long minutes) { |
| | | long hours = minutes / 60; |
| | | long mins = minutes % 60; |
| | | return mins == 0 ? hours + " å°æ¶" : hours + " å°æ¶ " + mins + " åé"; |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.enums.MdmItemTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.api.item.MesMdItemApi; |
| | | import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemSyncReqDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachinerySaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryTypeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkshopDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.dv.machinery.MesDvMachineryMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanMachineryService; |
| | | import cn.iocoder.yudao.module.mes.service.dv.checkrecord.MesDvCheckRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.dv.maintenrecord.MesDvMaintenRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.dv.repair.MesDvRepairService; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService; |
| | | import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; |
| | | import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkshopService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; |
| | | 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 java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | |
| | | @Service |
| | | @Validated |
| | | public class MesDvMachineryServiceImpl implements MesDvMachineryService { |
| | | |
| | | /** |
| | | * 设å¤èå¨ç©æçç±»åç¼ç ï¼mes_md_item_type / mdm_item_category ä¸â设å¤âè¡ç codeï¼ |
| | | */ |
| | | private static final String EQUIPMENT_ITEM_TYPE_CODE = "EQUIPMENT"; |
| | | /** |
| | | * 设å¤èå¨ç©æç计éåä½ç¼ç ï¼mes_md_unit_measure / mdm_unit_measure ä¸âå°âè¡ç codeï¼ |
| | | */ |
| | | private static final String EQUIPMENT_UNIT_CODE = "TAI"; |
| | | |
| | | @Resource |
| | | private MesDvMachineryMapper machineryMapper; |
| | |
| | | @Lazy |
| | | private MesDvRepairService repairService; |
| | | |
| | | // ========== 设å¤ç©æèå¨ä¾èµ ========== |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | @Resource |
| | | private MesMdItemApi mesMdItemApi; |
| | | @Resource |
| | | @Lazy |
| | | private MesMdItemTypeService mesMdItemTypeService; |
| | | @Resource |
| | | @Lazy |
| | | private MesMdUnitMeasureService mesMdUnitMeasureService; |
| | | @Resource |
| | | private MesWmTransactionService wmTransactionService; |
| | | @Resource |
| | | private MesWmWarehouseService wmWarehouseService; |
| | | @Resource |
| | | private MesWmWarehouseLocationService wmLocationService; |
| | | @Resource |
| | | private MesWmWarehouseAreaService wmAreaService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createMachinery(MesDvMachinerySaveReqVO createReqVO) { |
| | | // æ ¡éªè®¾å¤ç±»ååå¨ |
| | | machineryTypeService.getMachineryType(createReqVO.getMachineryTypeId()); |
| | |
| | | // æ ¡éªç¼ç å¯ä¸ |
| | | validateMachineryCodeUnique(null, createReqVO.getCode()); |
| | | |
| | | // æå
¥ |
| | | // åå»ºå¯¹åº MDM ç©æå¹¶åæ¥ MES ç©æï¼åä¸äºå¡ï¼å¤±è´¥æ´ä½åæ»ï¼ |
| | | Long itemId = createEquipmentMaterial(createReqVO.getCode(), createReqVO.getName(), |
| | | createReqVO.getSpecification(), createReqVO.getRemark()); |
| | | |
| | | // æå
¥è®¾å¤å°è´¦ |
| | | MesDvMachineryDO machinery = BeanUtils.toBean(createReqVO, MesDvMachineryDO.class); |
| | | machinery.setItemId(itemId); |
| | | machineryMapper.insert(machinery); |
| | | |
| | | // èªå¨çææ¡ç |
| | | barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.MACHINERY.getValue(), |
| | | machinery.getId(), machinery.getCode(), machinery.getName()); |
| | | // èªå¨å
¥è®¾å¤ä»ï¼åºå + æµæ°´ï¼ |
| | | createEquipmentStock(itemId, machinery.getId(), machinery.getCode()); |
| | | return machinery.getId(); |
| | | } |
| | | |
| | |
| | | public void updateMachinery(MesDvMachinerySaveReqVO updateReqVO) { |
| | | // æ ¡éªåå¨ |
| | | validateMachineryExists(updateReqVO.getId()); |
| | | MesDvMachineryDO existMachinery = machineryMapper.selectById(updateReqVO.getId()); |
| | | // æ ¡éªè®¾å¤ç±»ååå¨ |
| | | machineryTypeService.getMachineryType(updateReqVO.getMachineryTypeId()); |
| | | // æ ¡éªè½¦é´åå¨ |
| | |
| | | |
| | | // æ´æ° |
| | | MesDvMachineryDO updateObj = BeanUtils.toBean(updateReqVO, MesDvMachineryDO.class); |
| | | // ç©æå
³èç±å建æ¶èªå¨çæï¼æ´æ°ä¸å
许æ¸
空ï¼å端ä¹ä¸ä¼ å
¥ itemIdï¼ |
| | | updateObj.setItemId(existMachinery.getItemId()); |
| | | machineryMapper.updateById(updateObj); |
| | | } |
| | | |
| | |
| | | public void deleteMachinery(Long id) { |
| | | // æ ¡éªåå¨ |
| | | validateMachineryExists(id); |
| | | // æ ¡éªå·²çæç©æå¹¶å
¥è®¾å¤ä»ï¼é¿å
åºå/æµæ°´å¤±å»ä¸å¡ä¸»ä½ï¼ç¦æ¢å é¤ |
| | | MesDvMachineryDO machinery = machineryMapper.selectById(id); |
| | | if (machinery.getItemId() != null) { |
| | | throw exception(DV_MACHINERY_HAS_ITEM); |
| | | } |
| | | // æ ¡éªå
³èæ°æ® |
| | | if (checkPlanMachineryService.getCheckPlanMachineryCountByMachineryId(id) > 0) { |
| | | throw exception(DV_MACHINERY_HAS_CHECK_PLAN); |
| | |
| | | machinery.setMachineryTypeId(machineryType.getId()); |
| | | machinery.setWorkshopId(workshop.getId()); |
| | | machinery.setWorkstationId(workstationId); |
| | | // åå»ºå¯¹åº MDM ç©æå¹¶åæ¥ MES ç©æï¼åä¸äºå¡ï¼ |
| | | machinery.setItemId(createEquipmentMaterial(machinery.getCode(), machinery.getName(), |
| | | machinery.getSpecification(), machinery.getRemark())); |
| | | machineryMapper.insert(machinery); |
| | | // èªå¨çææ¡ç |
| | | barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.MACHINERY.getValue(), |
| | | machinery.getId(), machinery.getCode(), machinery.getName()); |
| | | // èªå¨å
¥è®¾å¤ä»ï¼åºå + æµæ°´ï¼ |
| | | createEquipmentStock(machinery.getItemId(), machinery.getId(), machinery.getCode()); |
| | | respVO.getCreateCodes().add(importItem.getCode()); |
| | | } else if (updateSupport) { |
| | | // 3.5.2 æ´æ° |
| | |
| | | updateObj.setMachineryTypeId(machineryType.getId()); |
| | | updateObj.setWorkshopId(workshop.getId()); |
| | | updateObj.setWorkstationId(workstationId); |
| | | // ç©æå
³èç±å建æ¶èªå¨çæï¼æ´æ°ä¸å
许æ¸
空 |
| | | updateObj.setItemId(existMachinery.getItemId()); |
| | | machineryMapper.updateById(updateObj); |
| | | respVO.getUpdateCodes().add(importItem.getCode()); |
| | | } else { |
| | |
| | | return respVO; |
| | | } |
| | | |
| | | /** |
| | | * å建设å¤å¯¹åºç©æï¼å
å¨ MDM å»ºä¸»æ°æ®ç©æï¼åæ¾å¼åæ¥ MES ç©æï¼ä¸¤å¥ä¸»æ°æ® id 对é½ï¼ã |
| | | * |
| | | * @return MDM ç©æç¼å·ï¼= MES ç©æç¼å·ï¼ |
| | | */ |
| | | private Long createEquipmentMaterial(String code, String name, String specification, String remark) { |
| | | // 1. è§£æâ设å¤âç±»åï¼MES ä¾§ï¼ä¸âå°âåä½ï¼MDM ä¾§ + MES ä¾§ï¼ï¼ç¼ºå¤±åæç¤ºä¸»æ°æ®æªåå§å |
| | | MesMdItemTypeDO itemType = mesMdItemTypeService.getItemTypeByCode(EQUIPMENT_ITEM_TYPE_CODE); |
| | | if (itemType == null) { |
| | | throw exception(DV_MACHINERY_EQUIP_MASTER_MISSING); |
| | | } |
| | | if (mesMdUnitMeasureService.getUnitMeasureByCode(EQUIPMENT_UNIT_CODE) == null) { |
| | | throw exception(DV_MACHINERY_EQUIP_MASTER_MISSING); |
| | | } |
| | | CommonResult<MdmUnitMeasureRespDTO> unitResult = mdmUnitMeasureApi.getUnitMeasureByCode(EQUIPMENT_UNIT_CODE); |
| | | MdmUnitMeasureRespDTO mdmUnit = unitResult.isSuccess() ? unitResult.getData() : null; |
| | | if (mdmUnit == null) { |
| | | throw exception(DV_MACHINERY_EQUIP_MASTER_MISSING); |
| | | } |
| | | |
| | | // 2. å建 MDM ç©æï¼å类使ç¨â设å¤âåç±»ï¼å
¶ id ä¸ MES ç±»å id 对é½ï¼ç±åå§åèæ¬ä¿è¯ï¼ |
| | | MdmItemCreateReqDTO createReqDTO = new MdmItemCreateReqDTO(); |
| | | createReqDTO.setCode(code); |
| | | createReqDTO.setName(name); |
| | | createReqDTO.setSpecification(specification); |
| | | createReqDTO.setRemark(remark); |
| | | createReqDTO.setCategoryId(itemType.getId()); |
| | | createReqDTO.setUnitMeasureId(mdmUnit.getId()); |
| | | createReqDTO.setItemType(MdmItemTypeEnum.EQUIPMENT.getType()); |
| | | createReqDTO.setStatus(0); |
| | | createReqDTO.setIsBatchManaged(false); |
| | | Long mdmItemId = mdmItemApi.createItem(createReqDTO).getCheckedData(); |
| | | |
| | | // 3. æ¾å¼åæ¥ MES ç©æï¼MdmItemCreateReqDTO æ syncMes å¼å
³ï¼ä¸ä¼èªå¨åæ¥ï¼ |
| | | MesMdItemSyncReqDTO syncReqDTO = new MesMdItemSyncReqDTO(); |
| | | syncReqDTO.setCode(code); |
| | | syncReqDTO.setName(name); |
| | | syncReqDTO.setSpecification(specification); |
| | | syncReqDTO.setRemark(remark); |
| | | syncReqDTO.setUnitCode(EQUIPMENT_UNIT_CODE); |
| | | syncReqDTO.setItemTypeCode(EQUIPMENT_ITEM_TYPE_CODE); |
| | | syncReqDTO.setBatchFlag(false); |
| | | syncReqDTO.setSafeStockFlag(false); |
| | | syncReqDTO.setStatus(0); |
| | | syncReqDTO.setMdmItemId(mdmItemId); |
| | | mesMdItemApi.createItem(syncReqDTO); |
| | | return mdmItemId; |
| | | } |
| | | |
| | | /** |
| | | * 设å¤èªå¨å
¥è®¾å¤ä»ï¼åå»ºä¸æ¡å
¥åºæ°é为 1 çåºåäºå¡ï¼ä»åº/åºåº/åºä½åç³»ç»å
置设å¤ä»ã |
| | | * åºåè¡ãæ°é䏿µæ°´ç»ä¸ç» {@link MesWmTransactionService}ï¼ç¦æ¢ç´æ¥ååºå表ã |
| | | */ |
| | | private void createEquipmentStock(Long itemId, Long machineryId, String machineryCode) { |
| | | MesWmWarehouseDO warehouse = wmWarehouseService.getWarehouseByCode(MesWmWarehouseDO.EQUIPMENT_WAREHOUSE); |
| | | MesWmWarehouseLocationDO location = wmLocationService.getWarehouseLocationByCode(MesWmWarehouseLocationDO.EQUIPMENT_LOCATION); |
| | | MesWmWarehouseAreaDO area = wmAreaService.getWarehouseAreaByCode(MesWmWarehouseAreaDO.EQUIPMENT_AREA); |
| | | if (warehouse == null || location == null || area == null) { |
| | | throw exception(DV_MACHINERY_EQUIP_MASTER_MISSING); |
| | | } |
| | | wmTransactionService.createTransaction(new MesWmTransactionSaveReqDTO() |
| | | .setType(MesWmTransactionTypeEnum.IN.getType()) |
| | | .setItemId(itemId) |
| | | .setQuantity(BigDecimal.ONE) |
| | | .setWarehouseId(warehouse.getId()) |
| | | .setLocationId(location.getId()) |
| | | .setAreaId(area.getId()) |
| | | .setBizType(MesBizTypeConstants.DV_MACHINERY) |
| | | .setBizId(machineryId) |
| | | .setBizCode(machineryCode) |
| | | .setBizLineId(machineryId)); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.barcode.MesWmBarcodeConfigDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES æ¡ç é
ç½® Service æ¥å£ |
| | | * |
| | |
| | | */ |
| | | MesWmBarcodeConfigDO validateBarcodeConfigByBizType(Integer bizType); |
| | | |
| | | /** |
| | | * è·åå¯ç¨ç¶æçæ¡ç é
ç½®å表ï¼ç¨äºæ«ç è§£ææ¶åæ¥æ¨¡æ¿ï¼ |
| | | * |
| | | * @return å¯ç¨ç¶æçæ¡ç é
ç½®å表 |
| | | */ |
| | | List<MesWmBarcodeConfigDO> getEnableBarcodeConfigList(); |
| | | |
| | | } |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | | |
| | |
| | | return config; |
| | | } |
| | | |
| | | @Override |
| | | public List<MesWmBarcodeConfigDO> getEnableBarcodeConfigList() { |
| | | return barcodeConfigMapper.selectEnableList(); |
| | | } |
| | | |
| | | } |
| | |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * MES æ¡ç æ¸
å Service æ¥å£ |
| | |
| | | * |
| | | * @param bizType ä¸å¡ç±»å |
| | | * @param bizCode ä¸å¡ç¼ç |
| | | * @param bizName ä¸å¡åç§° |
| | | * @return çæçæ¡ç å
容 |
| | | */ |
| | | String generateBarcodeContent(Integer bizType, String bizCode); |
| | | String generateBarcodeContent(Integer bizType, String bizCode, String bizName); |
| | | |
| | | /** |
| | | * æ¸²ææ¡ç /äºç»´ç å¾çï¼æå¡ç«¯ zxing æå¾ï¼å³æ¶é¢è§ç¨ Base64ï¼ |
| | | * |
| | | * @param content æ¡ç å
容 |
| | | * @param format æ¡ç æ ¼å¼ {@link cn.iocoder.yudao.module.mes.enums.wm.BarcodeFormatEnum} |
| | | * @param width å¾ç宽度 |
| | | * @param height å¾çé«åº¦ |
| | | * @return PNG å¾ç Base64 data-URL |
| | | */ |
| | | String renderBarcodeImage(String content, Integer format, Integer width, Integer height); |
| | | |
| | | /** |
| | | * è§£ææ¡ç å
å®¹ï¼æå¡ç«¯æ«ç è§£æï¼ |
| | | * |
| | | * <p>ä¼å
ææ¡ç å
容精确å½ä¸å·²ææ¡ç è®°å½ï¼è¿åä¸å¡å¯¹è±¡ä¿¡æ¯ï¼ |
| | | * å¦åéåå¯ç¨ç¶æçæ¡ç é
ç½®ï¼æ contentFormat 模æ¿åè§£åºåå ä½ç¬¦å段ã |
| | | * |
| | | * @param content æ«æå°çæ¡ç å
容 |
| | | * @return è§£æç»æï¼matched/bizType/bizCode çåæ®µï¼ |
| | | */ |
| | | Map<String, Object> parseBarcodeContent(String content); |
| | | |
| | | /** |
| | | * æ ¹æ®æ¡ç é
ç½®ç¼å·è·åç¸å
³èçæ¡ç æ°é |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.barcode; |
| | | |
| | | import cn.hutool.core.codec.Base64; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.barcode.MesWmBarcodeConfigDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.barcode.MesWmBarcodeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.barcode.MesWmBarcodeMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.BarcodeFormatEnum; |
| | | import com.google.zxing.BarcodeFormat; |
| | | import com.google.zxing.MultiFormatWriter; |
| | | import com.google.zxing.client.j2se.MatrixToImageWriter; |
| | | import com.google.zxing.common.BitMatrix; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class MesWmBarcodeServiceImpl implements MesWmBarcodeService { |
| | | |
| | | /** |
| | | * å
å®¹æ ¼å¼æ¨¡æ¿ä¸çå ä½ç¬¦è¯å«æ£å |
| | | */ |
| | | private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\{[A-Za-z0-9_]+\\}"); |
| | | |
| | | @Resource |
| | | private MesWmBarcodeMapper barcodeMapper; |
| | |
| | | |
| | | // 2. çææ¡ç å
容ï¼å¹¶æ ¡éªå¯ä¸æ§ |
| | | String content = generateAndValidateContent(createReqVO.getId(), |
| | | createReqVO.getContent(), config.getContentFormat(), createReqVO.getBizCode()); |
| | | createReqVO.getContent(), config.getContentFormat(), createReqVO.getBizCode(), |
| | | createReqVO.getBizName()); |
| | | |
| | | // 3. ä¿åæ¡ç è®°å½ |
| | | MesWmBarcodeDO barcode = BeanUtils.toBean(createReqVO, MesWmBarcodeDO.class).setContent(content) |
| | |
| | | } |
| | | |
| | | @Override |
| | | public String generateBarcodeContent(Integer bizType, String bizCode) { |
| | | public String generateBarcodeContent(Integer bizType, String bizCode, String bizName) { |
| | | // 1.1 æ ¡éªåæ° |
| | | if (bizType == null) { |
| | | throw exception(BARCODE_BIZ_TYPE_NOT_EXISTS); |
| | |
| | | MesWmBarcodeConfigDO config = barcodeConfigService.validateBarcodeConfigByBizType(bizType); |
| | | |
| | | // 2. çææ¡ç å
容 |
| | | return generateBarcodeContent(config.getContentFormat(), bizCode); |
| | | return generateBarcodeContent(config.getContentFormat(), bizCode, bizName); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | // 2. çææ¡ç å
容ï¼å¹¶æ ¡éªå¯ä¸æ§ |
| | | String content = generateAndValidateContent(updateReqVO.getId(), |
| | | updateReqVO.getContent(), config.getContentFormat(), updateReqVO.getBizCode()); |
| | | updateReqVO.getContent(), config.getContentFormat(), updateReqVO.getBizCode(), |
| | | updateReqVO.getBizName()); |
| | | |
| | | // 3. æ´æ°ï¼å·æ° configId å formatï¼ç¡®ä¿ä¸ææ°é
ç½®ä¸è´ï¼ |
| | | MesWmBarcodeDO updateObj = BeanUtils.toBean(updateReqVO, MesWmBarcodeDO.class) |
| | |
| | | * @param bizCode ä¸å¡ç¼ç |
| | | * @return æç»æ¡ç å
容 |
| | | */ |
| | | private String generateAndValidateContent(Long id, String content, String contentFormat, String bizCode) { |
| | | private String generateAndValidateContent(Long id, String content, String contentFormat, String bizCode, String bizName) { |
| | | // 1. 妿å端æªä¼ éå
容ï¼åèªå¨çæ |
| | | if (StrUtil.isBlank(content)) { |
| | | content = generateBarcodeContent(contentFormat, bizCode); |
| | | content = generateBarcodeContent(contentFormat, bizCode, bizName); |
| | | } |
| | | // 2. æ ¡éªæ¡ç å
容å¯ä¸æ§ï¼æé¤èªèº«ï¼ |
| | | if (StrUtil.isNotBlank(content)) { |
| | |
| | | * |
| | | * @param contentFormat å
å®¹æ ¼å¼æ¨¡æ¿ |
| | | * @param bizCode ä¸å¡ç¼ç |
| | | * @param bizName ä¸å¡åç§° |
| | | * @return æ¡ç å
容 |
| | | */ |
| | | private String generateBarcodeContent(String contentFormat, String bizCode) { |
| | | private String generateBarcodeContent(String contentFormat, String bizCode, String bizName) { |
| | | if (StrUtil.isBlank(contentFormat)) { |
| | | return bizCode; |
| | | } |
| | | return contentFormat.replace(MesWmBarcodeConfigDO.PLACEHOLDER_BUSINESS_CODE, bizCode); |
| | | // 1. æ¿æ¢å·²æ¯æçå ä½ç¬¦ |
| | | String content = contentFormat |
| | | .replace(MesWmBarcodeConfigDO.PLACEHOLDER_BUSINESS_CODE, StrUtil.nullToEmpty(bizCode)) |
| | | .replace(MesWmBarcodeConfigDO.PLACEHOLDER_BUSINESS_NAME, StrUtil.nullToEmpty(bizName)); |
| | | // 2. æ¸
空模æ¿ä¸å
¶å®æªå¡«å
çæªç¥å ä½ç¬¦ï¼é¿å
{XXX} æ®ç影快ç |
| | | return PLACEHOLDER_PATTERN.matcher(content).replaceAll(""); |
| | | } |
| | | |
| | | @Override |
| | | public String renderBarcodeImage(String content, Integer format, Integer width, Integer height) { |
| | | if (StrUtil.isBlank(content)) { |
| | | throw exception(BARCODE_CONTENT_EMPTY); |
| | | } |
| | | int w = width != null && width > 0 ? width : 200; |
| | | int h = height != null && height > 0 ? height : 200; |
| | | try { |
| | | BitMatrix bitMatrix = new MultiFormatWriter().encode(content, toZxingFormat(format), w, h); |
| | | BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix); |
| | | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| | | ImageIO.write(image, "png", out); |
| | | return "data:image/png;base64," + Base64.encode(out.toByteArray()); |
| | | } catch (Exception e) { |
| | | log.error("[renderBarcodeImage] æ¡ç 渲æå¤±è´¥ï¼content={}, format={}", content, format, e); |
| | | throw new RuntimeException("æ¡ç 渲æå¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å°é¡¹ç®æ¡ç æ ¼å¼æä¸¾å¼æ å°ä¸º zxing æ¡ç æ ¼å¼ |
| | | * |
| | | * @param format é¡¹ç®æ¡ç æ ¼å¼ {@link BarcodeFormatEnum} |
| | | * @return zxing æ¡ç æ ¼å¼ |
| | | */ |
| | | private BarcodeFormat toZxingFormat(Integer format) { |
| | | if (format == null) { |
| | | return BarcodeFormat.CODE_128; |
| | | } |
| | | switch (format) { |
| | | case 1: // BarcodeFormatEnum.QR_CODE |
| | | return BarcodeFormat.QR_CODE; |
| | | case 2: // BarcodeFormatEnum.EAN13 |
| | | return BarcodeFormat.EAN_13; |
| | | case 3: // BarcodeFormatEnum.CODE39 |
| | | return BarcodeFormat.CODE_39; |
| | | case 4: // BarcodeFormatEnum.UPC_A |
| | | return BarcodeFormat.UPC_A; |
| | | default: |
| | | throw exception(BARCODE_FORMAT_INVALID); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> parseBarcodeContent(String content) { |
| | | if (StrUtil.isBlank(content)) { |
| | | throw exception(BARCODE_CONTENT_EMPTY); |
| | | } |
| | | // 1. ä¼å
ææ¡ç å
容精确å½ä¸å·²ææ¡ç è®°å½ |
| | | MesWmBarcodeDO barcode = barcodeMapper.selectByContent(content); |
| | | if (barcode != null) { |
| | | Map<String, Object> result = new LinkedHashMap<>(); |
| | | result.put("matched", true); |
| | | result.put("barcodeId", barcode.getId()); |
| | | result.put("configId", barcode.getConfigId()); |
| | | result.put("format", barcode.getFormat()); |
| | | result.put("bizType", barcode.getBizType()); |
| | | result.put("bizId", barcode.getBizId()); |
| | | result.put("bizCode", barcode.getBizCode()); |
| | | result.put("bizName", barcode.getBizName()); |
| | | result.put("content", barcode.getContent()); |
| | | return result; |
| | | } |
| | | // 2. æªå½ä¸æ¶ï¼éåå¯ç¨ç¶æçé
ç½®æå
å®¹æ ¼å¼æ¨¡æ¿åè§£ |
| | | List<MesWmBarcodeConfigDO> configs = barcodeConfigService.getEnableBarcodeConfigList(); |
| | | for (MesWmBarcodeConfigDO config : configs) { |
| | | Map<String, Object> fields = matchByTemplate(config.getContentFormat(), content); |
| | | if (fields != null) { |
| | | Map<String, Object> result = new LinkedHashMap<>(); |
| | | result.put("matched", false); |
| | | result.put("configId", config.getId()); |
| | | result.put("format", config.getFormat()); |
| | | result.put("bizType", config.getBizType()); |
| | | result.put("bizCode", fields.get(MesWmBarcodeConfigDO.PLACEHOLDER_BUSINESS_CODE)); |
| | | result.put("bizName", fields.get(MesWmBarcodeConfigDO.PLACEHOLDER_BUSINESS_NAME)); |
| | | result.put("fields", fields); |
| | | return result; |
| | | } |
| | | } |
| | | // 3. åæªå½ä¸ |
| | | Map<String, Object> result = new LinkedHashMap<>(); |
| | | result.put("matched", false); |
| | | result.put("content", content); |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * æå
å®¹æ ¼å¼æ¨¡æ¿åè§£æ¡ç å
容 |
| | | * |
| | | * @param contentFormat å
å®¹æ ¼å¼æ¨¡æ¿ |
| | | * @param content å¾
è§£æçæ¡ç å
容 |
| | | * @return å ä½ç¬¦ -> å®é
å¼çæ å°ï¼ä¸å¹é
è¿å null |
| | | */ |
| | | private Map<String, Object> matchByTemplate(String contentFormat, String content) { |
| | | if (StrUtil.isBlank(contentFormat) || !contentFormat.contains("{")) { |
| | | return null; |
| | | } |
| | | // 1. å°æ¨¡æ¿è½¬ä¸ºæ£åï¼åé¢é转ä¹ï¼å ä½ç¬¦è½¬ä¸ºæè·ç» |
| | | List<String> placeholders = new ArrayList<>(); |
| | | StringBuilder regexSb = new StringBuilder(); |
| | | Matcher matcher = PLACEHOLDER_PATTERN.matcher(contentFormat); |
| | | int lastEnd = 0; |
| | | while (matcher.find()) { |
| | | regexSb.append(Pattern.quote(contentFormat.substring(lastEnd, matcher.start()))); |
| | | placeholders.add(matcher.group()); |
| | | regexSb.append("(.+?)"); |
| | | lastEnd = matcher.end(); |
| | | } |
| | | if (placeholders.isEmpty()) { |
| | | return null; |
| | | } |
| | | regexSb.append(Pattern.quote(contentFormat.substring(lastEnd))); |
| | | |
| | | // 2. å
¨éå¹é
å¹¶æååå ä½ç¬¦å¼ |
| | | Matcher contentMatcher = Pattern.compile(regexSb.toString()).matcher(content); |
| | | if (!contentMatcher.matches()) { |
| | | return null; |
| | | } |
| | | Map<String, Object> fields = new LinkedHashMap<>(); |
| | | for (int i = 0; i < placeholders.size(); i++) { |
| | | fields.put(placeholders.get(i), contentMatcher.group(i + 1)); |
| | | } |
| | | return fields; |
| | | } |
| | | |
| | | @Override |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line.MesWmEquipmentReceiptLinePageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line.MesWmEquipmentReceiptLineSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptLineDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES 设å¤å
¥åºåè¡ Service æ¥å£ |
| | | */ |
| | | public interface MesWmEquipmentReceiptLineService { |
| | | |
| | | /** |
| | | * å建设å¤å
¥åºåè¡ |
| | | */ |
| | | Long createEquipmentReceiptLine(@Valid MesWmEquipmentReceiptLineSaveReqVO createReqVO); |
| | | |
| | | /** |
| | | * æ´æ°è®¾å¤å
¥åºåè¡ |
| | | */ |
| | | void updateEquipmentReceiptLine(@Valid MesWmEquipmentReceiptLineSaveReqVO updateReqVO); |
| | | |
| | | /** |
| | | * å é¤è®¾å¤å
¥åºåè¡ |
| | | */ |
| | | void deleteEquipmentReceiptLine(Long id); |
| | | |
| | | /** |
| | | * æå
¥åºåç¼å·å é¤è¡ï¼çº§èå é¤ï¼ |
| | | */ |
| | | void deleteByReceiptId(Long receiptId); |
| | | |
| | | /** |
| | | * è·å¾è®¾å¤å
¥åºåè¡ |
| | | */ |
| | | MesWmEquipmentReceiptLineDO getEquipmentReceiptLine(Long id); |
| | | |
| | | /** |
| | | * æå
¥åºåç¼å·è·å¾è¡å表 |
| | | */ |
| | | List<MesWmEquipmentReceiptLineDO> getEquipmentReceiptLineListByReceiptId(Long receiptId); |
| | | |
| | | /** |
| | | * è·å¾è®¾å¤å
¥åºåè¡å页 |
| | | */ |
| | | PageResult<MesWmEquipmentReceiptLineDO> getEquipmentReceiptLinePage(MesWmEquipmentReceiptLinePageReqVO pageReqVO); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt; |
| | | |
| | | import cn.hutool.core.util.ObjUtil; |
| | | 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.equipmentreceipt.vo.line.MesWmEquipmentReceiptLinePageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.line.MesWmEquipmentReceiptLineSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptLineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.equipmentreceipt.MesWmEquipmentReceiptLineMapper; |
| | | import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService; |
| | | 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.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * MES 设å¤å
¥åºåè¡ Service å®ç°ç±» |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class MesWmEquipmentReceiptLineServiceImpl implements MesWmEquipmentReceiptLineService { |
| | | |
| | | @Resource |
| | | private MesWmEquipmentReceiptLineMapper equipmentReceiptLineMapper; |
| | | @Resource |
| | | private MesDvMachineryService machineryService; |
| | | @Resource |
| | | @Lazy |
| | | private MesWmEquipmentReceiptService equipmentReceiptService; |
| | | |
| | | @Override |
| | | public Long createEquipmentReceiptLine(MesWmEquipmentReceiptLineSaveReqVO createReqVO) { |
| | | // æ ¡éªå
¥åºåå¯ç¼è¾ |
| | | equipmentReceiptService.validateEquipmentReceiptEditable(createReqVO.getReceiptId()); |
| | | // æ ¡éªè®¾å¤åå¨ä¸å·²å
³èç©æ |
| | | validateMachineryHasItem(createReqVO.getMachineryId()); |
| | | // æ ¡éªæ°é |
| | | validateQuantity(createReqVO.getQuantity()); |
| | | |
| | | MesWmEquipmentReceiptLineDO line = BeanUtils.toBean(createReqVO, MesWmEquipmentReceiptLineDO.class); |
| | | equipmentReceiptLineMapper.insert(line); |
| | | return line.getId(); |
| | | } |
| | | |
| | | @Override |
| | | public void updateEquipmentReceiptLine(MesWmEquipmentReceiptLineSaveReqVO updateReqVO) { |
| | | // æ ¡éªè¡åå¨ |
| | | validateEquipmentReceiptLineExists(updateReqVO.getId()); |
| | | // æ ¡éªå
¥åºåå¯ç¼è¾ |
| | | equipmentReceiptService.validateEquipmentReceiptEditable(updateReqVO.getReceiptId()); |
| | | // æ ¡éªè®¾å¤åå¨ä¸å·²å
³èç©æ |
| | | validateMachineryHasItem(updateReqVO.getMachineryId()); |
| | | // æ ¡éªæ°é |
| | | validateQuantity(updateReqVO.getQuantity()); |
| | | |
| | | MesWmEquipmentReceiptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmEquipmentReceiptLineDO.class); |
| | | equipmentReceiptLineMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteEquipmentReceiptLine(Long id) { |
| | | // æ ¡éªè¡åå¨ |
| | | MesWmEquipmentReceiptLineDO line = validateEquipmentReceiptLineExists(id); |
| | | // æ ¡éªå
¥åºåå¯ç¼è¾ |
| | | equipmentReceiptService.validateEquipmentReceiptEditable(line.getReceiptId()); |
| | | |
| | | equipmentReceiptLineMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteByReceiptId(Long receiptId) { |
| | | equipmentReceiptLineMapper.delete(MesWmEquipmentReceiptLineDO::getReceiptId, receiptId); |
| | | } |
| | | |
| | | @Override |
| | | public MesWmEquipmentReceiptLineDO getEquipmentReceiptLine(Long id) { |
| | | return equipmentReceiptLineMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesWmEquipmentReceiptLineDO> getEquipmentReceiptLineListByReceiptId(Long receiptId) { |
| | | return equipmentReceiptLineMapper.selectListByReceiptId(receiptId); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<MesWmEquipmentReceiptLineDO> getEquipmentReceiptLinePage(MesWmEquipmentReceiptLinePageReqVO pageReqVO) { |
| | | return equipmentReceiptLineMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | private MesWmEquipmentReceiptLineDO validateEquipmentReceiptLineExists(Long id) { |
| | | MesWmEquipmentReceiptLineDO line = equipmentReceiptLineMapper.selectById(id); |
| | | if (line == null) { |
| | | throw exception(WM_EQUIP_RECEIPT_LINE_NOT_EXISTS); |
| | | } |
| | | return line; |
| | | } |
| | | |
| | | private void validateMachineryHasItem(Long machineryId) { |
| | | machineryService.validateMachineryExists(machineryId); |
| | | MesDvMachineryDO machinery = machineryService.getMachinery(machineryId); |
| | | if (machinery == null || machinery.getItemId() == null) { |
| | | throw exception(WM_EQUIP_RECEIPT_MACHINERY_NOT_VALID); |
| | | } |
| | | } |
| | | |
| | | private void validateQuantity(BigDecimal quantity) { |
| | | if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw exception(WM_EQUIP_RECEIPT_QUANTITY_INVALID); |
| | | } |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.MesWmEquipmentReceiptPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.MesWmEquipmentReceiptSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface MesWmEquipmentReceiptService { |
| | | |
| | | String APPROVE_CATEGORY_CODE = "equipment_receipt_approve"; |
| | | |
| | | Long createEquipmentReceipt(@Valid MesWmEquipmentReceiptSaveReqVO createReqVO); |
| | | |
| | | void updateEquipmentReceipt(@Valid MesWmEquipmentReceiptSaveReqVO updateReqVO); |
| | | |
| | | void deleteEquipmentReceipt(Long id); |
| | | |
| | | MesWmEquipmentReceiptDO getEquipmentReceipt(Long id); |
| | | |
| | | PageResult<MesWmEquipmentReceiptDO> getEquipmentReceiptPage(MesWmEquipmentReceiptPageReqVO pageReqVO); |
| | | |
| | | void submitEquipmentReceiptApproval(Long id, String processDefinitionKey); |
| | | |
| | | void updateEquipmentReceiptAuditStatus(Long id, Integer bpmResult); |
| | | |
| | | List<Map<String, Object>> getEquipmentReceiptApprovalProcessDefinitionList(); |
| | | |
| | | void finishEquipmentReceipt(Long id); |
| | | |
| | | void cancelEquipmentReceipt(Long id); |
| | | |
| | | MesWmEquipmentReceiptDO validateEquipmentReceiptExists(Long id); |
| | | |
| | | void validateEquipmentReceiptEditable(Long id); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | 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.dal.dataobject.definition.BpmProcessDefinitionInfoDO; |
| | | import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.MesWmEquipmentReceiptPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.MesWmEquipmentReceiptSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptLineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.equipmentreceipt.MesWmEquipmentReceiptMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmEquipmentReceiptStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | |
| | | 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.module.mes.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * MES 设å¤å
¥åºå Service å®ç°ç±» |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class MesWmEquipmentReceiptServiceImpl implements MesWmEquipmentReceiptService { |
| | | |
| | | @Resource |
| | | private MesWmEquipmentReceiptMapper equipmentReceiptMapper; |
| | | @Resource |
| | | @Lazy |
| | | private MesWmEquipmentReceiptLineService equipmentReceiptLineService; |
| | | @Resource |
| | | private MesWmTransactionService wmTransactionService; |
| | | @Resource |
| | | private MesWmWarehouseService wmWarehouseService; |
| | | @Resource |
| | | private MesWmWarehouseLocationService wmLocationService; |
| | | @Resource |
| | | private MesWmWarehouseAreaService wmAreaService; |
| | | @Resource |
| | | private BpmProcessInstanceApi processInstanceApi; |
| | | @Resource |
| | | private BpmProcessDefinitionService bpmProcessDefinitionService; |
| | | |
| | | @Override |
| | | public Long createEquipmentReceipt(MesWmEquipmentReceiptSaveReqVO createReqVO) { |
| | | // æ ¡éªç¼ç å¯ä¸ |
| | | validateCodeUnique(null, createReqVO.getCode()); |
| | | |
| | | MesWmEquipmentReceiptDO receipt = BeanUtils.toBean(createReqVO, MesWmEquipmentReceiptDO.class); |
| | | receipt.setStatus(MesWmEquipmentReceiptStatusEnum.PREPARE.getStatus()); |
| | | equipmentReceiptMapper.insert(receipt); |
| | | return receipt.getId(); |
| | | } |
| | | |
| | | @Override |
| | | public void updateEquipmentReceipt(MesWmEquipmentReceiptSaveReqVO updateReqVO) { |
| | | // æ ¡éªåå¨ + èç¨¿ç¶æ |
| | | validateEquipmentReceiptExistsAndPrepare(updateReqVO.getId()); |
| | | // æ ¡éªç¼ç å¯ä¸ |
| | | validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); |
| | | |
| | | MesWmEquipmentReceiptDO updateObj = BeanUtils.toBean(updateReqVO, MesWmEquipmentReceiptDO.class); |
| | | equipmentReceiptMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteEquipmentReceipt(Long id) { |
| | | // æ ¡éªåå¨ + èç¨¿ç¶æ |
| | | validateEquipmentReceiptExistsAndPrepare(id); |
| | | |
| | | // 级èå é¤è¡ |
| | | equipmentReceiptLineService.deleteByReceiptId(id); |
| | | // å é¤ä¸»è¡¨ |
| | | equipmentReceiptMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | | public MesWmEquipmentReceiptDO getEquipmentReceipt(Long id) { |
| | | return equipmentReceiptMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<MesWmEquipmentReceiptDO> getEquipmentReceiptPage(MesWmEquipmentReceiptPageReqVO pageReqVO) { |
| | | return equipmentReceiptMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void submitEquipmentReceiptApproval(Long id, String processDefinitionKey) { |
| | | // æ ¡éªåå¨ + èç¨¿ç¶æ |
| | | validateEquipmentReceiptExistsAndPrepare(id); |
| | | // æ ¡éªè³å°æä¸æ¡è¡ |
| | | List<MesWmEquipmentReceiptLineDO> lines = equipmentReceiptLineService.getEquipmentReceiptLineListByReceiptId(id); |
| | | if (CollUtil.isEmpty(lines)) { |
| | | throw exception(WM_EQUIP_RECEIPT_NO_LINE); |
| | | } |
| | | // å建 BPM æµç¨å®ä¾ |
| | | String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(), |
| | | new BpmProcessInstanceCreateReqDTO() |
| | | .setProcessDefinitionKey(processDefinitionKey) |
| | | .setBusinessKey(String.valueOf(id))); |
| | | // æäº¤å®¡æ¹ï¼è稿 â 审æ¹ä¸ï¼ |
| | | equipmentReceiptMapper.updateById(new MesWmEquipmentReceiptDO() |
| | | .setId(id) |
| | | .setStatus(MesWmEquipmentReceiptStatusEnum.APPROVING.getStatus()) |
| | | .setProcessInstanceId(processInstanceId)); |
| | | } |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> getEquipmentReceiptApprovalProcessDefinitionList() { |
| | | return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateEquipmentReceiptAuditStatus(Long id, Integer bpmResult) { |
| | | // 1. æ ¡éªåå¨ |
| | | MesWmEquipmentReceiptDO receipt = validateEquipmentReceiptExists(id); |
| | | if (!MesWmEquipmentReceiptStatusEnum.APPROVING.getStatus().equals(receipt.getStatus())) { |
| | | log.warn("[updateEquipmentReceiptAuditStatus] 设å¤å
¥åºå({}) ä¸å¤äºå®¡æ¹ä¸ç¶æ", id); |
| | | return; |
| | | } |
| | | // 2. æ ¹æ®å®¡æ¹ç»ææ´æ°ç¶æ |
| | | Integer newStatus = convertBpmResultToStatus(bpmResult); |
| | | if (newStatus != null) { |
| | | equipmentReceiptMapper.updateById(new MesWmEquipmentReceiptDO().setId(id).setStatus(newStatus)); |
| | | } |
| | | } |
| | | |
| | | private Integer convertBpmResultToStatus(Integer bpmResult) { |
| | | if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) { |
| | | return MesWmEquipmentReceiptStatusEnum.APPROVED.getStatus(); |
| | | } |
| | | if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) { |
| | | return MesWmEquipmentReceiptStatusEnum.PREPARE.getStatus(); |
| | | } |
| | | if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) { |
| | | return MesWmEquipmentReceiptStatusEnum.CANCELED.getStatus(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) { |
| | | List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService |
| | | .getProcessDefinitionInfoListByCategory(categoryCode); |
| | | if (CollUtil.isEmpty(definitionInfoList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // è¿æ»¤æ¿æ´»ç¶æï¼ä¿çææ°çæ¬ |
| | | Map<String, ProcessDefinition> latestVersionMap = new HashMap<>(); |
| | | for (BpmProcessDefinitionInfoDO info : definitionInfoList) { |
| | | ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId()); |
| | | if (pd == null || pd.isSuspended()) { |
| | | continue; |
| | | } |
| | | ProcessDefinition existing = latestVersionMap.get(pd.getKey()); |
| | | if (existing == null || pd.getVersion() > existing.getVersion()) { |
| | | latestVersionMap.put(pd.getKey(), pd); |
| | | } |
| | | } |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (ProcessDefinition pd : latestVersionMap.values()) { |
| | | Map<String, Object> item = new HashMap<>(); |
| | | item.put("id", pd.getId()); |
| | | item.put("key", pd.getKey()); |
| | | item.put("name", pd.getName()); |
| | | result.add(item); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private Long getCurrentUserId() { |
| | | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); |
| | | if (authentication != null && authentication.getPrincipal() instanceof Long) { |
| | | return (Long) authentication.getPrincipal(); |
| | | } |
| | | return 1L; // é»è®¤ç¨æ· |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void finishEquipmentReceipt(Long id) { |
| | | // æ ¡éªåå¨ |
| | | MesWmEquipmentReceiptDO receipt = validateEquipmentReceiptExists(id); |
| | | if (ObjUtil.notEqual(MesWmEquipmentReceiptStatusEnum.APPROVED.getStatus(), receipt.getStatus())) { |
| | | throw exception(WM_EQUIP_RECEIPT_STATUS_NOT_APPROVED); |
| | | } |
| | | |
| | | // 2. éåææè¡ï¼åºå®è®¾å¤ä»ä¸å
ç»ï¼å建 IN åºåäºå¡ |
| | | createEquipmentStockTransaction(receipt); |
| | | |
| | | // 3. æ§è¡å
¥åºï¼å·²å®¡æ¹ â å·²å®æï¼ |
| | | equipmentReceiptMapper.updateById(new MesWmEquipmentReceiptDO() |
| | | .setId(id).setStatus(MesWmEquipmentReceiptStatusEnum.FINISHED.getStatus())); |
| | | } |
| | | |
| | | private void createEquipmentStockTransaction(MesWmEquipmentReceiptDO receipt) { |
| | | // åºå®ä½¿ç¨è®¾å¤ä»ä¸å
ç» |
| | | MesWmWarehouseDO warehouse = wmWarehouseService.getWarehouseByCode(MesWmWarehouseDO.EQUIPMENT_WAREHOUSE); |
| | | MesWmWarehouseLocationDO location = wmLocationService.getWarehouseLocationByCode(MesWmWarehouseLocationDO.EQUIPMENT_LOCATION); |
| | | MesWmWarehouseAreaDO area = wmAreaService.getWarehouseAreaByCode(MesWmWarehouseAreaDO.EQUIPMENT_AREA); |
| | | |
| | | List<MesWmEquipmentReceiptLineDO> lines = equipmentReceiptLineService.getEquipmentReceiptLineListByReceiptId(receipt.getId()); |
| | | wmTransactionService.createTransactionList(convertList(lines, line -> new MesWmTransactionSaveReqDTO() |
| | | .setType(MesWmTransactionTypeEnum.IN.getType()) |
| | | .setItemId(line.getItemId()) |
| | | .setQuantity(line.getQuantity() == null ? BigDecimal.ONE : line.getQuantity()) |
| | | .setWarehouseId(warehouse.getId()).setLocationId(location.getId()).setAreaId(area.getId()) |
| | | .setBizType(MesBizTypeConstants.DV_EQUIPMENT_RECEIPT).setBizId(receipt.getId()) |
| | | .setBizCode(receipt.getCode()).setBizLineId(line.getId()))); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cancelEquipmentReceipt(Long id) { |
| | | // æ ¡éªåå¨ |
| | | MesWmEquipmentReceiptDO receipt = validateEquipmentReceiptExists(id); |
| | | |
| | | // 已宿åå·²åæ¶ç¶æä¸å
è®¸åæ¶ |
| | | if (ObjUtil.equal(MesWmEquipmentReceiptStatusEnum.FINISHED.getStatus(), receipt.getStatus()) |
| | | || ObjUtil.equal(MesWmEquipmentReceiptStatusEnum.CANCELED.getStatus(), receipt.getStatus())) { |
| | | throw exception(WM_EQUIP_RECEIPT_CANCEL_NOT_ALLOWED); |
| | | } |
| | | |
| | | // åæ¶ |
| | | equipmentReceiptMapper.updateById(new MesWmEquipmentReceiptDO() |
| | | .setId(id).setStatus(MesWmEquipmentReceiptStatusEnum.CANCELED.getStatus())); |
| | | } |
| | | |
| | | @Override |
| | | public MesWmEquipmentReceiptDO validateEquipmentReceiptExists(Long id) { |
| | | MesWmEquipmentReceiptDO receipt = equipmentReceiptMapper.selectById(id); |
| | | if (receipt == null) { |
| | | throw exception(WM_EQUIP_RECEIPT_NOT_EXISTS); |
| | | } |
| | | return receipt; |
| | | } |
| | | |
| | | private void validateCodeUnique(Long id, String code) { |
| | | MesWmEquipmentReceiptDO receipt = equipmentReceiptMapper.selectByCode(code); |
| | | if (receipt == null) { |
| | | return; |
| | | } |
| | | if (id == null || ObjUtil.notEqual(id, receipt.getId())) { |
| | | throw exception(WM_EQUIP_RECEIPT_CODE_DUPLICATE); |
| | | } |
| | | } |
| | | |
| | | private MesWmEquipmentReceiptDO validateEquipmentReceiptExistsAndPrepare(Long id) { |
| | | MesWmEquipmentReceiptDO receipt = validateEquipmentReceiptExists(id); |
| | | if (ObjUtil.notEqual(MesWmEquipmentReceiptStatusEnum.PREPARE.getStatus(), receipt.getStatus())) { |
| | | throw exception(WM_EQUIP_RECEIPT_STATUS_NOT_PREPARE); |
| | | } |
| | | return receipt; |
| | | } |
| | | |
| | | @Override |
| | | public void validateEquipmentReceiptEditable(Long id) { |
| | | validateEquipmentReceiptExistsAndPrepare(id); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt.listener; |
| | | |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; |
| | | import cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt.MesWmEquipmentReceiptService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 设å¤å
¥åºå BPM 审æ¹ç¶æçå¬å¨ |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class MesWmEquipmentReceiptStatusListener |
| | | extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener { |
| | | |
| | | @Resource |
| | | private MesWmEquipmentReceiptService equipmentReceiptService; |
| | | |
| | | @Override |
| | | protected String getProcessDefinitionKey() { |
| | | return MesWmEquipmentReceiptService.APPROVE_CATEGORY_CODE; |
| | | } |
| | | |
| | | @Override |
| | | protected void onEvent(BpmProcessInstanceStatusEvent event) { |
| | | Long id; |
| | | try { |
| | | id = Long.parseLong(event.getBusinessKey()); |
| | | } catch (NumberFormatException e) { |
| | | log.warn("[onEvent] businessKey({}) 䏿¯ææç设å¤å
¥åºåç¼å·", event.getBusinessKey()); |
| | | return; |
| | | } |
| | | log.info("[onEvent] æ¶å°BPM审æ¹äºä»¶ï¼equipmentReceiptId={}, status={}", id, event.getStatus()); |
| | | try { |
| | | equipmentReceiptService.updateEquipmentReceiptAuditStatus(id, event.getStatus()); |
| | | log.info("[onEvent] 设å¤å
¥åºå({}) 审æ¹ç¶ææ´æ°å®æ", id); |
| | | } catch (Exception e) { |
| | | log.error("[onEvent] æ´æ°è®¾å¤å
¥åºå审æ¹ç¶æå¤±è´¥ï¼equipmentReceiptId={}", id, e); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnDetailRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnInStockPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnInStockReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnOutStockReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.sn.MesWmSnDO; |
| | | |
| | |
| | | */ |
| | | void deleteSnByUuid(String uuid); |
| | | |
| | | /** |
| | | * å
¥åºç»è®°ï¼æ SN 建ç«åºåäºå¡å¹¶å
¥å°ï¼åä»¶å
¥åºï¼ |
| | | * |
| | | * @param reqVO å
¥åºç»è®°è¯·æ± |
| | | */ |
| | | void registerSnInStock(MesWmSnInStockReqVO reqVO); |
| | | |
| | | /** |
| | | * åºåºæ ¸éï¼æ SN 建ç«åºåºäºå¡å¹¶æ ¸éï¼åä»¶åºåºï¼ |
| | | * |
| | | * @param reqVO åºåºæ ¸éè¯·æ± |
| | | */ |
| | | void outboundSn(MesWmSnOutStockReqVO reqVO); |
| | | |
| | | /** |
| | | * è·å¾ SN åä»¶æç»ï¼ç¶æãå¨åºä½ç½®ãæè¿ä¸ç¬åºåäºå¡ï¼ |
| | | * |
| | | * @param snCode SN ç |
| | | * @return SN åä»¶æç» |
| | | */ |
| | | MesWmSnDetailRespVO getSnDetail(String snCode); |
| | | |
| | | /** |
| | | * æç¶æ/ç©æ/åºä½ç维度å页æ¥è¯¢ SN ç ï¼å¨åºæ ¸å¯¹ï¼ |
| | | * |
| | | * @param reqVO å页æ¥è¯¢ |
| | | * @return SN ç å页 |
| | | */ |
| | | PageResult<MesWmSnDO> getSnInStockPage(MesWmSnInStockPageReqVO reqVO); |
| | | |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | 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.sn.vo.MesWmSnDetailRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnGroupRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnInStockPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnInStockReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnOutStockReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.sn.vo.MesWmSnPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.sn.MesWmSnDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.sn.MesWmSnMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.transaction.MesWmTransactionMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmSnStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | 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.module.mes.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * MES SN ç Service å®ç°ç±» |
| | |
| | | |
| | | @Resource |
| | | private MesWmSnMapper snMapper; |
| | | @Resource |
| | | private MesWmTransactionMapper transactionMapper; |
| | | |
| | | @Resource |
| | | private MesMdAutoCodeRecordService autoCodeRecordService; |
| | |
| | | private MesProWorkOrderService workOrderService; |
| | | @Resource |
| | | private MesWmBarcodeService barcodeService; |
| | | @Resource |
| | | private MesWmTransactionService transactionService; |
| | | @Resource |
| | | private MesWmWarehouseService warehouseService; |
| | | @Resource |
| | | private MesWmWarehouseLocationService locationService; |
| | | @Resource |
| | | private MesWmWarehouseAreaService areaService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | snMapper.deleteByUuid(uuid); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void registerSnInStock(MesWmSnInStockReqVO reqVO) { |
| | | // 1. æ ¡éª SN åå¨ä¸ç©æå¹é
|
| | | MesWmSnDO sn = validateSnExists(reqVO.getCode()); |
| | | validateSnItemMatch(sn, reqVO.getItemId()); |
| | | // 2. æ ¡éªç©æå¯ç¨åºåå·ç®¡ç |
| | | MesMdmItemDO item = mdmItemService.validateItemExists(reqVO.getItemId()); |
| | | if (!Boolean.TRUE.equals(item.getIsSerialManaged())) { |
| | | throw exception(WM_SN_ITEM_NOT_SERIAL); |
| | | } |
| | | // 3. ç¶ææ ¡éªï¼å·²å¨åºåæç»éå¤ç»è®° |
| | | if (ObjUtil.equal(sn.getStatus(), MesWmSnStatusEnum.IN_STOCK.getStatus())) { |
| | | throw exception(WM_SN_ALREADY_IN_STOCK); |
| | | } |
| | | // 4. æ ¡éªåºåä½ç½®åå¨ï¼å»ç»ä¸æ··æ¾è§åç±äºå¡å
é¨å
åºï¼ |
| | | warehouseService.validateWarehouseExists(reqVO.getWarehouseId()); |
| | | locationService.validateWarehouseLocationExists(reqVO.getLocationId()); |
| | | areaService.validateWarehouseAreaExists(reqVO.getAreaId()); |
| | | // 5. å建åä»¶å
¥åºäºå¡ï¼+1ï¼ |
| | | transactionService.createTransaction(new MesWmTransactionSaveReqDTO() |
| | | .setType(MesWmTransactionTypeEnum.IN.getType()) |
| | | .setBizType(MesBizTypeConstants.WM_SN) |
| | | .setBizId(sn.getId()).setBizCode(sn.getCode()).setBizLineId(sn.getId()) |
| | | .setItemId(sn.getItemId()).setQuantity(BigDecimal.ONE) |
| | | .setBatchId(sn.getBatchId()).setBatchCode(sn.getBatchCode()) |
| | | .setSnCode(sn.getCode()) |
| | | .setWarehouseId(reqVO.getWarehouseId()).setLocationId(reqVO.getLocationId()).setAreaId(reqVO.getAreaId())); |
| | | // 6. æ´æ° SNï¼å¨åº + è®°å½åºä½ |
| | | snMapper.updateById(new MesWmSnDO().setId(sn.getId()) |
| | | .setStatus(MesWmSnStatusEnum.IN_STOCK.getStatus()) |
| | | .setWarehouseId(reqVO.getWarehouseId()).setLocationId(reqVO.getLocationId()).setAreaId(reqVO.getAreaId()) |
| | | .setRemark(reqVO.getRemark())); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void outboundSn(MesWmSnOutStockReqVO reqVO) { |
| | | // 1. æ ¡éª SN åå¨ä¸ç©æå¹é
|
| | | MesWmSnDO sn = validateSnExists(reqVO.getCode()); |
| | | validateSnItemMatch(sn, reqVO.getItemId()); |
| | | // 2. ç¶ææ ¡éªï¼å¿
é¡»å¨åºä¸è®°å½è¿åºä½ |
| | | if (!ObjUtil.equal(sn.getStatus(), MesWmSnStatusEnum.IN_STOCK.getStatus()) |
| | | || sn.getWarehouseId() == null || sn.getLocationId() == null || sn.getAreaId() == null) { |
| | | throw exception(WM_SN_NOT_IN_STOCK); |
| | | } |
| | | // 3. å建åä»¶åºåºäºå¡ï¼-1ï¼ï¼æ SN å¨åºä½ç½®ç²¾ç¡®å®ä½åºåè®°å½ |
| | | transactionService.createTransaction(new MesWmTransactionSaveReqDTO() |
| | | .setType(MesWmTransactionTypeEnum.OUT.getType()) |
| | | .setBizType(MesBizTypeConstants.WM_SN) |
| | | .setBizId(sn.getId()).setBizCode(sn.getCode()).setBizLineId(sn.getId()) |
| | | .setItemId(sn.getItemId()).setQuantity(BigDecimal.ONE.negate()) |
| | | .setBatchId(sn.getBatchId()).setBatchCode(sn.getBatchCode()) |
| | | .setSnCode(sn.getCode()) |
| | | .setWarehouseId(sn.getWarehouseId()).setLocationId(sn.getLocationId()).setAreaId(sn.getAreaId())); |
| | | // 4. æ´æ° SNï¼å·²åºåº + æ¸
空å¨åºä½ç½® |
| | | snMapper.markOutStockAndClearLocation(sn.getId()); |
| | | snMapper.updateById(new MesWmSnDO().setId(sn.getId()).setRemark(reqVO.getRemark())); |
| | | } |
| | | |
| | | @Override |
| | | public MesWmSnDetailRespVO getSnDetail(String snCode) { |
| | | MesWmSnDO sn = validateSnExists(snCode); |
| | | MesWmSnDetailRespVO resp = BeanUtils.toBean(sn, MesWmSnDetailRespVO.class); |
| | | MesWmTransactionDO transaction = transactionMapper.selectLatestBySnCode(snCode); |
| | | if (transaction != null) { |
| | | MesWmTransactionTypeEnum typeEnum = MesWmTransactionTypeEnum.valueOf(transaction.getType()); |
| | | resp.setLastTransactionType(transaction.getType()); |
| | | resp.setLastTransactionTypeName(typeEnum != null ? typeEnum.getName() : null); |
| | | resp.setLastTransactionQuantity(transaction.getQuantity()); |
| | | resp.setLastTransactionBizType(transaction.getBizType()); |
| | | resp.setLastTransactionBizCode(transaction.getBizCode()); |
| | | resp.setLastTransactionTime(transaction.getTransactionTime()); |
| | | } |
| | | return resp; |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<MesWmSnDO> getSnInStockPage(MesWmSnInStockPageReqVO reqVO) { |
| | | return snMapper.selectStatusPage(reqVO); |
| | | } |
| | | |
| | | private MesWmSnDO validateSnExists(String code) { |
| | | MesWmSnDO sn = snMapper.selectByCode(code); |
| | | if (sn == null) { |
| | | throw exception(WM_SN_NOT_EXISTS); |
| | | } |
| | | return sn; |
| | | } |
| | | |
| | | private void validateSnItemMatch(MesWmSnDO sn, Long itemId) { |
| | | if (ObjUtil.notEqual(sn.getItemId(), itemId)) { |
| | | throw exception(WM_SN_ITEM_MISMATCH); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.plan.MesWmStockTakingPlanDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | */ |
| | | PageResult<MesWmStockTakingPlanDO> getStockTakingPlanPage(MesWmStockTakingPlanPageReqVO pageReqVO); |
| | | |
| | | /** |
| | | * è·åå¯ç¨ä¸å¼å¯å®æèªå¨çæççç¹æ¹æ¡å表 |
| | | * |
| | | * <p>ä¾åå°å®æ¶ä»»å¡æ«æï¼æåæ¹æ¡é
ç½®ç cron 卿èªå¨å建çç¹ä»»å¡ã |
| | | * |
| | | * @return çç¹æ¹æ¡å表 |
| | | */ |
| | | List<MesWmStockTakingPlanDO> getEnableAutoGeneratePlanList(); |
| | | |
| | | /** |
| | | * æ´æ°çç¹æ¹æ¡ä¸æ¬¡èªå¨çææ¶é´ |
| | | * |
| | | * @param id çç¹æ¹æ¡ç¼å· |
| | | * @param time 䏿¬¡èªå¨çææ¶é´ |
| | | */ |
| | | void updateStockTakingPlanLastGenerateTime(Long id, LocalDateTime time); |
| | | |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.plan.MesWmStockTakingPlanMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockTakingTypeEnum; |
| | | import jakarta.annotation.Resource; |
| | | import org.quartz.CronExpression; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | |
| | | return stockTakingPlanMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesWmStockTakingPlanDO> getEnableAutoGeneratePlanList() { |
| | | return stockTakingPlanMapper.selectEnableAutoGenerateList(); |
| | | } |
| | | |
| | | @Override |
| | | public void updateStockTakingPlanLastGenerateTime(Long id, LocalDateTime time) { |
| | | stockTakingPlanMapper.updateById(new MesWmStockTakingPlanDO().setId(id).setLastGenerateTime(time)); |
| | | } |
| | | |
| | | private void validatePlanCodeUnique(Long id, String code) { |
| | | MesWmStockTakingPlanDO plan = stockTakingPlanMapper.selectByCode(code); |
| | | if (plan == null) { |
| | |
| | | throw exception(WM_STOCK_TAKING_PLAN_DYNAMIC_TIME_INVALID); |
| | | } |
| | | } |
| | | |
| | | // æ ¡éªå®æèªå¨çæé
ç½®ï¼å¼å¯èªå¨çææ¶ cron å¿
å¡«ä¸åæ³ |
| | | if (Boolean.TRUE.equals(saveReqVO.getAutoGenerate())) { |
| | | if (StrUtil.isBlank(saveReqVO.getGenerateCron())) { |
| | | throw exception(WM_STOCK_TAKING_PLAN_AUTO_GENERATE_CRON_REQUIRED); |
| | | } |
| | | if (!CronExpression.isValidExpression(saveReqVO.getGenerateCron())) { |
| | | throw exception(WM_STOCK_TAKING_PLAN_AUTO_GENERATE_CRON_INVALID); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.stocktaking.plan.MesWmStockTakingPlanParamService; |
| | | 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; |
| | |
| | | private MesWmMaterialStockService materialStockService; |
| | | @Resource |
| | | private MesWmStockTakingTaskService stockTakingTaskService; |
| | | // ä¸ ResultService ç¸äºå¼ç¨ï¼ResultServiceImpl 已注å
¥ LineServiceï¼ï¼é¡»ç¨ @Lazy æç ´å¾ªç¯ |
| | | @Lazy |
| | | @Resource |
| | | private MesWmStockTakingTaskResultService stockTakingTaskResultService; |
| | | @Resource |
| | | private cn.iocoder.yudao.module.mdm.api.item.MdmItemApi mdmItemApi; |
| | | |
| | |
| | | // 3. æ¹éçææç»è¡ |
| | | List<MesWmStockTakingTaskLineDO> lines = convertList(stocks, stock -> MesWmStockTakingTaskLineDO.builder() |
| | | .taskId(task.getId()).materialStockId(stock.getId()).itemId(stock.getItemId()) |
| | | .batchId(stock.getBatchId()).quantity(stock.getQuantity()).takingQuantity(BigDecimal.ZERO) |
| | | .batchId(stock.getBatchId()).batchCode(stock.getBatchCode()) |
| | | .quantity(stock.getQuantity()).takingQuantity(BigDecimal.ZERO) |
| | | .warehouseId(stock.getWarehouseId()).locationId(stock.getLocationId()).areaId(stock.getAreaId()) |
| | | .status(MesWmStockTakingTaskLineStatusEnum.LOSS.getStatus()).build()); |
| | | stockTakingTaskLineMapper.insertBatch(lines); |
| | |
| | | if (CollUtil.isEmpty(list)) { |
| | | return respVO; |
| | | } |
| | | // 0. æ ¡éªçç¹ä»»å¡å¤äºçç¹ä¸ç¶æï¼ä¸äººå·¥å½å
¥çç¹ç»æå£å¾ä¸è´ï¼ä»
çç¹ä¸å¯å¯¼å
¥ï¼ |
| | | stockTakingTaskService.validateStockTakingTaskExistsAndApproving(taskId); |
| | | // 1. è·åçç¹ä»»å¡è¡ |
| | | List<MesWmStockTakingTaskLineDO> lines = stockTakingTaskLineMapper.selectListByTaskId(taskId); |
| | | if (CollUtil.isEmpty(lines)) { |
| | |
| | | continue; |
| | | } |
| | | updateStockTakingTaskLineTakingQuantity(matched.getId(), row.getTakingQuantity()); |
| | | // 忥åçç¹ç»æï¼ä¿è¯å·®å¼æ ¸éæ¥æºï¼task_resultï¼ä¸è´ |
| | | stockTakingTaskResultService.upsertResultForImport(matched, row.getTakingQuantity()); |
| | | respVO.setSuccessCount(respVO.getSuccessCount() + 1); |
| | | } |
| | | return respVO; |
| | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.result.MesWmStockTakingTaskResultSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | */ |
| | | List<MesWmStockTakingTaskResultDO> getStockTakingTaskResultListByTaskId(Long taskId); |
| | | |
| | | /** |
| | | * Excel 导å
¥åºæ¯åæ¥çç¹ç»æ |
| | | * |
| | | * <p>è¥çç¹è¡å·²åå¨çç¹ç»æåè¦çå
¶å®çæ°éï¼å¦åæçç¹è¡ç»´åº¦æ°å»ºä¸æ¡çç¹ç»æï¼ |
| | | * 使纯导å
¥çå®çæ°æ®ä¹è¿å
¥ {@code task_result}ï¼ä¸äººå·¥/æ«ç å½å
¥å£å¾ä¸è´ï¼ä¿è¯å®ææ¶å·®å¼æ ¸éææ®å¯ä¾ã |
| | | * |
| | | * @param line çç¹ä»»å¡è¡ï¼æ¿è½½è´¦é¢æ°éä¸åºåç»´åº¦ï¼ |
| | | * @param takingQuantity å®çæ°é |
| | | */ |
| | | void upsertResultForImport(MesWmStockTakingTaskLineDO line, BigDecimal takingQuantity); |
| | | |
| | | } |
| | |
| | | |
| | | import java.math.BigDecimal; |
| | | 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_STOCK_TAKING_TASK_LINE_ALREADY_TAKEN; |
| | |
| | | return stockTakingTaskResultMapper.selectListByTaskId(taskId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void upsertResultForImport(MesWmStockTakingTaskLineDO line, BigDecimal takingQuantity) { |
| | | // 1. æ¥è¯¢è¯¥ä»»å¡ä¸æ¯å¦å·²åå¨è¯¥è¡ççç¹ç»æ |
| | | MesWmStockTakingTaskResultDO existing = stockTakingTaskResultMapper.selectListByTaskId(line.getTaskId()).stream() |
| | | .filter(result -> Objects.equals(result.getLineId(), line.getId())) |
| | | .findFirst().orElse(null); |
| | | if (existing != null) { |
| | | // 2. å·²åå¨ï¼è¦çå®çæ°éï¼éå¤å¯¼å
¥ä»¥æå䏿¬¡ä¸ºåï¼ |
| | | existing.setTakingQuantity(takingQuantity); |
| | | stockTakingTaskResultMapper.updateById(existing); |
| | | return; |
| | | } |
| | | // 3. ä¸åå¨ï¼æçç¹è¡ç»´åº¦æ°å»ºï¼è´¦é¢æ°éåè¡è´¦é¢æ°éï¼ä¿è¯æ ¸éå·®é¢å£å¾ä¸è´ |
| | | MesWmStockTakingTaskResultDO result = MesWmStockTakingTaskResultDO.builder() |
| | | .taskId(line.getTaskId()).lineId(line.getId()).materialStockId(line.getMaterialStockId()) |
| | | .itemId(line.getItemId()).batchId(line.getBatchId()).batchCode(line.getBatchCode()) |
| | | .warehouseId(line.getWarehouseId()).locationId(line.getLocationId()).areaId(line.getAreaId()) |
| | | .quantity(line.getQuantity()).takingQuantity(takingQuantity) |
| | | .build(); |
| | | stockTakingTaskResultMapper.insert(result); |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªçç¹ç»ææ¯å¦åå¨ |
| | | * |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * MES çç¹ä»»å¡ Service æ¥å£ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface MesWmStockTakingTaskService { |
| | | |
| | | /** |
| | | * çç¹ç»æå®¡æ¹ BPM åç±»ç¼ç |
| | | */ |
| | | String APPROVE_CATEGORY_CODE = "stock_taking_result_approve"; |
| | | |
| | | /** |
| | | * å建çç¹ä»»å¡ |
| | |
| | | void deleteStockTakingTask(Long id); |
| | | |
| | | /** |
| | | * æäº¤çç¹ä»»å¡ |
| | | * å¼å§çç¹ï¼è稿 â çç¹ä¸ï¼ |
| | | * |
| | | * <p>ä»
èç¨¿ç¶æå¯æ§è¡ï¼æ ¡éªä»»å¡è¡é空å置为çç¹ä¸ï¼è¥å¼å¯å»ç»åå»ç»ä»»å¡è¡çåºåã |
| | | * çç¹ä¸å¯å½å
¥å®çæ°éãExcel 导å
¥å®çã |
| | | * |
| | | * @param id çç¹ä»»å¡ç¼å· |
| | | */ |
| | | void submitStockTakingTask(Long id); |
| | | |
| | | /** |
| | | * 宿çç¹ä»»å¡ |
| | | * æäº¤çç¹ç»æå®¡æ¹ï¼çç¹ä¸ â çç¹ä¸ + å建 BPM æµç¨å®ä¾ï¼ |
| | | * |
| | | * <p>å½å
¥/导å
¥å®æåæäº¤ç»æå®¡æ¹ï¼æ ¡éªçç¹ä¸åå¨ä¸è³å°ä¸æ¡çç¹ç»æãä¸ç»æå®¡æ¹æªæäº¤è¿ï¼ |
| | | * å建 BPM æµç¨å®ä¾å¹¶åå {@code processInstanceId}ã审æ¹éè¿åææ§è¡å·®å¼æ ¸éå¹¶ç½®ä¸ºå·²å®æã |
| | | * |
| | | * @param id çç¹ä»»å¡ç¼å· |
| | | * @param processDefinitionKey BPM æµç¨å®ä¹ Key |
| | | */ |
| | | void finishStockTakingTask(Long id); |
| | | void submitStockTakingResultApproval(Long id, String processDefinitionKey); |
| | | |
| | | /** |
| | | * æ´æ°çç¹ä»»å¡ç»æå®¡æ¹ç¶æï¼BPM 审æ¹åè°ï¼ |
| | | * |
| | | * <p>ä»
çç¹ä¸ç¶æå¤çï¼ |
| | | * <ul> |
| | | * <li>审æ¹éè¿ï¼è§£å»åºåï¼åäºå¡èªå¨æ ¸éçç/çäºå¹¶ç½®ä¸ºå·²å®æï¼</li> |
| | | * <li>审æ¹é©³åï¼æ¸
空æµç¨å®ä¾ç¼å·ï¼ä»»å¡ä¿æçç¹ä¸ï¼å¯ä¿®æ¹å®çåéæ°æäº¤ï¼</li> |
| | | * <li>审æ¹åæ¶ï¼è§£å»åºåå¹¶ç½®ä¸ºå·²åæ¶ã</li> |
| | | * </ul> |
| | | * |
| | | * @param id çç¹ä»»å¡ç¼å· |
| | | * @param bpmResult BPM 审æ¹ç»æï¼éè¿/驳å/åæ¶ï¼ |
| | | */ |
| | | void updateStockTakingTaskResultAuditStatus(Long id, Integer bpmResult); |
| | | |
| | | /** |
| | | * è·åçç¹ç»æå®¡æ¹å¯ç¨ç BPM æµç¨å®ä¹å表 |
| | | * |
| | | * @return æµç¨å®ä¹å表ï¼id/key/nameï¼ |
| | | */ |
| | | List<Map<String, Object>> getStockTakingTaskResultApprovalProcessDefinitionList(); |
| | | |
| | | /** |
| | | * åæ¶çç¹ä»»å¡ |
| | |
| | | * @param id çç¹ä»»å¡ç¼å· |
| | | */ |
| | | void cancelStockTakingTask(Long id); |
| | | |
| | | /** |
| | | * ç±çç¹æ¹æ¡æå¨æèªå¨çæçç¹ä»»å¡ |
| | | * |
| | | * <p>ä¾åå°å®æ¶ä»»å¡è°ç¨ï¼åºäºå·²å¯ç¨ä¸å¼å¯èªå¨çæçæ¹æ¡å建è稿çç¹ä»»å¡å¹¶çææç»è¡ï¼ |
| | | * ä»»å¡ç¼ç èªå¨çæãå建æååååæ¹æ¡ä¸æ¬¡èªå¨çææ¶é´ï¼é¿å
åä¸å¨æéå¤çæã |
| | | * |
| | | * @param planId çç¹æ¹æ¡ç¼å· |
| | | * @return çç¹ä»»å¡ç¼å· |
| | | */ |
| | | Long createStockTakingTaskFromPlan(Long planId); |
| | | |
| | | /** |
| | | * è·å¾çç¹ä»»å¡ |
| | |
| | | * @return çç¹ä»»å¡åé¡µç»æ |
| | | */ |
| | | PageResult<MesWmStockTakingTaskDO> getStockTakingTaskPage(MesWmStockTakingTaskPageReqVO pageReqVO); |
| | | |
| | | /** |
| | | * å¤ççç¹å·®å¼ï¼è°æ´åºå |
| | | * |
| | | * è¯¥æ¹æ³ä¼æ¯è¾çç¹ç»æä¸åºåå°è´¦çå·®å¼ï¼ |
| | | * - ççï¼åºåå¢å ï¼å建å
¥åºäºå¡ |
| | | * - çäºï¼åºååå°ï¼å建åºåºäºå¡ |
| | | * |
| | | * @param id çç¹ä»»å¡ç¼å· |
| | | */ |
| | | void processStockTakingDifference(Long id); |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskLineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskResultDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.plan.MesWmStockTakingPlanDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.stocktaking.task.MesWmStockTakingTaskMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockTakingTaskStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.stocktaking.plan.MesWmStockTakingPlanService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | 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.dal.dataobject.definition.BpmProcessDefinitionInfoDO; |
| | | import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | |
| | | 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.common.util.collection.CollectionUtils.convertMap; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class MesWmStockTakingTaskServiceImpl implements MesWmStockTakingTaskService { |
| | | |
| | | @Resource |
| | | private MesWmStockTakingTaskMapper stockTakingTaskMapper; |
| | | |
| | | @Resource |
| | | private BpmProcessInstanceApi processInstanceApi; |
| | | @Resource |
| | | private BpmProcessDefinitionService bpmProcessDefinitionService; |
| | | |
| | | @Resource |
| | | private MesWmMaterialStockService materialStockService; |
| | |
| | | |
| | | @Resource |
| | | private MesWmTransactionService wmTransactionService; |
| | | |
| | | @Resource |
| | | private MesMdAutoCodeRecordService mesMdAutoCodeRecordService; |
| | | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | |
| | | stockTakingTaskLineService.generateStockTakingLines(task, true); |
| | | } |
| | | return task.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createStockTakingTaskFromPlan(Long planId) { |
| | | // 1. æ ¡éªæ¹æ¡åå¨ãå·²å¯ç¨ä¸å¼å¯å®æèªå¨çæ |
| | | MesWmStockTakingPlanDO plan = stockTakingPlanService.validateStockTakingPlanEnabled(planId); |
| | | if (!Boolean.TRUE.equals(plan.getAutoGenerate())) { |
| | | throw exception(WM_STOCK_TAKING_PLAN_NOT_AUTO_GENERATE); |
| | | } |
| | | |
| | | // 2. èªå¨çæä»»å¡ç¼ç ï¼è§åï¼çç¹ä»»å¡ç¼ç ï¼ |
| | | String code = mesMdAutoCodeRecordService.generateAutoCode( |
| | | MesMdAutoCodeRuleCodeEnum.WM_STOCK_TAKING_CODE.getCode()); |
| | | |
| | | // 3. å¤ç¨å建é»è¾çæè稿任å¡ï¼å
鍿 ¡éªç¼ç å¯ä¸ãæ¹æ¡å¯ç¨ï¼å¹¶ææ¹æ¡çæçç¹æç»è¡ï¼ |
| | | Long taskId = createStockTakingTask(new MesWmStockTakingTaskSaveReqVO() |
| | | .setCode(code) |
| | | .setName(plan.getName()) |
| | | .setTakingDate(LocalDateTime.now()) |
| | | .setType(plan.getType()) |
| | | .setUserId(getCurrentUserId()) |
| | | .setPlanId(planId) |
| | | .setStartTime(plan.getStartTime()) |
| | | .setEndTime(plan.getEndTime()) |
| | | .setBlindFlag(plan.getBlindFlag()) |
| | | .setFrozen(plan.getFrozen()) |
| | | .setRemark("æ¹æ¡å®æèªå¨çæ")); |
| | | |
| | | // 4. ååæ¬æ¬¡çææ¶é´ï¼é¿å
åä¸å¨æéå¤çæï¼ä¸å建åäºå¡ï¼ |
| | | stockTakingPlanService.updateStockTakingPlanLastGenerateTime(planId, LocalDateTime.now()); |
| | | return taskId; |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void finishStockTakingTask(Long id) { |
| | | // 1. æ ¡éªä»»å¡åå¨ä¸ä¸ºå®¡æ¹ä¸ç¶æ |
| | | public void submitStockTakingResultApproval(Long id, String processDefinitionKey) { |
| | | // 1.1 æ ¡éªä»»å¡åå¨ä¸å¤äºçç¹ä¸ç¶æ |
| | | MesWmStockTakingTaskDO task = validateStockTakingTaskExistsAndApproving(id); |
| | | // 1.2 æ ¡éªç»æå®¡æ¹æªæäº¤è¿ï¼é¿å
éå¤æäº¤ï¼ |
| | | if (task.getProcessInstanceId() != null) { |
| | | throw exception(WM_STOCK_TAKING_TASK_ALREADY_SUBMIT_APPROVAL); |
| | | } |
| | | // 1.3 æ ¡éªè³å°æä¸æ¡çç¹ç»æ |
| | | List<MesWmStockTakingTaskResultDO> results = stockTakingTaskResultService.getStockTakingTaskResultListByTaskId(id); |
| | | if (CollUtil.isEmpty(results)) { |
| | | throw exception(WM_STOCK_TAKING_TASK_NO_RESULT); |
| | | } |
| | | |
| | | // 2. æ´æ°ä»»å¡ç¶æä¸ºå·²å®æ |
| | | // 2. å建 BPM æµç¨å®ä¾ |
| | | String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(), |
| | | new BpmProcessInstanceCreateReqDTO() |
| | | .setProcessDefinitionKey(processDefinitionKey) |
| | | .setBusinessKey(String.valueOf(id))); |
| | | |
| | | // 3. ååæµç¨å®ä¾ç¼å·ï¼ä»»å¡ä¿æçç¹ä¸ï¼çå¾
审æ¹ï¼ |
| | | stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO() |
| | | .setId(id).setProcessInstanceId(processInstanceId)); |
| | | } |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> getStockTakingTaskResultApprovalProcessDefinitionList() { |
| | | return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateStockTakingTaskResultAuditStatus(Long id, Integer bpmResult) { |
| | | // 1. æ ¡éªä»»å¡åå¨ |
| | | MesWmStockTakingTaskDO task = validateStockTakingTaskExists(id); |
| | | if (!MesWmStockTakingTaskStatusEnum.APPROVING.getStatus().equals(task.getStatus())) { |
| | | log.warn("[updateStockTakingTaskResultAuditStatus] çç¹ä»»å¡({}) ä¸å¤äºçç¹ä¸ç¶æï¼å¿½ç¥å®¡æ¹äºä»¶", id); |
| | | return; |
| | | } |
| | | // 2. 审æ¹éè¿ï¼å
ç½®ä¸ºå·²å®æï¼åè§£å»å¹¶åäºå¡èªå¨æ ¸éå·®å¼ |
| | | if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) { |
| | | // 2.1 å
ç½®ä¸ºå·²å®æï¼ä»»å¡ç¶æåæ´åï¼åç»éå¤ç审æ¹äºä»¶è¯»åå° FINISHED å³è¢«å¿½ç¥ï¼é¿å
é夿 ¸é |
| | | stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO().setId(id) |
| | | .setStatus(MesWmStockTakingTaskStatusEnum.FINISHED.getStatus())); |
| | | |
| | | // 3. è§£å»åºå |
| | | // 2.2 è§£å»åºåï¼é¡»å¨å·®å¼æ ¸éåè§£å»ï¼å¦åæ ¸éäºå¡ä¼è¢«åºåå»ç»æ ¡éªæ¦æª |
| | | if (Boolean.TRUE.equals(task.getFrozen())) { |
| | | List<MesWmStockTakingTaskLineDO> lines = stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id); |
| | | updateMaterialStockFrozen(lines, false); |
| | | updateMaterialStockFrozen(stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id), false); |
| | | } |
| | | // 2.3 èªå¨æ ¸éçç¹å·®å¼ï¼ççå
¥åº / çäºåºåºï¼åäºå¡å
æ´æ°åºåå°è´¦ï¼ä»»ä¸æ¥å¤±è´¥æ´ä½åæ»ï¼ä»»å¡åé为çç¹ä¸ |
| | | doProcessStockTakingDifference(task); |
| | | return; |
| | | } |
| | | // 3. 审æ¹é©³åï¼æ¸
空æµç¨å®ä¾ç¼å·ï¼ä»»å¡ä¿æçç¹ä¸ï¼å¯ä¿®æ¹å®çåéæ°æäº¤ç»æå®¡æ¹ |
| | | if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) { |
| | | stockTakingTaskMapper.clearProcessInstanceId(id); |
| | | return; |
| | | } |
| | | // 4. 审æ¹åæ¶ï¼è§£å»åºåå¹¶ç½®ä¸ºå·²åæ¶ |
| | | if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) { |
| | | if (Boolean.TRUE.equals(task.getFrozen())) { |
| | | updateMaterialStockFrozen(stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id), false); |
| | | } |
| | | stockTakingTaskMapper.clearProcessInstanceId(id); |
| | | stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO().setId(id) |
| | | .setStatus(MesWmStockTakingTaskStatusEnum.CANCELED.getStatus())); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·ååç±»ä¸çå¯ç¨ BPM æµç¨å®ä¹ï¼è¿æ»¤æèµ·æµç¨ï¼å Key ä¿çææ°çæ¬ï¼ |
| | | * |
| | | * @param categoryCode æµç¨åç±»ç¼ç |
| | | * @return æµç¨å®ä¹å表ï¼id/key/nameï¼ |
| | | */ |
| | | private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) { |
| | | List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService |
| | | .getProcessDefinitionInfoListByCategory(categoryCode); |
| | | if (CollUtil.isEmpty(definitionInfoList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // è¿æ»¤æ¿æ´»ç¶æï¼ä¿çææ°çæ¬ |
| | | Map<String, ProcessDefinition> latestVersionMap = new HashMap<>(); |
| | | for (BpmProcessDefinitionInfoDO info : definitionInfoList) { |
| | | ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId()); |
| | | if (pd == null || pd.isSuspended()) { |
| | | continue; |
| | | } |
| | | ProcessDefinition existing = latestVersionMap.get(pd.getKey()); |
| | | if (existing == null || pd.getVersion() > existing.getVersion()) { |
| | | latestVersionMap.put(pd.getKey(), pd); |
| | | } |
| | | } |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (ProcessDefinition pd : latestVersionMap.values()) { |
| | | Map<String, Object> item = new HashMap<>(); |
| | | item.put("id", pd.getId()); |
| | | item.put("key", pd.getKey()); |
| | | item.put("name", pd.getName()); |
| | | result.add(item); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private Long getCurrentUserId() { |
| | | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); |
| | | if (authentication != null && authentication.getPrincipal() instanceof Long) { |
| | | return (Long) authentication.getPrincipal(); |
| | | } |
| | | return 1L; // é»è®¤ç¨æ· |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | task.setStatus(MesWmStockTakingTaskStatusEnum.CANCELED.getStatus()); |
| | | stockTakingTaskMapper.updateById(task); |
| | | // 忶忏
空æµç¨å®ä¾ç¼å·ï¼é¿å
æ®çå®¡æ¹æ è®°å½±ååç»éæ°å¼å§çç¹ |
| | | stockTakingTaskMapper.clearProcessInstanceId(id); |
| | | if (Boolean.TRUE.equals(task.getFrozen())) { |
| | | updateMaterialStockFrozen(stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id), false); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void processStockTakingDifference(Long id) { |
| | | // 1. æ ¡éªä»»å¡åå¨ä¸å·²å®æ |
| | | MesWmStockTakingTaskDO task = validateStockTakingTaskExists(id); |
| | | if (!MesWmStockTakingTaskStatusEnum.FINISHED.getStatus().equals(task.getStatus())) { |
| | | throw exception(WM_STOCK_TAKING_TASK_NOT_FINISHED); |
| | | } |
| | | |
| | | // 2. è·åçç¹ç»æå表 |
| | | List<MesWmStockTakingTaskResultDO> results = stockTakingTaskResultService.getStockTakingTaskResultListByTaskId(id); |
| | | /** |
| | | * èªå¨æ ¸éçç¹å·®å¼ï¼æçç¹ç»æéè¡çæ IN/OUT åºåäºå¡æ´æ°åºåå°è´¦ |
| | | * |
| | | * <p>ä»
ç± {@link #updateStockTakingTaskResultAuditStatus} ç审æ¹éè¿åæ¯å¨åäºå¡å
è°ç¨ï¼ |
| | | * 失败æ´ä½åæ»ï¼ä»»å¡åé为çç¹ä¸ç¶æï¼é¿å
éå¤è°æ´ã |
| | | * |
| | | * @param task å·²ç½®ä¸ºå·²å®æã已解å»ççç¹ä»»å¡ |
| | | */ |
| | | private void doProcessStockTakingDifference(MesWmStockTakingTaskDO task) { |
| | | // 1. è·åçç¹ç»æå表 |
| | | List<MesWmStockTakingTaskResultDO> results = stockTakingTaskResultService.getStockTakingTaskResultListByTaskId(task.getId()); |
| | | if (CollUtil.isEmpty(results)) { |
| | | return; // æ çç¹ç»æï¼æ éå¤ç |
| | | } |
| | | |
| | | // 2. å»ºç« è¡å· -> çç¹è¡ æ å°ï¼ä»¥çç¹è¡ï¼åºåå¿«ç
§ï¼ä¸ºååå¡«åºåç¼å·ä¸ç»´åº¦ï¼ |
| | | // é¿å
åºåºæ ¸éæ (ç©æ+ä½ç½®+æ¹æ¬¡) ç»åé®å¹é
å°å
¶å®ä¾åºå/åºä½çè´¦é¢è¡èæ£éåºå |
| | | Map<Long, MesWmStockTakingTaskLineDO> lineMap = convertMap( |
| | | stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(task.getId()), |
| | | MesWmStockTakingTaskLineDO::getId); |
| | | |
| | | // 3. éåç»æï¼å¤çå·®å¼ |
| | | for (MesWmStockTakingTaskResultDO result : results) { |
| | |
| | | continue; |
| | | } |
| | | |
| | | // 计ç®å·®å¼ï¼çç¹æ°é - è´¦é¢æ°é |
| | | // 计ç®å·®å¼ï¼çç¹æ°é - è´¦é¢æ°éï¼çç为æ£ãçäºä¸ºè´ï¼ |
| | | BigDecimal difference = takingQuantity.subtract(bookQuantity); |
| | | |
| | | if (difference.compareTo(BigDecimal.ZERO) == 0) { |
| | | continue; // æ å·®å¼ï¼è·³è¿ |
| | | } |
| | | |
| | | // 4. å建åºåè°æ´äºå¡ |
| | | MesWmStockTakingTaskLineDO line = result.getLineId() != null ? lineMap.get(result.getLineId()) : null; |
| | | |
| | | // 4. å建åºåè°æ´äºå¡ï¼ççä¼ æ£æ°å
¥åºï¼çäºç´æ¥ä¼ è´æ°åºåºï¼createTransaction æ ¡éªåºåºæ°éå¿
须为è´ï¼ |
| | | MesWmTransactionSaveReqDTO transaction = new MesWmTransactionSaveReqDTO() |
| | | .setItemId(result.getItemId()) |
| | | .setBatchId(result.getBatchId()) |
| | | .setBatchCode(result.getBatchCode()) |
| | | .setWarehouseId(result.getWarehouseId()) |
| | | .setLocationId(result.getLocationId()) |
| | | .setAreaId(result.getAreaId()) |
| | | .setType(difference.compareTo(BigDecimal.ZERO) > 0 |
| | | ? MesWmTransactionTypeEnum.IN.getType() : MesWmTransactionTypeEnum.OUT.getType()) |
| | | .setQuantity(difference) |
| | | .setItemId(line != null ? line.getItemId() : result.getItemId()) |
| | | .setBatchId(line != null ? line.getBatchId() : result.getBatchId()) |
| | | .setBatchCode(line != null ? line.getBatchCode() : result.getBatchCode()) |
| | | .setWarehouseId(line != null ? line.getWarehouseId() : result.getWarehouseId()) |
| | | .setLocationId(line != null ? line.getLocationId() : result.getLocationId()) |
| | | .setAreaId(line != null ? line.getAreaId() : result.getAreaId()) |
| | | .setMaterialStockId(line != null ? line.getMaterialStockId() : result.getMaterialStockId()) |
| | | .setBizId(task.getId()) |
| | | .setBizCode(task.getCode()) |
| | | .setBizLineId(result.getLineId()); |
| | | |
| | | if (difference.compareTo(BigDecimal.ZERO) > 0) { |
| | | // ççï¼åºåå¢å |
| | | transaction.setType(MesWmTransactionTypeEnum.IN.getType()) |
| | | .setQuantity(difference) |
| | | .setBizLineId(result.getLineId()) |
| | | .setBizType(MesBizTypeConstants.WM_STOCK_TAKING); |
| | | } else { |
| | | // çäºï¼åºååå° |
| | | transaction.setType(MesWmTransactionTypeEnum.OUT.getType()) |
| | | .setQuantity(difference.negate()) // åºåºæ°éä¼ æ£æ°ï¼ä½å
é¨ä¼è½¬ä¸ºè´æ° |
| | | .setBizType(MesBizTypeConstants.WM_STOCK_TAKING); |
| | | } |
| | | |
| | | wmTransactionService.createTransaction(transaction); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.listener; |
| | | |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; |
| | | import cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * MES çç¹ç»æå®¡æ¹ BPM ç¶æçå¬å¨ |
| | | * |
| | | * çå¬çç¹ç»æå®¡æ¹æµç¨å®ä¾ç¶æåæ´äºä»¶ï¼å®¡æ¹éè¿åè§£å»åºåå¹¶èªå¨æ ¸éçç¹å·®å¼ç½®ä¸ºå·²å®æï¼ |
| | | * 驳ååä»»å¡ä¿æçç¹ä¸å¯ä¿®æ¹å®çéæ°æäº¤ï¼åæ¶åè§£å»å¹¶ç½®ä¸ºå·²åæ¶ |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class MesWmStockTakingTaskResultStatusListener |
| | | extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener { |
| | | |
| | | @Resource |
| | | private MesWmStockTakingTaskService stockTakingTaskService; |
| | | |
| | | @Override |
| | | protected String getProcessDefinitionKey() { |
| | | return MesWmStockTakingTaskService.APPROVE_CATEGORY_CODE; |
| | | } |
| | | |
| | | @Override |
| | | protected void onEvent(BpmProcessInstanceStatusEvent event) { |
| | | Long id; |
| | | try { |
| | | id = Long.parseLong(event.getBusinessKey()); |
| | | } catch (NumberFormatException e) { |
| | | log.warn("[onEvent] businessKey({}) 䏿¯ææççç¹ä»»å¡ç¼å·", event.getBusinessKey()); |
| | | return; |
| | | } |
| | | log.info("[onEvent] æ¶å°çç¹ç»æå®¡æ¹äºä»¶ï¼stockTakingTaskId={}, status={}", id, event.getStatus()); |
| | | try { |
| | | stockTakingTaskService.updateStockTakingTaskResultAuditStatus(id, event.getStatus()); |
| | | log.info("[onEvent] çç¹ä»»å¡({}) ç»æå®¡æ¹ç¶ææ´æ°å®æ", id); |
| | | } catch (Exception e) { |
| | | log.error("[onEvent] æ´æ°çç¹ä»»å¡ç»æå®¡æ¹ç¶æå¤±è´¥ï¼stockTakingTaskId={}", id, e); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | // 3. æå
¥äºå¡æµæ°´ |
| | | MesWmTransactionDO transaction = MesWmTransactionDO.builder() |
| | | .type(reqDTO.getType()).quantity(reqDTO.getQuantity()).transactionTime(LocalDateTime.now()) |
| | | .itemId(reqDTO.getItemId()).batchId(reqDTO.getBatchId()).batchCode(reqDTO.getBatchCode()) |
| | | .itemId(reqDTO.getItemId()).batchId(reqDTO.getBatchId()).batchCode(reqDTO.getBatchCode()).snCode(reqDTO.getSnCode()) |
| | | .warehouseId(reqDTO.getWarehouseId()).locationId(reqDTO.getLocationId()).areaId(reqDTO.getAreaId()) |
| | | .bizType(reqDTO.getBizType()).bizId(reqDTO.getBizId()).bizCode(reqDTO.getBizCode()).bizLineId(reqDTO.getBizLineId()) |
| | | .materialStockId(materialStock.getId()).relatedTransactionId(reqDTO.getRelatedTransactionId()) |
| | |
| | | * æ¹æ¬¡å· |
| | | */ |
| | | private String batchCode; |
| | | /** |
| | | * SN ç ï¼åºåå·ç®¡çç©æååè¿åºï¼ |
| | | */ |
| | | private String snCode; |
| | | |
| | | // ===== åºåä½ç½® ===== |
| | | |