Просмотр исходного кода

feat(hr): 添加职位津贴数据服务和有效日期过滤功能

- 新增 QFilterCommonHelper.getValidDateFilter 方法用于获取有效时间范围内的过滤条件
- 实现 HasPosAllowDataService 类提供职位津贴薪酬函数数据查询功能
- 添加对管理人员任命和职位津贴的逻辑判断和过滤处理
- 集成日期范围查询和人员职位档案的数据查询功能
- 实现按人员分组并取最新一条职位记录的业务逻辑
- 完善职位津贴享受状态的计算和返回机制
wyc 1 неделя назад
Родитель
Сommit
5e092b5572

+ 20 - 0
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/orm/helper/QFilterCommonHelper.java

@@ -185,4 +185,24 @@ public final class QFilterCommonHelper {
 
         return beginFilter.and(endFilter.or(nullEndFilter));
     }
+
+    /**
+     * 获取有效时间范围内的QFilter实例
+     * 如果结束时间为空,则表示持续有效
+     * @param beginDateProperty 开始时间字段名
+     * @param endDateProperty 结束时间字段名
+     * @param date 获取的日期
+     * @return: kd.bos.orm.query.QFilter
+     * @author W.Y.C
+     * @date: 2025/07/07
+     */
+    public static QFilter getValidDateFilter(String beginDateProperty, String endDateProperty,Date date) {
+        // 创建组合条件 (beginTime <= currentTime AND (endTime >= currentTime OR endTime IS NULL))
+        Date currentDate = new Date();
+        QFilter beginFilter = new QFilter(beginDateProperty, QCP.less_equals, date);
+        QFilter endFilter = new QFilter(endDateProperty, QCP.large_equals, date);
+        QFilter nullEndFilter = new QFilter(endDateProperty, QCP.is_null, null);
+
+        return beginFilter.and(endFilter.or(nullEndFilter));
+    }
 }

+ 151 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/HasPosAllowDataService.java

@@ -0,0 +1,151 @@
+package nckd.jxccl.hr.psms.common;
+
+import kd.bos.common.enums.EnableEnum;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.entity.constant.StatusEnum;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
+import kd.sdk.swc.hscs.common.api.ICustomFetchDataService;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 否有享受职位津贴薪酬函数
+ *
+ * @author W.Y.C
+ * @version 1.0
+ * @date 2026/1/3 20:53
+ */
+public class HasPosAllowDataService implements ICustomFetchDataService {
+
+    @Override
+    public Map<Long, Map<String, Object>> fetchDataCalPerson(List<Long> calPersonIdList, Map<Long, Map<String, Object>> paramsMap, Map<String, Object> extParamMap) {
+        Map<Long, Map<String, Object>> resultMap = new HashMap<Long, Map<String, Object>>();
+
+        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
+                .add(FormConstant.ID_KEY)
+                .add(FormConstant.EMP_NUMBER_KEY)
+                .add(FormConstant.NAME_KEY)
+                .add(FormConstant.ORG_KEY)
+                .addGroup(new String[]{"caltask"}, "calcount", "payrolldate")
+                .addGroup(new String[]{"caltask", "calrule"}, FormConstant.ID_KEY)
+                .addGroup(new String[]{FormConstant.EMPLOYEE_KEY}, FormConstant.ID_KEY);
+        QFilter qFilter = new QFilter(FormConstant.ID_KEY, "in", calPersonIdList);
+        DynamicObject[] load = new HRBaseServiceHelper("hsas_calperson").load(queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
+        if(load != null && load.length > 0) {
+            Map<Long, Long> employeeToCalPersonMap = Arrays.stream(load)
+                    .collect(Collectors.toMap(
+                            obj -> obj.getLong(FormConstant.ID_KEY),
+                            obj -> obj.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY))
+                            ));
+            long orgId = load[0].getLong(String.join(".", FormConstant.ORG_KEY, FormConstant.ID_KEY));
+            //核算任务
+            DynamicObject calTask = load[0].getDynamicObject("caltask");
+            //薪资所属年月
+            Date date = calTask.getDate("payrolldate");
+            int year = DateUtil.getYear(date);
+            int month = DateUtil.getMonthValue(date);
+            //核算规则
+            long calRuleId = calTask.getLong(String.join(".", "calrule", FormConstant.ID_KEY));
+            //核算次数
+            int calCount = calTask.getInt("calcount");
+
+            //查询非“高级人才”聘任类型的职位档案
+            QFilter personPosFileFilter = new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode())
+                    .and(PositionStructureConstant.NCKD_TYPESTATE, QCP.not_in, new String[]{TypeStateEnum.HIGH_PROFESSIONAL_EMPLOYMENT.getCode()})
+                    .and(QFilterCommonHelper.getValidDateFilter(PositionStructureConstant.NCKD_BEGINDATE, PositionStructureConstant.NCKD_ENDDATE,date))
+                    .and(new QFilter(PositionStructureConstant.NCKD_PERSON, QCP.in, employeeToCalPersonMap.values()));
+            QueryFieldBuilder personPosFileFieldBuilder = QueryFieldBuilder.create()
+                    .add(FormConstant.ID_KEY)
+                    .addIdNumberName(FormConstant.NCKD_PERSON)
+                    .add(PositionStructureConstant.NCKD_ISSALADJPUSH)
+                    .add(PositionStructureConstant.NCKD_BEGINDATE)
+                    .add(PositionStructureConstant.CREATE_TIME_KEY)
+                    .add(PositionStructureConstant.NCKD_TYPESTATE)
+                    .addIdNumberNameWithExtras(new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},PositionStructureConstant.JOBLEVELSEQ,PositionStructureConstant.NCKD_COEFFICIENT)
+                    .orderDesc(PositionStructureConstant.NCKD_BEGINDATE);
+            DynamicObjectCollection personPosFileColl = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, personPosFileFieldBuilder.buildSelect(), new QFilter[]{personPosFileFilter});
+            //筛选出管理人员任命
+            List<DynamicObject> managementPostFile = personPosFileColl.stream().filter(obj -> TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT.getCode().equalsIgnoreCase(obj.getString(PositionStructureConstant.NCKD_TYPESTATE))).collect(Collectors.toList());
+            List<Long> managementPersonIds = managementPostFile.stream().map(obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY))).collect(Collectors.toList());
+
+            //如果是管理人员任命则必须“配置有职位津贴”才能享受职位津贴
+            //查询职位津贴
+            QFilter positionAllowanceFilter = new QFilter(PositionStructureConstant.NCKD_PERSON, QCP.in, managementPersonIds)
+                    .and(QFilterCommonHelper.getValidDateFilter(PositionStructureConstant.NCKD_STARTDATE, PositionStructureConstant.NCKD_ENDDATE,date))
+                    //已确认或已审批
+                    .and(new QFilter(PositionStructureConstant.STATUS, QCP.in, new String[]{StatusEnum.B.toString(), StatusEnum.C.toString()}));
+            QueryFieldBuilder positionAllowanceFieldBuilder = QueryFieldBuilder.create()
+                    .add(FormConstant.ID_KEY)
+                    .addIdNumberName(PositionStructureConstant.NCKD_PERSON);
+            DynamicObjectCollection positionAllowanceColl = QueryServiceHelper.query(PositionStructureConstant.MANAGERALLOWANCE_ENTITYID, positionAllowanceFieldBuilder.buildSelect(), new QFilter[]{positionAllowanceFilter});
+            // 获取有职位津贴的人员ID列表
+            List<Long> positionAllowancePersonIds = positionAllowanceColl.stream()
+                    .map(obj -> obj.getLong(String.join(".", PositionStructureConstant.NCKD_PERSON, FormConstant.ID_KEY)))
+                    .collect(Collectors.toList());
+            // 找出没有职位津贴的管理人员ID
+            List<Long> noAllowanceManagementPersonIds = managementPostFile.stream()
+                    .map(obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY)))
+                    .filter(personId -> !positionAllowancePersonIds.contains(personId))
+                    .collect(Collectors.toList());
+
+            //去掉"管理人员任命"及是"管理人员任命"但是没有津贴的人员
+            List<DynamicObject> posAllowFileCollect = personPosFileColl.stream()
+                    .filter(obj -> {
+                        Long personId = obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
+                        String typeState = obj.getString(PositionStructureConstant.NCKD_TYPESTATE);
+                        // 去掉类型为“管理人员任命”的记录
+                        if (TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT.getCode().equalsIgnoreCase(typeState)) {
+                            return false;
+                        }
+                        // 如果是管理人员但没有津贴,则该人员的所有记录都不保留
+                        if (noAllowanceManagementPersonIds.contains(personId)) {
+                            return false;
+                        }
+                        // 其他情况保留
+                        return true;
+                    })
+                    .collect(Collectors.toList());
+            //分组,取最新一条
+            Map<Long, DynamicObject> posAllowFileMap = posAllowFileCollect.stream()
+                    .collect(Collectors.groupingBy(
+                            obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY)),
+                            Collectors.collectingAndThen(
+                                    Collectors.maxBy((o1, o2) -> {
+                                        Date date1 = o1.getDate(PositionStructureConstant.NCKD_BEGINDATE);
+                                        Date date2 = o2.getDate(PositionStructureConstant.NCKD_BEGINDATE);
+                                        return date1 != null && date2 != null ? date1.compareTo(date2) : 0;
+                                    }),
+                                    optional -> optional.orElse(null)
+                            )
+                    ))
+                    .entrySet().stream()
+                    .filter(entry -> entry.getValue() != null) // 过滤掉值为null的条目
+                    .collect(Collectors.toMap(
+                            Map.Entry::getKey,
+                            Map.Entry::getValue));
+            for (Long calPersonId : calPersonIdList) {
+                Long personId = employeeToCalPersonMap.get(calPersonId);
+                DynamicObject dynamicObject = posAllowFileMap.get(personId);
+                Map<String, Object> result = new HashMap<String, Object>();
+                //享受返回1,不享受返回0
+                result.put("hasPosAllow",dynamicObject != null ? "1" : "0");
+                resultMap.put(calPersonId, result);
+            }
+        }
+        return resultMap;
+    }
+}