|
|
@@ -0,0 +1,213 @@
|
|
|
+package nckd.jxccl.hr.ijp.plugin.operate;
|
|
|
+
|
|
|
+import kd.bos.context.RequestContext;
|
|
|
+import kd.bos.dataentity.OperateOption;
|
|
|
+import kd.bos.dataentity.entity.DynamicObject;
|
|
|
+import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
|
+import kd.bos.dataentity.utils.ObjectUtils;
|
|
|
+import kd.bos.entity.EntityMetadataCache;
|
|
|
+import kd.bos.entity.MainEntityType;
|
|
|
+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.logging.Log;
|
|
|
+import kd.bos.logging.LogFactory;
|
|
|
+import kd.bos.orm.query.QCP;
|
|
|
+import kd.bos.orm.query.QFilter;
|
|
|
+import kd.bos.servicehelper.BusinessDataServiceHelper;
|
|
|
+import kd.bos.servicehelper.QueryServiceHelper;
|
|
|
+import kd.bos.servicehelper.operation.SaveServiceHelper;
|
|
|
+import kd.sdk.plugin.Plugin;
|
|
|
+import nckd.jxccl.base.common.constant.FormConstant;
|
|
|
+import nckd.jxccl.base.common.enums.ijp.TalentTypeEnum;
|
|
|
+import nckd.jxccl.base.common.exception.ValidationException;
|
|
|
+import nckd.jxccl.base.common.utils.DateUtil;
|
|
|
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
|
|
|
+import nckd.jxccl.base.common.utils.StrFormatter;
|
|
|
+import nckd.jxccl.base.entity.helper.EntityHelper;
|
|
|
+import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
|
|
|
+import nckd.jxccl.hr.ijp.common.IntJobPostConstant;
|
|
|
+import nckd.jxccl.hr.psms.common.PositionStructureConstant;
|
|
|
+
|
|
|
+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.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+* 内部人力资源市场-三类人员记录生成-反审批
|
|
|
+* 实体标识:nckd_intjobpost
|
|
|
+* @author W.Y.C
|
|
|
+* @date 2026/1/8 21:34
|
|
|
+* @version 1.0
|
|
|
+*/
|
|
|
+public class IntJobPostUnAuditedOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
|
|
|
+
|
|
|
+ private static final Log logger = LogFactory.getLog(IntJobPostUnAuditedOpPlugin.class);
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onPreparePropertys(PreparePropertysEventArgs e) {
|
|
|
+ e.getFieldKeys().addAll(billEntityType.getAllFields().keySet());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void beginOperationTransaction(BeginOperationTransactionArgs e) {
|
|
|
+
|
|
|
+ List<Long> personIds = new ArrayList<>();
|
|
|
+ List<Long> entityIds = new ArrayList<>();
|
|
|
+ for (DynamicObject dataEntity : e.getDataEntities()) {
|
|
|
+ DynamicObjectCollection entryEntity = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
|
|
|
+ for (DynamicObject entry : entryEntity) {
|
|
|
+ DynamicObject person = entry.getDynamicObject(PositionStructureConstant.NCKD_PERSON);
|
|
|
+ boolean isEnter = entry.getBoolean(IntJobPostConstant.NCKD_ISENTER);
|
|
|
+ if(isEnter){
|
|
|
+ personIds.add(person.getLong(IntJobPostConstant.ID_KEY));
|
|
|
+ }
|
|
|
+ entityIds.add(entry.getLong(IntJobPostConstant.ID_KEY));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Map<Long, DynamicObject> empPosOrgRelMap = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployeesMap(personIds);
|
|
|
+ Map<Long, DynamicObject> latestRecordMap = getLatestRecordIdsByPersons(personIds, entityIds);
|
|
|
+ Map<Long, DynamicObject> latestLocusByPerson = findLatestLocusByPerson(personIds);
|
|
|
+ List<DynamicObject> savedRecords = new ArrayList<>();
|
|
|
+ List<DynamicObject> savedLocus = new ArrayList<>();
|
|
|
+ for (DynamicObject dataEntity : e.getDataEntities()) {
|
|
|
+ Date auditDate = dataEntity.getDate(IntJobPostConstant.AUDIT_DATE_KEY);
|
|
|
+ String talentType = dataEntity.getString(IntJobPostConstant.NCKD_TALENTTYPE);
|
|
|
+ TalentTypeEnum talentTypeEnum = TalentTypeEnum.getByCode(talentType);
|
|
|
+ DynamicObjectCollection entryEntity = dataEntity.getDynamicObjectCollection(FormConstant.NCKD_ENTRYENTITY);
|
|
|
+ for (DynamicObject entry : entryEntity) {
|
|
|
+ long id = entry.getLong(IntJobPostConstant.ID_KEY);
|
|
|
+ boolean isEnter = entry.getBoolean(IntJobPostConstant.NCKD_ISENTER);
|
|
|
+ long personId = entry.getLong(String.join(".", IntJobPostConstant.NCKD_PERSON, IntJobPostConstant.ID_KEY));
|
|
|
+ String name = entry.getString(String.join(".", IntJobPostConstant.NCKD_PERSON, IntJobPostConstant.NAME_KEY));
|
|
|
+ // --- A. 恢复旧记录 ---
|
|
|
+ // 逻辑:找到该单据对应的“上一条”记录。
|
|
|
+ // 实际上就是找那些被“此单据”截断的记录。
|
|
|
+ DynamicObject prevRecord = latestRecordMap.get(personId);
|
|
|
+ if(prevRecord != null) {
|
|
|
+ // 还原备份的值
|
|
|
+ prevRecord.set(IntJobPostConstant.NCKD_TOFOURDATE,prevRecord.get(IntJobPostConstant.NCKD_OLDTOFOURDATE));
|
|
|
+ // 只有当备份状态不为空时才还原,否则保持原样 (NVL逻辑)
|
|
|
+ if (prevRecord.get(IntJobPostConstant.NCKD_OLDSTATE) != null) {
|
|
|
+ prevRecord.set(IntJobPostConstant.NCKD_STATE, prevRecord.get(IntJobPostConstant.NCKD_OLDSTATE));
|
|
|
+ }
|
|
|
+ prevRecord.set(IntJobPostConstant.NCKD_ISCURRENTNEWEST, Boolean.TRUE);
|
|
|
+ savedRecords.add(prevRecord);
|
|
|
+ }
|
|
|
+
|
|
|
+ // --- B. 恢复旧轨迹 ---
|
|
|
+ DynamicObject prevLocus = latestLocusByPerson.get(personId);
|
|
|
+ if (prevLocus != null) {
|
|
|
+ prevLocus.set(IntJobPostConstant.NCKD_ENDDATE,prevLocus.get(IntJobPostConstant.NCKD_OLDENDDAY));
|
|
|
+ prevLocus.set(IntJobPostConstant.NCKD_ISCURRENTNEWEST,Boolean.TRUE);
|
|
|
+ savedLocus.add(prevLocus);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // --- A. 恢复旧记录 ---
|
|
|
+ // 逻辑:找到该单据对应的“上一条”记录。
|
|
|
+ // 实际上就是找那些被“此单据”截断的记录。
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // --- A. 处理旧记录 ---
|
|
|
+ // 1. 查询该员工最近的一条记录(排除当前单据产生的记录,按创建时间倒序取第一条)
|
|
|
+
|
|
|
+
|
|
|
+ //1、阶段1:备份原有记录
|
|
|
+ // 条件:单据中要进入市场(CFIsenter=1)的员工 + 他们最新的记录 + 记录来源不是当前单据
|
|
|
+ //目的:为反审批时恢复数据做准备
|
|
|
+
|
|
|
+ //阶段2:关闭原记录
|
|
|
+ //逻辑:一个员工只能有一条活跃记录(FIsSingle=1)
|
|
|
+ //状态变化:1(在市场中) → 4(退出市场)
|
|
|
+
|
|
|
+ //阶段3:创建新记录
|
|
|
+ //新记录状态:FIsSingle=1, CFInsidehrRecordState='1'
|
|
|
+
|
|
|
+ //阶段3:特殊处理
|
|
|
+ //A类员工:有预计退出时间(1年后)
|
|
|
+ //非A类员工:预计退出时间为null
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取每个人员最新一条记录
|
|
|
+ * @param personIds 人员ID
|
|
|
+ * @param entityIds 分录ID
|
|
|
+ * @return: java.util.Map<java.lang.Long, java.util.List < kd.bos.dataentity.entity.DynamicObject>>
|
|
|
+ * @author W.Y.C
|
|
|
+ * @date: 2026/01/13 15:56
|
|
|
+ */
|
|
|
+ public Map<Long, DynamicObject> getLatestRecordIdsByPersons(List<Long> personIds,List<Long> entityIds) {
|
|
|
+ QueryFieldBuilder intJobPostRecord = QueryFieldBuilder.create().add(IntJobPostConstant.ID_KEY)
|
|
|
+ .add(FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY,FormConstant.ID_KEY)
|
|
|
+ .add(IntJobPostConstant.NCKD_ISCURRENTNEWEST)
|
|
|
+ .orderDesc(IntJobPostConstant.CREATE_TIME_KEY);
|
|
|
+ QFilter filter = new QFilter(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY), QCP.in, personIds)
|
|
|
+ .and(IntJobPostConstant.NCKD_INTJOBPOSTENTRY,QCP.not_in,entityIds);
|
|
|
+ DynamicObjectCollection records = QueryServiceHelper.query(IntJobPostConstant.INTJOBPOSTRECORD_ENTITYID, intJobPostRecord.buildSelect(), new QFilter[]{filter});
|
|
|
+ Set<Long> uniquePersonIds = new HashSet<>();
|
|
|
+ List<Long> result = new ArrayList<>();
|
|
|
+ for (DynamicObject record : records) {
|
|
|
+ Long personId = record.getLong(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY));
|
|
|
+ if (uniquePersonIds.add(personId)) { // 如果是新的personId,添加到结果中
|
|
|
+ result.add(record.getLong(IntJobPostConstant.ID_KEY));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ MainEntityType intJobPostRecordEntityType = EntityMetadataCache.getDataEntityType(IntJobPostConstant.INTJOBPOSTRECORD_ENTITYID);
|
|
|
+ DynamicObject[] load = BusinessDataServiceHelper.load(result.toArray(new Long[0]), intJobPostRecordEntityType);
|
|
|
+ return Arrays.stream(load)
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ obj -> obj.getLong(String.join(".", FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
|
|
|
+ obj -> obj
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询最近的轨迹
|
|
|
+ * @param personIds 人员ID
|
|
|
+ * @return: java.util.Map<java.lang.Long, java.util.List < kd.bos.dataentity.entity.DynamicObject>>
|
|
|
+ * @author W.Y.C
|
|
|
+ * @date: 2026/01/13 15:56
|
|
|
+ */
|
|
|
+ public Map<Long, DynamicObject> findLatestLocusByPerson(List<Long> personIds) {
|
|
|
+ QueryFieldBuilder intJobPostLocus = QueryFieldBuilder.create().add(IntJobPostConstant.ID_KEY)
|
|
|
+ .add(FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY,FormConstant.ID_KEY)
|
|
|
+ .add(IntJobPostConstant.NCKD_ISCURRENTNEWEST)
|
|
|
+ .orderDesc(IntJobPostConstant.CREATE_TIME_KEY);
|
|
|
+ QFilter filter = new QFilter(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY), QCP.in, personIds);
|
|
|
+ DynamicObjectCollection records = QueryServiceHelper.query(IntJobPostConstant.INTJOBPOSTLOCUS_ENTITYID, intJobPostLocus.buildSelect(), new QFilter[]{filter});
|
|
|
+ Set<Long> uniquePersonIds = new HashSet<>();
|
|
|
+ List<Long> result = new ArrayList<>();
|
|
|
+ for (DynamicObject record : records) {
|
|
|
+ Long personId = record.getLong(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY));
|
|
|
+ if (uniquePersonIds.add(personId)) { // 如果是新的personId,添加到结果中
|
|
|
+ result.add(record.getLong(IntJobPostConstant.ID_KEY));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ MainEntityType intJobPostLocusEntityType = EntityMetadataCache.getDataEntityType(IntJobPostConstant.INTJOBPOSTLOCUS_ENTITYID);
|
|
|
+ DynamicObject[] load = BusinessDataServiceHelper.load(result.toArray(new Long[0]), intJobPostLocusEntityType);
|
|
|
+ return Arrays.stream(load)
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ obj -> obj.getLong(String.join(".",FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
|
|
|
+ obj -> obj
|
|
|
+ ));
|
|
|
+ }
|
|
|
+}
|