|
@@ -0,0 +1,154 @@
|
|
|
+package com.zjugis.module.adm.job.leave;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
+import com.xxl.job.core.handler.annotation.XxlJob;
|
|
|
+import com.zjugis.framework.common.util.date.DateUtils;
|
|
|
+import com.zjugis.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
+import com.zjugis.module.adm.dal.dataobject.attendance.AttendanceRecordDO;
|
|
|
+import com.zjugis.module.adm.dal.dataobject.staff.StaffRecordSDO;
|
|
|
+import com.zjugis.module.adm.dal.mysql.staff.RecordsMapper;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 年假计算
|
|
|
+ *
|
|
|
+ * @author jzh
|
|
|
+ * @since 2024/2/22 16:07
|
|
|
+ */
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+public class YearLeaveJob {
|
|
|
+ @Resource
|
|
|
+ private RecordsMapper recordsMapper;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 年假计算
|
|
|
+ */
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @XxlJob("annualLeaveJob")
|
|
|
+ public void annualLeaveJob() throws InterruptedException {
|
|
|
+
|
|
|
+ //查询未删除员工
|
|
|
+ List<StaffRecordSDO> staffs = recordsMapper.selectList(new LambdaQueryWrapperX<StaffRecordSDO>().eq(StaffRecordSDO::getDeleted, "0"));
|
|
|
+ List<StaffRecordSDO> res = new ArrayList<>();
|
|
|
+ for (StaffRecordSDO staff : staffs) {
|
|
|
+ int leave = statisticAnnualLeave(staff);
|
|
|
+ //剩余年假
|
|
|
+ int leftLeave = staff.getNj() == null ? 0 : staff.getNj();
|
|
|
+ staff.setNj(leave + leftLeave);
|
|
|
+ res.add(staff);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("年假计算完毕 开始入库");
|
|
|
+ if (CollectionUtil.isNotEmpty(res)) {
|
|
|
+ recordsMapper.updateBatch(res);
|
|
|
+ }
|
|
|
+ log.info("年假入库完毕 年假计算程序运行结束");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 一、年假逻辑:
|
|
|
+ * ①国家政策
|
|
|
+ * ≥ 1年 & < 10年:5天
|
|
|
+ * ≥10年 & < 20年:10天
|
|
|
+ * ≥20年:15天
|
|
|
+ * ②逻辑
|
|
|
+ * 入职有个初始年假天数。
|
|
|
+ * 每年1月1日23:50,计算每个人的新一年的年假天数
|
|
|
+ * ③每年3月1日 0:00,上一年度剩余年假清0,>新一年年假则=新一年年假,否则不管了
|
|
|
+ * 二,工龄
|
|
|
+ * 每入职满5年,公司奖励年假1天
|
|
|
+ * 司龄以1月1日算
|
|
|
+ */
|
|
|
+ private int statisticAnnualLeave(StaffRecordSDO staff) {
|
|
|
+ LocalDateTime now = DateUtils.getFirstDayOfYear(); //今年
|
|
|
+ LocalDateTime workTime = staff.getCjgzsj() == null ? now : staff.getCjgzsj(); // 参加工作时间
|
|
|
+ LocalDateTime enterTime = staff.getRgssj() == null ? now : staff.getRgssj();//入公司时间
|
|
|
+
|
|
|
+ //计算法定年假
|
|
|
+ int lowLeave = getLowAnnual(workTime, now);
|
|
|
+ //计算公司年假
|
|
|
+ int workLeave = getWorkAnnual(enterTime, now);
|
|
|
+ //初始年假 用于离职之后回来的员工
|
|
|
+ int initLeave = (staff.getCssl() == null ? 0 : staff.getCssl()) / 5;
|
|
|
+
|
|
|
+ //总年假
|
|
|
+ return lowLeave + workLeave + initLeave;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算公司年假
|
|
|
+ *
|
|
|
+ * @param enterTime 进公司时间
|
|
|
+ * @param now 现在
|
|
|
+ */
|
|
|
+ private int getWorkAnnual(LocalDateTime enterTime, LocalDateTime now) {
|
|
|
+ int year = DateUtils.getYears(enterTime, now);
|
|
|
+ return year / 5;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算法定年假
|
|
|
+ * <p>
|
|
|
+ * ①国家政策
|
|
|
+ * ≥ 1年 & < 10年:5天
|
|
|
+ * ≥10年 & < 20年:10天
|
|
|
+ * ≥20年:15天
|
|
|
+ *
|
|
|
+ * @param workTime 工作时间
|
|
|
+ * @param now 现在
|
|
|
+ */
|
|
|
+ private int getLowAnnual(LocalDateTime workTime, LocalDateTime now) {
|
|
|
+ int year = DateUtils.getYears(workTime, now);
|
|
|
+ if (1 <= year && 10 > year) {
|
|
|
+ return 5;
|
|
|
+ } else if (10 <= year && 20 > year) {
|
|
|
+ return 10;
|
|
|
+ } else if (20 <= year) {
|
|
|
+ return 15;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 上一年年假清零
|
|
|
+ */
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @XxlJob("annualLeaveClearJob")
|
|
|
+ public void annualLeaveClearJob() throws InterruptedException {
|
|
|
+ //查询未删除员工
|
|
|
+ List<StaffRecordSDO> staffs = recordsMapper.selectList(new LambdaQueryWrapperX<StaffRecordSDO>().eq(StaffRecordSDO::getDeleted, "0"));
|
|
|
+ List<StaffRecordSDO> res = new ArrayList<>();
|
|
|
+ for (StaffRecordSDO staff : staffs) {
|
|
|
+ int year = statisticAnnualLeave(staff);
|
|
|
+ int left = staff.getNj() == null ? 0 : staff.getNj();
|
|
|
+
|
|
|
+ if (year < left) {
|
|
|
+ staff.setNj(year);
|
|
|
+ res.add(staff);
|
|
|
+ }
|
|
|
+ res.add(staff);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("年假计算完毕 开始入库");
|
|
|
+ if (CollectionUtil.isNotEmpty(res)) {
|
|
|
+ recordsMapper.updateBatch(res);
|
|
|
+ }
|
|
|
+ log.info("年假入库完毕 年假计算程序运行结束");
|
|
|
+
|
|
|
+ }
|
|
|
+}
|