| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691 |
- package com.kingdee.eas.custom.compensation.service;
- import com.kingdee.bos.BOSException;
- import com.kingdee.bos.Context;
- import com.kingdee.eas.util.app.DbUtil;
- import com.kingdee.jdbc.rowset.IRowSet;
- import com.kingdee.shr.compensation.service.CalSubmitSchemeFunctionService;
- import com.kingdee.util.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import java.math.BigDecimal;
- import java.sql.Date;
- import java.sql.SQLException;
- import java.time.LocalDate;
- import java.time.format.DateTimeFormatter;
- import java.util.*;
- /**
- * 薪酬方案计算函数服务扩展类。
- * <p>
- * 提供以下薪酬计算相关的扩展函数:
- * <ul>
- * <li>当月入职/离职/转正人数统计</li>
- * <li>月末净增人数(入职-离职)</li>
- * <li>获取适用薪酬方案名称</li>
- * <li>获取薪酬档案中的固定薪资项目值</li>
- * </ul>
- */
- public class CalSubmitSchemeFunctionServiceEx extends CalSubmitSchemeFunctionService {
- private static final Logger logger = LoggerFactory.getLogger(CalSubmitSchemeFunctionServiceEx.class);
- /**
- * 人才留存奖金
- * @param ctx
- * @param paramMap
- * @param tempMap
- * @param mainTableName
- * @param mainTableRowFilter
- * @return
- */
- public double getTalentRetentionBonus(Context ctx, Map<String, Object> paramMap, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter,double isFixed) {
- try {
- //todo
- //计算的员工id
- String personId = (String) paramMap.get(mainTableName.toUpperCase() + "_FPERSONID");
- //计算的数据行
- String id = (String) paramMap.get(mainTableName.toUpperCase() + "_FID");
- String Effect = getEffect(ctx, tempMap, mainTableName, mainTableRowFilter, id);
- StringBuilder sql = new StringBuilder();
- sql.append(" /*dialect*/ ");
- // 主查询:按核算表和生效月份分组统计入职人数
- sql.append(" SELECT mt.fpersonid,substring(convert(varchar,mt.FEffectDate,120),0,8) FEffectDate,count(abt.pid) pNum from ").append(mainTableName).append(" mt ");
- // 关联子查询:通过北森应聘表匹配到人员,再关联其最近一次入职记录
- sql.append(" left join ( select ab.CFRecruitOwnerID,p.fid pid,t.fbizDate bizDate ");
- sql.append(" from CT_REC_ApplicantBeisen ab ");
- sql.append(" inner join T_REC_ResumeBaseRec rb on rb.CFCANDIDATEID = ab.CFCANDIDATEID ");
- sql.append(" inner join t_bd_person p on isnull(p.FIDCARDNO,p.FPASSPORTNO)=isnull(rb.FIdentityCardNo,rb.FPassportNo) ");
- // 取每个人员最近一次入职记录(ROW_NUMBER + rn=1)
- sql.append(" left join ( ");
- sql.append(" SELECT FPERSONID, FBIZDATE ");
- sql.append(" FROM ( ");
- sql.append(" SELECT ");
- sql.append(" e.FPERSONID, ");
- sql.append(" e.FBIZDATE, ");
- sql.append(" ROW_NUMBER() OVER (PARTITION BY e.FPERSONID ORDER BY e.FBIZDATE DESC) AS rn ");
- sql.append(" FROM T_HR_EmpEnrollBizBillEntry e ");
- sql.append(" LEFT JOIN T_HR_EmpEnrollBizBill b ON b.fid = e.FBillID ");
- sql.append(" where b.FBillState=3 ");
- sql.append(" ) t ");
- sql.append(" WHERE rn = 1) t on t.fpersonid=p.fid ) abt on abt.CFRecruitOwnerID=mt.fpersonid ");
- // 入职日期在生效日期当月范围内:[当月第一天, 下月第一天)
- sql.append(" AND abt.bizDate >= DATEADD(MONTH, DATEDIFF(MONTH, 0, mt.FEffectDate), 0)"); // 当月第一天 00:00:00.000
- sql.append(" AND abt.bizDate < DATEADD(MONTH, DATEDIFF(MONTH, 0, mt.FEffectDate) + 1, 0) "); // 下个月第一天 00:00:00.000
- sql.append(" AND mt.fid in(").append(mainTableRowFilter).append(") group by mt.fpersonid,substring(convert(varchar,mt.FEffectDate,120),0,8) ");
- IRowSet rs = DbUtil.executeQuery(ctx, sql.toString());
- //fixPayMap = new HashMap<>();
- while (rs.next()) {
- //获取人数
- String fpersonid = rs.getString("fpersonid");
- String FEffectDate = rs.getString("FEffectDate");
- int pNum = rs.getInt("pNum");
- //fixPayMap.put(fpersonid + "_" + FEffectDate, pNum);
- }
- }catch (Exception e){
- logger.error(e.getMessage(),e);
- }
- return 0D;
- }
- /**
- * 当月净增人数 = 当月入职人数 - 当月离职人数(通过招聘渠道入职但当月即离职的人员统计)。
- * @param ctx 上下文
- * @param paramMap 参数(含 FPERSONID、FID)
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @return 当月净增人数
- */
- public double getEndMonthRetainedUsers(Context ctx, Map<String, Object> paramMap, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter) {
- try {
- //计算的员工id
- String personId = (String) paramMap.get(mainTableName.toUpperCase() + "_FPERSONID");
- //计算的数据行
- String id = (String) paramMap.get(mainTableName.toUpperCase() + "_FID");
- String Effect = getEffect(ctx, tempMap, mainTableName,mainTableRowFilter, id);
- // 获取当月入职人数
- double ruzhiNum = getMonthRuzhiUsers(ctx, paramMap, tempMap, mainTableName, mainTableRowFilter);
- // 获取当月离职人数
- double lizhiNum = getMonthLiZhiUsers(ctx, paramMap, tempMap, mainTableName, mainTableRowFilter);
- // 净增 = 入职 - 离职
- return ((double) ruzhiNum - lizhiNum);
- } catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
- //ex.printStackTrace();
- }
- return (double) 0.0F;
- }
- /**
- * 当月入职人数(通过招聘渠道入职且在生效日期当月入职的人数)。
- * @param ctx 上下文
- * @param paramMap 参数(含 FPERSONID、FID)
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @return 当前人员在生效日期对应的当月入职人数
- */
- public double getMonthRuzhiUsers(Context ctx, Map<String, Object> paramMap, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter) {
- try {
- //计算的员工id
- String personId = (String) paramMap.get(mainTableName.toUpperCase() + "_FPERSONID");
- //计算的数据行
- String id = (String) paramMap.get(mainTableName.toUpperCase() + "_FID");
- String Effect = getEffect(ctx, tempMap, mainTableName,mainTableRowFilter, id);
- // 入职人数缓存 key
- String ruZhiMapKey = "getMonthRuzhiUsers_Map";
- // 查询生效日期当月入职的人数
- getRuZhiPersonNum(ctx, tempMap, mainTableName, mainTableRowFilter, ruZhiMapKey);
- Map<String, Integer> fixPayMap = (Map) tempMap.get(ruZhiMapKey);
- String key = personId + "_" + Effect;
- if (fixPayMap.containsKey(key)) {
- int num = fixPayMap.containsKey(key) ? fixPayMap.get(key) : 0;
- return (double) (num);
- } else {
- return (double) 0.0F;
- }
- } catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
- //ex.printStackTrace();
- }
- return (double) 0.0F;
- }
- /**
- * 当月转正人数(通过招聘渠道入职且在生效日期当月转正的人数)。
- * @param ctx 上下文
- * @param paramMap 参数(含 FPERSONID、FID)
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @return 当前人员在生效日期对应的当月转正人数
- */
- public double getMonthZhuanZhengUsers(Context ctx, Map<String, Object> paramMap, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter) {
- try {
- //计算的员工id
- String personId = (String) paramMap.get(mainTableName.toUpperCase() + "_FPERSONID");
- //计算的数据行
- String id = (String) paramMap.get(mainTableName.toUpperCase() + "_FID");
- String Effect = getEffect(ctx, tempMap, mainTableName,mainTableRowFilter, id);
- // 转正人数缓存 key
- String zhuanZhengMapKey = "getMonthZhuanZhengUsers_Map";
- // 查询生效日期当月转正的人数
- getZhuanZhengPersonNum(ctx, tempMap, mainTableName, mainTableRowFilter, zhuanZhengMapKey);
- Map<String, Integer> fixPayMap = (Map) tempMap.get(zhuanZhengMapKey);
- String key = personId + "_" + Effect;
- if (fixPayMap.containsKey(key)) {
- int num = fixPayMap.containsKey(key) ? fixPayMap.get(key) : 0;
- return (double) (num);
- } else {
- return (double) 0.0F;
- }
- } catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
- //ex.printStackTrace();
- }
- return (double) 0.0F;
- }
- /**
- * 当月离职人数(通过招聘渠道入职且在生效日期当月离职的人数)。
- * @param ctx 上下文
- * @param paramMap 参数(含 FPERSONID、FID)
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @return 当前人员在生效日期对应的当月离职人数
- */
- public double getMonthLiZhiUsers(Context ctx, Map<String, Object> paramMap, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter) {
- try {
- //计算的员工id
- String personId = (String) paramMap.get(mainTableName.toUpperCase() + "_FPERSONID");
- //计算的数据行
- String id = (String) paramMap.get(mainTableName.toUpperCase() + "_FID");
- String Effect = getEffect(ctx, tempMap, mainTableName,mainTableRowFilter, id);
- // 离职人数缓存 key
- String liZhiMapKey = "getMonthLiZhiUsers_Map";
- // 查询生效日期当月离职的人数
- getLiZhiPersonNum(ctx, tempMap, mainTableName, mainTableRowFilter, liZhiMapKey);
- Map<String, Integer> fixPayMap = (Map) tempMap.get(liZhiMapKey);
- String key = personId + "_" + Effect;
- if (fixPayMap.containsKey(key)) {
- int num = fixPayMap.containsKey(key) ? fixPayMap.get(key) : 0;
- return (double) (num);
- } else {
- return (double) 0.0F;
- }
- } catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
- //ex.printStackTrace();
- }
- return (double) 0.0F;
- }
- /**
- * 查询生效日期当月离职的人数,按"人员ID_生效年月"为 key 缓存到 tempMap。
- * <p>
- * 通过 CT_REC_ApplicantBeisen(北森应聘表)关联 T_HR_RESIGNBIZBILL(离职单据),
- * 统计招聘渠道入职的员工在生效日期当月离职的人数。
- * @param ctx 上下文
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @param lzZhiMapKey 缓存 key
- * @throws BOSException 数据库异常
- * @throws SQLException SQL异常
- */
- private static void getLiZhiPersonNum(Context ctx, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter, String lzZhiMapKey) throws BOSException, SQLException {
- Map<String, Integer> lzFixPayMap = (Map) tempMap.get(lzZhiMapKey);
- if(lzFixPayMap==null){
- StringBuilder sql = new StringBuilder();
- sql.append(" /*dialect*/ ");
- // 主查询:按核算表和生效月份分组统计离职人数
- sql.append(" SELECT mt.fpersonid,substring(convert(varchar,mt.FEffectDate,120),0,8) FEffectDate,count(abt.pid) pNum from ").append(mainTableName).append(" mt ");
- // 关联子查询:通过北森应聘表匹配到人员,再关联其最近一次离职记录
- sql.append(" left join ( select ab.CFRecruitOwnerID,p.fid pid,t.fbizDate bizDate ");
- sql.append(" from CT_REC_ApplicantBeisen ab ");
- sql.append(" inner join T_REC_ResumeBaseRec rb on rb.CFCANDIDATEID = ab.CFCANDIDATEID ");
- sql.append(" inner join t_bd_person p on isnull(p.FIDCARDNO,p.FPASSPORTNO)=isnull(rb.FIdentityCardNo,rb.FPassportNo) ");
- // 取每个人员最近一次离职记录(ROW_NUMBER + rn=1)
- sql.append(" left join ( ");
- sql.append(" SELECT FPERSONID, FBIZDATE ");
- sql.append(" FROM ( ");
- sql.append(" SELECT ");
- sql.append(" e.FPERSONID, ");
- sql.append(" e.FBIZDATE, ");
- sql.append(" ROW_NUMBER() OVER (PARTITION BY e.FPERSONID ORDER BY e.FBIZDATE DESC) AS rn ");
- sql.append(" FROM T_HR_RESIGNBIZBILLENTRY e ");
- sql.append(" LEFT JOIN T_HR_RESIGNBIZBILL b ON b.fid = e.FBillID ");
- sql.append(" where b.FBillState=3 ");
- sql.append(" ) t ");
- sql.append(" WHERE rn = 1) t on t.fpersonid=p.fid ) abt on abt.CFRecruitOwnerID=mt.fpersonid ");
- // 离职日期在生效日期当月范围内:[当月第一天, 下月第一天)
- sql.append(" AND abt.bizDate >= DATEADD(MONTH, DATEDIFF(MONTH, 0, mt.FEffectDate), 0)"); // 当月第一天 00:00:00.000
- sql.append(" AND abt.bizDate < DATEADD(MONTH, DATEDIFF(MONTH, 0, mt.FEffectDate) + 1, 0) "); // 下个月第一天 00:00:00.000
- sql.append(" AND mt.fid in(").append(mainTableRowFilter).append(") group by mt.fpersonid,substring(convert(varchar,mt.FEffectDate,120),0,8) ");
- IRowSet rs = DbUtil.executeQuery(ctx,sql.toString());
- lzFixPayMap = new HashMap<>();
- while (rs.next()) {
- //获取人数
- String fpersonid = rs.getString("fpersonid");
- String FEffectDate = rs.getString("FEffectDate");
- int pNum = rs.getInt("pNum");
- lzFixPayMap.put(fpersonid+"_"+FEffectDate,pNum);
- }
- tempMap.put(lzZhiMapKey, lzFixPayMap);
- }
- }
- /**
- * 查询生效日期当月入职的人数,按"人员ID_生效年月"为 key 缓存到 tempMap。
- * <p>
- * 通过 CT_REC_ApplicantBeisen(北森应聘表)关联 T_HR_EmpEnrollBizBill(入职单据),
- * 统计招聘渠道入职的员工在生效日期当月入职的人数。
- * @param ctx 上下文
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @param ruZhiMapKey 缓存 key
- * @throws BOSException 数据库异常
- * @throws SQLException SQL异常
- */
- private static void getRuZhiPersonNum(Context ctx, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter, String ruZhiMapKey) throws BOSException, SQLException {
- Map<String, Integer> fixPayMap = (Map) tempMap.get(ruZhiMapKey);
- if(fixPayMap==null){
- StringBuilder sql = new StringBuilder();
- sql.append(" /*dialect*/ ");
- // 主查询:按核算表和生效月份分组统计入职人数
- sql.append(" SELECT mt.fpersonid,substring(convert(varchar,mt.FEffectDate,120),0,8) FEffectDate,count(abt.pid) pNum from ").append(mainTableName).append(" mt ");
- // 关联子查询:通过北森应聘表匹配到人员,再关联其最近一次入职记录
- sql.append(" left join ( select ab.CFRecruitOwnerID,p.fid pid,t.fbizDate bizDate ");
- sql.append(" from CT_REC_ApplicantBeisen ab ");
- sql.append(" inner join T_REC_ResumeBaseRec rb on rb.CFCANDIDATEID = ab.CFCANDIDATEID ");
- sql.append(" inner join t_bd_person p on isnull(p.FIDCARDNO,p.FPASSPORTNO)=isnull(rb.FIdentityCardNo,rb.FPassportNo) ");
- // 取每个人员最近一次入职记录(ROW_NUMBER + rn=1)
- sql.append(" left join ( ");
- sql.append(" SELECT FPERSONID, FBIZDATE ");
- sql.append(" FROM ( ");
- sql.append(" SELECT ");
- sql.append(" e.FPERSONID, ");
- sql.append(" e.FBIZDATE, ");
- sql.append(" ROW_NUMBER() OVER (PARTITION BY e.FPERSONID ORDER BY e.FBIZDATE DESC) AS rn ");
- sql.append(" FROM T_HR_EmpEnrollBizBillEntry e ");
- sql.append(" LEFT JOIN T_HR_EmpEnrollBizBill b ON b.fid = e.FBillID ");
- sql.append(" where b.FBillState=3 ");
- sql.append(" ) t ");
- sql.append(" WHERE rn = 1) t on t.fpersonid=p.fid ) abt on abt.CFRecruitOwnerID=mt.fpersonid ");
- // 入职日期在生效日期当月范围内:[当月第一天, 下月第一天)
- sql.append(" AND abt.bizDate >= DATEADD(MONTH, DATEDIFF(MONTH, 0, mt.FEffectDate), 0)"); // 当月第一天 00:00:00.000
- sql.append(" AND abt.bizDate < DATEADD(MONTH, DATEDIFF(MONTH, 0, mt.FEffectDate) + 1, 0) "); // 下个月第一天 00:00:00.000
- sql.append(" AND mt.fid in(").append(mainTableRowFilter).append(") group by mt.fpersonid,substring(convert(varchar,mt.FEffectDate,120),0,8) ");
- IRowSet rs = DbUtil.executeQuery(ctx,sql.toString());
- fixPayMap = new HashMap<>();
- while (rs.next()) {
- //获取人数
- String fpersonid = rs.getString("fpersonid");
- String FEffectDate = rs.getString("FEffectDate");
- int pNum = rs.getInt("pNum");
- fixPayMap.put(fpersonid+"_"+FEffectDate,pNum);
- }
- tempMap.put(ruZhiMapKey, fixPayMap);
- }
- }
- /**
- * 查询生效日期当月转正的人数,按"人员ID_生效年月"为 key 缓存到 tempMap。
- * <p>
- * 通过 CT_REC_ApplicantBeisen(北森应聘表)关联 T_HR_EMPHIREBIZBILL(转正单据),
- * 统计招聘渠道入职的员工在生效日期当月转正的人数。
- * @param ctx 上下文
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @param ruZhiMapKey 缓存 key
- * @throws BOSException 数据库异常
- * @throws SQLException SQL异常
- */
- private static void getZhuanZhengPersonNum(Context ctx, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter, String ruZhiMapKey) throws BOSException, SQLException {
- Map<String, Integer> fixPayMap = (Map) tempMap.get(ruZhiMapKey);
- if(fixPayMap==null){
- StringBuilder sql = new StringBuilder();
- sql.append(" /*dialect*/ ");
- // 主查询:按核算表和生效月份分组统计转正人数
- sql.append(" SELECT mt.fpersonid,substring(convert(varchar,mt.FEffectDate,120),0,8) FEffectDate,count(abt.pid) pNum from ").append(mainTableName).append(" mt ");
- // 关联子查询:通过北森应聘表匹配到人员,再关联其最近一次转正记录
- sql.append(" left join ( select ab.CFRecruitOwnerID,p.fid pid,t.fbizDate bizDate ");
- sql.append(" from CT_REC_ApplicantBeisen ab ");
- sql.append(" inner join T_REC_ResumeBaseRec rb on rb.CFCANDIDATEID = ab.CFCANDIDATEID ");
- sql.append(" inner join t_bd_person p on isnull(p.FIDCARDNO,p.FPASSPORTNO)=isnull(rb.FIdentityCardNo,rb.FPassportNo) ");
- // 取每个人员最近一次转正记录(ROW_NUMBER + rn=1)
- sql.append(" left join ( ");
- sql.append(" SELECT FPERSONID, FBIZDATE ");
- sql.append(" FROM ( ");
- sql.append(" SELECT ");
- sql.append(" e.FPERSONID, ");
- sql.append(" e.FBIZDATE,e.FEnrollDate, ");
- sql.append(" ROW_NUMBER() OVER (PARTITION BY e.FPERSONID ORDER BY e.FBIZDATE DESC) AS rn ");
- sql.append(" FROM T_HR_EMPHIREBIZBILLENTRY e ");
- sql.append(" LEFT JOIN T_HR_EMPHIREBIZBILL b ON b.fid = e.FBillID ");
- sql.append(" where b.FBillState=3 ");
- sql.append(" ) t ");
- sql.append(" WHERE rn = 1) t on t.fpersonid=p.fid ) abt on abt.CFRecruitOwnerID=mt.fpersonid ");
- // 转正日期在生效日期当月范围内:[当月第一天, 下月第一天)
- sql.append(" AND abt.bizDate >= DATEADD(MONTH, DATEDIFF(MONTH, 0, mt.FEffectDate), 0)"); // 当月第一天 00:00:00.000
- sql.append(" AND abt.bizDate < DATEADD(MONTH, DATEDIFF(MONTH, 0, mt.FEffectDate) + 1, 0) "); // 下个月第一天 00:00:00.000
- sql.append(" AND mt.fid in(").append(mainTableRowFilter).append(") group by mt.fpersonid,substring(convert(varchar,mt.FEffectDate,120),0,8) ");
- IRowSet rs = DbUtil.executeQuery(ctx,sql.toString());
- fixPayMap = new HashMap<>();
- while (rs.next()) {
- //获取人数
- String fpersonid = rs.getString("fpersonid");
- String FEffectDate = rs.getString("FEffectDate");
- int pNum = rs.getInt("pNum");
- fixPayMap.put(fpersonid+"_"+FEffectDate,pNum);
- }
- tempMap.put(ruZhiMapKey, fixPayMap);
- }
- }
- /**
- * 获取生效日期的月份(yyyy-MM 格式)。
- * <p>
- * 优先从 tempMap 中以 "getEffect_" + id 为 key 查找缓存;
- * 缓存未命中时,一次性批量查询 mainTableRowFilter 范围内所有行的 FEffectDate,
- * 逐行以 "getEffect_" + fid 为 key 写入 tempMap,后续同一批次其他行直接命中缓存。
- * @param ctx 上下文
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件(用于批量加载)
- * @param id 当前数据行 FID
- * @return 生效日期对应的 yyyy-MM 格式月份字符串,若未查到则为空字符串
- * @throws BOSException 数据库异常
- * @throws SQLException SQL异常
- */
- private static String getEffect(Context ctx, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter, String id) throws BOSException, SQLException {
- String cacheKey = "getEffect_" + id;
- if (tempMap.containsKey(cacheKey)) {
- return (String) tempMap.get(cacheKey);
- }
- IRowSet rowSet = DbUtil.executeQuery(ctx, " SELECT mt.fid,mt.fpersonid,mt.FEffectDate from " + mainTableName + " mt where mt.fid in("+mainTableRowFilter+")");
- String Effect = "";
- while (rowSet.next()) {
- String fid = rowSet.getString("fid");
- LocalDate effectDate = rowSet.getDate("FEffectDate").toLocalDate();
- Effect = effectDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
- String Key = "getEffect_" + fid;
- tempMap.put(Key, Effect);
- }
- return (String) tempMap.getOrDefault(cacheKey, "");
- }
- /**
- * 获取适用薪酬方案名称(fname_l2)。
- * <p>
- * 通过计算表关联 T_HR_SBatchSubmitShemeBill 和 T_HR_SCalSubmitScheme,
- * 查询当前计算范围对应的薪酬方案名称,结果以"name"为 key 缓存。
- * @param ctx 上下文
- * @param paramMap 参数(含 FPERSONID、FID)
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @return 方案名称,未找到则返回空字符串
- */
- public String getApplicablePlan(Context ctx, Map<String, Object> paramMap, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter) {
- try {
- //计算的员工id
- String personId = (String) paramMap.get(mainTableName.toUpperCase() + "_FPERSONID");
- //计算的数据行
- String id = (String) paramMap.get(mainTableName.toUpperCase() + "_FID");
- //根据计算范围初始化薪酬项目信息
- String fixPayMapKey = "getApplicablePlan_SchemeName";
- if (tempMap.get(fixPayMapKey) == null) {
- StringBuilder sql = new StringBuilder();
- sql.append(" select sss.fname_l2 from "+mainTableName+" sbe ");
- sql.append(" left join T_HR_SBatchSubmitShemeBill ssb on ssb.fid=sbe.FBillID ");
- sql.append(" left join T_HR_SCalSubmitScheme sss on sss.fid=ssb.FSubmitSchemeID ");
- sql.append(" where sbe.fid in(" + mainTableRowFilter + ")");
- IRowSet rs = DbUtil.executeQuery(ctx, sql.toString());
- if (rs.next()) {
- Map<String, String> objectMap = new HashMap<>();
- objectMap.put("name", rs.getString("fname_l2"));
- tempMap.put(fixPayMapKey, objectMap);
- }
- }
- //获取薪酬项目值
- Map<String, String> fixPayMap = (Map) tempMap.get(fixPayMapKey);
- String key = "name";
- if (fixPayMap.containsKey(key)) {
- String schemeName = fixPayMap.get(key);
- return schemeName;
- } else {
- return "";
- }
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- //e.printStackTrace();
- return "";
- }
- }
- /**
- * 获取薪酬档案中指定薪资项目的金额。
- * <p>
- * 根据人员 ID 和薪酬项目名称,从 T_HR_SFIXADJUSTSALARY 表中查询固定薪酬数据。
- * 结果以 "personId_cmpItem" 为 key 缓存到 tempMap,后续同一计算范围直接复用。
- * @param ctx 上下文
- * @param paramMap 参数(含 FPERSONID、FID)
- * @param tempMap 临时缓存 Map
- * @param mainTableName 计算表对象名
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @param cmpItem 薪酬项目名称(对应 T_HR_SCMPITEM.FNAME_L2)
- * @param isFixed 是否固定薪酬(0=按FEffectDate匹配, 非0=按FEffectDate匹配;预留扩展)
- * @return 薪资项目金额,若人员或项目不存在则返回 0.0
- */
- public double getItemSalary(Context ctx, Map<String, Object> paramMap, HashMap<String, Object> tempMap, String mainTableName, String mainTableRowFilter,
- String cmpItem, double isFixed) {
- try {
- //计算的员工id
- String personId = (String) paramMap.get(mainTableName.toUpperCase() + "_FPERSONID");
- //计算的数据行
- String id = (String) paramMap.get(mainTableName.toUpperCase() + "_FID");
- //根据计算范围初始化薪酬项目信息
- String fixPayMapKey = "getItemSalary_fixPayMap_" + isFixed;
- if (!StringUtils.isEmpty(cmpItem) && personId != null) {
- if (tempMap.get(fixPayMapKey) == null) {
- tempMap.put(fixPayMapKey, this.initFixPayForMoneyMap(ctx, mainTableName, isFixed, mainTableRowFilter));
- }
- //获取薪酬项目值
- Map<String, BigDecimal> fixPayMap = (Map) tempMap.get(fixPayMapKey);
- String key = personId + "_" + cmpItem;
- if (fixPayMap.containsKey(key)) {
- BigDecimal money = fixPayMap.containsKey(key) ? (BigDecimal) fixPayMap.get(key) : new BigDecimal(0);
- double pay = money.doubleValue();
- return pay;
- } else {
- return (double) 0.0F;
- }
- } else {
- return (double) 0.0F;
- }
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- //e.printStackTrace();
- return (double) 0.0F;
- }
- }
- /**
- * 初始化固定薪酬数据 Map,以 "personId_cmpItem" 为 key,金额为 value。
- * <p>
- * 查询 T_HR_SFIXADJUSTSALARY(固定调整薪酬表),按生效日期匹配核算表中的薪酬项目。
- * 查询结果按 type 优先级排序:type=1(相同组织)优先于 type=0(无组织限制),
- * 同一 key 仅保留首次出现的记录(优先级最高的)。
- * @param ctx 上下文
- * @param mainTableName 计算表对象名
- * @param isFixed 是否固定薪酬(0=按FEffectDate匹配, 非0=按FEffectDate匹配;预留扩展)
- * @param mainTableRowFilter 计算表数据行过滤条件
- * @return key 为 "personId_cmpItem",value 为对应金额的 Map
- * @throws Exception 数据库异常
- */
- public Map<String, BigDecimal> initFixPayForMoneyMap(Context ctx, String mainTableName, double isFixed, String mainTableRowFilter) throws Exception {
- StringBuilder sb = new StringBuilder();
- String effectDayField = "";
- String key = null;
- String personId = "";
- String cmpItem = "";
- Map<String, BigDecimal> fixPayMap = new HashMap();
- Set<String> set = new HashSet();
- if (isFixed == (double) 0.0F) {
- effectDayField = "calTable.FEffectDate";
- } else {
- effectDayField = "calTable.FEffectDate";
- }
- sb.append(" SELECT DISTINCT CALTABLE.FPERSONID as personId, FIX.FMONEY MONEY, FIX.FCURRENCYID, ");
- sb.append(" CMPITEM.FNAME_L2 CMPITEM,FIX.FEFFECTDAY, ");
- // type: 0=组织为空(通用), 1=组织匹配(优先), 2=组织不匹配(排除)
- sb.append(" ( case when (fix.fpayhrorgunitid is null or fix.fpayhrorgunitid in ('')) then 0 when ( calTable.FHrOrgUnitID= fix.fpayhrorgunitid) then 1 else 2 end ) as type").append("\r\n");
- sb.append(" FROM " + mainTableName + " CALTABLE ");
- sb.append(" INNER JOIN T_HR_SFIXADJUSTSALARY FIX ON CALTABLE.FPERSONID=FIX.FPERSONID AND (FIX.FCurrencyID = CALTABLE.FCurrencyID OR FIX.FCurrencyID IS NULL)");
- sb.append(" LEFT JOIN T_HR_SCMPITEM CMPITEM ON CMPITEM.FID=FIX.FCMPITEMID ");
- sb.append(" WHERE FIX.feffectday <= ").append(effectDayField).append(" AND FIX.fleffectday >= ").append(effectDayField);
- sb.append(" AND CALTABLE.fid in(").append(mainTableRowFilter).append(")");
- IRowSet rs = DbUtil.executeQuery(ctx, sb.toString());
- List<Map<String, Object>> dataList = this.getDataFromExecuteQuery(rs);
- Iterator<Map<String, Object>> it = dataList.iterator();
- while (it.hasNext()) {
- Map<String, Object> data = (Map) it.next();
- personId = (String) data.get("personId");
- cmpItem = (String) data.get("CMPITEM");
- key = personId + "_" + cmpItem;
- if (!set.contains(key)) {
- set.add(key);
- BigDecimal money = (BigDecimal) data.get("MONEY");
- fixPayMap.put(key, money);
- }
- }
- return fixPayMap;
- }
- /**
- * 将 IRowSet 查询结果按优先级排序后转换为 List<Map>。
- * <p>
- * 排序规则:type=1(相同组织)的记录优先,type=0(无组织限制)的次之,type=2(组织不匹配)的排除。
- * 同一人员同一薪酬项目的 key 只保留首次出现(即优先级最高)的记录。
- * @param executeQuery 查询结果集
- * @return 按优先级排序后的数据列表
- * @throws SQLException SQL异常
- */
- public List<Map<String, Object>> getDataFromExecuteQuery(IRowSet executeQuery) throws SQLException {
- Map<String, Object> map = null;
- List<Map<String, Object>> dataList = null;
- Map<String, List<Map<String, Object>>> mapList = null;
- Map<String, List<Map<String, Object>>> mapListOne = null;
- Map<String, List<Map<String, Object>>> mapListZero = null;
- List<Map<String, Object>> list = null;
- List<Map<String, Object>> oneList = null;
- List<Map<String, Object>> zeroList = null;
- if (null != executeQuery) {
- String personId = null;
- dataList = new ArrayList();
- mapList = new HashMap();
- mapListOne = new HashMap();
- mapListZero = new HashMap();
- while (executeQuery.next()) {
- map = this.executeQueryToMap(executeQuery);
- personId = executeQuery.getString("personId");
- int type = executeQuery.getInt("type");
- if (mapList.containsKey(personId)) {
- list = (List) mapList.get(personId);
- list.add(map);
- } else {
- list = new ArrayList();
- list.add(map);
- mapList.put(personId, list);
- }
- // type=1: 组织匹配,优先使用
- if (type == 1) {
- if (mapListOne.containsKey(personId)) {
- oneList = (List) mapListOne.get(personId);
- oneList.add(map);
- } else {
- oneList = new ArrayList();
- oneList.add(map);
- mapListOne.put(personId, oneList);
- }
- // type=0: 无组织限制,次优
- } else if (type == 0) {
- if (mapListZero.containsKey(personId)) {
- zeroList = (List) mapListZero.get(personId);
- zeroList.add(map);
- } else {
- zeroList = new ArrayList();
- zeroList.add(map);
- mapListZero.put(personId, zeroList);
- }
- }
- // type=2(组织不匹配)排除,不加入结果
- }
- List<Map<String, Object>> var21 = null;
- // 合并结果:先加入 type=1(组织匹配),再加入 type=0(无组织限制)
- // 后续去重逻辑会保留首次出现的记录,从而实现优先级
- for (String str : mapList.keySet()) {
- List<Map<String, Object>> var22 = (List) mapList.get(str);
- if (mapListOne.containsKey(str)) {
- dataList.addAll((Collection) mapListOne.get(str));
- }
- if (mapListZero.containsKey(str)) {
- dataList.addAll((Collection) mapListZero.get(str));
- }
- }
- }
- return (List<Map<String, Object>>) (null != dataList && !dataList.isEmpty() ? dataList : new ArrayList(0));
- }
- /**
- * 将 IRowSet 当前行转换为 Map,提取固定薪酬相关字段。
- * @param executeQuery 查询结果集(已定位到某一行)
- * @return 包含 personId、MONEY、FCURRENCYID、CMPITEM、FEFFECTDAY 的 Map
- * @throws SQLException SQL异常
- */
- public Map<String, Object> executeQueryToMap(IRowSet executeQuery) throws SQLException {
- Map<String, Object> map = new HashMap();
- map.put("personId", executeQuery.getString("personId"));
- map.put("MONEY", executeQuery.getBigDecimal("MONEY") == null ? new BigDecimal(0) : executeQuery.getBigDecimal("MONEY"));
- map.put("FCURRENCYID", executeQuery.getString("FCURRENCYID"));
- map.put("CMPITEM", executeQuery.getString("CMPITEM"));
- map.put("FEFFECTDAY", executeQuery.getDate("FEFFECTDAY"));
- return map;
- }
- }
|