|
|
@@ -0,0 +1,444 @@
|
|
|
+package nckd.jxccl.hr.sdm.plugin.operate;
|
|
|
+
|
|
|
+import kd.bos.coderule.api.CodeRuleInfo;
|
|
|
+import kd.bos.coderule.opplugin.util.OrgUtil;
|
|
|
+import kd.bos.common.enums.EnableEnum;
|
|
|
+import kd.bos.dataentity.entity.DynamicObject;
|
|
|
+import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
|
+import kd.bos.dataentity.entity.LocaleString;
|
|
|
+import kd.bos.entity.EntityMetadataCache;
|
|
|
+import kd.bos.entity.QueryEntityType;
|
|
|
+import kd.bos.entity.operate.result.IOperateInfo;
|
|
|
+import kd.bos.entity.operate.result.OperationResult;
|
|
|
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
|
|
|
+import kd.bos.entity.plugin.PreparePropertysEventArgs;
|
|
|
+import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
|
|
|
+import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
|
|
|
+import kd.bos.exception.ErrorCode;
|
|
|
+import kd.bos.exception.KDBizException;
|
|
|
+import kd.bos.message.util.MessageUtils;
|
|
|
+import kd.bos.orm.ORM;
|
|
|
+import kd.bos.orm.query.QCP;
|
|
|
+import kd.bos.orm.query.QFilter;
|
|
|
+import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
|
|
|
+import kd.bos.servicehelper.operation.SaveServiceHelper;
|
|
|
+import kd.bos.servicehelper.user.UserServiceHelper;
|
|
|
+import kd.bos.url.UrlService;
|
|
|
+import kd.bos.workflow.engine.msg.info.MessageInfo;
|
|
|
+import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
|
|
|
+import kd.hr.hbp.business.servicehelper.HRQueryEntityHelper;
|
|
|
+import kd.hr.hbp.common.util.HRDateTimeUtils;
|
|
|
+import kd.hr.hbp.common.util.HRObjectUtils;
|
|
|
+import kd.sdk.hr.hrpi.business.helper.HRPIEmployeeServiceHelper;
|
|
|
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
|
|
|
+import nckd.jxccl.base.org.helper.OrgHelper;
|
|
|
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
|
|
|
+import nckd.jxccl.hr.sdm.common.SanDingConstant;
|
|
|
+import nckd.jxccl.hr.sdm.common.SanDingPlanEntryStatus;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.StringJoiner;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 发起任务OP插件
|
|
|
+ * @entity: nckd_sandingplan
|
|
|
+ * @operat: sendtask
|
|
|
+ * @author: jtd
|
|
|
+ * @date: 2025/12/3 15:01
|
|
|
+ */
|
|
|
+public class SendTaskOpPlugin extends AbstractOperationServicePlugIn {
|
|
|
+
|
|
|
+ /** 特殊借调变动操作编码 */
|
|
|
+ private static final String TSJD_CHGACTION_NUMBER = "JTCC_1001";
|
|
|
+ /** 跨公司调动 */
|
|
|
+ private static final String KGSDD_CHGACTION_NUMBER = "101060_S";
|
|
|
+ /** 获取岗位信息查询编码 */
|
|
|
+ private static final String NCKD_SDM_GETPOSITIONQUERY = "nckd_sdm_getpositionquery";
|
|
|
+ /** orm */
|
|
|
+ private static final ORM ORM_IMPL = ORM.create();
|
|
|
+ /** key->三定计划ID value->三定任务ID */
|
|
|
+ private static final Map<Long, Long> SANDING_TASK_MAP = new HashMap<Long, Long>();
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onPreparePropertys(PreparePropertysEventArgs e) {
|
|
|
+ super.onPreparePropertys(e);
|
|
|
+
|
|
|
+ e.getFieldKeys().addAll(billEntityType.getAllFields().keySet());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void beginOperationTransaction(BeginOperationTransactionArgs e) {
|
|
|
+ super.beginOperationTransaction(e);
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+
|
|
|
+ DynamicObject[] dyos = e.getDataEntities();
|
|
|
+ for (DynamicObject dyo : dyos) {
|
|
|
+ DynamicObjectCollection entryDyoColl = dyo.getDynamicObjectCollection(SanDingConstant.NCKD_ENTRYENTITY);
|
|
|
+ sendTask(dyo, entryDyoColl);
|
|
|
+ // 设置 已发送
|
|
|
+ dyo.set(SanDingConstant.NCKD_ISSEND_KEY, EnableEnum.YES.getCode());
|
|
|
+ }
|
|
|
+ // 保存数据
|
|
|
+ SaveServiceHelper.save(dyos);
|
|
|
+ } catch (Exception ex) {
|
|
|
+ throw new KDBizException(ex, new ErrorCode("sendTaskError", ex.getMessage()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void sendTask(DynamicObject billDyo, DynamicObjectCollection entryDyoColl) throws Exception {
|
|
|
+ // key 是否在职
|
|
|
+ String isHiredKey = String.join(".", SanDingConstant.NCKD_LABORRELSTATUS_KEY, SanDingConstant.IS_HIRED);
|
|
|
+ // Key 岗位BOID
|
|
|
+ String positionBoIdKey = String.join(".", SanDingConstant.POSITION_KEY, SanDingConstant.BOID_KEY);
|
|
|
+ // Key 员工BOID
|
|
|
+ String employeeBoIdKey = String.join(".", SanDingConstant.EMPLOYEE_KEY, SanDingConstant.BOID_KEY);
|
|
|
+ // Key 单位BOID
|
|
|
+ String companyBoIdKey = String.join(".", SanDingConstant.NCKD_COMPANY_KEY, SanDingConstant.BOID_KEY);
|
|
|
+ // 获取 所有单位BOID
|
|
|
+ Set<Long> companyBoIds = entryDyoColl.stream().map(entryDyo -> entryDyo.getLong(companyBoIdKey)).collect(Collectors.toSet());
|
|
|
+ // 获取 所有岗位数据
|
|
|
+ QFilter qFilter = new QFilter(String.join(".", SanDingConstant.ADMINORG, SanDingConstant.BELONGCOMPANY_KEY, SanDingConstant.BOID_KEY), QCP.in, companyBoIds).and(QFilterCommonHelper.getCurrentVersionFilter());
|
|
|
+ // 查询 BOID、行政组织、行政组织.所属公司
|
|
|
+ String queryFields = QueryFieldBuilder.create()
|
|
|
+ .add(SanDingConstant.BOID_KEY)
|
|
|
+ .add(SanDingConstant.SOURCEVID_KEY)
|
|
|
+ .add(SanDingConstant.HAOS_ADMINORGHR_BOID)
|
|
|
+ .add(SanDingConstant.HAOS_ADMINORGHR_SOURCEVID)
|
|
|
+ .add(SanDingConstant.HAOS_ADMINORGHR_BELONGCOMPANY_BOID)
|
|
|
+ .buildSelect();
|
|
|
+ String orderBys = QueryFieldBuilder.create()
|
|
|
+ .addAsc(SanDingConstant.ADMINORG, SanDingConstant.LEVEL_KEY)
|
|
|
+ .addAsc(SanDingConstant.ADMINORG, SanDingConstant.INDEX_KEY)
|
|
|
+ .addDesc(SanDingConstant.ISLEADER_KEY)
|
|
|
+ .addAsc(SanDingConstant.NUMBER_KEY)
|
|
|
+ .buildOrder();
|
|
|
+ DynamicObjectCollection positionDyoColl = HRQueryEntityHelper.getInstance().getQueryDyoColl((QueryEntityType) EntityMetadataCache.getDataEntityType(NCKD_SDM_GETPOSITIONQUERY), queryFields, new QFilter[]{qFilter}, orderBys);
|
|
|
+ // 获取 所有岗位BOID
|
|
|
+ Set<Long> positionBoIdSet = positionDyoColl.stream().map(positionDyo -> positionDyo.getLong(SanDingConstant.BOID_KEY)).collect(Collectors.toSet());
|
|
|
+ // 处理成 key->公司BOID value->List<Map<String, Long>>
|
|
|
+ Map<Long, List<Map<String, Long>>> companyPositionMap = positionDyoColl.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ positionDyo -> positionDyo.getLong(SanDingConstant.HAOS_ADMINORGHR_BELONGCOMPANY_BOID),
|
|
|
+ Collectors.mapping(
|
|
|
+ positionDyo -> {
|
|
|
+ Map<String, Long> positionOrgMap = new HashMap<>();
|
|
|
+ positionOrgMap.put("positionBoId", positionDyo.getLong(SanDingConstant.BOID_KEY));
|
|
|
+ positionOrgMap.put("positionSourceVid", positionDyo.getLong(SanDingConstant.BOID_KEY));
|
|
|
+ positionOrgMap.put("adminOrgBoId", positionDyo.getLong(SanDingConstant.HAOS_ADMINORGHR_BOID));
|
|
|
+ positionOrgMap.put("adminOrgSourceVid", positionDyo.getLong(SanDingConstant.HAOS_ADMINORGHR_BOID));
|
|
|
+ return positionOrgMap;
|
|
|
+ },
|
|
|
+ Collectors.toList()
|
|
|
+ )
|
|
|
+ ));
|
|
|
+ // 获取 所有岗位当前在职人数
|
|
|
+ HRBaseServiceHelper empPosOrgRelServiceHelper = HRBaseServiceHelper.create(SanDingConstant.HRPI_EMPPOSORGREL);
|
|
|
+ // 获取当前日期
|
|
|
+ Date nowDate = HRDateTimeUtils.getNowDate();
|
|
|
+ // 过滤 主任职 并且 开始日期<=当前日期 并且 结束日期>=当前日期 并且 用工关系状态.是否在职=1 并且 变动操作.编码<>特殊借调 并且 岗位BOID
|
|
|
+ qFilter = new QFilter(SanDingConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
|
|
|
+ .and(new QFilter(SanDingConstant.STARTDATE, QCP.less_equals, nowDate))
|
|
|
+ .and(new QFilter(SanDingConstant.ENDDATE, QCP.large_equals, nowDate))
|
|
|
+ .and(new QFilter(isHiredKey, QCP.equals, EnableEnum.YES.getCode()))
|
|
|
+ .and(new QFilter(String.join(".", SanDingConstant.CHGACTION, SanDingConstant.NUMBER_KEY), QCP.not_equals, TSJD_CHGACTION_NUMBER))
|
|
|
+ .and(new QFilter(positionBoIdKey, QCP.in, positionBoIdSet));
|
|
|
+ // 排序 行政组织.物理层级、行政组织.排序号、岗位.是否负责人岗位
|
|
|
+ orderBys = QueryFieldBuilder.create()
|
|
|
+ .addAsc(SanDingConstant.ADMINORG, SanDingConstant.LEVEL_KEY)
|
|
|
+ .addAsc(SanDingConstant.ADMINORG, SanDingConstant.INDEX_KEY)
|
|
|
+ .addDesc(SanDingConstant.POSITION_KEY, SanDingConstant.ISLEADER_KEY)
|
|
|
+ .buildOrder();
|
|
|
+ DynamicObject[] empPosOrgRelDyos = empPosOrgRelServiceHelper.queryOriginalArray(positionBoIdKey, new QFilter[]{qFilter}, orderBys);
|
|
|
+ // 处理成 key->岗位BOID value->岗位当前在职人数
|
|
|
+ Map<Long, Integer> positionInStaffEmployeeCountMap = Arrays.stream(empPosOrgRelDyos).map(empPosOrgRelDyo -> empPosOrgRelDyo.getLong(positionBoIdKey)).collect(Collectors.groupingBy(Function.identity(), Collectors.collectingAndThen(Collectors.counting(), Long::intValue)));
|
|
|
+ // 获取上年
|
|
|
+ String y1 = String.valueOf(HRDateTimeUtils.getYear(HRDateTimeUtils.getNowDate())-1);
|
|
|
+ // 获取上上年
|
|
|
+ String y2 = String.valueOf(HRDateTimeUtils.getYear(HRDateTimeUtils.getNowDate())-2);
|
|
|
+ // 获取上上上年
|
|
|
+ String y3 = String.valueOf(HRDateTimeUtils.getYear(HRDateTimeUtils.getNowDate())-3);
|
|
|
+ // 获取上上上上年
|
|
|
+ String y4 = String.valueOf(HRDateTimeUtils.getYear(HRDateTimeUtils.getNowDate())-4);
|
|
|
+ // 过滤 主任职 并且 用工关系状态.是否在职<>1 并且 开始日期>=三年前年初 并且 开始日期<=去年年末 并且 岗位BOID
|
|
|
+ qFilter = new QFilter(SanDingConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
|
|
|
+ .and(new QFilter(isHiredKey, QCP.not_equals, EnableEnum.YES.getCode()))
|
|
|
+ .and(new QFilter(SanDingConstant.STARTDATE, QCP.large_equals, HRDateTimeUtils.parseDate(y3+"-01-01", HRDateTimeUtils.YYYY_MM_DD)))
|
|
|
+ .and(new QFilter(SanDingConstant.STARTDATE, QCP.less_equals, HRDateTimeUtils.parseDate(y1+"-12-31", HRDateTimeUtils.YYYY_MM_DD)))
|
|
|
+ .and(new QFilter(positionBoIdKey, QCP.in, positionBoIdSet));
|
|
|
+ // 查询 岗位ID、开始日期
|
|
|
+ String selectFields = QueryFieldBuilder.create().add(positionBoIdKey).add(SanDingConstant.STARTDATE).buildSelect();
|
|
|
+ // 获取不在职人数
|
|
|
+ empPosOrgRelDyos = empPosOrgRelServiceHelper.queryOriginalArray(selectFields, new QFilter[]{qFilter}, orderBys);
|
|
|
+ // 处理成 key->岗位BOID@开始年 value->岗位不在职人数
|
|
|
+ Map<String, Integer> yOutSysMap = Arrays.stream(empPosOrgRelDyos).map(empPosOrgRelDyo -> empPosOrgRelDyo.getLong(positionBoIdKey) + "@" + HRDateTimeUtils.getYear(empPosOrgRelDyo.getDate(SanDingConstant.STARTDATE))).collect(Collectors.groupingBy(Function.identity(), Collectors.collectingAndThen(Collectors.counting(), Long::intValue)));
|
|
|
+ Map<String, Integer> y1OutSysMap = new HashMap<String, Integer>();
|
|
|
+ Map<String, Integer> y2OutSysMap = new HashMap<String, Integer>();
|
|
|
+ Map<String, Integer> y3OutSysMap = new HashMap<String, Integer>();
|
|
|
+ for (Map.Entry<String, Integer> entry : yOutSysMap.entrySet()) {
|
|
|
+ String[] keys = entry.getKey().split("@");
|
|
|
+ String year = keys[1];
|
|
|
+ if (y1.equals(year)) {
|
|
|
+ y1OutSysMap.put(entry.getKey(), entry.getValue());
|
|
|
+ }
|
|
|
+ if (y2.equals(year)) {
|
|
|
+ y2OutSysMap.put(entry.getKey(), entry.getValue());
|
|
|
+ }
|
|
|
+ if (y3.equals(year)) {
|
|
|
+ y3OutSysMap.put(entry.getKey(), entry.getValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 过滤 主任职 并且 开始日期>=三年前年初 并且 结束日期<=去年年末 并且 变动操作.编码=跨公司调动 并且 岗位BOID
|
|
|
+ qFilter = new QFilter(SanDingConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
|
|
|
+ .and(new QFilter(SanDingConstant.STARTDATE, QCP.large_equals, HRDateTimeUtils.parseDate(y3+"-01-01", HRDateTimeUtils.YYYY_MM_DD)))
|
|
|
+ .and(new QFilter(SanDingConstant.ENDDATE, QCP.less_equals, HRDateTimeUtils.parseDate(y1+"-12-31", HRDateTimeUtils.YYYY_MM_DD)))
|
|
|
+ .and(new QFilter(String.join(".", SanDingConstant.CHGACTION, SanDingConstant.NUMBER_KEY), QCP.equals, KGSDD_CHGACTION_NUMBER))
|
|
|
+ .and(new QFilter(positionBoIdKey, QCP.in, positionBoIdSet));
|
|
|
+ empPosOrgRelDyos = empPosOrgRelServiceHelper.queryOriginalArray(String.join(".", SanDingConstant.EMPLOYEE_KEY, SanDingConstant.BOID_KEY), new QFilter[]{qFilter}, orderBys);
|
|
|
+ // 获取 员工BOID
|
|
|
+ Set<Long> employeeBoIdSet = new HashSet<Long>();
|
|
|
+ // 处理成 key->员工BOID value->List<跨公司调动任职经历id>
|
|
|
+ Map<Long, List<Long>> employeeBoIdMap = new HashMap<Long, List<Long>>();
|
|
|
+ for (DynamicObject empPosOrgRelDyo : empPosOrgRelDyos) {
|
|
|
+ long employeeBoId = empPosOrgRelDyo.getLong(employeeBoIdKey);
|
|
|
+ if (employeeBoIdMap.containsKey(employeeBoId)) {
|
|
|
+ List<Long> empPosOrgRelIdList = employeeBoIdMap.get(employeeBoId);
|
|
|
+ empPosOrgRelIdList.add(empPosOrgRelDyo.getLong(SanDingConstant.BOID_KEY));
|
|
|
+ } else {
|
|
|
+ List<Long> empPosOrgRelIdList = new ArrayList<Long>();
|
|
|
+ empPosOrgRelIdList.add(empPosOrgRelDyo.getLong(SanDingConstant.BOID_KEY));
|
|
|
+ employeeBoIdMap.put(employeeBoId, empPosOrgRelIdList);
|
|
|
+ }
|
|
|
+ employeeBoIdSet.add(employeeBoId);
|
|
|
+ }
|
|
|
+ // 过滤 主任职 并且 (结束日期>=四年前年末 并且 结束日期 <= 去年年末 或者 开始日期>=三年前年末 并且 结束日期<=去年年末) 并且 员工BOID
|
|
|
+ qFilter = new QFilter(SanDingConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
|
|
|
+ .and(
|
|
|
+ new QFilter(SanDingConstant.ENDDATE, QCP.large_equals, HRDateTimeUtils.parseDate(y4+"-12-31", HRDateTimeUtils.YYYY_MM_DD))
|
|
|
+ .and(SanDingConstant.ENDDATE, QCP.less_equals, HRDateTimeUtils.parseDate(y1+"-12-31", HRDateTimeUtils.YYYY_MM_DD))
|
|
|
+ .or(SanDingConstant.STARTDATE, QCP.large_equals, HRDateTimeUtils.parseDate(y3+"-12-31", HRDateTimeUtils.YYYY_MM_DD))
|
|
|
+ .and(SanDingConstant.ENDDATE, QCP.less_equals, HRDateTimeUtils.parseDate(y1+"-12-31", HRDateTimeUtils.YYYY_MM_DD))
|
|
|
+ )
|
|
|
+ .and(new QFilter(SanDingConstant.STARTDATE, QCP.large_equals, HRDateTimeUtils.parseDate(y3+"-01-01", HRDateTimeUtils.YYYY_MM_DD)))
|
|
|
+ .and(new QFilter(SanDingConstant.ENDDATE, QCP.less_equals, HRDateTimeUtils.parseDate(y1+"-12-31", HRDateTimeUtils.YYYY_MM_DD)))
|
|
|
+ .and(new QFilter(SanDingConstant.EMPLOYEE_KEY, QCP.in, employeeBoIdSet));
|
|
|
+ selectFields = QueryFieldBuilder.create().add(SanDingConstant.EMPLOYEE_KEY, SanDingConstant.BOID_KEY).add(SanDingConstant.ID_KEY).add(SanDingConstant.POSITION_KEY, SanDingConstant.BOID_KEY).add(SanDingConstant.ENDDATE).buildSelect();
|
|
|
+ // 获取 员工的所有主任职记录
|
|
|
+ orderBys = QueryFieldBuilder.create().addAsc(SanDingConstant.EMPLOYEE_KEY, SanDingConstant.EMP_NUMBER_KEY).addAsc(SanDingConstant.STARTDATE).buildOrder();
|
|
|
+ empPosOrgRelDyos = empPosOrgRelServiceHelper.queryOriginalArray(selectFields, new QFilter[]{qFilter}, orderBys);
|
|
|
+ // 处理成 key->员工BOID value->List<员工所有主任职记录>
|
|
|
+ Map<Long, List<DynamicObject>> empPosOrgRelDyoListMap = Arrays.stream(empPosOrgRelDyos).collect(Collectors.groupingBy(empPosOrgRelDyo -> empPosOrgRelDyo.getLong(SanDingConstant.EMPLOYEE_KEY)));
|
|
|
+ // 处理成 key->岗位BOID@年 value->List<跨公司调动任职经历id>
|
|
|
+ Map<String, List<Long>> kgsddEmpPosOrgRelIdListMap = new HashMap<String, List<Long>>();
|
|
|
+ // 对于跨公司调动来说,这笔任职属于流入,需要根据人定位到这条任职经历的上一条主任职记录,才是流出的任职记录,流出任职经历的结束时间所在的年才是流出年
|
|
|
+ for (Map.Entry<Long, List<Long>> entry : employeeBoIdMap.entrySet()) {
|
|
|
+ Long employeeBoId = entry.getKey();
|
|
|
+ List<Long> empPosOrgRelIdList = entry.getValue();
|
|
|
+ List<DynamicObject> empPosOrgRelDyoList = empPosOrgRelDyoListMap.get(employeeBoId);
|
|
|
+ for (Long empPosOrgRelId : empPosOrgRelIdList) {
|
|
|
+ for (int i = 0; i < empPosOrgRelDyoList.size(); i++) {
|
|
|
+ DynamicObject empPosOrgRelDyo = empPosOrgRelDyoList.get(i);
|
|
|
+ if (empPosOrgRelId == empPosOrgRelDyo.getLong(SanDingConstant.ID_KEY)) {
|
|
|
+ DynamicObject lastEmpPosOrgRelDyo = empPosOrgRelDyoList.get(i - 1);
|
|
|
+ Long positionBoId = lastEmpPosOrgRelDyo.getLong(positionBoIdKey);
|
|
|
+ String year = String.valueOf(HRDateTimeUtils.getYear(lastEmpPosOrgRelDyo.getDate(SanDingConstant.ENDDATE)));
|
|
|
+ String key = positionBoId + "@" + year;
|
|
|
+ List<Long> kgsddEmpPosOrgRelIdList = kgsddEmpPosOrgRelIdListMap.get(key);
|
|
|
+ if (HRObjectUtils.isEmpty(kgsddEmpPosOrgRelIdList)) {
|
|
|
+ kgsddEmpPosOrgRelIdList = new ArrayList<Long>();
|
|
|
+ kgsddEmpPosOrgRelIdList.add(positionBoId);
|
|
|
+ kgsddEmpPosOrgRelIdListMap.put(key, kgsddEmpPosOrgRelIdList);
|
|
|
+ } else {
|
|
|
+ kgsddEmpPosOrgRelIdList.add(positionBoId);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 处理成 key->岗位BOID@年 value->数量
|
|
|
+ Map<String, Integer> kgsddEmpPosOrgRelMap = kgsddEmpPosOrgRelIdListMap.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue().size()));
|
|
|
+ // key->单位BOID@岗位BOID value->定员数
|
|
|
+ Map<String, Integer> lastSanDingTaskMap = new HashMap<String, Integer>();
|
|
|
+ DynamicObject lastSanDingPlanDyo = getLastSanDingPlanDyo(billDyo.getLong(SanDingConstant.ID_KEY), SanDingConstant.ID_KEY);
|
|
|
+ if (!HRObjectUtils.isEmpty(lastSanDingPlanDyo)) {
|
|
|
+ long sanDingPlanId = lastSanDingPlanDyo.getLong(SanDingConstant.ID_KEY);
|
|
|
+ // 查询 单据体.定员数、单据体.岗位.BOID、单位.BOID
|
|
|
+ selectFields = QueryFieldBuilder.create()
|
|
|
+ .add(SanDingConstant.NCKD_ENTRYENTITY, SanDingConstant.NCKD_AUTHORIZEDSTRENGTH_KEY)
|
|
|
+ .add(SanDingConstant.NCKD_ENTRYENTITY, SanDingConstant.NCKD_POSITION_KEY, SanDingConstant.BOID_KEY)
|
|
|
+ .add(companyBoIdKey)
|
|
|
+ .buildSelect();
|
|
|
+ // 获取三定任务ID
|
|
|
+ DynamicObject[] lastSanDingTaskDyos = HRBaseServiceHelper.create(SanDingConstant.NCKD_SANDINGTASK_ENTITY).queryOriginalArray(selectFields, new QFilter[]{new QFilter(String.join(".", SanDingConstant.NCKD_SANDINGPLAN_KEY, SanDingConstant.ID_KEY), QCP.equals, sanDingPlanId)});
|
|
|
+ for (DynamicObject lastSanDingTaskDyo : lastSanDingTaskDyos) {
|
|
|
+ Long positionBoId = lastSanDingTaskDyo.getLong(String.join(".", SanDingConstant.NCKD_ENTRYENTITY, SanDingConstant.NCKD_POSITION_KEY, SanDingConstant.BOID_KEY));
|
|
|
+ int authorizedStrength = lastSanDingTaskDyo.getInt(String.join(".", SanDingConstant.NCKD_ENTRYENTITY, SanDingConstant.NCKD_AUTHORIZEDSTRENGTH_KEY));
|
|
|
+ Long companyBoId = lastSanDingTaskDyo.getLong(companyBoIdKey);
|
|
|
+ lastSanDingTaskMap.put(companyBoId+"@"+positionBoId, authorizedStrength);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 构建三定任务
|
|
|
+ HRBaseServiceHelper sanDingTaskServiceHelper = HRBaseServiceHelper.create(SanDingConstant.NCKD_SANDINGTASK_ENTITY);
|
|
|
+ List<DynamicObject> sanDingTaskDyoList = new ArrayList<DynamicObject>();
|
|
|
+ for (DynamicObject entryDyo : entryDyoColl) {
|
|
|
+ // 设置 状态为未提交
|
|
|
+ entryDyo.set(SanDingConstant.NCKD_STATUS_KEY, SanDingPlanEntryStatus.UNSUBMIT.getCode());
|
|
|
+ // 构建 三定任务
|
|
|
+ DynamicObject sanDingTaskDyo = sanDingTaskServiceHelper.generateEmptyDynamicObject();
|
|
|
+ // 设置 ID
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.ID_KEY, ORM_IMPL.genLongId(sanDingTaskDyo.getDataEntityType()));
|
|
|
+ // 设置 创建人
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.CREATOR_KEY, UserServiceHelper.getCurrentUserId());
|
|
|
+ // 设置 主业务组织
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.ORG_KEY, OrgHelper.getCreateOrg(SanDingConstant.NCKD_SANDINGTASK_ENTITY));
|
|
|
+ // 设置 单据状态
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.BILL_STATUS_KEY, "A");// 默认暂存
|
|
|
+ // 设置 审批状态
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.AUDIT_STATUS, "A");// 默认暂存
|
|
|
+ // 设置 单据编码
|
|
|
+ CodeRuleInfo codeRuleInfo = CodeRuleServiceHelper.getCodeRule(SanDingConstant.NCKD_SANDINGTASK_ENTITY, sanDingTaskDyo, OrgUtil.getMainOrgId(sanDingTaskDyo));
|
|
|
+ if (codeRuleInfo == null) {
|
|
|
+ throw new KDBizException("三定任务没有可使用的编码规则");
|
|
|
+ }
|
|
|
+ String number = CodeRuleServiceHelper.readNumber(codeRuleInfo, sanDingTaskDyo);
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.BILL_NO_KEY, number);
|
|
|
+ // 设置 三定计划
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.NCKD_SANDINGPLAN_KEY, billDyo);
|
|
|
+ // 设置 三定计划分录
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.NCKD_SDP_ENTRY_KEY, entryDyo);
|
|
|
+ // 设置 单位
|
|
|
+ sanDingTaskDyo.set(SanDingConstant.NCKD_COMPANY_KEY, entryDyo.getLong(String.join(".", SanDingConstant.NCKD_COMPANY_KEY, SanDingConstant.ID_KEY)));
|
|
|
+ // 构建单据体
|
|
|
+ DynamicObjectCollection sanDingTaskEntryDyoColl = sanDingTaskDyo.getDynamicObjectCollection(SanDingConstant.NCKD_ENTRYENTITY);
|
|
|
+ List<Map<String, Long>> positionBoIdList = companyPositionMap.get(entryDyo.getLong(companyBoIdKey));
|
|
|
+ for (Map<String, Long> positionOrgMap : positionBoIdList) {
|
|
|
+ DynamicObject sanDingTaskEntryDyo = sanDingTaskEntryDyoColl.addNew();
|
|
|
+ // 岗位BOID
|
|
|
+ Long positionBoId = positionOrgMap.get("positionBoId");
|
|
|
+ // 设置 组织
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_ADMINORG, positionOrgMap.get("adminOrgSourceVid"));
|
|
|
+ // 设置 岗位
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_POSITION_KEY, positionOrgMap.get("positionSourceVid"));
|
|
|
+ // 设置 定员数
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_AUTHORIZEDSTRENGTH_KEY, lastSanDingTaskMap.getOrDefault(entryDyo.getLong(companyBoIdKey)+"@"+positionBoId, 0));
|
|
|
+ // 设置 实际占编人数
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_ACTUALSTAFFCOUNT_KEY, positionInStaffEmployeeCountMap.getOrDefault(positionBoId, 0));
|
|
|
+ // 设置 缺编人数
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_STAFFINGSHORTFALL_KEY, 0);
|
|
|
+ // 设置 前一年流失人数(系统数)
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_Y1OUT_SYS_KEY, y1OutSysMap.getOrDefault(positionBoId + "@" + y1, 0) + kgsddEmpPosOrgRelMap.getOrDefault(positionBoId + "@" + y1, 0));
|
|
|
+ // 设置 前两年流失人数(系统数)
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_Y2OUT_SYS_KEY, y2OutSysMap.getOrDefault(positionBoId + "@" + y2, 0) + kgsddEmpPosOrgRelMap.getOrDefault(positionBoId + "@" + y2, 0));
|
|
|
+ // 设置 前三年流失人数(系统数)
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_Y3OUT_SYS_KEY, y3OutSysMap.getOrDefault(positionBoId + "@" + y3, 0) + kgsddEmpPosOrgRelMap.getOrDefault(positionBoId + "@" + y3, 0));
|
|
|
+ // 设置 前一年流失人数(确认数)
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_Y1OUT_CONF_KEY, sanDingTaskEntryDyo.get(SanDingConstant.NCKD_Y1OUT_SYS_KEY));
|
|
|
+ // 设置 前两年流失人数(确认数)
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_Y2OUT_CONF_KEY, sanDingTaskEntryDyo.get(SanDingConstant.NCKD_Y2OUT_SYS_KEY));
|
|
|
+ // 设置 前三年流失人数(确认数)
|
|
|
+ sanDingTaskEntryDyo.set(SanDingConstant.NCKD_Y3OUT_CONF_KEY, sanDingTaskEntryDyo.get(SanDingConstant.NCKD_Y3OUT_SYS_KEY));
|
|
|
+ }
|
|
|
+ sanDingTaskDyoList.add(sanDingTaskDyo);
|
|
|
+ SANDING_TASK_MAP.put(entryDyo.getLong(SanDingConstant.ID_KEY), sanDingTaskDyo.getLong(SanDingConstant.ID_KEY));
|
|
|
+ }
|
|
|
+ // 保存
|
|
|
+ OperationResult operationResult = SaveServiceHelper.saveOperate(SanDingConstant.NCKD_SANDINGTASK_ENTITY, sanDingTaskDyoList.toArray(new DynamicObject[0]));
|
|
|
+ if (operationResult != null && !operationResult.isSuccess()) {
|
|
|
+ StringJoiner errorMsg = new StringJoiner(";");
|
|
|
+ for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
|
|
|
+ errorMsg.add(error.getMessage());
|
|
|
+ }
|
|
|
+ if (!HRObjectUtils.isEmpty(operationResult.getMessage())) {
|
|
|
+ errorMsg.add(operationResult.getMessage());
|
|
|
+ }
|
|
|
+ throw new KDBizException(errorMsg.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static DynamicObject getLastSanDingPlanDyo(Long id, String selectFields) {
|
|
|
+ // 排序 年度降序、适用批次人力资源需求批次.编码降序
|
|
|
+ String orderBys = QueryFieldBuilder.create().addDesc(SanDingConstant.NCKD_SANDINGYEAR_KEY).addDesc(SanDingConstant.NCKD_SANDINGTIME_KEY, SanDingConstant.NUMBER_KEY).buildOrder();
|
|
|
+ // 获取最近一个三定计划
|
|
|
+ DynamicObject[] lastSanDingPlanDyos = HRBaseServiceHelper.create(SanDingConstant.NCKD_SANDINGPLAN_ENTITY).queryOriginalArray(selectFields, new QFilter[]{new QFilter(SanDingConstant.ID_KEY, QCP.not_equals, id)}, orderBys);
|
|
|
+ if (lastSanDingPlanDyos.length > 0) {
|
|
|
+ return HRBaseServiceHelper.create(SanDingConstant.NCKD_SANDINGPLAN_ENTITY).loadSingle(lastSanDingPlanDyos[0].getLong(SanDingConstant.ID_KEY));
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void endOperationTransaction(EndOperationTransactionArgs e) {
|
|
|
+ super.endOperationTransaction(e);
|
|
|
+
|
|
|
+ try {
|
|
|
+ DynamicObject[] dyos = e.getDataEntities();
|
|
|
+ for (DynamicObject dyo : dyos) {
|
|
|
+ DynamicObjectCollection entryDyoColl = dyo.getDynamicObjectCollection(SanDingConstant.NCKD_ENTRYENTITY);
|
|
|
+ for (DynamicObject entryDyo : entryDyoColl) {
|
|
|
+ sendMessage(entryDyo);
|
|
|
+ }
|
|
|
+ updateLastSanDingPlanEndDate(dyo);
|
|
|
+ }
|
|
|
+ } catch (Exception ex) {
|
|
|
+ throw new KDBizException(ex, new ErrorCode("sendMessageError", ex.getMessage()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendMessage(DynamicObject entryDyo) {
|
|
|
+ // 构建 消息
|
|
|
+ MessageInfo messageInfo = new MessageInfo();
|
|
|
+ // 设置 消息标题
|
|
|
+ messageInfo.setMessageTitle(new LocaleString("三定任务填报提醒"));
|
|
|
+ // 设置 文本消息内容
|
|
|
+ messageInfo.setMessageContent(new LocaleString("您有一个三定任务待填报,请尽快处理,点击下方【快速处理】链接处理。"));
|
|
|
+ // 设置 消息类型
|
|
|
+ messageInfo.setType(MessageInfo.TYPE_MESSAGE);
|
|
|
+ // 设置 实体编码
|
|
|
+ messageInfo.setEntityNumber(SanDingConstant.NCKD_SANDINGTASK_ENTITY);
|
|
|
+ // 设置 标签
|
|
|
+ messageInfo.setTag("三定管理");
|
|
|
+ long managerBoId = entryDyo.getDynamicObject(SanDingConstant.NCKD_MANAGER_KEY).getLong(SanDingConstant.BOID_KEY);
|
|
|
+ // 设置 消息接收人
|
|
|
+// List<Long> userIds = getUserIds(Collections.singletonList(managerBoId));
|
|
|
+ List<Long> userIds = new ArrayList<Long>();
|
|
|
+ userIds.add(2306610598445593600L);
|
|
|
+ messageInfo.setUserIds(userIds);
|
|
|
+ // 设置 消息Web端url
|
|
|
+ messageInfo.setContentUrl(UrlService.getDomainContextUrl() + "/index.html?formId="+SanDingConstant.NCKD_SANDINGTASK_ENTITY+"&pkId=" + SANDING_TASK_MAP.get(entryDyo.getLong(SanDingConstant.ID_KEY)));
|
|
|
+ MessageUtils.sendMessage(messageInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Long> getUserIds(List<Long> managerBoIdList) {
|
|
|
+ // 获取 所有负责人userId
|
|
|
+ Map<String, Object> result = HRPIEmployeeServiceHelper.queryUserIdsByEmployeeIds(managerBoIdList, null);
|
|
|
+ if ((Boolean) result.get("success")) {
|
|
|
+ Map<Long, Map<String, Object>> retMap = (Map<Long, Map<String, Object>>) result.get("data");
|
|
|
+ // 从返回结果中提取用户ID列表
|
|
|
+ List<Long> userIds = retMap.values().stream().map(reMap -> (Long) reMap.get("user")).collect(Collectors.toList());
|
|
|
+ return userIds;
|
|
|
+ } else {
|
|
|
+ throw new KDBizException((String) result.get("message"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateLastSanDingPlanEndDate(DynamicObject dyo) {
|
|
|
+ Date startDate = dyo.getDate(SanDingConstant.NCKD_STARTDATE_KEY);
|
|
|
+ DynamicObject lastSanDingPlanDyo = getLastSanDingPlanDyo(dyo.getLong(SanDingConstant.ID_KEY), String.join(",", SanDingConstant.ID_KEY, SanDingConstant.NCKD_ENDDATE));
|
|
|
+ if (!HRObjectUtils.isEmpty(lastSanDingPlanDyo)) {
|
|
|
+ lastSanDingPlanDyo.set(SanDingConstant.NCKD_ENDDATE, HRDateTimeUtils.addDay(startDate, -1));
|
|
|
+ SaveServiceHelper.save(new DynamicObject[]{lastSanDingPlanDyo});
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|