年休假开发

This commit is contained in:
zhangming 2025-05-27 11:25:17 +08:00
parent 5f988d3099
commit c2434cd182
3 changed files with 324 additions and 1 deletions

View File

@ -0,0 +1,8 @@
# 年休假id
annual_leave_rule_id=3
# 病假id
sick_leave_rule_id=14
# 是否初始化结转 1是开启其他是关闭
init_carry_over=1
# 结转额度
carry_over_limit=7

View File

@ -5,11 +5,13 @@ import com.engine.kq.bean.KQChildrenBean;
import com.engine.kq.entity.KQBalanceOfLeaveEntity;
import com.engine.kq.entity.KQOvertimeRulesDetailEntity;
import com.engine.kq.entity.KQUsageHistoryEntity;
import com.engine.kq.enums.KqSplitFlowTypeEnum;
import com.engine.kq.jucailin.util.KQDateUtil;
import com.engine.kq.log.KQLog;
import com.engine.kq.wfset.bean.OvertimeBalanceTimeBean;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import weaver.common.DateUtil;
import weaver.common.StringUtil;
import weaver.conn.RecordSet;
@ -236,6 +238,7 @@ public class KQBalanceOfLeaveBiz {
*/
public static BigDecimal getCanUseAmount(String resourceId, String ruleId, String belongYear, BigDecimal baseAmount, String legalOrWelfare, String date) {
BigDecimal canUseAmount = new BigDecimal("0");
BaseBean baseBean = new BaseBean();
try {
//人员缓存类
ResourceComInfo resourceComInfo = new ResourceComInfo();
@ -255,6 +258,8 @@ public class KQBalanceOfLeaveBiz {
/*********************************************************************************/
baseBean.writeLog("getCanUseAmount date:" + date);
baseBean.writeLog("getCanUseAmount ruleId:" + ruleId);
//指定日期--用于计算已释放天数的日期
Calendar searchDate = DateUtil.getCalendar(date);
//指定日期的年份
@ -315,6 +320,17 @@ public class KQBalanceOfLeaveBiz {
return new BigDecimal("0");
}
} else if (searchYear.compareTo(belongYear) == 0) {
String annualRuleId = baseBean.getPropValue("zhuyou_prop_zm", "annual_leave_rule_id");
if (StringUtils.isEmpty(annualRuleId)) {
annualRuleId = "3";
}
if (StringUtils.equals(annualRuleId, ruleId)) {
if (monthOfYear.compareTo(new BigDecimal("7")) < 0) {
return baseAmount.divide(new BigDecimal("2"), RoundingMode.HALF_UP);
} else {
return baseAmount;
}
}
}
if (distributionMode == 6) {
calendar = getReleaseDateByDis6(resourceId, ruleId, belongYear, legalOrWelfare);
@ -2836,6 +2852,7 @@ public class KQBalanceOfLeaveBiz {
*/
private static double getBaseAmount(Map<String, Object> params) {
BigDecimal baseAmount = new BigDecimal("0");
BaseBean baseBean = new BaseBean();
int decimalDigit = 2;
try {
//当前日期
@ -2848,6 +2865,8 @@ public class KQBalanceOfLeaveBiz {
String workStartDate = Util.null2String(params.get("workStartDate"));
//人员的入职日期
String companyStartDate = Util.null2String(params.get("companyStartDate"));
String ruleId = Util.null2String(params.get("ruleId"));
String resourceId = Util.null2String(params.get("resourceId"));
//假期规则的ID
String rulesDetailId = Util.null2String(params.get("rulesDetailId"));
@ -2873,6 +2892,14 @@ public class KQBalanceOfLeaveBiz {
String ageLimitChangeDatetemp = "";
//入职日期or参加工作日期
String date4CalcAgeLimit = "";
baseBean.writeLog("getBaseAmount resourceId:" + resourceId);
baseBean.writeLog("getBaseAmount belongYear:" + belongYear);
baseBean.writeLog("getBaseAmount currentYear:" + currentYear);
baseBean.writeLog("getBaseAmount distributionMode:" + distributionMode);
baseBean.writeLog("getBaseAmount calcMethod:" + calcMethod);
baseBean.writeLog("getBaseAmount ruleId:" + ruleId);
if (distributionMode == 2) {
date4CalcAgeLimit = companyStartDate;
//根据假期基数的计算方式得出假期基数发放日期假期基数变动日期工龄or司龄的变动日期
@ -2905,6 +2932,12 @@ public class KQBalanceOfLeaveBiz {
}
}
baseBean.writeLog("getBaseAmount date4CalcAgeLimit:" + date4CalcAgeLimit);
baseBean.writeLog("getBaseAmount baseAmountReleaseDate:" + baseAmountReleaseDate);
baseBean.writeLog("getBaseAmount baseAmountChangeDate:" + baseAmountChangeDate);
baseBean.writeLog("getBaseAmount ageLimitChangeDate:" + ageLimitChangeDate);
baseBean.writeLog("getBaseAmount ageLimitChangeDatetemp:" + ageLimitChangeDatetemp);
//批处理日期因为存在当前年份批处理上一年份或者批处理下一年份所以需要做一些特殊处理
String date4CalcAmount = "";
if (belongYear.compareTo(currentYear) < 0) {
@ -2919,21 +2952,72 @@ public class KQBalanceOfLeaveBiz {
//折算后的假期余额保留几位小数
decimalDigit = Util.getIntValue("" + params.get("decimalDigit"), 2);
String annualRuleId = baseBean.getPropValue("zhuyou_prop_zm", "annual_leave_rule_id");
if (StringUtils.isEmpty(annualRuleId)) {
annualRuleId = "3";
}
//人员在假期基数发放日期时对应的工龄or司龄
int ageLimit = getAgeLimit(date4CalcAgeLimit, baseAmountReleaseDate);
if (StringUtils.equals(ruleId, annualRuleId)) {
ageLimit = getAgeLimit(date4CalcAgeLimit, belongYear + "-12-31");
}
baseBean.writeLog("getBaseAmount ageLimit:" + ageLimit);
//人员在假期基数发放日期时应有的假期基数
BigDecimal baseAmount_releaseDate = getAmountByAgeLimit(distributionMode, rulesDetailId, annualAmount, ageLimit, -1, -1, -1, "");
baseBean.writeLog("getBaseAmount baseAmount_releaseDate:" + baseAmount_releaseDate);
//人员在工龄or司龄变动日期时对应的工龄or司龄
int ageLimit_ageLimitChangeDate = getAgeLimit(date4CalcAgeLimit, ageLimitChangeDate);
if (StringUtils.equals(ruleId, annualRuleId)) {
ageLimit_ageLimitChangeDate = ageLimit;
}
baseBean.writeLog("getBaseAmount ageLimit_ageLimitChangeDate:" + ageLimit_ageLimitChangeDate);
//人员在工龄or司龄变动日期时应有的假期基数
BigDecimal baseAmount_ageLimitChangeDate = getAmountByAgeLimit(distributionMode, rulesDetailId, annualAmount, ageLimit_ageLimitChangeDate, -1, -1, -1, "");
baseBean.writeLog("getBaseAmount baseAmount_ageLimitChangeDate:" + baseAmount_ageLimitChangeDate);
//如果人员在假期基数发放日期时对应的假期基数为0并且批处理日期小于工龄or司龄变动日期则假期基数应该是0
if (baseAmount_releaseDate.doubleValue() <= 0 && date4CalcAmount.compareTo(ageLimitChangeDate) < 0) {
return 0;
}
// 年假不发放场景
if (StringUtils.equals(ruleId, annualRuleId) && StringUtils.isNotEmpty(belongYear)) {
Year belongYearTemp = Year.parse(belongYear);
Year previousYear = belongYearTemp.minusYears(1); // 或者使用 minus(1)
// RecordSet rsTemp = new RecordSet();
// String preBaseAmount = null;
// rsTemp.executeQuery("select baseAmount from kq_balanceOfLeave where (isDelete is null or isDelete<>1) and resourceId = ?" +
// " and leaveRulesId = ? and belongYear = ?", resourceId, annualRuleId, previousYear);
// if (rsTemp.next()) {
// preBaseAmount = Util.null2s(rsTemp.getString("baseAmount"), "0");
// }
//
// if (StringUtils.isNotEmpty(preBaseAmount) && new BigDecimal(preBaseAmount).compareTo(BigDecimal.ZERO) > 0) {
String start = previousYear + "-01-01";
String end = previousYear + "-12-31";
String hrmLeaveData = getHrmLeaveData(resourceId, start, end);
baseBean.writeLog("getBaseAmount hrmLeaveData:" + hrmLeaveData);
if (StringUtils.isEmpty(hrmLeaveData)) {
hrmLeaveData = "0";
}
BigDecimal hrmLeaveDataBd = new BigDecimal(hrmLeaveData);
if (ageLimit >= 1 && ageLimit < 10) {
if (hrmLeaveDataBd.compareTo(new BigDecimal("60")) >= 0) {
return 0;
}
} else if (ageLimit >= 10 && ageLimit < 20) {
if (hrmLeaveDataBd.compareTo(new BigDecimal("90")) >= 0) {
return 0;
}
} else if (ageLimit > 20) {
if (hrmLeaveDataBd.compareTo(new BigDecimal("120")) >= 0) {
return 0;
}
}
// }
}
//如果calcMethod==0假期基数按比例精确计算
boolean needCalc0 = false;
//是否需要折算
@ -3043,6 +3127,9 @@ public class KQBalanceOfLeaveBiz {
}
}
baseBean.writeLog("getBaseAmount baseAmount:" + baseAmount);
baseBean.writeLog("getBaseAmount needCalc0:" + needCalc0);
if (needCalc0) {
baseAmount = baseAmount_releaseDate;
@ -3077,6 +3164,9 @@ public class KQBalanceOfLeaveBiz {
}
}
baseBean.writeLog("getBaseAmount baseAmount B:" + baseAmount);
baseBean.writeLog("getBaseAmount needConvert:" + needConvert);
if (needConvert) {
//这一年一共有多少天
BigDecimal actualMaximum = new BigDecimal("" + calendar.getActualMaximum(Calendar.DAY_OF_YEAR));
@ -3097,12 +3187,75 @@ public class KQBalanceOfLeaveBiz {
baseAmount = baseAmount.multiply(actualMaximum.subtract(dayOfYear)).divide(actualMaximum.multiply(new BigDecimal("0.5")), 0, RoundingMode.DOWN).multiply(new BigDecimal("0.5"));
}
}
baseBean.writeLog("getBaseAmount baseAmount C:" + baseAmount);
} catch (Exception e) {
e.printStackTrace();
}
return baseAmount.setScale(decimalDigit, RoundingMode.HALF_UP).doubleValue();
}
public static String getHrmLeaveData(String resourceId, String startDate, String endDate) {
String sickRuleId = new BaseBean().getPropValue("zhuyou_prop_zm", "sick_leave_rule_id");
RecordSet rs = new RecordSet();
KQLeaveRulesComInfo kqLeaveRulesComInfo = new KQLeaveRulesComInfo();
double xjsc = 0;
String sql = " select resourceid, newleavetype, durationrule, sum(duration) as val from hrmresource a, "+ KqSplitFlowTypeEnum.LEAVEBACK.getTablename()+" b "+
" where a.id = b.resourceid and newleavetype = " + sickRuleId + " and resourceid = " + resourceId + " and belongdate >='"+startDate+"' and belongdate <='"+endDate+"' " +
" group by resourceid, newleavetype, durationrule ";
rs.execute(sql);
while (rs.next()) {
String resourceid = rs.getString("resourceid");
String belongdate = rs.getString("belongdate");
String newleavetype = rs.getString("newleavetype");
String durationrule = rs.getString("durationrule");
double value = rs.getDouble("val")<0?0:rs.getDouble("val");
double proportion = Util.getDoubleValue(kqLeaveRulesComInfo.getProportion(newleavetype));
if (KQUnitBiz.isLeaveHour(newleavetype, kqLeaveRulesComInfo)) {//按小时
if (!KQUnitBiz.isLeaveHour(durationrule)){
if (proportion>0) {
value = value * proportion;
}
}
} else {//按天
if (!KQUnitBiz.isLeaveHour(durationrule)){
if (proportion > 0) {
value = value * proportion;
}
}
}
xjsc = xjsc + value;
}
double qjsc = 0;
sql = " select resourceid, newleavetype, durationrule, sum(duration) as val,belongdate from hrmresource a, "+ KqSplitFlowTypeEnum.LEAVE.getTablename()+" b "+
" where a.id = b.resourceid and newleavetype = " + sickRuleId + " and resourceid = " + resourceId + " and belongdate >='"+startDate+"' and belongdate <='"+endDate+"' " +
" group by resourceid, newleavetype, durationrule,belongdate ";
rs.execute(sql);
while (rs.next()) {
String resourceid = rs.getString("resourceid");
String belongdate = rs.getString("belongdate");
String newleavetype = rs.getString("newleavetype");
String durationrule = rs.getString("durationrule");
double value = rs.getDouble("val") < 0 ? 0 : rs.getDouble("val");
double proportion = Util.getDoubleValue(kqLeaveRulesComInfo.getProportion(newleavetype));
if (KQUnitBiz.isLeaveHour(newleavetype, kqLeaveRulesComInfo)) {//按小时
if (!KQUnitBiz.isLeaveHour(durationrule)) {
if (proportion > 0) {
value = value * proportion;
}
}
} else {//按天
if (!KQUnitBiz.isLeaveHour(durationrule)) {
if (proportion > 0) {
value = value * proportion;
}
}
}
qjsc = qjsc + value;
}
return String.format("%.2f", (qjsc - xjsc) / 8);
}
/**
* [4-每年发放固定天数]计算假期基数
*

View File

@ -0,0 +1,162 @@
package weaver.interfaces.zhuyou.cronjob;
import com.engine.kq.biz.KQBalanceOfLeaveBiz;
import org.apache.commons.lang3.StringUtils;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.interfaces.schedule.BaseCronJob;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
/**
* @version 1.0
* @Title ecology-9
* @Company 泛微软件
* @CreateDate 2025/5/26
* @Description 年假结转
* @Author AdminZm
*/
public class AnnualLeaveCarryOverJob extends BaseCronJob {
BaseBean baseBean = new BaseBean();
@Override
public void execute() {
baseBean.writeLog("AnnualLeaveCarryOverJob start.");
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate currentDate = LocalDate.now(); // 获取当前日期
int year = currentDate.getYear(); // 获取年份
int month = currentDate.getMonthValue(); // 获取月份
int day = currentDate.getDayOfMonth(); // 获取日期
String annualRuleId = baseBean.getPropValue("zhuyou_prop_zm", "annual_leave_rule_id");
// 是否初始化结转 1是开启其他是关闭
String initCarryOver = baseBean.getPropValue("zhuyou_prop_zm", "init_carry_over");
// 结转额度
String carryOverLimit = baseBean.getPropValue("zhuyou_prop_zm", "carry_over_limit");
if (StringUtils.isEmpty(carryOverLimit)) {
carryOverLimit = "7";
}
RecordSet rs = new RecordSet();
RecordSet rs1 = new RecordSet();
baseBean.writeLog("AnnualLeaveCarryOverJob initCarryOver:" + initCarryOver);
if (StringUtils.isNotEmpty(initCarryOver) && StringUtils.equals(initCarryOver, "1")) {
String sql = "select * from kq_balanceOfLeave where (isDelete is null or isDelete<>1) and leaveRulesId = ? and belongYear = ?";
if (month < 7) {
int qnYear = currentDate.minusYears(1).getYear(); // 获取上一年年份
rs.executeQuery(sql, annualRuleId, qnYear);
while (rs.next()) {
String resourceId = Util.null2s(rs.getString("resourceId"), "0");
// 基数
BigDecimal baseAmount = new BigDecimal(Util.null2s(rs.getString("baseAmount"), "0"));
// 额外
BigDecimal extraAmount = new BigDecimal(Util.null2s(rs.getString("extraAmount"), "0"));
// 已休
BigDecimal usedAmount = new BigDecimal(Util.null2s(rs.getString("usedAmount"), "0"));
// 剩余
BigDecimal resAmount = baseAmount.add(extraAmount).subtract(usedAmount);
if (resAmount.compareTo(new BigDecimal(carryOverLimit)) > 0) {
resAmount = new BigDecimal(carryOverLimit);
}
if (resAmount.compareTo(BigDecimal.ZERO) > 0) {
rs1.executeUpdate("UPDATE kq_balanceOfLeave SET extraAmount = ? WHERE extraAmount <= 0 " +
"AND resourceId = ? AND leaveRulesId = ? AND belongYear = ?", resAmount, resourceId, annualRuleId, year);
}
}
} else {
rs.executeQuery(sql, annualRuleId, year);
while (rs.next()) {
String id = Util.null2s(rs.getString("id"), "0");
// 基数
BigDecimal baseAmount = new BigDecimal(Util.null2s(rs.getString("baseAmount"), "0"));
// 额外
BigDecimal extraAmount = new BigDecimal(Util.null2s(rs.getString("extraAmount"), "0"));
if (extraAmount.compareTo(BigDecimal.ZERO) > 0) {
continue;
}
// 上半年释放
BigDecimal oldBase = baseAmount.divide(new BigDecimal("2"), RoundingMode.HALF_UP);
// 剩余释放
BigDecimal resBase = baseAmount.subtract(oldBase);
// 已休
BigDecimal usedAmount = new BigDecimal(Util.null2s(rs.getString("usedAmount"), "0"));
// 剩余
BigDecimal resAmount = oldBase.add(extraAmount).subtract(usedAmount).subtract(resBase);
if (resAmount.compareTo(new BigDecimal(carryOverLimit)) > 0) {
resAmount = new BigDecimal(carryOverLimit);
}
if (resAmount.compareTo(BigDecimal.ZERO) > 0) {
rs1.executeUpdate("UPDATE kq_balanceOfLeave SET extraAmount = ? WHERE id = ?", resAmount, id);
}
}
}
} else {
String sql = "select * from kq_balanceOfLeave where (isDelete is null or isDelete<>1) and leaveRulesId = ? and belongYear = ?";
// 1月1日执行的结转
if (month == 1 && day == 1) {
int qnYear = currentDate.minusYears(1).getYear(); // 获取上一年年份
rs.executeQuery(sql, annualRuleId, qnYear);
while (rs.next()) {
String resourceId = Util.null2s(rs.getString("resourceId"), "0");
// 基数
BigDecimal baseAmount = new BigDecimal(Util.null2s(rs.getString("baseAmount"), "0"));
// 额外
BigDecimal extraAmount = new BigDecimal(Util.null2s(rs.getString("extraAmount"), "0"));
// 已休
BigDecimal usedAmount = new BigDecimal(Util.null2s(rs.getString("usedAmount"), "0"));
// 剩余
BigDecimal resAmount = baseAmount.add(extraAmount).subtract(usedAmount);
if (resAmount.compareTo(new BigDecimal(carryOverLimit)) > 0) {
resAmount = new BigDecimal(carryOverLimit);
}
if (resAmount.compareTo(BigDecimal.ZERO) > 0) {
rs1.executeUpdate("UPDATE kq_balanceOfLeave SET extraAmount = ? WHERE extraAmount <= 0 " +
"AND resourceId = ? AND leaveRulesId = ? AND belongYear = ?", resAmount, resourceId, annualRuleId, year);
}
}
}
// 7月1日执行的结转
if (month == 7 && day == 1) {
rs.executeQuery(sql, annualRuleId, year);
while (rs.next()) {
String id = Util.null2s(rs.getString("id"), "0");
// 基数
BigDecimal baseAmount = new BigDecimal(Util.null2s(rs.getString("baseAmount"), "0"));
// 额外
BigDecimal extraAmount = new BigDecimal(Util.null2s(rs.getString("extraAmount"), "0"));
if (extraAmount.compareTo(BigDecimal.ZERO) > 0) {
continue;
}
// 上半年释放
BigDecimal oldBase = baseAmount.divide(new BigDecimal("2"), RoundingMode.HALF_UP);
// 剩余释放
BigDecimal resBase = baseAmount.subtract(oldBase);
// 已休
BigDecimal usedAmount = new BigDecimal(Util.null2s(rs.getString("usedAmount"), "0"));
// 剩余
BigDecimal resAmount = oldBase.add(extraAmount).subtract(usedAmount).subtract(resBase);
if (resAmount.compareTo(new BigDecimal(carryOverLimit)) > 0) {
resAmount = new BigDecimal(carryOverLimit);
}
if (resAmount.compareTo(BigDecimal.ZERO) > 0) {
rs1.executeUpdate("UPDATE kq_balanceOfLeave SET extraAmount = ? WHERE id = ?", resAmount, id);
}
}
}
}
} catch (Exception e) {
baseBean.writeLog("AnnualLeaveCarryOverJob error:" + e);
}
baseBean.writeLog("AnnualLeaveCarryOverJob end.");
}
}