Commit 3924978fd7322595dff1e9529fb4eb5670fb7a03

Authored by 张志伟
1 parent f77829b1

:zap: feature(*): 调整工资发放逻辑

- 调整工资发放逻辑
fw-morax-common/src/main/java/cn/fw/morax/common/constant/TimeTaskConstant.java
... ... @@ -24,12 +24,12 @@ public class TimeTaskConstant {
24 24 /**
25 25 * 缓存计算绩效组得分定时器 绩效组人员数据上报完成后
26 26 */
27   - public static final String CACHE_CALCULATE_KPI_GROUP = "0 0 3 * * ?";
  27 + public static final String CACHE_CALCULATE_KPI_GROUP = "0 0 4 * * ?";
28 28  
29 29 /**
30 30 * 缓存计算绩效排名包定时器 绩效组人员数据上报完成后
31 31 */
32   - public static final String CACHE_CALCULATE_KPI_GROUP_RANK = "0 0 4 * * ?";
  32 + public static final String CACHE_CALCULATE_KPI_GROUP_RANK = "0 0 5 * * ?";
33 33  
34 34 /**
35 35 * 薪酬组人员定时器 每天凌晨1点
... ... @@ -39,7 +39,7 @@ public class TimeTaskConstant {
39 39 /**
40 40 * 缓存计算薪酬组得分定时器 每天凌晨5点,绩效得分计算完成后
41 41 */
42   - public static final String CACHE_CALCULATE_SALARY_GROUP = "0 0 5 * * ?";
  42 + public static final String CACHE_CALCULATE_SALARY_GROUP = "0 0 6 * * ?";
43 43  
44 44 /**
45 45 * 薪酬组定时器 每个月1号凌晨3点
... ... @@ -57,11 +57,6 @@ public class TimeTaskConstant {
57 57 public static final String SALARY_CONFIRM_TODO = "1 0 0/2 * * ?";
58 58  
59 59 /**
60   - * 薪酬确认推送检查 每隔两小时
61   - */
62   - public static final String SALARY_CONFIRM_TODO_CHECK = "1 0 0/2 * * ?";
63   -
64   - /**
65 60 * 绩效报表定时器 每天凌晨8点
66 61 */
67 62 public static final String KPI_REPORT = "0 0 8 * * ?";
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/KpiCalcTask.java
... ... @@ -12,6 +12,7 @@ import org.springframework.scheduling.annotation.Scheduled;
12 12 import org.springframework.stereotype.Component;
13 13  
14 14 import java.time.LocalDate;
  15 +import java.time.YearMonth;
15 16  
16 17 /**
17 18 * @author : kurisu
... ... @@ -46,7 +47,7 @@ public class KpiCalcTask {
46 47 }
47 48  
48 49 /**
49   - * 需要计算绩效得分的绩效组写入缓存 每天3
  50 + * 需要计算绩效得分的绩效组写入缓存 每天4
50 51 */
51 52 @Scheduled(cron = TimeTaskConstant.CACHE_CALCULATE_KPI_GROUP)
52 53 public void cacheCalculableKpiGroup() {
... ... @@ -71,7 +72,7 @@ public class KpiCalcTask {
71 72 }
72 73  
73 74 /**
74   - * 需要计算绩效排名的绩效组写入缓存 每天4
  75 + * 需要计算绩效排名的绩效组写入缓存 每天5
75 76 */
76 77 @Scheduled(cron = TimeTaskConstant.CACHE_CALCULATE_KPI_GROUP_RANK)
77 78 public void cacheCalculableKpiGroupRank() {
... ... @@ -86,4 +87,22 @@ public class KpiCalcTask {
86 87 public void calcuStarLevel() {
87 88 kpiPoolBizService.calcuStarLevel();
88 89 }
  90 +
  91 + /**
  92 + * 缓存上月最后一天的绩效组为绩效分最终计算做准备
  93 + * 每个月2号 0点10分执行
  94 + */
  95 + @Scheduled(cron = "0 10 0 2 * ?")
  96 + public void cacheFinalCalculableKpiGroup() {
  97 + kpiCalculateService.cacheCalculableKpiGroupIds(YearMonth.now().minusMonths(1L).atEndOfMonth());
  98 + }
  99 +
  100 + /**
  101 + * 缓存上月最后一天的绩效组为绩效组排名的最终计算做准备
  102 + * 每个月2号 1点执行
  103 + */
  104 + @Scheduled(cron = "0 0 1 2 * ?")
  105 + public void cacheFinalCalculableKpiGroupRank() {
  106 + kpiPoolBizService.cacheCalculableKpiGroupRank(YearMonth.now().minusMonths(1L).atEndOfMonth());
  107 + }
89 108 }
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/PayoffTask.java
... ... @@ -47,58 +47,59 @@ public class PayoffTask {
47 47 this.salaryConfirmBizService = salaryConfirmBizService;
48 48 }
49 49  
50   -// /**
51   -// * 发放工资的准备
52   -// */
  50 + /**
  51 + * 发放工资的准备
  52 + * [展示不对接财务]
  53 + */
53 54 // @Scheduled(initialDelay = 1000L * 10, fixedRate = 1000L * 30)
54   -// public void read2payoff() {
  55 + public void read2payoff() {
55 56 // payoffBizService.read2payoff();
56   -// }
57   -//
58   -// /**
59   -// * 发放工资
60   -// */
  57 + }
  58 +
  59 + /**
  60 + * 发放工资
  61 + * [暂时不对接财务]
  62 + */
61 63 // @Scheduled(initialDelay = 1000L * 20, fixedRate = 1000L * 20)
62   -// public void go2pay() {
63   -// payoffBizService.go2payoff();
64   -// }
65   -//
66   -// /**
67   -// * 生成工资单
68   -// */
69   -// @Scheduled(initialDelay = 1000L * 60, fixedRate = 1000L * 60)
70   -// public void createSalarySheet() {
71   -// Lock lock = distributedLocker.lock(LOCK_KEY);
72   -// if (((RLock) lock).isLocked()) {
73   -// List<GroupDTO> list = oopRpcService.allGroups();
74   -// if (!CollectionUtils.isEmpty(list)) {
75   -// for (GroupDTO groupDTO : list) {
76   -// payoffBizService.createSalarySheet(groupDTO.getId());
77   -// }
78   -// }
79   -// lock.unlock();
80   -// }
81   -// }
82   -//
83   -// /**
84   -// * 生成工资确认待办(在申述期开始时发送工资确认待办)
85   -// * 每隔两小时检查一次是否有未生成确认待办的薪酬池数据
86   -// */
87   -// @Scheduled(cron = TimeTaskConstant.SALARY_CONFIRM_TODO)
88   -// public void createSalaryConfirmTodo() {
89   -// log.info("定时任务【生成工资确认待办】开始执行");
90   -// List<GroupDTO> list = oopRpcService.allGroups();
91   -// for (GroupDTO groupDTO : list) {
92   -// salaryConfirmBizService.createSalaryConfirmTodo(groupDTO.getId());
93   -// }
94   -// }
95   -//
96   -// /**
97   -// * 每隔两小时检查待办推送
98   -// */
99   -// @Scheduled(cron = TimeTaskConstant.SALARY_CONFIRM_TODO_CHECK)
100   -// public void pushTodo() {
101   -// log.info("定时任务【推送工资确认待办】开始执行");
102   -// salaryConfirmBizService.pushConfirm();
103   -// }
  64 + public void go2pay() {
  65 + // payoffBizService.go2payoff();
  66 + }
  67 +
  68 + /**
  69 + * 生成工资单
  70 + * 每两个小时执行
  71 + */
  72 + @Scheduled(cron = "0 0 0/2 * * ?")
  73 + public void createSalarySheet() {
  74 + Lock lock = distributedLocker.lock(LOCK_KEY);
  75 + if (((RLock) lock).isLocked()) {
  76 + List<GroupDTO> list = oopRpcService.allGroups();
  77 + if (!CollectionUtils.isEmpty(list)) {
  78 + for (GroupDTO groupDTO : list) {
  79 + payoffBizService.createSalarySheet(groupDTO.getId());
  80 + }
  81 + }
  82 + lock.unlock();
  83 + }
  84 + }
  85 +
  86 + /**
  87 + * 生成工资确认待办(在申述期开始时发送工资确认待办)
  88 + * 每隔两小时检查一次是否有未生成确认待办的薪酬池数据
  89 + */
  90 + @Scheduled(cron = TimeTaskConstant.SALARY_CONFIRM_TODO)
  91 + public void createSalaryConfirmTodo() {
  92 + List<GroupDTO> list = oopRpcService.allGroups();
  93 + for (GroupDTO groupDTO : list) {
  94 + salaryConfirmBizService.createSalaryConfirmTodo(groupDTO.getId());
  95 + }
  96 + }
  97 +
  98 + /**
  99 + * 每隔两小时检查待办推送
  100 + */
  101 + @Scheduled(cron = "0 0/10 * * * ?")
  102 + public void pushTodo() {
  103 + salaryConfirmBizService.pushConfirm();
  104 + }
104 105 }
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryCalcTask.java
... ... @@ -45,7 +45,7 @@ public class SalaryCalcTask {
45 45 }
46 46  
47 47 /**
48   - * 需要计算薪酬的薪酬组写入缓存 每天5
  48 + * 需要计算薪酬的薪酬组写入缓存 每天6
49 49 */
50 50 @Scheduled(cron = TimeTaskConstant.CACHE_CALCULATE_SALARY_GROUP)
51 51 public void cacheCalculableKpiGroup() {
... ... @@ -70,4 +70,13 @@ public class SalaryCalcTask {
70 70 salaryCalcService.retryCalcSalary();
71 71 }
72 72  
  73 + /**
  74 + * 缓存上月最后一天的薪酬组为薪资的最终计算做准备
  75 + * 每个月2号 2点执行
  76 + */
  77 + @Scheduled(cron = "0 0 2 2 * ?")
  78 + public void cacheFinalCalculableKpiGroup() {
  79 + salaryCalcService.prepareCalcSalary(LocalDate.now().minusDays(1L));
  80 + }
  81 +
73 82 }
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/salary/PayoffBizService.java
... ... @@ -82,19 +82,19 @@ public class PayoffBizService {
82 82 * 准备
83 83 */
84 84 public void read2payoff() {
85   -// List<PayrollRecord> list = payrollRecordService.list(Wrappers.<PayrollRecord>lambdaQuery()
86   -// .eq(PayrollRecord::getPayrollStatus, SalaryPayrollStatusEnum.WAITING)
87   -// );
88   -// if (CollectionUtils.isEmpty(list)) {
89   -// return;
90   -// }
91   -// BoundSetOperations<String, String> setOps = stringRedisTemplate.boundSetOps(getPayoffKey());
92   -// for (PayrollRecord payrollRecord : list) {
93   -// String idstr = String.valueOf(payrollRecord.getId());
94   -// if (!Boolean.TRUE.equals(setOps.isMember(idstr))) {
95   -// setOps.add(idstr);
96   -// }
97   -// }
  85 + List<PayrollRecord> list = payrollRecordService.list(Wrappers.<PayrollRecord>lambdaQuery()
  86 + .eq(PayrollRecord::getPayrollStatus, SalaryPayrollStatusEnum.WAITING)
  87 + );
  88 + if (CollectionUtils.isEmpty(list)) {
  89 + return;
  90 + }
  91 + BoundSetOperations<String, String> setOps = stringRedisTemplate.boundSetOps(getPayoffKey());
  92 + for (PayrollRecord payrollRecord : list) {
  93 + String idstr = String.valueOf(payrollRecord.getId());
  94 + if (!Boolean.TRUE.equals(setOps.isMember(idstr))) {
  95 + setOps.add(idstr);
  96 + }
  97 + }
98 98 }
99 99  
100 100  
... ... @@ -120,7 +120,7 @@ public class PayoffBizService {
120 120 .eq(SalaryGeneralSettin::getYn, Boolean.TRUE)
121 121 .eq(SalaryGeneralSettin::getGroupId, groupId)
122 122 , Boolean.FALSE);
123   - int payoffDate = Optional.ofNullable(settin.getPayoffDate()).orElse(5);
  123 + int payoffDate = Optional.ofNullable(settin.getPayoffDate()).orElse(10);
124 124 int dayOfMonth = LocalDate.now().getDayOfMonth();
125 125 if (dayOfMonth >= payoffDate) {
126 126 List<SalaryPool> salaryPoolList = salaryPoolService.list(Wrappers.<SalaryPool>lambdaQuery()
... ... @@ -128,7 +128,6 @@ public class PayoffBizService {
128 128 .eq(SalaryPool::getPaid, Boolean.FALSE)
129 129 .eq(SalaryPool::getRegular, Boolean.TRUE)
130 130 .eq(SalaryPool::getYn, Boolean.TRUE)
131   - .last(" limit 500 ")
132 131 );
133 132 if (CollectionUtils.isEmpty(salaryPoolList)) {
134 133 return;
... ... @@ -159,6 +158,8 @@ public class PayoffBizService {
159 158 if (Objects.isNull(corporateRecord)) {
160 159 return;
161 160 }
  161 + // fixme 暂时自动发放工资不对接财务,后续放开
  162 + corporateRecord.setPayrollStatus(SalaryPayrollStatusEnum.COMPLETE);
162 163 BigDecimal reward = pool.getReward();
163 164 if (maxAmount.compareTo(BigDecimal.ZERO) > 0 && reward.compareTo(maxAmount) > 0) {
164 165 corporateRecord.setAmount(maxAmount);
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/salary/SalaryConfirmBizService.java
... ... @@ -25,7 +25,6 @@ import org.springframework.stereotype.Service;
25 25 import org.springframework.transaction.annotation.Transactional;
26 26 import org.springframework.util.CollectionUtils;
27 27  
28   -import java.time.LocalDate;
29 28 import java.time.LocalDateTime;
30 29 import java.time.YearMonth;
31 30 import java.util.*;
... ... @@ -116,12 +115,12 @@ public class SalaryConfirmBizService {
116 115 if (Objects.isNull(settin)) {
117 116 settin = salaryGeneralSettinService.initData(groupId);
118 117 }
119   - String datesOfAppeal = Optional.ofNullable(settin.getDatesOfAppeal()).orElse("1,5");
  118 + String datesOfAppeal = Optional.ofNullable(settin.getDatesOfAppeal()).orElse("3,5");
120 119 String[] daysArr = datesOfAppeal.split(",");
121   - int day = Integer.parseInt(daysArr[1]);
122   - final LocalDateTime planTime = YearMonth.now().atDay(day).atTime(9, 0);
123   - int payoffDate = Optional.ofNullable(settin.getPayoffDate()).orElse(5);
124   - final LocalDateTime deadline = YearMonth.now().atDay(payoffDate).atStartOfDay().minusSeconds(1L);
  120 + int day = Integer.parseInt(daysArr[0]);
  121 + final LocalDateTime planTime = YearMonth.now().atDay(day).atTime(9, 0,0);
  122 + int endDay = Integer.parseInt(daysArr[1]);
  123 + final LocalDateTime deadline = YearMonth.now().atDay(endDay).atTime(23, 59, 59);
125 124 createConfirms(planTime, deadline, groupId);
126 125 } finally {
127 126 lock.unlock();
... ... @@ -133,8 +132,8 @@ public class SalaryConfirmBizService {
133 132 */
134 133 public void pushConfirm() {
135 134 List<SalaryConfirm> list = salaryConfirmService.list(Wrappers.<SalaryConfirm>lambdaQuery()
136   - .ge(SalaryConfirm::getPlanTime, LocalDateTime.now().minusDays(3L))
137   - .le(SalaryConfirm::getDeadline, LocalDate.now().plusDays(1L).atStartOfDay())
  135 + .le(SalaryConfirm::getPlanTime, LocalDateTime.now())
  136 + .gt(SalaryConfirm::getDeadline, LocalDateTime.now().plusHours(2L))
138 137 .eq(SalaryConfirm::getPushedTodo, Boolean.FALSE)
139 138 .eq(SalaryConfirm::getYn, Boolean.TRUE)
140 139 .last(" limit 500 ")
... ...