|
@@ -3,10 +3,13 @@ package com.malk.kaiyue.service.impl;
|
|
|
import cn.hutool.core.date.DateTime;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.NumberUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.malk.kaiyue.entity.AdvancedLeave;
|
|
|
+import com.malk.kaiyue.entity.KaiyueLog;
|
|
|
import com.malk.kaiyue.mapper.AdvancedLeaveMapper;
|
|
|
+import com.malk.kaiyue.mapper.KaiyueLogMapper;
|
|
|
import com.malk.kaiyue.service.KYCDService;
|
|
|
import com.malk.server.common.McR;
|
|
|
import com.malk.server.dingtalk.DDConf;
|
|
@@ -21,6 +24,8 @@ import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.text.ParseException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
@@ -36,6 +41,9 @@ public class KYCDServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
|
|
|
@Autowired
|
|
|
private AdvancedLeaveMapper advancedLeaveMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private KaiyueLogMapper kaiyueLogMapper;
|
|
|
+
|
|
|
@Value("${dingtalk_cd.appKey}")
|
|
|
private String appKey;
|
|
|
|
|
@@ -58,6 +66,9 @@ public class KYCDServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
|
|
|
//体验社-成都年假测试
|
|
|
// private static final String LEAVE_CODE = "609a84ed-54d4-4ecd-a44f-4c55b04c37ea";
|
|
|
|
|
|
+ //预支年假
|
|
|
+ private static final double ADVANCE_LEAVE = 8.0;
|
|
|
+
|
|
|
@Override
|
|
|
public List<String> getEmployeeUserId() {
|
|
|
Map<String,Object> map = new HashMap<>();
|
|
@@ -118,7 +129,7 @@ public class KYCDServiceImpl 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,b433c687-c3b3-4f97-8498-d23944f3316b,80292628-1c88-4c25-9c40-3e91283552e7");
|
|
|
+ map.put("field_filter_list","sys00-name,sys01-positionLevel,sys00-confirmJoinTime,b433c687-c3b3-4f97-8498-d23944f3316b,80292628-1c88-4c25-9c40-3e91283552e7,sys01-employeeType");
|
|
|
map.put("agentid",agentId);
|
|
|
|
|
|
List<String> result = new ArrayList<>();
|
|
@@ -126,123 +137,148 @@ public class KYCDServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
|
|
|
if (Objects.nonNull(map)){
|
|
|
DDR ddr = (DDR) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/v2/list", null, DDConf.initTokenParams(access_token), map, DDR.class);
|
|
|
List<Map> employeeData = (List<Map>) ddr.getResult();
|
|
|
-
|
|
|
+ String year = DateUtil.year(new Date()) + "";
|
|
|
//遍历员工信息
|
|
|
for (Map data : employeeData) {
|
|
|
String userId = data.get("userid").toString();
|
|
|
- //入职日期
|
|
|
- String confirmJoinTime = "";
|
|
|
- //职级
|
|
|
- String positionLevel = "";
|
|
|
- //姓名
|
|
|
- String name = "";
|
|
|
- //原职级
|
|
|
- String oldPositionLevel = "";
|
|
|
- //升职日期
|
|
|
- String promotionTime = "";
|
|
|
-
|
|
|
- List<Map> fieldDataList = (List<Map>) data.get("field_data_list");
|
|
|
- for (Map fieldData : fieldDataList) {
|
|
|
- String fieldCode = fieldData.get("field_code").toString();
|
|
|
- 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();
|
|
|
- switch (fieldCode){
|
|
|
- case "sys00-confirmJoinTime": confirmJoinTime = value;break;
|
|
|
- case "sys01-positionLevel": positionLevel = value;break;
|
|
|
- case "sys00-name": name = value;break;
|
|
|
- case "b433c687-c3b3-4f97-8498-d23944f3316b": oldPositionLevel = value;break;//成都原职级
|
|
|
+
|
|
|
+ KaiyueLog kaiyueLog = new KaiyueLog();
|
|
|
+ kaiyueLog.setCity("cd");
|
|
|
+ kaiyueLog.setUserId(userId);
|
|
|
+
|
|
|
+ kaiyueLog.setYear(year);
|
|
|
+
|
|
|
+ try{
|
|
|
+ //入职日期
|
|
|
+ String confirmJoinTime = "";
|
|
|
+ //职级
|
|
|
+ String positionLevel = "";
|
|
|
+ //姓名
|
|
|
+ String name = "";
|
|
|
+ //原职级
|
|
|
+ String oldPositionLevel = "";
|
|
|
+ //升职日期
|
|
|
+ String promotionTime = "";
|
|
|
+ //员工类型
|
|
|
+ String employeeType = "";
|
|
|
+
|
|
|
+ List<Map> fieldDataList = (List<Map>) data.get("field_data_list");
|
|
|
+ for (Map fieldData : fieldDataList) {
|
|
|
+ String fieldCode = fieldData.get("field_code").toString();
|
|
|
+ List<Map> fieldValueList = (List<Map>) fieldData.get("field_value_list");
|
|
|
+
|
|
|
+ if (Objects.nonNull(fieldValueList.get(0).get("value"))){
|
|
|
+ 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;
|
|
|
+ case "sys00-name": name = value;break;
|
|
|
+ case "b433c687-c3b3-4f97-8498-d23944f3316b": oldPositionLevel = value;break;//成都原职级
|
|
|
// case "7482b192-9f1d-49fa-adab-6f33f7d0951e": oldPositionLevel = value;break;//高级假期原职级
|
|
|
- case "80292628-1c88-4c25-9c40-3e91283552e7": promotionTime = value;break;//升职日期
|
|
|
- default:break;
|
|
|
+ case "80292628-1c88-4c25-9c40-3e91283552e7": promotionTime = value;break;//升职日期
|
|
|
+ case "sys01-employeeType": employeeType = label;break;
|
|
|
+ default:break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- //若没有原职级 则默认原职级是现职级
|
|
|
- if ("".equals(oldPositionLevel)){
|
|
|
- oldPositionLevel = positionLevel;
|
|
|
- }
|
|
|
- //若没有升职日期 则默认升职日期是入职日期
|
|
|
- if ("".equals(promotionTime)){
|
|
|
- promotionTime = confirmJoinTime;
|
|
|
- }
|
|
|
|
|
|
- if ("".equals(confirmJoinTime) || "".equals(positionLevel) || "".equals(name) || "".equals(oldPositionLevel)){
|
|
|
- log.info("更新员工年假余额:参数缺啦!");
|
|
|
- return McR.errorParam("参数缺啦!");
|
|
|
- }
|
|
|
+ //若员工类型为劳务外包或实习 不发放年假
|
|
|
+ if (!employeeType.equals("全职")) {
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ kaiyueLog.setMsg("员工类型不为全职 不发放年假");
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- //假期有效开始日期为当年1月1日
|
|
|
- DateTime beginDate = DateUtil.beginOfYear(new Date());
|
|
|
- //假期有效截至日期为当年12月31日
|
|
|
- DateTime endDate = DateUtil.endOfYear(new Date());
|
|
|
- //今天
|
|
|
- DateTime today = DateUtil.date();
|
|
|
- //当年天数
|
|
|
- int yearDays = DateUtil.dayOfYear(endDate);
|
|
|
- //年假
|
|
|
- double yearLeave = 0.0;
|
|
|
- //预支年假
|
|
|
- double advanceLeave = 8.0;
|
|
|
-
|
|
|
-
|
|
|
- //获取原职级年假基数
|
|
|
- int oldPositionLevelBaseNum = getAnnualLeaveBaseNum(oldPositionLevel);
|
|
|
- //获取现职级年假基数
|
|
|
- int positionLevelBaseNum = getAnnualLeaveBaseNum(positionLevel);
|
|
|
-
|
|
|
- //获取入职日期的月日
|
|
|
- String confirmJoinMonthAndDay = confirmJoinTime.substring(5);
|
|
|
- String year = DateUtil.year(new Date()) + "";
|
|
|
- //今年入职周年日
|
|
|
- DateTime anniversaryOfEmployment = DateUtil.parse(year + "-" + confirmJoinMonthAndDay);
|
|
|
-
|
|
|
- //计算今天是入职第几周年
|
|
|
- long anniversary = DateUtil.betweenYear(DateUtil.parse(confirmJoinTime), anniversaryOfEmployment, true) - 1;
|
|
|
- //判断员工是否当年新入职
|
|
|
- if (DateUtil.year(DateUtil.parse(confirmJoinTime)) == DateUtil.year(new Date())){
|
|
|
- //分两段计算:入职日到升职日,升职日到年底
|
|
|
- long day1 = DateUtil.betweenDay(DateUtil.parse(confirmJoinTime), DateUtil.parse(promotionTime), true);
|
|
|
- long day2 = DateUtil.betweenDay(DateUtil.parse(promotionTime), endDate, true);
|
|
|
- yearLeave = (double) (day1 * oldPositionLevelBaseNum + day2 * positionLevelBaseNum ) / yearDays;
|
|
|
- }else {
|
|
|
- //升职日期在今年入职周年日之前
|
|
|
- if (DateUtil.compare(anniversaryOfEmployment, DateUtil.parse(promotionTime)) >= 0){
|
|
|
- //升职日期在今年
|
|
|
- if (DateUtil.compare(DateUtil.parse(promotionTime),today) >= 0){
|
|
|
- //获取年初到升职日的天数
|
|
|
- int day1 = DateUtil.dayOfYear(DateUtil.parse(promotionTime));
|
|
|
- //获升职值日到入职周年日的天数
|
|
|
- long day2 = DateUtil.betweenDay(DateUtil.parse(promotionTime), anniversaryOfEmployment, true);
|
|
|
- //获取入职周年日到年底的天数
|
|
|
- long day3 = DateUtil.betweenDay(anniversaryOfEmployment, endDate, true);
|
|
|
- //分三段计算:年初-升职日,升职日到入职周年日,入职周年日到年底
|
|
|
- yearLeave = (double) (day1 * (oldPositionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (positionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day3 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays ;
|
|
|
- }else{
|
|
|
+ //若没有原职级 则默认原职级是现职级
|
|
|
+ if ("".equals(oldPositionLevel)){
|
|
|
+ oldPositionLevel = positionLevel;
|
|
|
+ }
|
|
|
+ //若没有升职日期 则默认升职日期是入职日期
|
|
|
+ if ("".equals(promotionTime)){
|
|
|
+ promotionTime = confirmJoinTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ("".equals(confirmJoinTime) || "".equals(positionLevel) || "".equals(name) || "".equals(oldPositionLevel)){
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ kaiyueLog.setMsg("更新员工年假余额:参数缺啦!");
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //假期有效开始日期为当年1月1日
|
|
|
+ DateTime beginDate = DateUtil.beginOfYear(new Date());
|
|
|
+ //假期有效截至日期为当年12月31日
|
|
|
+ DateTime endDate = DateUtil.endOfYear(new Date());
|
|
|
+ //今天
|
|
|
+ DateTime today = DateUtil.date();
|
|
|
+ //当年天数
|
|
|
+ int yearDays = DateUtil.dayOfYear(endDate);
|
|
|
+ //年假
|
|
|
+ double yearLeave = 0.0;
|
|
|
+ //预支年假
|
|
|
+ double advanceLeave = 8.0;
|
|
|
+
|
|
|
+
|
|
|
+ //获取原职级年假基数
|
|
|
+ int oldPositionLevelBaseNum = getAnnualLeaveBaseNum(oldPositionLevel);
|
|
|
+ //获取现职级年假基数
|
|
|
+ int positionLevelBaseNum = getAnnualLeaveBaseNum(positionLevel);
|
|
|
+
|
|
|
+ //获取入职日期的月日
|
|
|
+ String confirmJoinMonthAndDay = confirmJoinTime.substring(5);
|
|
|
+
|
|
|
+ //今年入职周年日
|
|
|
+ DateTime anniversaryOfEmployment = DateUtil.parse(year + "-" + confirmJoinMonthAndDay);
|
|
|
+
|
|
|
+ //计算今天是入职第几周年
|
|
|
+ long anniversary = DateUtil.betweenYear(DateUtil.parse(confirmJoinTime), anniversaryOfEmployment, true) - 1;
|
|
|
+ //判断员工是否当年新入职
|
|
|
+ if (DateUtil.year(DateUtil.parse(confirmJoinTime)) == DateUtil.year(new Date())){
|
|
|
+ //分两段计算:入职日到升职日,升职日到年底
|
|
|
+ long day1 = DateUtil.betweenDay(DateUtil.parse(confirmJoinTime), DateUtil.parse(promotionTime), true);
|
|
|
+ long day2 = DateUtil.betweenDay(DateUtil.parse(promotionTime), endDate, true);
|
|
|
+ yearLeave = (double) (day1 * oldPositionLevelBaseNum + day2 * positionLevelBaseNum ) / yearDays;
|
|
|
+ }else {
|
|
|
+ //升职日期在今年入职周年日之前
|
|
|
+ if (DateUtil.compare(anniversaryOfEmployment, DateUtil.parse(promotionTime)) >= 0){
|
|
|
+ //升职日期在今年
|
|
|
+ if (DateUtil.compare(DateUtil.parse(promotionTime),today) >= 0){
|
|
|
+ //获取年初到升职日的天数
|
|
|
+ int day1 = DateUtil.dayOfYear(DateUtil.parse(promotionTime));
|
|
|
+ //获升职值日到入职周年日的天数
|
|
|
+ long day2 = DateUtil.betweenDay(DateUtil.parse(promotionTime), anniversaryOfEmployment, true);
|
|
|
+ //获取入职周年日到年底的天数
|
|
|
+ long day3 = DateUtil.betweenDay(anniversaryOfEmployment, endDate, true);
|
|
|
+ //分三段计算:年初-升职日,升职日到入职周年日,入职周年日到年底
|
|
|
+ yearLeave = (double) (day1 * (oldPositionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (positionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day3 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays ;
|
|
|
+ }else{
|
|
|
+ //获取年初到入职周年日的天数
|
|
|
+ int day1 = DateUtil.dayOfYear(anniversaryOfEmployment);
|
|
|
+ //获取入职周年日到年底的天数
|
|
|
+ long day2 = DateUtil.betweenDay(anniversaryOfEmployment, endDate, true);
|
|
|
+ //分两段计算:年初到入职周年日,入职周年日到年底
|
|
|
+ yearLeave = (double) (day1 * (positionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays ;
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ //升职日在今年入职周年日之后
|
|
|
//获取年初到入职周年日的天数
|
|
|
int day1 = DateUtil.dayOfYear(anniversaryOfEmployment);
|
|
|
- //获取入职周年日到年底的天数
|
|
|
- long day2 = DateUtil.betweenDay(anniversaryOfEmployment, endDate, true);
|
|
|
- //分两段计算:年初到入职周年日,入职周年日到年底
|
|
|
- yearLeave = (double) (day1 * (positionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays ;
|
|
|
+ //获取入职周年日到升职日的天数
|
|
|
+ long day2 = DateUtil.betweenDay(anniversaryOfEmployment, DateUtil.parse(promotionTime), true);
|
|
|
+ //获取升职日到年底的天数
|
|
|
+ long day3 = DateUtil.betweenDay(DateUtil.parse(promotionTime), endDate, true);
|
|
|
+ //分三段计算:年初-入职周年日,入职周年日到升职日,升职日到年底
|
|
|
+ yearLeave = (double) (day1 * (oldPositionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (oldPositionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1)) + day3 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays;
|
|
|
}
|
|
|
- }else {
|
|
|
- //升职日在今年入职周年日之后
|
|
|
- //获取年初到入职周年日的天数
|
|
|
- int day1 = DateUtil.dayOfYear(anniversaryOfEmployment);
|
|
|
- //获取入职周年日到升职日的天数
|
|
|
- long day2 = DateUtil.betweenDay(anniversaryOfEmployment, DateUtil.parse(promotionTime), true);
|
|
|
- //获取升职日到年底的天数
|
|
|
- long day3 = DateUtil.betweenDay(DateUtil.parse(promotionTime), endDate, true);
|
|
|
- //分三段计算:年初-入职周年日,入职周年日到升职日,升职日到年底
|
|
|
- yearLeave = (double) (day1 * (oldPositionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (oldPositionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1)) + day3 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
- //年假小数
|
|
|
+ //年假小数
|
|
|
/*double yearLeaveDecimalPart = yearLeave - (int) yearLeave;
|
|
|
if (yearLeaveDecimalPart < 0.25){
|
|
|
yearLeave = (int) yearLeave;
|
|
@@ -251,39 +287,40 @@ public class KYCDServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
|
|
|
}else if (yearLeaveDecimalPart < 1){
|
|
|
yearLeave = (int) yearLeave + 1;
|
|
|
}*/
|
|
|
- yearLeave = Math.round(yearLeave * 100.0) / 100.0;
|
|
|
-
|
|
|
- //查询出用户消费年假记录 当返回leaveRecords中calType为null或不返回该字段则为请假消耗 将计算出的年假数减去请假消耗的数量
|
|
|
- Map body = new HashMap();
|
|
|
- body.put("opUserId",opUserId);
|
|
|
- body.put("leaveCode",LEAVE_CODE);
|
|
|
- body.put("userIds",new String[]{userId});
|
|
|
- body.put("pageNumber",0);
|
|
|
- body.put("pageSize",50);
|
|
|
- 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;
|
|
|
- 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;
|
|
|
+ yearLeave = Math.round(yearLeave * 100.0) / 100.0;
|
|
|
+
|
|
|
+ //查询出用户消费年假记录 当返回leaveRecords中calType为null或不返回该字段则为请假消耗 将计算出的年假数减去请假消耗的数量
|
|
|
+ Map body = new HashMap();
|
|
|
+ body.put("opUserId",opUserId);
|
|
|
+ body.put("leaveCode",LEAVE_CODE);
|
|
|
+ body.put("userIds",new String[]{userId});
|
|
|
+ body.put("pageNumber",0);
|
|
|
+ body.put("pageSize",50);
|
|
|
+ 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;
|
|
|
+ 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())){
|
|
|
+ //判断是否为正常请假而不是接口测试或期初假期发放
|
|
|
+ String leaveReason = getString(use.get("leaveReason"));
|
|
|
+ if (Arrays.asList("期初年假发放","去年预支扣除","去年预支假清空").contains(leaveReason)){
|
|
|
+ //若是请假消耗或管理员手动减少
|
|
|
+ if (!use.containsKey("calType") || Objects.isNull(use.get("calType")) || "delete".equals(use.get("calType").toString())){
|
|
|
+ useLeaveNum += ((int) use.get("recordNumPerDay"))/100.0;
|
|
|
+ }
|
|
|
+ //注:若是管理员手动增加 则假期余额会多出一个BCXsunNm记录增加的假期天数 最终会在设置的假期余额的基础上加上这些天数
|
|
|
+ //故此处手动新增的假期余额不做处理
|
|
|
}
|
|
|
- //注:若是管理员手动增加 则假期余额会多出一个BCXsunNm记录增加的假期天数 最终会在设置的假期余额的基础上加上这些天数
|
|
|
- //故此处手动新增的假期余额不做处理
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
- //年假余额
|
|
|
+ /*//年假余额
|
|
|
BigDecimal annualLeaveNum = new BigDecimal(0.00);
|
|
|
|
|
|
//查询员工年假余额
|
|
@@ -303,69 +340,34 @@ public class KYCDServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
- LambdaQueryWrapper<AdvancedLeave> advancedLeaveLambdaQueryWrapper = new LambdaQueryWrapper<>();;
|
|
|
- advancedLeaveLambdaQueryWrapper.eq(AdvancedLeave::getUserId,userId)
|
|
|
- .eq(AdvancedLeave::getYear,year)
|
|
|
- .eq(AdvancedLeave::getValidFlag,"1")
|
|
|
- .eq(AdvancedLeave::getCity,"cd");
|
|
|
- AdvancedLeave advancedLeave = advancedLeaveMapper.selectOne(advancedLeaveLambdaQueryWrapper);
|
|
|
-
|
|
|
- if (Objects.nonNull(advancedLeave)){
|
|
|
- advanceLeave = Double.valueOf(advancedLeave.getLeaveNum());
|
|
|
- }else {
|
|
|
- advancedLeave = new AdvancedLeave();
|
|
|
-
|
|
|
- //1月1日 则根据年假余额计算当年预支假
|
|
|
- if (DateUtil.beginOfYear(new Date()).equals(today)){
|
|
|
- //年假余额小于8时
|
|
|
- if (annualLeaveNum.compareTo(new BigDecimal(8)) < 0){
|
|
|
- advanceLeave = Double.parseDouble(annualLeaveNum.subtract(annualLeaveNum.remainder(new BigDecimal(0.5))).toString());
|
|
|
- }
|
|
|
+ LambdaQueryWrapper<AdvancedLeave> advancedLeaveLambdaQueryWrapper = new LambdaQueryWrapper<>();;
|
|
|
+ advancedLeaveLambdaQueryWrapper.eq(AdvancedLeave::getUserId,userId)
|
|
|
+ .eq(AdvancedLeave::getYear,year)
|
|
|
+ .eq(AdvancedLeave::getValidFlag,"1")
|
|
|
+ .eq(AdvancedLeave::getCity,"cd");
|
|
|
+ AdvancedLeave advancedLeave = advancedLeaveMapper.selectOne(advancedLeaveLambdaQueryWrapper);
|
|
|
|
|
|
- advancedLeave.setLeaveNum(advanceLeave + "");
|
|
|
- advancedLeave.setUserId(userId);
|
|
|
- advancedLeave.setYear(String.valueOf(DateUtil.year(new Date())));
|
|
|
- advancedLeave.setCity("hq");
|
|
|
- advancedLeaveMapper.insert(advancedLeave);
|
|
|
+ if (Objects.nonNull(advancedLeave)){
|
|
|
+ advanceLeave = Double.valueOf(advancedLeave.getLeaveNum());
|
|
|
}else {
|
|
|
- //若当天不是1月1日且表中没有预支假记录 则默认预支假为8天
|
|
|
+ advancedLeave = new AdvancedLeave();
|
|
|
advancedLeave.setLeaveNum(advanceLeave + "");
|
|
|
advancedLeave.setUserId(userId);
|
|
|
- advancedLeave.setYear(String.valueOf(DateUtil.year(new Date())));
|
|
|
+ advancedLeave.setYear(year);
|
|
|
advancedLeave.setCity("cd");
|
|
|
advancedLeaveMapper.insert(advancedLeave);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- /*LambdaQueryWrapper<AdvancedLeave> advancedLeaveLambdaQueryWrapper = new LambdaQueryWrapper<>();;
|
|
|
- advancedLeaveLambdaQueryWrapper.eq(AdvancedLeave::getUserId,userId)
|
|
|
- .eq(AdvancedLeave::getCity,"cd")
|
|
|
- .eq(AdvancedLeave::getValidFlag,"1");
|
|
|
- AdvancedLeave advancedLeave = advancedLeaveMapper.selectOne(advancedLeaveLambdaQueryWrapper);
|
|
|
- if (Objects.nonNull(advancedLeave)){
|
|
|
- advanceLeave = Double.valueOf(advancedLeave.getLeaveNum());
|
|
|
- }else {
|
|
|
- advanceLeave = NumberUtil.sub(yearLeave - useLeaveNum).doubleValue() >= 8 ? 8 : NumberUtil.sub(yearLeave - useLeaveNum).intValue();
|
|
|
- advancedLeave = new AdvancedLeave();
|
|
|
- advancedLeave.setLeaveNum(advanceLeave + "");
|
|
|
- advancedLeave.setUserId(userId);
|
|
|
- advancedLeave.setYear(String.valueOf(DateUtil.year(new Date())));
|
|
|
- advancedLeave.setCity("cd");
|
|
|
- advancedLeaveMapper.insert(advancedLeave);
|
|
|
- }*/
|
|
|
-
|
|
|
-
|
|
|
- //年假总数
|
|
|
- int realYearLeave = NumberUtil.sub(yearLeave, useLeaveNum, -advanceLeave).doubleValue() < 0 ? 0 : NumberUtil.sub(yearLeave, useLeaveNum, -advanceLeave).multiply(new BigDecimal(100)).intValue();
|
|
|
+ //年假总数
|
|
|
+ int realYearLeave = NumberUtil.sub(yearLeave, useLeaveNum, -advanceLeave).doubleValue() < 0 ? 0 : NumberUtil.sub(yearLeave, useLeaveNum, -advanceLeave).multiply(new BigDecimal(100)).intValue();
|
|
|
|
|
|
|
|
|
-
|
|
|
- //获取员工原年假余额 取较大值
|
|
|
- if (annualLeaveNum.multiply(new BigDecimal(100)).intValue() > realYearLeave){
|
|
|
+ //获取员工原年假余额 取较大值
|
|
|
+ /*if (annualLeaveNum.multiply(new BigDecimal(100)).intValue() > realYearLeave){
|
|
|
realYearLeave = annualLeaveNum.multiply(new BigDecimal(100)).intValue();
|
|
|
- }
|
|
|
+ }*/
|
|
|
/*Map balanceMap = new HashMap();
|
|
|
balanceMap.put("leave_code",LEAVE_CODE);
|
|
|
balanceMap.put("op_userid",opUserId);
|
|
@@ -387,51 +389,63 @@ public class KYCDServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
|
|
|
}*/
|
|
|
|
|
|
|
|
|
- //更新假期余额接口的body
|
|
|
- DateTime deadline = DateUtil.parse((DateUtil.year(new Date()) + 1) + "-03-31");
|
|
|
- Map<String,Object> updateBody = new HashMap<>();
|
|
|
- Map<String,Object> leave_quotas = new HashMap<>();
|
|
|
- //额度有效期开始时间,毫秒级时间戳
|
|
|
- leave_quotas.put("start_time",beginDate.getTime());
|
|
|
- //额度有效期结束时间,毫秒级时间戳。
|
|
|
- leave_quotas.put("end_time",deadline.getTime());
|
|
|
- //操作原因
|
|
|
- leave_quotas.put("reason","接口测试修改");
|
|
|
- //以天计算的额度总数 假期类型按天计算时,该值不为空且按百分之一天折算。 例如:1000=10天。
|
|
|
- leave_quotas.put("quota_num_per_day",realYearLeave);
|
|
|
- //以小时计算的额度总数 假期类型按小时,计算该值不为空且按百分之一小时折算。例如:1000=10小时。
|
|
|
- leave_quotas.put("quota_num_per_hour",0);
|
|
|
- //额度所对应的周期,格式必须是"yyyy",例如"2021"
|
|
|
- leave_quotas.put("quota_cycle",DateUtil.year(new Date())+"");
|
|
|
- //自定义添加的假期类型:年假开发测试的leave_code
|
|
|
- leave_quotas.put("leave_code",LEAVE_CODE);
|
|
|
- //要更新的员工的userId
|
|
|
- leave_quotas.put("userid",userId);
|
|
|
-
|
|
|
- updateBody.put("leave_quotas",leave_quotas);
|
|
|
- //当前企业内拥有OA审批应用权限的管理员的userId
|
|
|
- updateBody.put("op_userid",opUserId);
|
|
|
-
|
|
|
- String bodyStr = realYearLeave + userId;
|
|
|
-
|
|
|
- // 检查更新事件是否已经处理过,如果是,则忽略该更新
|
|
|
- if (isUpdateLeave(bodyStr)) {
|
|
|
- log.info("更新事件已处理,忽略该回调...");
|
|
|
- return null;
|
|
|
- }
|
|
|
+ //更新假期余额接口的body
|
|
|
+ DateTime deadline = DateUtil.parse((DateUtil.year(new Date()) + 1) + "-03-31");
|
|
|
+ Map<String,Object> updateBody = new HashMap<>();
|
|
|
+ Map<String,Object> leave_quotas = new HashMap<>();
|
|
|
+ //额度有效期开始时间,毫秒级时间戳
|
|
|
+ leave_quotas.put("start_time",beginDate.getTime());
|
|
|
+ //额度有效期结束时间,毫秒级时间戳。
|
|
|
+ leave_quotas.put("end_time",deadline.getTime());
|
|
|
+ //操作原因
|
|
|
+ leave_quotas.put("reason","接口测试修改");
|
|
|
+ //以天计算的额度总数 假期类型按天计算时,该值不为空且按百分之一天折算。 例如:1000=10天。
|
|
|
+ leave_quotas.put("quota_num_per_day",realYearLeave);
|
|
|
+ //以小时计算的额度总数 假期类型按小时,计算该值不为空且按百分之一小时折算。例如:1000=10小时。
|
|
|
+ leave_quotas.put("quota_num_per_hour",0);
|
|
|
+ //额度所对应的周期,格式必须是"yyyy",例如"2021"
|
|
|
+ leave_quotas.put("quota_cycle",DateUtil.year(new Date())+"");
|
|
|
+ //自定义添加的假期类型:年假开发测试的leave_code
|
|
|
+ leave_quotas.put("leave_code",LEAVE_CODE);
|
|
|
+ //要更新的员工的userId
|
|
|
+ leave_quotas.put("userid",userId);
|
|
|
+
|
|
|
+ updateBody.put("leave_quotas",leave_quotas);
|
|
|
+ //当前企业内拥有OA审批应用权限的管理员的userId
|
|
|
+ updateBody.put("op_userid",opUserId);
|
|
|
+
|
|
|
+/* String bodyStr = realYearLeave + userId;
|
|
|
+
|
|
|
+ // 检查更新事件是否已经处理过,如果是,则忽略该更新
|
|
|
+ if (isUpdateLeave(bodyStr)) {
|
|
|
+ log.info("更新事件已处理,忽略该回调...");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
|
|
|
- // 将更新和当前时间戳添加到已处理集合中
|
|
|
- long currentTime = System.currentTimeMillis();
|
|
|
- bodyList.put(bodyStr, currentTime);
|
|
|
+ // 将更新和当前时间戳添加到已处理集合中
|
|
|
+ long currentTime = System.currentTimeMillis();
|
|
|
+ bodyList.put(bodyStr, currentTime);*/
|
|
|
|
|
|
- result.add("姓名:"+name+",职级:" + positionLevel+",原职级:" + oldPositionLevel+ ",年假基数:" + yearLeave + "天,入职日期:" + confirmJoinTime + ",升职日期:" + promotionTime + ",开始日期:" + beginDate+",截止日期:" + deadline);
|
|
|
+ result.add("姓名:"+name+",职级:" + positionLevel+",原职级:" + oldPositionLevel+ ",年假基数:" + yearLeave + "天,入职日期:" + confirmJoinTime + ",升职日期:" + promotionTime + ",开始日期:" + beginDate+",截止日期:" + deadline);
|
|
|
|
|
|
- //更新假期余额
|
|
|
- UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/vacation/quota/update", null, DDConf.initTokenParams(access_token), updateBody, DDR.class);
|
|
|
+ //更新假期余额
|
|
|
+ Map map3 = JSON.parseObject(UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/vacation/quota/update", null, DDConf.initTokenParams(access_token), updateBody));
|
|
|
+ kaiyueLog.setMsg(getString(map3.get("errmsg")));
|
|
|
+ if ((boolean)map3.get("success")){
|
|
|
+ kaiyueLog.setState("1");
|
|
|
+ }else {
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ }
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+ }catch (Exception e){
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ kaiyueLog.setMsg("接口异常:"+e.getMessage());
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- log.info(result.stream().collect(Collectors.joining(",")));
|
|
|
- return McR.success(result);
|
|
|
+
|
|
|
+ return McR.success();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -532,6 +546,342 @@ public class KYCDServiceImpl extends ServiceImpl<AdvancedLeaveMapper, AdvancedLe
|
|
|
return leaveMap;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public McR grantEmployeeAnnualLeave() {
|
|
|
+ //获取accessToken
|
|
|
+ String access_token = ddClient.getAccessToken(appKey,appSecret);
|
|
|
+
|
|
|
+ //获取员工userId集合
|
|
|
+ List<String> userIdList = getEmployeeUserId();
|
|
|
+// List<String> userIdList = Arrays.asList("253434204020308091");
|
|
|
+
|
|
|
+
|
|
|
+ //遍历集合给所有员工更新年假余额
|
|
|
+ if (Objects.nonNull(userIdList) && !userIdList.isEmpty()) {
|
|
|
+ Map map = new HashMap();
|
|
|
+ //查询接口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,b433c687-c3b3-4f97-8498-d23944f3316b,80292628-1c88-4c25-9c40-3e91283552e7,sys01-employeeType");
|
|
|
+ map.put("agentid", agentId);
|
|
|
+
|
|
|
+ String year = DateUtil.year(new Date()) + "";
|
|
|
+
|
|
|
+ for (String userId : userIdList) {
|
|
|
+ KaiyueLog kaiyueLog = new KaiyueLog();
|
|
|
+ kaiyueLog.setCity("cd");
|
|
|
+ kaiyueLog.setUserId(userId);
|
|
|
+ kaiyueLog.setYear(year+"");
|
|
|
+ try{
|
|
|
+ map.put("userid_list", userId);
|
|
|
+ //获取员工花名册字段信息
|
|
|
+ DDR ddr = (DDR) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/v2/list", null, DDConf.initTokenParams(access_token), map, DDR.class);
|
|
|
+ List<Map> employeeData = (List<Map>) ddr.getResult();
|
|
|
+
|
|
|
+ //遍历员工信息
|
|
|
+ for (Map data : employeeData) {
|
|
|
+ //入职日期
|
|
|
+ String confirmJoinTime = "";
|
|
|
+ //职级
|
|
|
+ String positionLevel = "";
|
|
|
+ //姓名
|
|
|
+ String name = "";
|
|
|
+ //原职级
|
|
|
+ String oldPositionLevel = "";
|
|
|
+ //升职日期
|
|
|
+ String promotionTime = "";
|
|
|
+ //员工类型
|
|
|
+ String employeeType = "";
|
|
|
+
|
|
|
+ List<Map> fieldDataList = (List<Map>) data.get("field_data_list");
|
|
|
+ for (Map fieldData : fieldDataList) {
|
|
|
+ String fieldCode = fieldData.get("field_code").toString();
|
|
|
+ List<Map> fieldValueList = (List<Map>) fieldData.get("field_value_list");
|
|
|
+
|
|
|
+ if (Objects.nonNull(fieldValueList.get(0).get("value"))) {
|
|
|
+ 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;
|
|
|
+ case "sys00-name":
|
|
|
+ name = value;
|
|
|
+ break;
|
|
|
+ case "b433c687-c3b3-4f97-8498-d23944f3316b":
|
|
|
+ oldPositionLevel = value;
|
|
|
+ break;//成都原职级
|
|
|
+ case "80292628-1c88-4c25-9c40-3e91283552e7":
|
|
|
+ promotionTime = value;
|
|
|
+ break;//升职日期
|
|
|
+ case "sys01-employeeType":
|
|
|
+ employeeType = label;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //若员工类型不为全职 不发放年假
|
|
|
+ if (!employeeType.equals("全职")) {
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ kaiyueLog.setMsg("员工类型不为全职 不发放年假");
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //若没有原职级 则默认原职级是现职级
|
|
|
+ if ("".equals(oldPositionLevel)) {
|
|
|
+ oldPositionLevel = positionLevel;
|
|
|
+ }
|
|
|
+ //若没有升职日期 则默认升职日期是入职日期
|
|
|
+ if ("".equals(promotionTime)) {
|
|
|
+ promotionTime = confirmJoinTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ("".equals(confirmJoinTime) || "".equals(positionLevel) || "".equals(name) || "".equals(oldPositionLevel)) {
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ kaiyueLog.setMsg("更新员工年假余额:参数缺啦!");
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ /*String dateString = "2025-01-01";
|
|
|
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+ Date now = dateFormat.parse(dateString);*/
|
|
|
+
|
|
|
+ Date now = new Date();
|
|
|
+
|
|
|
+ //获取入职日期的月日
|
|
|
+ String confirmJoinMonthAndDay = confirmJoinTime.substring(5);
|
|
|
+
|
|
|
+ //获取去年年份
|
|
|
+ String lastYear = DateUtil.year(now) - 1 + "";
|
|
|
+ //今年入职周年日
|
|
|
+ DateTime anniversaryOfEmployment = DateUtil.parse(year + "-" + confirmJoinMonthAndDay);
|
|
|
+ //假期有效开始日期为当年1月1日
|
|
|
+ DateTime beginDate = DateUtil.beginOfYear(now);
|
|
|
+ //假期有效截至日期为次年3月31日
|
|
|
+ DateTime deadline = DateUtil.parse((DateUtil.year(now) + 1) + "-03-31");
|
|
|
+
|
|
|
+ DateTime endYearDate = DateUtil.endOfYear(now);
|
|
|
+ //今天
|
|
|
+ DateTime today = DateUtil.date();
|
|
|
+ //当年天数
|
|
|
+ int yearDays = DateUtil.dayOfYear(endYearDate);
|
|
|
+ //年假
|
|
|
+ double yearLeave = 0.0;
|
|
|
+
|
|
|
+ //获取原职级年假基数
|
|
|
+ int oldPositionLevelBaseNum = getAnnualLeaveBaseNum(oldPositionLevel);
|
|
|
+ //获取现职级年假基数
|
|
|
+ int positionLevelBaseNum = getAnnualLeaveBaseNum(positionLevel);
|
|
|
+
|
|
|
+
|
|
|
+ //新增今年预支假+今年实有年假----------------------------------------------------------------------------------------------
|
|
|
+ //计算今天是入职第几周年
|
|
|
+ long anniversary = DateUtil.betweenYear(DateUtil.parse(confirmJoinTime), anniversaryOfEmployment, true) - 1;
|
|
|
+ //判断员工是否当年新入职
|
|
|
+ if (DateUtil.year(DateUtil.parse(confirmJoinTime)) == DateUtil.year(now)) {
|
|
|
+ //分两段计算:入职日到升职日,升职日到年底
|
|
|
+ long day1 = DateUtil.betweenDay(DateUtil.parse(confirmJoinTime), DateUtil.parse(promotionTime), true);
|
|
|
+ long day2 = DateUtil.betweenDay(DateUtil.parse(promotionTime), endYearDate, true);
|
|
|
+ yearLeave = (double) (day1 * oldPositionLevelBaseNum + day2 * positionLevelBaseNum) / yearDays;
|
|
|
+ } else {
|
|
|
+ //升职日期在今年入职周年日之前
|
|
|
+ if (DateUtil.compare(anniversaryOfEmployment, DateUtil.parse(promotionTime)) >= 0) {
|
|
|
+ //升职日期在今年
|
|
|
+ if (DateUtil.compare(DateUtil.parse(promotionTime), today) >= 0) {
|
|
|
+ //获取年初到升职日的天数
|
|
|
+ int day1 = DateUtil.dayOfYear(DateUtil.parse(promotionTime));
|
|
|
+ //获升职值日到入职周年日的天数
|
|
|
+ long day2 = DateUtil.betweenDay(DateUtil.parse(promotionTime), anniversaryOfEmployment, true);
|
|
|
+ //获取入职周年日到年底的天数
|
|
|
+ long day3 = DateUtil.betweenDay(anniversaryOfEmployment, endYearDate, true);
|
|
|
+ //分三段计算:年初-升职日,升职日到入职周年日,入职周年日到年底
|
|
|
+ yearLeave = (double) (day1 * (oldPositionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (positionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day3 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays;
|
|
|
+ } else {
|
|
|
+ //获取年初到入职周年日的天数
|
|
|
+ int day1 = DateUtil.dayOfYear(anniversaryOfEmployment);
|
|
|
+ //获取入职周年日到年底的天数
|
|
|
+ long day2 = DateUtil.betweenDay(anniversaryOfEmployment, endYearDate, true);
|
|
|
+ //分两段计算:年初到入职周年日,入职周年日到年底
|
|
|
+ yearLeave = (double) (day1 * (positionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //升职日在今年入职周年日之后
|
|
|
+ //获取年初到入职周年日的天数
|
|
|
+ int day1 = DateUtil.dayOfYear(anniversaryOfEmployment);
|
|
|
+ //获取入职周年日到升职日的天数
|
|
|
+ long day2 = DateUtil.betweenDay(anniversaryOfEmployment, DateUtil.parse(promotionTime), true);
|
|
|
+ //获取升职日到年底的天数
|
|
|
+ long day3 = DateUtil.betweenDay(DateUtil.parse(promotionTime), endYearDate, true);
|
|
|
+ //分三段计算:年初-入职周年日,入职周年日到升职日,升职日到年底
|
|
|
+ yearLeave = (double) (day1 * (oldPositionLevelBaseNum + (anniversary > 4 ? 4 : anniversary)) + day2 * (oldPositionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1)) + day3 * (positionLevelBaseNum + (anniversary + 1 > 4 ? 4 : anniversary + 1))) / yearDays;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ yearLeave = Math.round(yearLeave * 100.0) / 100.0;
|
|
|
+
|
|
|
+ //今年年假总数
|
|
|
+ int realYearLeave = (int) ((yearLeave + ADVANCE_LEAVE) * 100);
|
|
|
+
|
|
|
+ //更新假期余额接口的body
|
|
|
+ Map<String, Object> updateBody = new HashMap<>();
|
|
|
+ Map<String, Object> leave_quotas = new HashMap<>();
|
|
|
+ //额度有效期开始时间,毫秒级时间戳
|
|
|
+ leave_quotas.put("start_time", beginDate.getTime());
|
|
|
+ //额度有效期结束时间,毫秒级时间戳。
|
|
|
+ leave_quotas.put("end_time", deadline.getTime());
|
|
|
+ //操作原因
|
|
|
+ leave_quotas.put("reason", "期初年假发放");
|
|
|
+ //以天计算的额度总数 假期类型按天计算时,该值不为空且按百分之一天折算。 例如:1000=10天。
|
|
|
+ leave_quotas.put("quota_num_per_day", realYearLeave);
|
|
|
+ //以小时计算的额度总数 假期类型按小时,计算该值不为空且按百分之一小时折算。例如:1000=10小时。
|
|
|
+ leave_quotas.put("quota_num_per_hour", 0);
|
|
|
+ //额度所对应的周期,格式必须是"yyyy",例如"2021"
|
|
|
+ leave_quotas.put("quota_cycle", DateUtil.year(now) + "");
|
|
|
+ //自定义添加的假期类型:年假开发测试的leave_code
|
|
|
+ leave_quotas.put("leave_code", LEAVE_CODE);
|
|
|
+ //要更新的员工的userId
|
|
|
+ leave_quotas.put("userid", userId);
|
|
|
+
|
|
|
+ updateBody.put("leave_quotas", leave_quotas);
|
|
|
+ //当前企业内拥有OA审批应用权限的管理员的userId
|
|
|
+ updateBody.put("op_userid", opUserId);
|
|
|
+
|
|
|
+ //更新假期余额
|
|
|
+ Map map1 = JSON.parseObject(UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/vacation/quota/update", null, DDConf.initTokenParams(access_token), updateBody));
|
|
|
+
|
|
|
+ kaiyueLog.setMsg(getString(map1.get("errmsg")));
|
|
|
+ if ((boolean)map1.get("success")){
|
|
|
+ kaiyueLog.setState("1");
|
|
|
+ }else {
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ }
|
|
|
+ //休眠一分钟 一个员工一分钟内只能更新一次假期余额
|
|
|
+ Thread.sleep(6000);
|
|
|
+
|
|
|
+ //查询员工次年结余年假----------------------------------------------------------------------------------------------
|
|
|
+ List<Map> leaveQuotasList = new ArrayList<>();
|
|
|
+ getLeaveNum(LEAVE_CODE, userId, 0, 50, leaveQuotasList);
|
|
|
+
|
|
|
+
|
|
|
+ if (Objects.nonNull(leaveQuotasList)) {
|
|
|
+ //假期有效开始日期为去年1月1日
|
|
|
+ String dateString2 = lastYear + "-01-01";
|
|
|
+ SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+ DateTime lastYearBeginDate = DateUtil.beginOfYear(dateFormat2.parse(dateString2));
|
|
|
+ //假期有效截至日期为今年3月31日
|
|
|
+ DateTime lastYearDeadline = DateUtil.parse(DateUtil.year(now) + "-03-31");
|
|
|
+ //更新假期余额接口的body
|
|
|
+ Map<String, Object> lastUpdateBody = new HashMap<>();
|
|
|
+ Map<String, Object> lastLeaveQuotas = new HashMap<>();
|
|
|
+ //额度有效期开始时间,毫秒级时间戳
|
|
|
+ lastLeaveQuotas.put("start_time", lastYearBeginDate.getTime());
|
|
|
+ //额度有效期结束时间,毫秒级时间戳。
|
|
|
+ lastLeaveQuotas.put("end_time", lastYearDeadline.getTime());
|
|
|
+ //操作原因
|
|
|
+ lastLeaveQuotas.put("reason", "去年预支假清空");
|
|
|
+ lastLeaveQuotas.put("leave_code", LEAVE_CODE);
|
|
|
+ //要更新的员工的userId
|
|
|
+ lastLeaveQuotas.put("userid", userId);
|
|
|
+
|
|
|
+ lastUpdateBody.put("leave_quotas", lastLeaveQuotas);
|
|
|
+ //当前企业内拥有OA审批应用权限的管理员的userId
|
|
|
+ lastUpdateBody.put("op_userid", opUserId);
|
|
|
+
|
|
|
+ //记录剩余清空的假期数
|
|
|
+ int remainedClearLeaveNum = 800;
|
|
|
+
|
|
|
+ for (Map leaveQuotas : leaveQuotasList) {
|
|
|
+ String quotaCycle = leaveQuotas.get("quota_cycle").toString();
|
|
|
+ if (quotaCycle.contains(lastYear)) {
|
|
|
+ int usedNum = 0;
|
|
|
+ int quotaNum = 0;
|
|
|
+
|
|
|
+ if (Objects.isNull(leaveQuotas.get("quota_num_per_hour")) && Objects.nonNull(leaveQuotas.get("quota_num_per_day"))) {
|
|
|
+ quotaNum = (int) leaveQuotas.get("quota_num_per_day");
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(leaveQuotas.get("used_num_per_day"))) {
|
|
|
+ usedNum = (int) leaveQuotas.get("used_num_per_day");
|
|
|
+ }
|
|
|
+
|
|
|
+ //若此周期年假余额>0
|
|
|
+ if (quotaNum - usedNum > 0 && remainedClearLeaveNum > 0) {
|
|
|
+ lastLeaveQuotas.put("quota_cycle", quotaCycle);
|
|
|
+ if (quotaNum - usedNum >= remainedClearLeaveNum) {
|
|
|
+ lastLeaveQuotas.put("quota_num_per_day", quotaNum - remainedClearLeaveNum);
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ lastLeaveQuotas.put("quota_num_per_day", usedNum);
|
|
|
+ remainedClearLeaveNum -= quotaNum - usedNum;
|
|
|
+ }
|
|
|
+ Map map2 = JSON.parseObject(UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/vacation/quota/update", null, DDConf.initTokenParams(access_token), lastUpdateBody));
|
|
|
+
|
|
|
+ kaiyueLog.setMsg(getString(map2.get("errmsg")));
|
|
|
+ if ((boolean)map2.get("success")){
|
|
|
+ kaiyueLog.setState("1");
|
|
|
+ }else {
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ }
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+
|
|
|
+ //休眠一分钟 一个员工一分钟内只能更新一次假期余额
|
|
|
+ Thread.sleep(6000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ AdvancedLeave advancedLeave = new AdvancedLeave();
|
|
|
+ advancedLeave.setUserId(userId);
|
|
|
+ advancedLeave.setCity("cd");
|
|
|
+ advancedLeave.setYear(year);
|
|
|
+
|
|
|
+ if (remainedClearLeaveNum > 0) {
|
|
|
+ //去年预支假期今年扣除
|
|
|
+ leave_quotas.put("quota_num_per_day", realYearLeave - remainedClearLeaveNum);
|
|
|
+ leave_quotas.put("reason", "去年预支扣除");
|
|
|
+ updateBody.put("leave_quotas", leave_quotas);
|
|
|
+
|
|
|
+ Map map3 =JSON.parseObject(UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/vacation/quota/update", null, DDConf.initTokenParams(access_token), updateBody));
|
|
|
+
|
|
|
+ kaiyueLog.setMsg(getString(map3.get("errmsg")));
|
|
|
+ if ((boolean)map3.get("success")){
|
|
|
+ kaiyueLog.setState("1");
|
|
|
+ }else {
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ }
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+
|
|
|
+ advancedLeave.setLeaveNum((800 - remainedClearLeaveNum) / 100.0 + "");
|
|
|
+ } else {
|
|
|
+ advancedLeave.setLeaveNum("8.0");
|
|
|
+ }
|
|
|
+ advancedLeaveMapper.insert(advancedLeave);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ kaiyueLog.setState("0");
|
|
|
+ kaiyueLog.setMsg("接口异常:"+e.getMessage());
|
|
|
+ kaiyueLogMapper.insert(kaiyueLog);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return McR.success();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getString(Object label) {
|
|
|
+ return Objects.isNull(label) ? "" : label.toString();
|
|
|
+ }
|
|
|
+
|
|
|
private List<Map> getLeaveNum(String leave_code,String userId,int offset,int size,List<Map> leaveQuotasList) {
|
|
|
String access_token = ddClient.getAccessToken(appKey,appSecret);
|
|
|
|