From c2434cd182bb5a174b41b4a3075211d56c816478 Mon Sep 17 00:00:00 2001 From: zhangming <965499528@qq.com> Date: Tue, 27 May 2025 11:25:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B9=B4=E4=BC=91=E5=81=87=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WEB-INF/prop/zhuyou_prop_zm.properties | 8 + .../engine/kq/biz/KQBalanceOfLeaveBiz.java | 155 ++++++++++++++++- .../cronjob/AnnualLeaveCarryOverJob.java | 162 ++++++++++++++++++ 3 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/prop/zhuyou_prop_zm.properties create mode 100644 src/weaver/interfaces/zhuyou/cronjob/AnnualLeaveCarryOverJob.java diff --git a/WEB-INF/prop/zhuyou_prop_zm.properties b/WEB-INF/prop/zhuyou_prop_zm.properties new file mode 100644 index 0000000..b00a998 --- /dev/null +++ b/WEB-INF/prop/zhuyou_prop_zm.properties @@ -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 \ No newline at end of file diff --git a/src/com/engine/kq/biz/KQBalanceOfLeaveBiz.java b/src/com/engine/kq/biz/KQBalanceOfLeaveBiz.java index ac10d80..96848f1 100644 --- a/src/com/engine/kq/biz/KQBalanceOfLeaveBiz.java +++ b/src/com/engine/kq/biz/KQBalanceOfLeaveBiz.java @@ -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 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-每年发放固定天数]计算假期基数 * diff --git a/src/weaver/interfaces/zhuyou/cronjob/AnnualLeaveCarryOverJob.java b/src/weaver/interfaces/zhuyou/cronjob/AnnualLeaveCarryOverJob.java new file mode 100644 index 0000000..71edeca --- /dev/null +++ b/src/weaver/interfaces/zhuyou/cronjob/AnnualLeaveCarryOverJob.java @@ -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."); + } +}