|
@@ -0,0 +1,221 @@
|
|
|
|
+package nckd.jimin.jyyy.hr.tsrsc.plugin.workflow;
|
|
|
|
+
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import kd.bos.dataentity.entity.DynamicObject;
|
|
|
|
+import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
|
|
+import kd.bos.exception.KDException;
|
|
|
|
+import kd.bos.logging.Log;
|
|
|
|
+import kd.bos.logging.LogFactory;
|
|
|
|
+import kd.bos.orm.query.QFilter;
|
|
|
|
+import kd.bos.servicehelper.BusinessDataServiceHelper;
|
|
|
|
+import kd.bos.workflow.api.AgentExecution;
|
|
|
|
+import kd.bos.workflow.engine.extitf.IWorkflowPlugin;
|
|
|
|
+import nckd.jimin.jyyy.hr.tsrsc.plugin.util.MokaApiUtil;
|
|
|
|
+
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 临时招聘申请审批流程-工作流插件<br>
|
|
|
|
+ * 流程编码:Proc_nckd_casrecrapply_audit_1<br>
|
|
|
|
+ * 审批通过的临时招聘申请同步给 Moka 的招聘需求界面
|
|
|
|
+ * @author :Tyx
|
|
|
|
+ * @since :2025-05-28
|
|
|
|
+ */
|
|
|
|
+public class CasRecrApplyMokaWorkFlowPlugin implements IWorkflowPlugin {
|
|
|
|
+ private static Log log = LogFactory.getLog(CasRecrApplyMokaWorkFlowPlugin.class);
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void notify(AgentExecution execution) {
|
|
|
|
+ // 单据的BusinessKey(业务ID)
|
|
|
|
+ String businessKey = execution.getBusinessKey();
|
|
|
|
+ // 目标单据
|
|
|
|
+ DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(
|
|
|
|
+ businessKey,
|
|
|
|
+ execution.getEntityNumber()
|
|
|
|
+ );
|
|
|
|
+ // 申请人数为零
|
|
|
|
+ if (dynamicObject == null || dynamicObject.getInt("nckd_applynum") <= 0) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ // 错误列表
|
|
|
|
+ ArrayList<String> errList = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ // 对外招聘组织 的 对外招聘组织编码(number)
|
|
|
|
+ Map<String, String> recruitOrgMap = getRecruitOrgMap();
|
|
|
|
+
|
|
|
|
+ DynamicObjectCollection entryEntity = dynamicObject.getDynamicObjectCollection("entryentity");
|
|
|
|
+ for (DynamicObject entry : entryEntity) {
|
|
|
|
+ // 招聘人数为零,跳过
|
|
|
|
+ // 原单编号
|
|
|
|
+ String billNo = ((DynamicObject) entry.getParent()).getString("billno");
|
|
|
|
+ // 排序号
|
|
|
|
+ int seq = entry.getInt("seq");
|
|
|
|
+
|
|
|
|
+ // 需求人数
|
|
|
|
+ String name = ((DynamicObject) entry.getParent()).getDynamicObjectType().getName();
|
|
|
|
+ int needNumber = 0;
|
|
|
|
+ try {
|
|
|
|
+ needNumber = "nckd_yearcasreplan".equals(name) ? entry.getInt("nckd_approvednum") : entry.getInt("nckd_recruitnum");
|
|
|
|
+ } catch (NullPointerException e) {
|
|
|
|
+ String msg = String.format("单据编号为【%s】的第%s条数据:%s",
|
|
|
|
+ billNo, seq, "需求人数或公司核定人数未填写"
|
|
|
|
+ );
|
|
|
|
+ errList.add(msg);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (needNumber > 0) {
|
|
|
|
+ // 生产请求json
|
|
|
|
+ JSONObject body = getRequestBody(entry, needNumber, recruitOrgMap);
|
|
|
|
+
|
|
|
|
+ // 新建 招聘需求
|
|
|
|
+ // 招聘类型
|
|
|
|
+ String recruitTypeFlag;
|
|
|
|
+ switch (entry.getString("nckd_recruittype.number")) {
|
|
|
|
+ case "1010_S":
|
|
|
|
+ // 校园招聘
|
|
|
|
+ recruitTypeFlag = "2";
|
|
|
|
+ break;
|
|
|
|
+ case "1020_S":
|
|
|
|
+ // 社会招聘
|
|
|
|
+ recruitTypeFlag = "1";
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 发送新建招聘需求请求
|
|
|
|
+ JSONObject responseObj = null;
|
|
|
|
+ try {
|
|
|
|
+ responseObj = MokaApiUtil.addMokaCurrentHire(recruitTypeFlag, body);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 记录调用日志
|
|
|
|
+ MokaApiUtil.newApiLog(
|
|
|
|
+ "nckd_casrecrapply",
|
|
|
|
+ "临时招聘申请",
|
|
|
|
+ "lszp",
|
|
|
|
+ MokaApiUtil.getParamValue("moka_url")
|
|
|
|
+ + "/api-platform/v1/headcount"
|
|
|
|
+ + "?currentHireMode=" + recruitTypeFlag,
|
|
|
|
+ body.toString(),
|
|
|
|
+ responseObj.toString()
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ if (responseObj.getInteger("code") != 0) {
|
|
|
|
+ String msg = String.format("第%s条数据:%s",
|
|
|
|
+ seq, responseObj.getString("msg")
|
|
|
|
+ );
|
|
|
|
+ errList.add(msg);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!errList.isEmpty()) {
|
|
|
|
+ throw new KDException("该临时招聘申请新建Moka招聘需求时,发生以下错误:\r\n" + String.join("\r\n", errList));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取新建招聘需求请求体
|
|
|
|
+ *
|
|
|
|
+ * @param entry 单据体的行
|
|
|
|
+ * @param needNumber
|
|
|
|
+ * @param recruitOrgMap 对外招聘组织编码Map
|
|
|
|
+ * @return 请求体
|
|
|
|
+ */
|
|
|
|
+ public static JSONObject getRequestBody(DynamicObject entry, int needNumber, Map<String, String> recruitOrgMap) {
|
|
|
|
+ // 招聘部门的编码
|
|
|
|
+ String orgNumber = entry.getString("nckd_recruitorg.number");
|
|
|
|
+
|
|
|
|
+ // 专业类别
|
|
|
|
+ DynamicObjectCollection majorTypes = entry.getDynamicObjectCollection("nckd_majortype");
|
|
|
|
+ // 把专业类别里的所有值用;拼接
|
|
|
|
+ String majorType = majorTypes.stream()
|
|
|
|
+ .map(major -> ((DynamicObject) major.get("fbasedataid")).getString("name"))
|
|
|
|
+ .reduce((a, b) -> a + ";" + b)
|
|
|
|
+ .orElse("");
|
|
|
|
+
|
|
|
|
+ String recruitTypeFlag = "";
|
|
|
|
+ switch (entry.getString("nckd_recruittype.number")) {
|
|
|
|
+ case "1010_S":
|
|
|
|
+ // 校园招聘
|
|
|
|
+ recruitTypeFlag = "校园招聘";
|
|
|
|
+ break;
|
|
|
|
+ case "1020_S":
|
|
|
|
+ // 社会招聘
|
|
|
|
+ recruitTypeFlag = "社会招聘";
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+// JSONObject customData = new JSONObject()
|
|
|
|
+// // 自定义字段-专业类别
|
|
|
|
+// .fluentPut(MokaApiUtil.getParamValue("moka_majortype"), majorType)
|
|
|
|
+// // 自定义字段-招聘类型
|
|
|
|
+// .fluentPut(MokaApiUtil.getParamValue("moka_recruitype"), recruitTypeFlag);
|
|
|
|
+
|
|
|
|
+ // 分录id
|
|
|
|
+ String pkId = entry.getPkValue().toString();
|
|
|
|
+
|
|
|
|
+ JSONObject body = new JSONObject()
|
|
|
|
+ // 招聘需求编号,编号全局唯一,且不可修改
|
|
|
|
+ .fluentPut("number", pkId)
|
|
|
|
+ // 招聘需求名称
|
|
|
|
+ .fluentPut("jobName", entry.getString("nckd_recruitpost.name"))
|
|
|
|
+ // 需求人数
|
|
|
|
+ .fluentPut("needNumber", needNumber)
|
|
|
|
+ // 部门code,组织架构同步接口传的department_code
|
|
|
|
+ //.fluentPut("departmentCode", entry.getString("nckd_recruitorg.number"))
|
|
|
|
+ // 学历要求
|
|
|
|
+ .fluentPut("education", entry.getString("nckd_education.name"))
|
|
|
|
+ // 招聘部门
|
|
|
|
+ .fluentPut("departmentCode", recruitOrgMap.get(orgNumber))
|
|
|
|
+ // 最低薪资
|
|
|
|
+ .fluentPut("minSalary", entry.getInt("nckd_payrangemin"))
|
|
|
|
+ // 最高薪资
|
|
|
|
+ .fluentPut("maxSalary", entry.getInt("nckd_payrange"))
|
|
|
|
+ // 薪资单位 0:k/月
|
|
|
|
+ .fluentPut("salaryUnit", 0)
|
|
|
|
+ // 自定义字段
|
|
|
|
+ //.fluentPut("customData", customData)
|
|
|
|
+ // 招聘需求开始时间。日期格式为:ISO8601
|
|
|
|
+ .fluentPut("startDate", LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME));
|
|
|
|
+ return body;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 对外招聘组织
|
|
|
|
+ * @return Map:key 为 组织编码,value 为 对外招聘组织编码
|
|
|
|
+ */
|
|
|
|
+ public static Map<String, String> getRecruitOrgMap() {
|
|
|
|
+ DynamicObject[] recruitOrgs = BusinessDataServiceHelper.load(
|
|
|
|
+ "tsrbs_foreignadminorg",
|
|
|
|
+ "id,name,number,entryentity,entryentity.realadminorg",
|
|
|
|
+ new QFilter[]{null}
|
|
|
|
+ );
|
|
|
|
+ HashMap<String, String> recruitOrgMap = new HashMap<>();
|
|
|
|
+ for (DynamicObject recruitOrg : recruitOrgs) {
|
|
|
|
+ DynamicObjectCollection entryEntity = recruitOrg.getDynamicObjectCollection("entryentity");
|
|
|
|
+ for (DynamicObject obj : entryEntity) {
|
|
|
|
+ recruitOrgMap.put(obj.getString("realadminorg.number"), recruitOrg.getString("number"));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return recruitOrgMap;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|