Browse Source

虹桥凯悦v3.0

wzy 7 months ago
parent
commit
ca98f6251b

+ 4 - 11
mjava-kaiyue/src/main/java/com/malk/kaiyue/controller/KYHQController.java

@@ -76,22 +76,14 @@ public class KYHQController extends DDCallbackController {
         return McR.success(result);
     }
 
-
-    //每年1月1日 00:00定时更新员工旧职级
-    /*@Scheduled(cron = "0 0 0 1 1 ? ")
-    @GetMapping("/cronUpdateEmployeeOldPositionLevel")
-    McR cronUpdateEmployeeOldPositionLevel(){
-        System.out.println("定时更新员工旧职级开始执行"+new Date());
-        return kycdService.updateEmployeeOldPositionLevel();
-    }*/
-
     //每天 00:00定时更新员工年假数
-   /* @Scheduled(cron = "0 0 0 * * ? ")
+    //todo 20241101 年假规则无法满足客户需求 暂时停用
+//    @Scheduled(cron = "0 0 0 * * ? ")
     @GetMapping("/cronUpdateEmployeeAnnualLeaveNum")
     McR cronUpdateEmployeeAnnualLeaveNum(){
         System.out.println("定时更新员工年假数开始执行"+new Date());
         return kyhqService.updateEmployeeAnnualLeaveNum();
-    }*/
+    }
 
     //保存十分钟内已处理的回调事件
     private Map<String, Long> eventList = new HashMap<>();
@@ -131,6 +123,7 @@ public class KYHQController extends DDCallbackController {
             map.put("userid_list", userId);
             //更新员工年假余额
             log.info("----- [DD]更新员工年假余额 -----");
+            //todo 虹桥凯悦年假每日发放   故不需要订阅事件
             kyhqService.getEmployeeAnnualLeaveNum(map);
             return success;
         }

+ 0 - 6
mjava-kaiyue/src/main/java/com/malk/kaiyue/service/KYHQService.java

@@ -16,12 +16,6 @@ public interface KYHQService extends IService<AdvancedLeave> {
 
     Map getEmployeeAnnualLeaveNum(Map<String, Object> map);
 
-    /**
-     * 每年1月1日 00:00定时更新员工旧职级
-     * @return
-     */
-//    McR updateEmployeeOldPositionLevel();
-
     /**
      * 每年1月1日 01:00定时更新员工年假数
      * @return

+ 87 - 47
mjava-kaiyue/src/main/java/com/malk/kaiyue/service/impl/KYHQServiceImpl.java

@@ -52,11 +52,17 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
     @Value("${dingtalk_hq.operator}")
     private String opUserId;
 
-    //虹桥凯悦-年假(测试)
+    //虹桥凯悦-年假(停用)
 //    private static final String LEAVE_CODE = "9e87c02b-3825-4662-90b5-89968ed73271";
 
     //虹桥凯悦-年假
-    private static final String LEAVE_CODE = "126b5424-fce2-4e77-a981-9efa3d240b1a";
+    private static final String LEAVE_CODE = "9c49213b-6be0-4f6d-b376-15f7131ce6c6";
+
+    //虹桥凯悦-年假(测)
+//    private static final String LEAVE_CODE = "d6a6e8d2-bff6-4ea2-b88a-50208074a04f";
+
+    //虹桥凯悦-年假(旧)
+//    private static final String LEAVE_CODE = "126b5424-fce2-4e77-a981-9efa3d240b1a";
 
     //虹桥凯悦-补休假
     private static final String COMPENSATORY_LEAVE_CODE = "b57e2a2a-b553-4955-b2a2-21c9f42f5420";
@@ -67,7 +73,7 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
         Map<String,Object> map = new HashMap<>();
         //在职员工状态筛选,可以查询多个状态。不同状态之间使用英文逗号分隔。
         //2:试用期  3:正式  5:待离职  -1:无状态
-        map.put("status_list","3");
+        map.put("status_list","2,3");
         //分页游标,从0开始。根据返回结果里的next_cursor是否为空来判断是否还有下一页,且再次调用时offset设置成next_cursor的值。
         map.put("offset",0);
         //分页大小,最大50。
@@ -122,7 +128,7 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
         //查询接口body添加参数
         //field_filter_list:要查询字段(花名册字段信息参考:https://open.dingtalk.com/document/orgapp/roster-custom-field-business-code)
         //agentid:企业内部应用AgentId
-        map.put("field_filter_list","sys00-name,sys01-positionLevel,sys00-confirmJoinTime,371db808-4043-4f03-9c27-8fc8a08e741d,b00c205d-c509-4f01-8706-5279d10532f8,sys05-nowContractStartTime,sys05-contractRenewCount");
+        map.put("field_filter_list","sys00-name,sys01-positionLevel,sys01-employeeType,sys00-confirmJoinTime,371db808-4043-4f03-9c27-8fc8a08e741d,b00c205d-c509-4f01-8706-5279d10532f8,sys05-nowContractStartTime,sys05-contractRenewCount");
         map.put("agentid",agentId);
 
         List<Map> errorList = new ArrayList<>();
@@ -150,6 +156,8 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                     String contractStartTime = "";
                     //合同续签次数
                     int contractRenewCount = 0;
+                    //员工类型
+                    String employeeType = "";
 
                     List<Map> fieldDataList = (List<Map>) data.get("field_data_list");
                     for (Map fieldData : fieldDataList) {
@@ -157,7 +165,8 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                         List<Map> fieldValueList = (List<Map>) fieldData.get("field_value_list");
 
                         if (Objects.nonNull(fieldValueList.get(0).get("value"))){
-                            String value = fieldValueList.get(0).get("value").toString();
+                            String value = getString(fieldValueList.get(0).get("value"));
+                            String label = getString(fieldValueList.get(0).get("label"));
                             switch (fieldCode){
                                 case "sys00-confirmJoinTime": confirmJoinTime = value;break;
                                 case "sys01-positionLevel": positionLevel = value;break;
@@ -165,11 +174,27 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                                 case "371db808-4043-4f03-9c27-8fc8a08e741d": oldPositionLevel = value;break;//原职级
                                 case "b00c205d-c509-4f01-8706-5279d10532f8": promotionTime = value;break;//升职日期
                                 case "sys05-nowContractStartTime": contractStartTime = value;break;
-                                case "sys05-contractRenewCount": contractRenewCount = Integer.valueOf(value);break;
+                                case "sys05-contractRenewCount": contractRenewCount = value.equals("") ? 0 : Integer.valueOf(value);break;
+                                case "sys01-employeeType": employeeType = label;break;
                                 default:break;
                             }
                         }
                     }
+                    if (employeeType.equals("劳务外包")){
+                        Map successMap = new HashMap();
+                        successMap.put(userId,"姓名:"+name+",劳务外包不发放年假");
+                        successList.add(successMap);
+
+                        continue;
+                    }
+                    if (employeeType.equals("实习")){
+                        Map successMap = new HashMap();
+                        successMap.put(userId,"姓名:"+name+",实习生不发放年假");
+                        successList.add(successMap);
+
+                        continue;
+                    }
+
                     //若没有原职级 则默认原职级是现职级
                     if ("".equals(oldPositionLevel)){
                         oldPositionLevel = positionLevel;
@@ -197,6 +222,7 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                     DateTime endDate = DateUtil.beginOfDay(DateUtil.endOfYear(new Date()));
                     //今天
                     DateTime today = DateUtil.date();
+//                    DateTime today = DateUtil.offsetDay(DateUtil.date(),1);
                     //当年天数
                     int yearDays = DateUtil.dayOfYear(endDate);
                     //年假
@@ -284,7 +310,7 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                     yearLeave = Math.floor(yearLeave * 100.0) / 100.0;
 
                     //查询出用户消费年假记录 当返回leaveRecords中calType为null或不返回该字段则为请假消耗 将计算出的年假数减去请假消耗的数量
-                /*Map body = new HashMap();
+                Map body = new HashMap();
                 body.put("opUserId",opUserId);
                 body.put("leaveCode",LEAVE_CODE);
                 body.put("userIds",new String[]{userId});
@@ -293,24 +319,28 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                 DDR_New useDdr = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/attendance/vacations/records/query", DDConf.initTokenHeader(access_token), null, body, DDR_New.class);
                 Map useResult = (Map) useDdr.getResult();
                 List<Map> useList = (List<Map>) useResult.get("leaveRecords");
-                Double useLeaveNum = 0d;
+                int useLeaveNum = 0;
                 if (Objects.nonNull(useList) && !useList.isEmpty()){
                     for (Map use : useList) {
                         DateTime gmtCreate = DateUtil.date((long) use.get("gmtCreate"));
                         //获取今年请假记录
                         if (DateUtil.year(gmtCreate) == DateUtil.year(new Date())){
                             //判断是否为正常请假而不是接口测试或期初假期发放
-                            if (!"接口测试修改".equals(use.get("leaveReason").toString()) && !"期初假期发放".equals(use.get("leaveReason").toString())){
-                                //若是请假消耗或管理员手动减少
-                                if (!use.containsKey("calType") || Objects.isNull(use.get("calType")) || "delete".equals(use.get("calType").toString())){
-                                    useLeaveNum += (int) use.get("recordNumPerDay") / 100;
+                            if (!"接口测试修改".equals(use.get("leaveReason").toString()) && !"接口年假发放".equals(use.get("leaveReason").toString())){
+                                //请假消耗此处无需计算 !use.containsKey("calType") || Objects.isNull(use.get("calType"))
+                                //若是管理员手动减少
+                                if (use.containsKey("calType") && Objects.nonNull(use.get("calType"))){
+                                    if ("delete".equals(use.get("calType").toString())){
+                                        useLeaveNum += (int) use.get("recordNumPerDay");
+                                    }/*else if("add".equals(use.get("calType").toString())){
+                                        //注:若是管理员手动增加 则假期余额会多出一个 quota_cycle=年份-编码记录 增加的假期天数
+                                        //最终更新假期余额的quota_cycle=年份  故此处手动新增的假期余额不做处理
+                                    }*/
                                 }
-                                //注:若是管理员手动增加 则假期余额会多出一个BCXsunNm记录增加的假期天数  最终会在设置的假期余额的基础上加上这些天数
-                                //故此处手动新增的假期余额不做处理
                             }
                         }
                     }
-                }*/
+                }
 
                     //年假余额
                     BigDecimal annualLeaveNum = new BigDecimal(0.00);
@@ -340,32 +370,36 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                             .eq(AdvancedLeave::getValidFlag,"1")
                             .eq(AdvancedLeave::getCity,"hq");
                     AdvancedLeave advancedLeave = advancedLeaveMapper.selectOne(advancedLeaveLambdaQueryWrapper);
-                    if (Objects.nonNull(advancedLeave)){
-//                        advanceLeave = Double.valueOf(advancedLeave.getLeaveNum());
-                        //年假余额大于3时 默认3
-                        if (annualLeaveNum.compareTo(new BigDecimal(3)) > 0){
-                            annualLeaveNum = new BigDecimal(3);
-                        }
-                        advanceLeave = Double.parseDouble(annualLeaveNum.subtract(annualLeaveNum.remainder(new BigDecimal(0.5))).toString());
 
-                        advancedLeave.setLeaveNum(advanceLeave+"");
-                        advancedLeaveMapper.updateById(advancedLeave);
-                    }
-                    else {
+                    if (Objects.nonNull(advancedLeave)){
+                        advanceLeave = Double.valueOf(advancedLeave.getLeaveNum());
+                    }else {
                         advancedLeave = new AdvancedLeave();
 
-                        //todo 暂时预支假全都设置为3天
-                        //todo 数据表里任何年份都没有记录时 默认预支假为3天
-                        advanceLeave = 3.0;
-                        advancedLeave.setLeaveNum(advanceLeave + "");
-                        advancedLeave.setUserId(userId);
-                        advancedLeave.setYear(String.valueOf(DateUtil.year(new Date())));
-                        advancedLeave.setCity("hq");
-                        advancedLeaveMapper.insert(advancedLeave);
+                        //1月1日 则根据年假余额计算当年预支假
+                        if (DateUtil.beginOfYear(new Date()).equals(today)){
+                            //年假余额小于3时
+                            if (annualLeaveNum.compareTo(new BigDecimal(3)) < 0){
+                                advanceLeave = Double.parseDouble(annualLeaveNum.subtract(annualLeaveNum.remainder(new BigDecimal(0.5))).toString());
+                            }
+
+                            advancedLeave.setLeaveNum(advanceLeave + "");
+                            advancedLeave.setUserId(userId);
+                            advancedLeave.setYear(String.valueOf(DateUtil.year(new Date())));
+                            advancedLeave.setCity("hq");
+                            advancedLeaveMapper.insert(advancedLeave);
+                        }else {
+                            //若当天不是1月1日且表中没有预支假记录 则默认预支假为3天
+                            advancedLeave.setLeaveNum(advanceLeave + "");
+                            advancedLeave.setUserId(userId);
+                            advancedLeave.setYear(String.valueOf(DateUtil.year(new Date())));
+                            advancedLeave.setCity("hq");
+                            advancedLeaveMapper.insert(advancedLeave);
+                        }
                     }
 
                     //年假总数
-                    int realYearLeave =  NumberUtil.sub(yearLeave, -advanceLeave) < 0 ? 0 : (int) (NumberUtil.sub(yearLeave, -advanceLeave) * 100);
+                    int realYearLeave =  NumberUtil.sub(yearLeave, -advanceLeave) < 0 ? 0 : (int) (NumberUtil.sub(yearLeave, -advanceLeave) * 100) ;
 
                     //获取员工原年假余额 取较大值
                 /*Map balanceMap = new HashMap();
@@ -402,7 +436,7 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                     //操作原因
                     leave_quotas.put("reason","接口测试修改");
                     //以天计算的额度总数 假期类型按天计算时,该值不为空且按百分之一天折算。 例如:1000=10天。
-                    leave_quotas.put("quota_num_per_day",realYearLeave);
+                    leave_quotas.put("quota_num_per_day",realYearLeave - useLeaveNum);
                     //以小时计算的额度总数 假期类型按小时,计算该值不为空且按百分之一小时折算。例如:1000=10小时。
                     leave_quotas.put("quota_num_per_hour",0);
                     //额度所对应的周期,格式必须是"yyyy",例如"2021"
@@ -428,13 +462,14 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                     long currentTime = System.currentTimeMillis();
                     bodyList.put(bodyStr, currentTime);
 
-                    Map successMap = new HashMap();
-                    successMap.put(userId,"姓名:"+name+",职级:" + positionLevel+",原职级:" + oldPositionLevel+",入职日期:" + confirmJoinTime + ",升职日期:" + promotionTime + ",年假数:"+ realYearLeave + ",开始日期:" + beginDate+",截止日期:" + endDate);
-                    successList.add(successMap);
                     //更新假期余额
                     UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/vacation/quota/update", null, DDConf.initTokenParams(access_token), updateBody, DDR.class);
 
+                    Map successMap = new HashMap();
+                    successMap.put(userId,"姓名:"+name+",职级:" + positionLevel+",原职级:" + oldPositionLevel+",入职日期:" + confirmJoinTime + ",升职日期:" + promotionTime + ",年假数:"+ realYearLeave + ",开始日期:" + beginDate+",截止日期:" + endDate);
+                    successList.add(successMap);
                 }catch (Exception e){
+                    log.info("更新员工年假失败:{}",e);
                     Map errorMap = new HashMap();
                     errorMap.put(userId,e.getMessage());
                     errorList.add(errorMap);
@@ -450,6 +485,10 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
         return result;
     }
 
+    private String getString(Object label) {
+        return Objects.isNull(label) ? "" : label.toString();
+    }
+
 
     @Override
     public McR updateEmployeeAnnualLeaveNum() {
@@ -513,17 +552,18 @@ public class KYHQServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
                 }
             }
         }
-
-        if (annualLeaveNum.compareTo(new BigDecimal(3)) >= 0){
-            annualLeaveNum = annualLeaveNum.subtract(new BigDecimal(3));
-            leaveMap.put("可预支年假",3);
+        //todo 2024年预支假临时改为5天 2025年预支假改为3天
+        if (annualLeaveNum.compareTo(new BigDecimal(5)) >= 0){
+            annualLeaveNum = annualLeaveNum.subtract(new BigDecimal(5));
+            leaveMap.put("可预支年假",5);
             leaveMap.put("实际年假余额",annualLeaveNum);
             leaveMap.put("已预支年假",0);
         }else {
-            BigDecimal relYearLeave = annualLeaveNum.remainder(new BigDecimal(0.5));
-            leaveMap.put("可预支年假",annualLeaveNum.subtract(relYearLeave));
-            leaveMap.put("实际年假余额",annualLeaveNum.subtract(new BigDecimal(3)));
-            leaveMap.put("已预支年假",new BigDecimal(3).subtract(annualLeaveNum).add(relYearLeave));
+            //不考虑年假最小单位为半天的情况 预支假可以不是0.5的倍数
+//            BigDecimal relYearLeave = annualLeaveNum.remainder(new BigDecimal(0.5));
+            leaveMap.put("可预支年假",annualLeaveNum);
+            leaveMap.put("实际年假余额",annualLeaveNum.subtract(new BigDecimal(5)));
+            leaveMap.put("已预支年假",new BigDecimal(5).subtract(annualLeaveNum));
         }
 
         //获取员工补休假余额