| | |
| | | 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.attendance.vo.HrmAttendanceRecordPageReqVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceMyStatusRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordRespVO; |
| | | import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRuleRespVO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceHolidayDO; |
| | | import cn.iocoder.yudao.module.hrm.enums.HrmAttendanceHolidayTypeEnum; |
| | | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| | | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceRecordDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceRuleDO; |
| | | import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceExceptionDO; |
| | |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.time.DayOfWeek; |
| | | import java.time.Duration; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | |
| | | private HrmAttendanceRuleService attendanceRuleService; |
| | | @Resource |
| | | private HrmAttendanceHolidayService attendanceHolidayService; |
| | | @Resource |
| | | private DeptApi deptApi; |
| | | |
| | | @Override |
| | | public PageResult<HrmAttendanceRecordDO> getAttendanceRecordPage(HrmAttendanceRecordPageReqVO pageReqVO) { |
| | |
| | | attendanceRecordMapper.updateById(record); |
| | | } |
| | | |
| | | // ==================== æçèå¤ç¶æï¼App æå¡é¡µï¼ ==================== |
| | | |
| | | @Override |
| | | public HrmAttendanceMyStatusRespVO getMyStatus(Long loginUserId, LocalDate date) { |
| | | LocalDate queryDate = date != null ? date : LocalDate.now(); |
| | | // 1. ç»å½ç¨æ· -> åå·¥æ¡£æ¡ |
| | | HrmEmployeeDO employee = employeeService.getEmployeeByUserId(loginUserId); |
| | | if (employee == null) { |
| | | throw exception(EMPLOYEE_NOT_EXISTS, |
| | | "å½åç»å½è´¦å·æªå
³èå工档æ¡ï¼æ æ³æå¡ã请è系管çåå¨ãå工管çãä¸å°è¯¥ç»å½è´¦å·ç»å®å°åå·¥ã"); |
| | | } |
| | | HrmAttendanceMyStatusRespVO respVO = new HrmAttendanceMyStatusRespVO(); |
| | | respVO.setUserId(loginUserId); |
| | | respVO.setEmployeeId(employee.getId()); |
| | | respVO.setEmployeeName(employee.getName()); |
| | | respVO.setDeptId(employee.getDeptId()); |
| | | if (employee.getDeptId() != null) { |
| | | DeptRespDTO dept = deptApi.getDept(employee.getDeptId()); |
| | | if (dept != null) { |
| | | respVO.setDeptName(dept.getName()); |
| | | } |
| | | } |
| | | respVO.setDate(queryDate); |
| | | respVO.setServerTime(LocalDateTime.now()); |
| | | |
| | | // 2. æ¯å¦å·¥ä½æ¥ + 伿¯åå |
| | | boolean workDay = attendanceHolidayService.isWorkDay(queryDate); |
| | | respVO.setWorkDay(workDay); |
| | | if (!workDay) { |
| | | respVO.setRestDayReason(getRestDayReason(queryDate)); |
| | | } |
| | | |
| | | // 3. å½åçæè§åï¼é¨é¨è§åä¼å
ï¼å
¶æ¬¡å
¨å±è§åï¼ææ¥æå¹é
çæåºé´ï¼ |
| | | HrmAttendanceRuleDO rule = attendanceRuleService.getAttendanceRuleByDeptId(employee.getDeptId(), queryDate); |
| | | if (rule != null) { |
| | | HrmAttendanceRuleRespVO ruleRespVO = BeanUtils.toBean(rule, HrmAttendanceRuleRespVO.class); |
| | | if (rule.getDeptId() != null) { |
| | | DeptRespDTO ruleDept = deptApi.getDept(rule.getDeptId()); |
| | | if (ruleDept != null) { |
| | | ruleRespVO.setDeptName(ruleDept.getName()); |
| | | } |
| | | } |
| | | respVO.setRule(ruleRespVO); |
| | | } |
| | | |
| | | // 4. 彿¥èå¤è®°å½ |
| | | HrmAttendanceRecordDO record = attendanceRecordMapper.selectByUserIdAndDate(employee.getId(), queryDate); |
| | | if (record != null) { |
| | | respVO.setRecord(buildRecordRespVO(record, employee)); |
| | | } |
| | | |
| | | // 5. å½å坿å¡ç¶æ |
| | | respVO.setClockable(buildClockable(workDay, rule, record, queryDate)); |
| | | return respVO; |
| | | } |
| | | |
| | | /** |
| | | * 伿¯æ¥åå ï¼ä¼å
åè忥é
ç½®åç§°ï¼æªé
ç½®æ¶æææç»åºâå¨å
/卿¥â |
| | | */ |
| | | private String getRestDayReason(LocalDate date) { |
| | | List<HrmAttendanceHolidayDO> holidays = attendanceHolidayService.getAttendanceHolidayListByDateRange(date, date); |
| | | for (HrmAttendanceHolidayDO holiday : holidays) { |
| | | if (HrmAttendanceHolidayTypeEnum.REST_DAY.getType().equals(holiday.getType())) { |
| | | return holiday.getName(); |
| | | } |
| | | } |
| | | DayOfWeek dayOfWeek = date.getDayOfWeek(); |
| | | if (dayOfWeek == DayOfWeek.SATURDAY) { |
| | | return "å¨å
"; |
| | | } |
| | | if (dayOfWeek == DayOfWeek.SUNDAY) { |
| | | return "卿¥"; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * æå»ºæå¡è®°å½è¿å VOï¼è¡¥é½æå¡ç±»ååç§°ä¸åå·¥ä¿¡æ¯ |
| | | */ |
| | | private HrmAttendanceRecordRespVO buildRecordRespVO(HrmAttendanceRecordDO record, HrmEmployeeDO employee) { |
| | | HrmAttendanceRecordRespVO recordRespVO = BeanUtils.toBean(record, HrmAttendanceRecordRespVO.class); |
| | | recordRespVO.setClockInTypeName(HrmAttendanceClockTypeEnum.getNameByType(record.getClockInType())); |
| | | recordRespVO.setClockOutTypeName(HrmAttendanceClockTypeEnum.getNameByType(record.getClockOutType())); |
| | | if (employee != null) { |
| | | recordRespVO.setUserName(employee.getName()); |
| | | } |
| | | return recordRespVO; |
| | | } |
| | | |
| | | /** |
| | | * 计ç®å½å坿å¡ç¶æ |
| | | */ |
| | | private HrmAttendanceMyStatusRespVO.Clockable buildClockable(boolean workDay, HrmAttendanceRuleDO rule, |
| | | HrmAttendanceRecordDO record, LocalDate date) { |
| | | HrmAttendanceMyStatusRespVO.Clockable clockable = new HrmAttendanceMyStatusRespVO.Clockable(); |
| | | if (!workDay) { |
| | | clockable.setClockIn(false); |
| | | clockable.setClockOut(false); |
| | | clockable.setNextAction("none"); |
| | | clockable.setMessage("仿¥ä¼æ¯ï¼æ éæå¡"); |
| | | return clockable; |
| | | } |
| | | if (rule == null) { |
| | | clockable.setClockIn(false); |
| | | clockable.setClockOut(false); |
| | | clockable.setNextAction("none"); |
| | | clockable.setMessage("æªé
ç½®èå¤è§åï¼è¯·è系管çå"); |
| | | return clockable; |
| | | } |
| | | // åªæä¸çå¡ã没æä¸çå¡ï¼å½æ¥å·²ç»æï¼ä¸åå
è®¸ç»§ç»æå¡ |
| | | if (record != null && record.getClockInTime() == null && record.getClockOutTime() != null) { |
| | | clockable.setClockIn(false); |
| | | clockable.setClockOut(false); |
| | | clockable.setNextAction("none"); |
| | | clockable.setMessage("仿¥ç¼ºä¸çå¡ï¼å·²å®æä¸çæå¡"); |
| | | return clockable; |
| | | } |
| | | // ä»å¤©è¿æ²¡æä¸çå¡ |
| | | if (record == null || record.getClockInTime() == null) { |
| | | clockable.setClockIn(true); |
| | | clockable.setClockOut(false); |
| | | clockable.setNextAction("in"); |
| | | clockable.setMessage("å¯ä¸çæå¡"); |
| | | // ä»
å½å¤©æ¥è¯¢æ¶æç¤ºå·²è¿å°æ¶é¿ |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | if (rule.getWorkStartTime() != null && date.equals(now.toLocalDate())) { |
| | | LocalDateTime workStart = LocalDateTime.of(date, rule.getWorkStartTime()); |
| | | int lateAllowMinutes = rule.getLateAllowMinutes() != null ? rule.getLateAllowMinutes() : 0; |
| | | if (now.isAfter(workStart.plusMinutes(lateAllowMinutes))) { |
| | | long lateMinutes = Duration.between(workStart, now).toMinutes(); |
| | | clockable.setMessage("å·²è¶
è¿ä¸çæ¶é´ " + lateMinutes + " åé"); |
| | | } |
| | | } |
| | | return clockable; |
| | | } |
| | | // å·²æä¸çå¡ãæªæä¸çå¡ |
| | | if (record.getClockOutTime() == null) { |
| | | clockable.setClockIn(false); |
| | | clockable.setClockOut(true); |
| | | clockable.setNextAction("out"); |
| | | clockable.setMessage("å·²ä¸çæå¡ï¼å¯ä¸çæå¡"); |
| | | return clockable; |
| | | } |
| | | // ä¸ä¸çå¡é½å·²æ |
| | | clockable.setClockIn(false); |
| | | clockable.setClockOut(false); |
| | | clockable.setNextAction("none"); |
| | | clockable.setMessage("仿¥å·²å®ææå¡"); |
| | | return clockable; |
| | | } |
| | | |
| | | } |