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;
}
}