package com.kingdee.shr.customer.gtiit.osf; import com.kingdee.bos.BOSException; import com.kingdee.bos.Context; import com.kingdee.bos.bsf.service.app.IHRMsfService; import com.kingdee.eas.common.EASBizException; import com.kingdee.eas.util.app.DbUtil; import com.kingdee.jdbc.rowset.IRowSet; import com.kingdee.util.DateTimeUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import java.math.BigDecimal; import java.text.ParseException; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.*; /** * description: RetMoneyService
* date: 2025/4/21 10:37
* author: lhbj
* version: 1.0
*/ public class RetMoneyService implements IHRMsfService { // 定义日志记录器 private static Logger logger = Logger.getLogger("com.kingdee.shr.customer.gtiit.osf.RetMoneyService"); @Override public Object process(Context ctx, Map map) throws EASBizException, BOSException { try { String sql = "\n" + " /*dialect*/SELECT FMONEY ,FID ,FPERSONID ,FCMPITEMID,FEFFECTDAY ,FLEFFECTDAY,CFTraceability,CFRetroactiveDate,foldfixadjustsalaryid \n" + " FROM T_HR_SFixAdjustSalary where sysdate between FEFFECTDAY and FLEFFECTDAY \n" + " and CFTraceability='Yes' and FEFFECTDAY < cfretroactivedate "; HashSet list = new HashSet<>(); // 用于存储处理过的薪资调整记录ID logger.error("sql" + sql); // 记录SQL查询语句到日志中 IRowSet rs = DbUtil.executeQuery(ctx, sql); // 执行SQL查询,获取结果集 while (rs.next()) { BigDecimal sumMoney = BigDecimal.ZERO; // 初始化回溯薪资总额为0 BigDecimal money = rs.getBigDecimal("FMONEY"); // 获取当前记录的薪资调整金额 Date cfretroactivedate = new Date(rs.getDate("cfretroactivedate").getTime()); // 获取回溯日期 String personid = rs.getString("FPERSONID"); // 获取员工ID String cmpitemid = rs.getString("FCMPITEMID"); // 获取薪资调整项目ID Date mainEffectday = new Date(rs.getDate("FEFFECTDAY").getTime()); // 获取薪资调整生效日期 Date mainLeffectday = rs.getDate("FLEFFECTDAY"); // 获取薪资调整失效日期 logger.error("dettaiRs-mainEffectday:"+mainEffectday+",leffectday:"+mainLeffectday); //每工作日工资 String mainleftdayYearMonth = DateTimeUtils.format(mainEffectday, "yyyy-MM"); // 格式化生效日期为“年-月” String oldfixadjustsalaryid = rs.getString("foldfixadjustsalaryid"); // 获取旧的薪资调整ID String id = rs.getString("fid"); // 获取当前薪资调整记录ID if (StringUtils.isNotBlank(oldfixadjustsalaryid)) { String sqlOld = "\n" + " SELECT FMONEY ,FID ,FPERSONID ,FCMPITEMID,FEFFECTDAY ,FLEFFECTDAY,CFTraceability,CFRetroactiveDate,foldfixadjustsalaryid \n" + " FROM T_HR_SFixAdjustSalary where fid ='" + oldfixadjustsalaryid + "' "; logger.error("sqlOld================================= " + sqlOld); IRowSet dettaiRs = DbUtil.executeQuery(ctx, sqlOld); // 执行SQL查询,获取结果集 String detialid; if (dettaiRs.next()) { detialid = dettaiRs.getString("fid"); // 获取子查询记录的ID logger.error("start detialid================================= " + detialid); // 记录子查询记录的ID到日志中 BigDecimal detailMony = dettaiRs.getBigDecimal("FMONEY"); // 获取子查询记录的薪资调整金额 10000 logger.error("dettaiRs:retMoney " + detailMony); // 记录子查询记录的薪资调整金额到日志中 BigDecimal retMoney = money.subtract(detailMony); // 计算回溯薪资 logger.error("retMoney " + retMoney); // 记录回溯薪资到日志中 2000 Date effectday = dettaiRs.getDate("FEFFECTDAY"); // 获取子查询记录的生效日期 Date leffectday = dettaiRs.getDate("FLEFFECTDAY"); // 获取子查询记录的失效日期 logger.error("dettaiRs-effectday:"+effectday+",leffectday:"+leffectday); //每工作日工资 //获取月份差 List stringList = this.getMonthBetweenDate_V1(mainEffectday,cfretroactivedate); //获取开始日期 Calendar cal = Calendar.getInstance(); cal.setTime(mainEffectday); cal.set(Calendar.DAY_OF_MONTH, 1); String startDate = DateTimeUtils.format(cal.getTime(), "yyyy-MM-dd"); //结束日期 boolean endBool=false; Calendar cal2 = Calendar.getInstance(); cal2.setTime(cfretroactivedate); if(cal2.get(Calendar.DAY_OF_MONTH)>1){ cal2.add(Calendar.MONTH, 1); endBool=true; } cal2.set(Calendar.DAY_OF_MONTH, 1); cal2.add(Calendar.DAY_OF_MONTH, -1); String endDate = DateTimeUtils.format(cal2.getTime(), "yyyy-MM-dd"); //有效结束日期 String leffectDate = endDate; if(endBool){ leffectDate = DateTimeUtils.format(cfretroactivedate, "yyyy-MM-dd"); } //有效日期 String effectDate = DateTimeUtils.format(mainEffectday, "yyyy-MM-dd"); StringBuilder sqlDay = new StringBuilder(); sqlDay.append(" select to_char(wItem.fdate,'yyyy-MM-dd') from T_HR_ATS_WORKCALENDARITEM wItem "); sqlDay.append(" left join T_HR_ATS_WORKCALENDAR w on w.fid=wItem.fcalendargroupid "); sqlDay.append(" left join ( "); sqlDay.append(" select fcalendarid from T_HR_ATS_ATTENDANCEFILE "); sqlDay.append(" where fproposerid = ? "); sqlDay.append(" order by fleffdt desc "); sqlDay.append(" ) cal on cal.fcalendarid=w.fid "); sqlDay.append(" where wItem.fweek not in(0,6) "); sqlDay.append(" and to_char(wItem.fdate,'yyyy-MM-dd') >= ? "); sqlDay.append(" and to_char(wItem.fdate,'yyyy-MM-dd') <= ? "); sqlDay.append(" order by wItem.fdate desc "); logger.error("sqlDay:" + sqlDay.toString()); //每工作日工资 //由于每月的天数不一致所以需要每月分开这算 for(String yearMonth : stringList) { startDate=yearMonth+"-01"; Calendar endCal = Calendar.getInstance(); endCal.setTime(DateTimeUtils.parseDate(startDate)); endCal.add(Calendar.MONTH, 1); endCal.add(Calendar.DAY_OF_MONTH, -1); endDate=DateTimeUtils.format(endCal.getTime(), "yyyy-MM-dd");; logger.error("sqlDay-param:personid:" + personid+",startDate:"+startDate+",endDate:"+endDate); //每工作日工资 IRowSet dayRs1 = DbUtil.executeQuery(ctx, sqlDay.toString(), new String[]{personid, startDate, endDate}); // 执行SQL查询,获取结果集 BigDecimal days1 = BigDecimal.ZERO; if (dayRs1.next()) { days1 = new BigDecimal(dayRs1.size()); } BigDecimal days2 = BigDecimal.ZERO; String startDate2=startDate.compareTo(effectDate)>0?startDate:effectDate; String endDate2=endDate.compareTo(leffectDate)>0?leffectDate:endDate; logger.error("折算sqlDay-param:personid:" + personid+",effectDate:"+effectDate+",endDate:"+endDate); //每工作日工资 logger.error("折算sqlDay-param:personid:" + personid+",startDate2:"+startDate2+",endDate2:"+endDate2); //每工作日工资 IRowSet dayRs2 = DbUtil.executeQuery(ctx, sqlDay.toString(),new String[]{personid,startDate2,endDate2}); // 执行SQL查询,获取结果集 if (dayRs2.next()){ days2= new BigDecimal(dayRs2.size()); } logger.error("sumMoney-days1:" + days1); //每工作日工资 logger.error("sumMoney-days2:" + days2); //每工作日工资 logger.error("sumMoney:" + sumMoney); //每工作日工资 if(days1.compareTo(BigDecimal.ZERO) > 0) { BigDecimal dayMoney = retMoney.divide(days1,BigDecimal.ROUND_HALF_UP,BigDecimal.ROUND_HALF_UP); logger.error("sumMoney-day:" + dayMoney); //每工作日工资 sumMoney = sumMoney.add(dayMoney.multiply(days2)); logger.error("sumMoney-days:" + sumMoney); //折算工资 }else { sumMoney= sumMoney.add(BigDecimal.ZERO); } } // 定义SQL语句,用于检查是否存在特定的员工薪资支付表记录 String exiSql = "select * from CT_CUS_PersonPayForm where CFPersonID ='" + personid + "' and CFAdjustSalary='" + id + "' "; logger.error("exiSql sql " + exiSql); // 记录SQL语句到日志中 IRowSet extRs = DbUtil.executeQuery(ctx, exiSql); // 执行SQL查询,获取结果集 String insertSql; // 如果结果集不为空且包含记录 if (extRs != null && extRs.size() > 0) { // 定义SQL语句,用于更新员工薪资支付表中的回溯薪资 insertSql = "/*dialect*/ update CT_CUS_PersonPayForm set CFRetMoney=" + sumMoney.setScale(2, 4) +",CFMonth=to_date('" + DateTimeUtils.format(cfretroactivedate) + "','yyyy-MM-dd')"+ " where CFAdjustSalary='" + id + "' "; logger.error("updateSql " + insertSql); // 记录SQL语句到日志中 DbUtil.execute(ctx, insertSql); // 执行SQL更新操作 } else { // 如果结果集为空或不包含记录 // 定义SQL语句,用于向员工薪资支付表中插入新的回溯薪资记录 insertSql = " /*dialect*/ insert into CT_CUS_PersonPayForm(fid,CFPersonID,CFMonth,CFRetMoney,cfadjustsalary) values(newbosid('5FB9A7AC'),'" + personid + "',to_date('" + DateTimeUtils.format(cfretroactivedate) + "','yyyy-MM-dd')" + "," + sumMoney.setScale(2, 5) + ",'" + id + "')"; logger.error("insertSql " + insertSql); // 记录SQL语句到日志中 DbUtil.execute(ctx, insertSql); // 执行SQL插入操作 } } } } String sft = "update CT_CUS_PersonPayForm set CFRetMoney=0 where CFAdjustSalary in(select fid from T_HR_SFixAdjustSalary where CFTraceability='No')"; DbUtil.execute(ctx, sft); // 执行SQL插入操作 } catch (Exception e) { e.printStackTrace(); throw new BOSException(e); } return null; } // 获取两个日期之间的月份集合 public static List getMonthBetweenDate_V1(Date startTime, Date endTime) { List list = new ArrayList<>(); LocalDate startDate = startTime.toInstant() .atZone(ZoneId.systemDefault()) .toLocalDate(); LocalDate endDate = endTime.toInstant() .atZone(ZoneId.systemDefault()) .toLocalDate(); // 计算年份和月份差值 int startYear = startDate.getYear(); int startMonth = startDate.getMonthValue(); int endYear = endDate.getYear(); int endMonth = endDate.getMonthValue(); int yearDifference = endYear - startYear; int monthDifference = yearDifference * 12 + (endMonth - startMonth); // 如果 endDate 小于 startLocalDate 的下个月的第一天,则减去 1 LocalDate nextMonthFirstDay = startDate.plusMonths(monthDifference).withDayOfMonth(1); if (endDate.isBefore(nextMonthFirstDay)) { monthDifference--; } if (endDate.isAfter(nextMonthFirstDay)) { monthDifference++; } int month=0; do{ month++; String monthStr =startMonth+""; if(startMonth<10){ monthStr="0"+monthStr; } String yearMonth = startYear + "-" + monthStr; if(12==startMonth){ startMonth=1; startYear=startYear+1; }else { startMonth++; } list.add(yearMonth); }while (month < monthDifference); return list; } }