package com.kingdee.eas.custom.recuritment.task; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Maps; import com.kingdee.bos.metadata.entity.*; import com.kingdee.bos.metadata.query.util.CompareType; import com.kingdee.eas.basedata.person.PersonInfo; import com.kingdee.eas.custom.beisen.utils.BeisenApiClient; import com.kingdee.eas.custom.beisen.utils.BeisenParam; import com.kingdee.eas.custom.beisen.utils.BeisenParamByProperties; import com.kingdee.eas.custom.beisen.entity.PhaseStatusInfo; import com.kingdee.eas.hr.ats.AtsUtil; import com.kingdee.eas.hr.base.EmployeeTypeInfo; import com.kingdee.eas.hr.base.HRBillStateEnum; import com.kingdee.eas.util.app.DbUtil; import com.kingdee.shr.recuritment.*; import com.kingdee.shr.recuritment.app.OfferConfirmStateEnum; import com.kingdee.util.DateTimeUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import com.kingdee.bos.*; import com.kingdee.eas.common.EASBizException; import java.io.IOException; import java.lang.String; import java.util.*; public class BeisenTransferPhaseFacadeControllerBean extends AbstractBeisenTransferPhaseFacadeControllerBean { private static Logger logger = Logger.getLogger(BeisenTransferPhaseFacadeControllerBean.class); private Map phaseStatus = Maps.newHashMap(); //待录用报批单据状态 private static Set hireApprovalBillStatusSet = new HashSet<>(); //待录用报批招聘状态 private static Set hireApprovalResumeStateSet = new HashSet<>(); //录用终止报批招聘状态 private static Set hireTerminationResumeStateSet = new HashSet<>(); //待录用报批招聘状态 private static Set hireOfferStateSet = new HashSet<>(); private static Map beisenTransferPhaseErrorMap = new HashMap<>(); private final String RECAPPROVAL1 = "recApproval1"; private final String RECAPPROVAL2 = "recApproval2"; private final String OFFER1 = "offer1"; private final String OFFER2 = "offer2"; private final String OFFER3 = "offer3"; private final String OFFER4 = "offer4"; private final String OFFER5 = "offer5"; private final String ENROLL1 = "enroll1"; private final String ENROLL2 = "enroll2"; private final String ENROLL3 = "enroll3"; static { hireApprovalBillStatusSet.add(HRBillStateEnum.SAVED);//未提交 hireApprovalBillStatusSet.add(HRBillStateEnum.SUBMITED);//已提交 hireApprovalBillStatusSet.add(HRBillStateEnum.AUDITING);//审批中 hireApprovalResumeStateSet.add("0009");//待报批 hireApprovalResumeStateSet.add("0010");//报批中 hireTerminationResumeStateSet.add("0012");//终止报批 hireTerminationResumeStateSet.add("0011");//报批不通过 hireOfferStateSet.add("0013");//待入职 hireOfferStateSet.add("0015");//已预入职 beisenTransferPhaseErrorMap.put("applyDeleteApplyIds", "因在当前职位下被删除而转移失败"); beisenTransferPhaseErrorMap.put("applicantDeleteApplyIds", "因应聘者被删除而转移失败"); beisenTransferPhaseErrorMap.put("applicantBlackApplyIds", "因应聘者被拉黑而转移失败"); beisenTransferPhaseErrorMap.put("applicantLockedApplyIds", "因应聘者被锁定而转移失败"); beisenTransferPhaseErrorMap.put("applyStatusChangedApplyIds", "因应聘者阶段状态已发生变化而转移失败"); beisenTransferPhaseErrorMap.put("applyOtherReasonRejectedApplyIds", "因定制功能校验失败而转移失败"); beisenTransferPhaseErrorMap.put("applyByHunterOrRPOUnAcceptedIds", "因应聘者存在猎头/RPO简历且未被接受而转移失败"); beisenTransferPhaseErrorMap.put("applyTransferRuleFailedApplyIds", "因应聘者存在不符合准入规则而转移失败"); } public BeisenTransferPhaseFacadeControllerBean() throws IOException, BOSException { BeisenParamByProperties properties = null; try { properties = new BeisenParamByProperties(); } catch (IOException e) { logger.error("北森状态转移Facade获取配置文件报错: " + e.getMessage(), e); throw e; } Map config = properties.getConfig(); String phase1 = config.get("phase1"); String status1A = config.get("status1A"); String status1B = config.get("status1B"); String phase2 = config.get("phase2"); String status2A = config.get("status2A"); String status2B = config.get("status2B"); String status2C = config.get("status2C"); String status2D = config.get("status2D"); String status2E = config.get("status2E"); String phase3 = config.get("phase3"); String status3A = config.get("status3A"); String status3B = config.get("status3B"); String status3C = config.get("status3C"); if (StringUtils.isAnyBlank( phase1, phase2, phase3, status1A, status1B, status2A, status2B, status2C, status2D, status2E, phase3, status3A, status3B, status3C)) { throw new BOSException("北森阶段状态为空!"); } phaseStatus.put(RECAPPROVAL1, new PhaseStatusInfo(phase1, status1A)); phaseStatus.put(RECAPPROVAL2, new PhaseStatusInfo(phase1, status1B)); phaseStatus.put(OFFER1, new PhaseStatusInfo(phase2, status2A)); phaseStatus.put(OFFER2, new PhaseStatusInfo(phase2, status2B)); phaseStatus.put(OFFER3, new PhaseStatusInfo(phase2, status2C)); phaseStatus.put(OFFER4, new PhaseStatusInfo(phase2, status2D)); phaseStatus.put(OFFER5, new PhaseStatusInfo(phase2, status2E)); phaseStatus.put(ENROLL1, new PhaseStatusInfo(phase3, status3A)); phaseStatus.put(ENROLL2, new PhaseStatusInfo(phase3, status3B)); phaseStatus.put(ENROLL3, new PhaseStatusInfo(phase3, status3C)); } /** * 同步录用报批状态到北森 * * @param ctx * @param billId * @param preponeHours * @throws BOSException * @throws EASBizException */ @Override protected void _syncRecApprovalToBeisen(Context ctx, String billId, int preponeHours) throws BOSException, EASBizException { try { super._syncRecApprovalToBeisen(ctx, billId, preponeHours); IRecApproval iRecApproval = RecApprovalFactory.getLocalInstance(ctx); RecApprovalCollection recApprovalCollection = null; SelectorItemCollection sic = new SelectorItemCollection(); sic.add("*"); sic.add("resumeBaseRec.*"); sic.add("resumeBaseRec.resumeState.*"); if (StringUtils.isNotBlank(billId)) { FilterInfo filterInfo = new FilterInfo(); FilterItemCollection filterItems = filterInfo.getFilterItems(); filterItems.add(new FilterItemInfo("id", billId)); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); recApprovalCollection = iRecApproval.getRecApprovalCollection(viewInfo); if (recApprovalCollection.isEmpty()) { logger.error("未匹配到录用报批单据,单据id: " + billId); throw new BOSException("未匹配到录用报批单据"); } } else { if (preponeHours <= 0) { preponeHours = 2; } Date now = new Date(); Date before = DateTimeUtils.addHour(now, -preponeHours); //查询最近12小时内更新的录用报批 FilterInfo filterInfo = new FilterInfo(); FilterItemCollection filterItems = filterInfo.getFilterItems(); //最后更新时间大于等于 filterItems.add(new FilterItemInfo("lastUpdateTime", before, CompareType.GREATER_EQUALS)); //最后更新时间小于等于当前 filterItems.add(new FilterItemInfo("lastUpdateTime", now, CompareType.LESS_EQUALS)); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); recApprovalCollection = iRecApproval.getRecApprovalCollection(viewInfo); } if (recApprovalCollection == null || recApprovalCollection.isEmpty()) { logger.error("录用报批为空!"); return; } //维护录用报批与北森申请id映射关系 Map applyIdRecApprovalMap = new HashMap(); Map recApprovalMap = new HashMap(); IOffer iOffer = OfferFactory.getLocalInstance(ctx); for (int i = 0; i < recApprovalCollection.size(); i++) { RecApprovalInfo recApprovalInfo = recApprovalCollection.get(i); String fid = recApprovalInfo.getId().toString(); //简历基本信息 ResumeBaseRecInfo resumeBaseRec = recApprovalInfo.getResumeBaseRec(); String applyId = resumeBaseRec.getString("applyId"); if (StringUtils.isEmpty(applyId)) { String errorMsg = "北森申请id为空!"; logger.error(errorMsg); Set set = new HashSet(); set.add(fid); updateTable(ctx, "T_REC_RecApproval", errorMsg, "2", set); continue; } applyIdRecApprovalMap.put(applyId, fid); ResumeStateInfo resumeState = resumeBaseRec.getResumeState(); String resumeStateNumber = resumeState.getNumber();//招聘状态 String beisenStatus = null; //单据状态 HRBillStateEnum billState = recApprovalInfo.getBillState(); if (hireApprovalBillStatusSet.contains(billState) && hireApprovalResumeStateSet.contains(resumeStateNumber)) { //单据状态为未提交/未审批/审批中,招聘需求状态为待报批/报批中 北森录用报批状态为待录用报批 beisenStatus = RECAPPROVAL1; } else if (HRBillStateEnum.AUDITEND.equals(billState) && hireTerminationResumeStateSet.contains(resumeStateNumber)) { //单据状态为审批不通过,招聘需求状态为终止报批/报批不通过 北森录用报批状态为录用终止 beisenStatus = RECAPPROVAL2; } else if (HRBillStateEnum.AUDITED.equals(billState) && "0013".equals(resumeStateNumber)) { //单据状态为审批通过,招聘需求状态为待入职,Offer发送状态为空,北森状态为待发Offer try { OfferCollection offerCollection = iOffer.getOfferCollection("where resumeBaseRec ='" + resumeBaseRec.getId() + "'"); //offer发送状态 String sendState = null; if (!offerCollection.isEmpty()) { OfferInfo offerInfo = offerCollection.get(0); sendState = offerInfo.getSendState(); } if (!StringUtils.isEmpty(sendState)) { //Offer发送状态不为空,忽略 return; } } catch (BOSException e) { throw new BOSException("获取offer状态报错: " + e.getMessage()); } beisenStatus = OFFER1; } if (StringUtils.isNotBlank(beisenStatus)) { if (recApprovalMap.containsKey(beisenStatus)) { recApprovalMap.get(beisenStatus).add(applyId); } else { JSONArray applyIds = new JSONArray(); applyIds.add(applyId); recApprovalMap.put(beisenStatus, applyIds); } } } //处理北森状态转移请求 handleBeisenTransferPhaseQuery(ctx, recApprovalMap, applyIdRecApprovalMap, "T_REC_RecApproval"); } catch (Exception e) { logger.error("录用报批同步北森状态转移报错: " + e.getMessage(), e); } } /** * 同步offer状态到北森 * * @param ctx * @param billId * @throws BOSException * @throws EASBizException */ @Override protected void _syncOfferToBeisen(Context ctx, String billId, int preponeHours) throws BOSException, EASBizException { try { super._syncOfferToBeisen(ctx, billId, preponeHours); IOffer iOffer = OfferFactory.getLocalInstance(ctx); OfferCollection offerCollection = null; SelectorItemCollection sic = new SelectorItemCollection(); sic.add("*"); sic.add("resumeBaseRec.*"); sic.add("resumeBaseRec.resumeState.*"); sic.add("person.employeeType.isInCount"); if (StringUtils.isNotBlank(billId)) { FilterInfo filterInfo = new FilterInfo(); FilterItemCollection filterItems = filterInfo.getFilterItems(); filterItems.add(new FilterItemInfo("id", billId)); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); offerCollection = iOffer.getOfferCollection(viewInfo); if (offerCollection.isEmpty()) { logger.error("未匹配到offer单据,单据id: " + billId); throw new BOSException("未匹配到offer单据"); } } else { if (preponeHours <= 0) { preponeHours = 2; } Date now = new Date(); Date before = DateTimeUtils.addHour(now, -preponeHours); //查询最近12小时内更新的录用报批 FilterInfo filterInfo = new FilterInfo(); FilterItemCollection filterItems = filterInfo.getFilterItems(); //最后更新时间大于等于 filterItems.add(new FilterItemInfo("lastUpdateTime", before, CompareType.GREATER_EQUALS)); //最后更新时间小于等于当前 filterItems.add(new FilterItemInfo("lastUpdateTime", now, CompareType.LESS_EQUALS)); EntityViewInfo viewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); offerCollection = iOffer.getOfferCollection(viewInfo); } if (offerCollection == null || offerCollection.isEmpty()) { logger.error("offer为空!"); return; } //维护OfferId与北森申请id映射关系 Map applyIdOfferMap = new HashMap(); Map offerMap = new HashMap(); Map recApprovalMap = new HashMap(); for (int i = 0; i < offerCollection.size(); i++) { OfferInfo offerInfo = offerCollection.get(i); String fid = offerInfo.getId().toString(); //简历基本信息 ResumeBaseRecInfo resumeBaseRec = offerInfo.getResumeBaseRec(); String applyId = resumeBaseRec.getString("applyId"); if (StringUtils.isEmpty(applyId)) { String errorMsg = "北森申请id为空!"; logger.error(errorMsg); Set set = new HashSet(); set.add(fid); updateTable(ctx, "T_REC_Offer", errorMsg, "2", set); continue; } applyIdOfferMap.put(applyId, fid); ResumeStateInfo resumeState = resumeBaseRec.getResumeState(); String resumeStateNumber = resumeState.getNumber();//招聘状态 //发送状态 String sendState = offerInfo.getSendState(); //确认状态 OfferConfirmStateEnum confirmState = offerInfo.getConfirmState(); String beisenStatus = null; if ("0013".equals(resumeStateNumber) && StringUtils.isBlank(sendState) || "待发送".equals(sendState)) { //发送状态为空或待确认,招聘需求状态为待入职 北森录用报批状态为待发Offer beisenStatus = OFFER1; } else if ("0013".equals(resumeStateNumber) && "已发送".equals(sendState) && OfferConfirmStateEnum.TOBECONFIRM.equals(confirmState)) { //确认结果待确认,发送状态为已发送,招聘需求状态为待入职 北森录用报批状态为已发Offer beisenStatus = OFFER2; } else if ("0013".equals(resumeStateNumber) && "已发送".equals(sendState) && OfferConfirmStateEnum.ACCEPTED.equals(confirmState)) { //确认结果已接受,发送状态为已发送,招聘需求状态为待入职 北森录用报批状态为接受Offer beisenStatus = OFFER4; } else if ("0013".equals(resumeStateNumber) && "已发送".equals(sendState) && OfferConfirmStateEnum.REJECTED.equals(confirmState)) { //确认结果已拒绝,发送状态为已发送,招聘需求状态为待入职 北森录用报批状态为拒绝Offer beisenStatus = OFFER3; } else if ("0015".equals(resumeStateNumber)) { //招聘需求状态为已预入职 北森录用报批状态为等待入职 beisenStatus = OFFER5; } else if ("0017".equals(resumeStateNumber)) { //招聘需求状态为已入职 北森录用报批状态为已入职 PersonInfo person = offerInfo.getPerson(); if (person != null) { EmployeeTypeInfo employeeType = person.getEmployeeType(); if (employeeType != null && !employeeType.isIsInCount()) { //如果有审批通过的离职单,则忽略 return; } } beisenStatus = ENROLL1; } else if ("0016".equals(resumeStateNumber) || "0014".equals(resumeStateNumber)) { //招聘需求状态为放弃入职或终止入职 北森录用报批状态为取消入职 beisenStatus = ENROLL2; } if (StringUtils.isNotBlank(beisenStatus)) { if (recApprovalMap.containsKey(beisenStatus)) { offerMap.get(beisenStatus).add(applyId); } else { JSONArray applyIds = new JSONArray(); applyIds.add(applyId); offerMap.put(beisenStatus, applyIds); } } } handleBeisenTransferPhaseQuery(ctx, applyIdOfferMap, offerMap, "T_REC_Offer"); } catch (Exception e) { logger.error("offer同步北森状态转移报错: " + e.getMessage(), e); } } /** * 处理北森状态转移请求 * * @param ctx * @param recApprovalMap * @param applyIdStatusMap 北森状态与申请id * @param tableName 数据库表名 * @throws BOSException */ private void handleBeisenTransferPhaseQuery( Context ctx, Map recApprovalMap, Map applyIdStatusMap, String tableName ) throws BOSException, IOException { BeisenApiClient beisenApiClient = BeisenApiClient.getInstance(); for (String statusName : recApprovalMap.keySet()) { try { //申请id JSONArray applyIds = recApprovalMap.get(statusName); PhaseStatusInfo phaseStatusInfo = phaseStatus.get(statusName); JSONObject params = new JSONObject(); params.put("applyIds", applyIds); params.put("phaseId", phaseStatusInfo.getPhaseId()); params.put("statusId", phaseStatusInfo.getStatusId()); JSONObject response = beisenApiClient.callApi(BeisenParam.POST_TRANSFERPHASE_URL, params); int code = response.getIntValue("code"); String message = response.getString("message"); if (200 == code) { JSONObject data = response.getJSONObject("data"); //转移失败数 Integer noTransferCount = data.getInteger("noTransferCount"); if (noTransferCount > 0) { for (String key : beisenTransferPhaseErrorMap.keySet()) { JSONArray failApplyIds = data.getJSONArray(key); if (!failApplyIds.isEmpty()) { String errorMsg = beisenTransferPhaseErrorMap.get(key); Set fids = new HashSet<>(); failApplyIds.forEach((applyid) -> { fids.add(applyIdStatusMap.get(applyid)); }); updateTable(ctx, tableName, errorMsg, "2", fids); } } } else { Set fids = new HashSet<>(); applyIdStatusMap.values().forEach((id) -> { fids.add(id); }); updateTable(ctx, tableName, "成功", "1", fids); } } else { Set fids = new HashSet<>(); applyIdStatusMap.values().forEach((id) -> { fids.add(id); }); updateTable(ctx, tableName, message, "2", fids); } } catch (Exception e) { logger.error("同步北森状态转移报错: " + e.getMessage(), e); throw e; } } } /** * 更新offer/录用报批表执行结果和状态 * * @param ctx * @param tableName * @param message * @param status * @param fids * @throws BOSException */ private void updateTable( Context ctx, String tableName, String message, String status, Set fids ) throws BOSException { StringBuilder updateSql = new StringBuilder(); updateSql.append("update ").append(tableName).append(" set CFsyncBeisenResult ='"); updateSql.append(message).append("' ,CFsyncStatus = '").append(status).append("'"); updateSql.append(" where fid in (").append(AtsUtil.convertSetToString(fids)).append(")"); DbUtil.execute(ctx, updateSql.toString()); } }