|
|
@@ -0,0 +1,231 @@
|
|
|
+package nckd.jxccl.hr.psms.plugin.operate.other;
|
|
|
+
|
|
|
+import kd.bos.dataentity.OperateOption;
|
|
|
+import kd.bos.dataentity.entity.DynamicObject;
|
|
|
+import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
|
+import kd.bos.entity.ExtendedDataEntity;
|
|
|
+import kd.bos.entity.operate.result.IOperateInfo;
|
|
|
+import kd.bos.entity.operate.result.OperateErrorInfo;
|
|
|
+import kd.bos.entity.operate.result.OperationResult;
|
|
|
+import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
|
|
|
+import kd.bos.entity.plugin.AddValidatorsEventArgs;
|
|
|
+import kd.bos.entity.plugin.PreparePropertysEventArgs;
|
|
|
+import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
|
|
|
+import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
|
|
|
+import kd.bos.entity.validate.AbstractValidator;
|
|
|
+import kd.bos.orm.query.QCP;
|
|
|
+import kd.bos.orm.query.QFilter;
|
|
|
+import kd.bos.servicehelper.QueryServiceHelper;
|
|
|
+import kd.bos.servicehelper.operation.SaveServiceHelper;
|
|
|
+import kd.bos.servicehelper.user.UserServiceHelper;
|
|
|
+import kd.sdk.plugin.Plugin;
|
|
|
+import nckd.jxccl.base.common.constant.FormConstant;
|
|
|
+import nckd.jxccl.base.common.enums.psms.TypeStateEnum;
|
|
|
+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.base.org.helper.OrgHelper;
|
|
|
+import nckd.jxccl.hr.psms.common.PositionStructureConstant;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Optional;
|
|
|
+import java.util.StringJoiner;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 新建管理人员任命
|
|
|
+ * 实体标识:nckd_mgrappointmgmt
|
|
|
+ * @author W.Y.C
|
|
|
+ * @date 2025/12/4 21:25
|
|
|
+ * @version 1.0
|
|
|
+ */
|
|
|
+public class NewAppointMentOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onPreparePropertys(PreparePropertysEventArgs e) {
|
|
|
+
|
|
|
+ e.getFieldKeys().addAll(this.billEntityType.getAllFields().keySet());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onAddValidators(AddValidatorsEventArgs e) {
|
|
|
+ e.addValidator(new AbstractValidator() {
|
|
|
+ @Override
|
|
|
+ public void validate() {
|
|
|
+ List<Long> personIdList = new ArrayList<>();
|
|
|
+ for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
|
|
|
+ DynamicObject data = rowDataEntity.getDataEntity();
|
|
|
+ long personId = data.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
|
|
|
+ personIdList.add(personId);
|
|
|
+
|
|
|
+ DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
|
|
|
+ if (person != null) {
|
|
|
+ //设置每行对应的员工名称,用于准确显示每个错误属于哪个员工的
|
|
|
+ getOperationResult().getCustomData().put("DataEntityIndex_" + rowDataEntity.getDataEntityIndex(), "【" + person.getString(FormConstant.NAME_KEY) + "】");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<Long, List<DynamicObject>> mgrAppointMgmtMap = new HashMap<>();
|
|
|
+ //查询管理人员任命
|
|
|
+ QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
|
|
|
+ .add(FormConstant.ID_KEY)
|
|
|
+ .add(PositionStructureConstant.NCKD_BEGINDATE)
|
|
|
+ .add(PositionStructureConstant.NCKD_ENDDATE)
|
|
|
+ .add(PositionStructureConstant.NCKD_APPOINTSTATUS)
|
|
|
+ .addIdNumberName(PositionStructureConstant.NCKD_PERSON);
|
|
|
+ QFilter qFilter = new QFilter(PositionStructureConstant.NCKD_PERSON, QCP.in, personIdList);
|
|
|
+ qFilter.and(PositionStructureConstant.NCKD_TYPESTATE, QCP.equals, TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT.getCode());
|
|
|
+ DynamicObjectCollection query = QueryServiceHelper.query(PositionStructureConstant.NCKD_PERSONPOSFILE, queryFieldBuilder.buildSelect(), new QFilter[]{});
|
|
|
+ // 按用户ID分组
|
|
|
+ mgrAppointMgmtMap = query.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY))
|
|
|
+ ));
|
|
|
+
|
|
|
+ for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
|
|
|
+ DynamicObject data = rowDataEntity.getDataEntity();
|
|
|
+ DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
|
|
|
+ if(person == null){
|
|
|
+ this.addErrorMessage(rowDataEntity, "请选择员工。");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ long personId = person.getLong(FormConstant.ID_KEY);
|
|
|
+ String personName = person.getString(FormConstant.NAME_KEY);
|
|
|
+ if(data.getDate(PositionStructureConstant.NCKD_BEGINDATE) == null){
|
|
|
+ this.addErrorMessage(rowDataEntity, StrFormatter.format("【{}】的开始日期不能为空。", personName));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //管理人员任命校验
|
|
|
+ List<DynamicObject> dbmgrAppointMgmtList = mgrAppointMgmtMap.get(personId);
|
|
|
+ if (dbmgrAppointMgmtList != null) {
|
|
|
+ //1、判断有没有状态为【任命中=1】中的
|
|
|
+ boolean hasAppointingStatus = dbmgrAppointMgmtList.stream()
|
|
|
+ .anyMatch(obj -> "1".equals(obj.getString(PositionStructureConstant.NCKD_APPOINTSTATUS)));
|
|
|
+ if (hasAppointingStatus) {
|
|
|
+ this.addErrorMessage(rowDataEntity, StrFormatter.format("存在状态为【{}】的记录,不能任命。", "任命中"));
|
|
|
+ }
|
|
|
+
|
|
|
+ //2、判断有没有任命日期在有效时间内的
|
|
|
+ if (!hasAppointingStatus) {
|
|
|
+ Date beginDate = data.getDate(PositionStructureConstant.NCKD_BEGINDATE);
|
|
|
+
|
|
|
+ Optional<DynamicObject> lastAppointment = dbmgrAppointMgmtList.stream()
|
|
|
+ .filter(obj -> {
|
|
|
+ Date endDate = obj.getDate(PositionStructureConstant.NCKD_ENDDATE);
|
|
|
+ // 新的任命开始时间必须在上一条记录的结束时间之后
|
|
|
+ return endDate != null && beginDate != null && !beginDate.after(endDate);
|
|
|
+ })
|
|
|
+ .findFirst();
|
|
|
+
|
|
|
+ if (lastAppointment.isPresent()) {
|
|
|
+ DynamicObject appointment = lastAppointment.get();
|
|
|
+ Date endDate = appointment.getDate(PositionStructureConstant.NCKD_ENDDATE);
|
|
|
+ String periodMessage = StrFormatter.format("新的任命开始时间不能早于或等于上一任命的结束时间【{}】。",
|
|
|
+ endDate != null ? DateUtil.format(endDate, "yyyy-MM-dd") : "");
|
|
|
+ // 提示用户时间段信息
|
|
|
+ this.addErrorMessage(rowDataEntity, periodMessage);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void beginOperationTransaction(BeginOperationTransactionArgs e) {
|
|
|
+ List<Long> personidList = new ArrayList<>();
|
|
|
+ for (DynamicObject dataEntity : e.getDataEntities()) {
|
|
|
+ long personId = dataEntity.getLong(String.join(".", PositionStructureConstant.NCKD_PERSON, FormConstant.ID_KEY));
|
|
|
+ personidList.add(personId);
|
|
|
+ }
|
|
|
+ DynamicObject[] empPosOrgRelArray = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployees(personidList);
|
|
|
+ Map<Long, DynamicObject> empPosOrgRelMap = Arrays.stream(empPosOrgRelArray)
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ empPosOrgRelObj -> empPosOrgRelObj.getLong(String.join(".", PositionStructureConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
|
|
|
+ empPosOrgRelObj -> empPosOrgRelObj,
|
|
|
+ (existing, replacement) -> replacement // 如果有重复的key,使用新的值替换旧的值
|
|
|
+ ));
|
|
|
+ List<DynamicObject> newEntityList = new ArrayList<>();
|
|
|
+
|
|
|
+ DynamicObject org = OrgHelper.getCreateOrg(PositionStructureConstant.PERSONPOSFILE_ENTITYID);
|
|
|
+ String bdCtrlStrgy = null;
|
|
|
+ if(org != null) {
|
|
|
+ bdCtrlStrgy = OrgHelper.getBdCtrlStrgy(PositionStructureConstant.PERSONPOSFILE_ENTITYID, org.getLong(FormConstant.ID_KEY));
|
|
|
+ }
|
|
|
+ for (DynamicObject entry : e.getDataEntities()) {
|
|
|
+ DynamicObject newEntity = EntityHelper.newEntity(PositionStructureConstant.NCKD_PERSONPOSFILE);
|
|
|
+ DynamicObject person = entry.getDynamicObject(PositionStructureConstant.NCKD_PERSON);
|
|
|
+ long personId = person.getLong(FormConstant.ID_KEY);
|
|
|
+ String personName = person.getString(FormConstant.NAME_KEY);
|
|
|
+ DynamicObject empPosOrgRel = empPosOrgRelMap.get(personId);
|
|
|
+
|
|
|
+ newEntity.set(FormConstant.NCKD_PERSON, entry.get(FormConstant.NCKD_PERSON));
|
|
|
+ Date beginDate = entry.getDate(PositionStructureConstant.NCKD_BEGINDATE);
|
|
|
+ LocalDateTime beginDateDateTime = DateUtil.toLocalDateTime(beginDate);
|
|
|
+ newEntity.set(PositionStructureConstant.NCKD_BEGINDATE, beginDate);
|
|
|
+ newEntity.set(PositionStructureConstant.NCKD_TYPESTATE, TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT.getCode());
|
|
|
+ newEntity.set(PositionStructureConstant.NCKD_DEP, empPosOrgRel.get(PositionStructureConstant.ADMINORG));
|
|
|
+ newEntity.set(PositionStructureConstant.NCKD_POSITIONHR, empPosOrgRel.get(PositionStructureConstant.POSITION_KEY));
|
|
|
+ newEntity.set(PositionStructureConstant.NCKD_EXECUTEYEAR, beginDateDateTime.getYear());
|
|
|
+ newEntity.set(PositionStructureConstant.NCKD_APPOINTSTATUS, "1");
|
|
|
+ newEntity.set(FormConstant.CREATEORG_KEY, org);
|
|
|
+ newEntity.set(FormConstant.ORG_KEY, org);
|
|
|
+ newEntity.set(FormConstant.USEORG_KEY, org);
|
|
|
+ newEntity.set(FormConstant.CTRLSTRATEGY_KEY, bdCtrlStrgy);
|
|
|
+ newEntity.set(FormConstant.CREATOR_KEY, UserServiceHelper.getCurrentUserId());
|
|
|
+ newEntityList.add(newEntity);
|
|
|
+ }
|
|
|
+ OperateOption operateOption = OperateOption.create();
|
|
|
+ operateOption.setVariableValue(PositionStructureConstant.NCKD_TYPESTATE, TypeStateEnum.MANAGEMENT_SEQUENCE_EMPLOYMENT.getCode());
|
|
|
+ OperationResult operationResult = SaveServiceHelper.saveOperate(PositionStructureConstant.PERSONPOSFILE_ENTITYID, newEntityList.toArray(new DynamicObject[0]), operateOption);
|
|
|
+
|
|
|
+ if(operationResult != null && !operationResult.isSuccess()){
|
|
|
+ StringJoiner errorMsgJoiner = new StringJoiner(StrFormatter.LINE_SEPARATOR);
|
|
|
+ if(operationResult.getAllErrorOrValidateInfo() != null && !operationResult.getAllErrorOrValidateInfo().isEmpty()){
|
|
|
+ Iterator<IOperateInfo> iterator = operationResult.getAllErrorOrValidateInfo().iterator();
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ IOperateInfo operateInfo = iterator.next();
|
|
|
+ if(operateInfo instanceof OperateErrorInfo){
|
|
|
+ OperateErrorInfo operateErrorInfo = (OperateErrorInfo) operateInfo;
|
|
|
+ int dataEntityIndex = operateErrorInfo.getDataEntityIndex();
|
|
|
+ String prefix = operationResult.getCustomData().get("DataEntityIndex_" + dataEntityIndex);
|
|
|
+ if(StringUtils.isNotBlank(prefix)){
|
|
|
+ operateErrorInfo.setMessage(prefix + operateErrorInfo.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ errorMsgJoiner.add(operateInfo.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 如果没有具体的错误详情,则使用操作结果中的通用消息
|
|
|
+ if (StringUtils.isBlank(operationResult.getMessage())) {
|
|
|
+ errorMsgJoiner.add(operationResult.getMessage());
|
|
|
+ }
|
|
|
+ throw new ValidationException(errorMsgJoiner.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void endOperationTransaction(EndOperationTransactionArgs e) {
|
|
|
+ for (DynamicObject dataEntity : e.getDataEntities()) {
|
|
|
+ long id = dataEntity.getLong(FormConstant.ID_KEY);
|
|
|
+ DynamicObject dynamicObject = dataEntity.getDynamicObject(FormConstant.NCKD_PERSON);
|
|
|
+ if(dynamicObject != null) {
|
|
|
+ this.getOperationResult().getCustomData().put(id + "", "【" + dynamicObject.getString(FormConstant.NAME_KEY) + "】");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|