package nccloud.impl.hryf.entrymng.impl;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.hr.utils.MultiLangHelper;
import nc.hr.utils.PubEnv;
import nc.hr.utils.ResHelper;
import nc.itf.hi.IPsndocQryService;
import nc.itf.hi.IPsndocService;
import nc.itf.hi.entrymng.IEntrymngManageService;
import nc.itf.hi.entrymng.IEntrymngQueryService;
import nc.itf.hr.IHRLicenseChecker;
import nc.itf.hr.frame.IPersistenceHome;
import nc.itf.hr.frame.IPersistenceRetrieve;
import nc.itf.hr.frame.IPersistenceUpdate;
import nc.itf.hr.message.IHRMessageSend;
import nc.itf.org.IOrgConst;
import nc.itf.uap.busibean.SysinitAccessor;
import nc.itf.uap.rbac.IUserGroupQueryService;
import nc.itf.uap.rbac.IUserManage;
import nc.itf.uap.rbac.IUserManageQuery;
import nc.itf.uap.rbac.userpassword.IUserPasswordManage;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.pubitf.rbac.IUserPubService;
import nc.vo.hi.entrymng.AggEntryapplyVO;
import nc.vo.hi.entrymng.EntryapplyVO;
import nc.vo.hi.entrymng.EntrymngConst;
import nc.vo.hi.psndoc.CtrtVO;
import nc.vo.hi.psndoc.EduVO;
import nc.vo.hi.psndoc.PsnJobVO;
import nc.vo.hi.psndoc.PsnOrgVO;
import nc.vo.hi.psndoc.PsndocAggVO;
import nc.vo.hi.psndoc.PsndocVO;
import nc.vo.hr.message.HRBusiMessageVO;
import nc.vo.hr.tools.pub.HRConstEnum;
import nc.vo.ml.LanguageVO;
import nc.vo.ml.MultiLangContext;
import nc.vo.ml.MultiLangUtil;
import nc.vo.org.DeptVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.SuperVO;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFLiteralDate;
import nc.vo.pub.pf.IPfRetCheckInfo;
import nc.vo.sm.UserVO;
import nc.vo.uap.rbac.UserGroupVO;
import nc.vo.uif2.LoginContext;
import nccloud.commons.lang.ArrayUtils;
import nccloud.commons.lang.StringUtils;
import nccloud.dto.hryf.entrymng.EntryConst;
import nccloud.dto.hryf.entrymng.EntryMaterialVO;
import nccloud.dto.hryf.entrymng.OfferHandItemVO;
import nccloud.dto.hryf.tools.HRYFWorkFlowHelper;
import nccloud.itf.hrsscpub.utils.BusiActionConst;
import nccloud.itf.hrsscpub.utils.SatisfactSurveryUtil;
import nccloud.itf.hrsscpub.utils.WorkLoadCountUtil;
import nccloud.itf.hryf.entrymng.IEntrymngService;
import nccloud.itf.hryf.handover.IHandoverService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;

public class EntrymngServiceImpl implements IEntrymngService {

	@Override
	public void sendOffer(AggEntryapplyVO bill, LoginContext context, String busiCenterCode) throws BusinessException {

		EntryapplyVO head = (EntryapplyVO) bill.getParentVO();
		// 未发送或拒绝状态需要更新状态记录发送事件
		if (EntryConst.BILL_STATUS_REJECT_OFFER == head.getWorkflow_state() || IPfRetCheckInfo.PASSING == head.getWorkflow_state()) {
			// 更新单据状态
			head.setWorkflow_state(EntryConst.BILL_STATUS_SEND_OFFER);
			NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVO(null, head, new String[] { EntryapplyVO.WORKFLOW_STATE }, null);

			insertHandItem(head, context, EntryConst.SEND_OFFER);
		}

		// ncc1906 发送offer邮件
		// TODO 默认加上制单人和当前操作员,后续还会修改
		Hashtable<String, Object> var = new Hashtable<>();
		// TODO 接受/拒绝地址待补充
		// /hrpub/template/receiveOffer/main/index.html
		// /hrpub/template/refuseOffer/main/index.html
		String url = SysinitAccessor.getInstance().getParaString(IOrgConst.GLOBEORG, "HR0002");
		if (StringUtils.isBlank(url)) {
			url = "";
		}
		var.put("accept", url + "/ncc_mobile/mobile_hr/hrzz/login/receive-offer/main/index.html" +
				"?billid=" + head.getPk_entryapply() +
				"&ds=" + InvocationInfoProxy.getInstance().getUserDataSource() +
				"&bccode=" + busiCenterCode);
		var.put("refuse", url + "/ncc_mobile/mobile_hr/hrzz/login/refuse-offer/main/index.html" +
				"?billid=" + head.getPk_entryapply() +
				"&ds=" + InvocationInfoProxy.getInstance().getUserDataSource() +
				"&bccode=" + busiCenterCode);
		sendEmail(context, bill, var, EntryConst.ENTRY_MSG_RES_SEND_OFFER, new String[] { head.getBillmaker(), PubEnv.getPk_user() }, true);
		// 工作量统计
		WorkLoadCountUtil.count(new Object[]{bill}, BusiActionConst.SENDOFFER, EntrymngConst.BillTYPE_ENTRY);
	}

	public void sendEmail(LoginContext context, AggEntryapplyVO bill, Hashtable<String, Object> busiVar, String msgResCode, String[] otherREceiver, boolean isMailToStaff)
			throws BusinessException {
		EntryapplyVO head = (EntryapplyVO) bill.getParentVO();
		HRBusiMessageVO messageVO = new HRBusiMessageVO();
		messageVO.setBillVO(bill);
		messageVO.setBusiVarValues(busiVar);
		messageVO.setMsgrescode(msgResCode);
		messageVO.setPkorgs(new String[] { context.getPk_org() });
		if (isMailToStaff) {
			PsndocVO psndoc = (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsndocVO.class, head.getPk_psndoc());
			String email = psndoc.getSecret_email();// 入职使用私密邮箱做收件邮箱
//			if (StringUtils.isBlank(email)) {
//				email = psndoc.getSecret_email();
//			}
			if (StringUtils.isNotBlank(email)) {
				messageVO.setReceiverEmails(new String[] { email });
			}
			String mobile = psndoc.getMobile();
			if (StringUtils.isNotBlank(mobile)) {
				messageVO.setReceiverMobiles(new String[] { mobile });
			}
		}

		if (otherREceiver != null && otherREceiver.length > 0) {
			messageVO.setReceiverPkUsers(otherREceiver);
		}
		IHRMessageSend messageSendServer = NCLocator.getInstance().lookup(IHRMessageSend.class);
		try {
			messageSendServer.sendBuziMessage_RequiresNew(messageVO, new String[] { getUserContentLangCode(PubEnv.getPk_user()) });
		} catch (Exception ex) {
			// 发送通知报错
			Logger.error(ex.getMessage(), ex);
			throw new BusinessException(ex.getMessage(), ex);
		}
	}

	private String getUserContentLangCode(String userPk) throws BusinessException {
		UserVO[] users = NCLocator.getInstance().lookup(IUserPubService.class).getUsersByPKs(new String[] { userPk });
		if (ArrayUtils.isEmpty(users))
		{
			return null;
		}
		UserVO user = users[0];
		String pk_langcode = user.getContentlang();
		LanguageVO[] all = getAllEnabledLangVO();
		if (ArrayUtils.isEmpty(all))
		{
			return null;
		}
		for (LanguageVO languageVO : all) {
			if (languageVO.getPk_multilang().equals(pk_langcode))
			{
				return languageVO.getLangcode();
			}
		}
		return null;

	}

	private static LanguageVO[] getAllEnabledLangVO() {
		LanguageVO[] langvos = MultiLangContext.getInstance().getEnableLangVOs();
		if (ArrayUtils.isEmpty(langvos))
		{
			return null;
		}
		return langvos;
	}

	@Override
	public void rejectOffer(AggEntryapplyVO bill, LoginContext context) throws BusinessException {
		EntryapplyVO head = (EntryapplyVO) bill.getParentVO();
		head.setWorkflow_state(EntryConst.BILL_STATUS_REJECT_OFFER);
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVO(null, head, new String[] { EntryapplyVO.WORKFLOW_STATE }, null);

		insertHandItem(head, context, EntryConst.REJECT_OFFER);

		// 拒绝offer发邮件,给申请人发送
		sendEmail(context, bill, null, EntryConst.ENTRY_MSG_RES_REJECT_OFFER, new String[] { head.getBillmaker() }, false);
	}

	@Override
	public void acceptOffer(AggEntryapplyVO bill, LoginContext context) throws BusinessException {

		EntryapplyVO head = (EntryapplyVO) bill.getParentVO();
		head.setWorkflow_state(EntryConst.BILL_STATUS_ACCEPT_OFFER);
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVO(null, head, new String[] { EntryapplyVO.WORKFLOW_STATE }, null);

		insertHandItem(head, context, EntryConst.ACCEPT_OFFER);

		// ncc1906 如果是第一次发送offer 需要发送入职欢迎信
		if (isFirstAcceptOffer(head.getPk_entryapply())) {

			// 第一次接受offer的时候，生成自助用户，并关联预置角色
			UserVO user = createUser(head, context);

			// send email
			Hashtable<String, Object> var = new Hashtable<>();
			// 预入职地址待补充
			// /nccloud/resources/hrpub/template/login/main/index.html
			// 从参数取访问地址
			String url = SysinitAccessor.getInstance().getParaString(IOrgConst.GLOBEORG, "HR0002");
			if (StringUtils.isBlank(url)) {
				url = "";
			}
			var.put("preentryurl", url + "/ncc_mobile/mobile_hr/hrzz/login/login/main/index.html" +
					"?ds=" + InvocationInfoProxy.getInstance().getUserDataSource() +
					"&bccode=" + InvocationInfoProxy.getInstance().getBizCenterCode());
			var.put("username", user.getUser_code());

			IUserPasswordManage pswservice = NCLocator.getInstance().lookup(IUserPasswordManage.class);
			String newpsw = pswservice.resetUserPassWord(user.getCuserid());
			var.put("userpwd", newpsw.substring(newpsw.indexOf(":")+1));
			sendEmail(context, bill, var, EntryConst.ENTRY_MSG_RES_WELCOME, null, true);

			//将关联邮箱放到重置密码后面,这样就不会收到重置密码邮件了
			// 设置上email,未入职的时候使用的全是个人邮箱
			PsndocVO psndochr = (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsndocVO.class, head.getPk_psndoc());
			user = NCLocator.getInstance().lookup(IUserManageQuery.class).getUser(user.getCuserid());
			user.setEmail(psndochr.getSecret_email());
			NCLocator.getInstance().lookup(IUserManage.class).updateUser(user);
		}

	}

	private UserVO createUser(EntryapplyVO head, LoginContext context) throws BusinessException {
		UserVO user = null;
		UserVO[] users = NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserVOsByPsnDocID(head.getPk_psndoc());
		if (users != null && users.length > 0) {
			// 如果用户存在
			user = users[0];
			if (user.getEnablestate() != 2) {
				// 启用
				user = NCLocator.getInstance().lookup(IUserManage.class).enableUser(user);
			}
			if (user.getIsLocked() != null && user.getIsLocked().booleanValue()) {
				// 解锁
				user = NCLocator.getInstance().lookup(IUserManage.class).updateLockedTagByAdmin(user.getCuserid(), false);
			}
		} else {
			// 如果用户不存在,创建用户
			nc.vo.bd.psn.PsndocVO psndoc = (nc.vo.bd.psn.PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, nc.vo.bd.psn.PsndocVO.class,
					head.getPk_psndoc());
			String usercode = psndoc.getCode();
			user = NCLocator.getInstance().lookup(IUserManageQuery.class).findUserByCode(usercode, InvocationInfoProxy.getInstance().getUserDataSource());
			if (user != null) {
				// 员工号已经生成了用户,加上时间戳
				usercode = usercode + "_" + new Date().getTime();
			}
			psndoc.setCode(usercode);

			// UserGroupVO[] groups = NCLocator.getInstance().lookup(IUserGroupQueryService.class).getAllUserGroupInGroup(context.getPk_group());
			UserGroupVO[] groups = NCLocator.getInstance().lookup(IUserGroupQueryService.class)
					.queryUserGroupBySqlWhere("groupcode = 'hrzz_preentry_usergrp' and pk_org = '" + context.getPk_group() + "'");
			NCLocator.getInstance().lookup(IPsndocService.class).createUser(new nc.vo.bd.psn.PsndocVO[] { psndoc },
					groups != null && groups.length > 0 ? groups[0].getPk_usergroup() : "~");
			user = NCLocator.getInstance().lookup(IUserManageQuery.class).findUserByCode(usercode, InvocationInfoProxy.getInstance().getUserDataSource());

		}
		return user;
	}

	// 停用用户
	private void disableUser(EntryapplyVO head) throws BusinessException {
		UserVO[] users = NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserVOsByPsnDocID(head.getPk_psndoc());
		for (int i = 0; users != null && i < users.length; i++) {
			NCLocator.getInstance().lookup(IUserManage.class).disableUser(users[i]);
		}
	}

	private void insertHandItem(EntryapplyVO head, LoginContext context, int handtype) throws BusinessException {
		OfferHandItemVO offerItem = new OfferHandItemVO();
		offerItem.setPk_entryapply(head.getPk_entryapply());
		offerItem.setHandler(context.getPk_loginUser());
		offerItem.setHandtype(handtype);
		offerItem.setPk_group(context.getPk_group());
		offerItem.setPk_org(head.getPk_org());
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).insertVO(null, offerItem, null);
	}

	@Override
	public void commitOffer(AggEntryapplyVO bill, LoginContext context) throws BusinessException {
		EntryapplyVO head = (EntryapplyVO) bill.getParentVO();
		int state = head.getWorkflow_state();
		if (state == EntryConst.BILL_STATUS_REJECT_OFFER) {
			bill = NCLocator.getInstance().lookup(IEntrymngManageService.class).updateBill(bill, false);
			disableUser(head);
			// 推流程（此处拒绝offer推一次流程进入入职确认环节，下面会再推一次，拒绝入职的流程直接就会结束。）
			HRYFWorkFlowHelper.driveWorkFlow(context, EntrymngConst.BillTYPE_ENTRY, bill);
		} else {
			// 推流程
			HRYFWorkFlowHelper.driveWorkFlow(context, EntrymngConst.BillTYPE_ENTRY, bill);
			if (state == EntryConst.BILL_STATUS_ACCEPT_OFFER) {
				// 接受offer,发送入职准备提醒邮件
				String managerUserid = null;
				PsnJobVO psnjob = (PsnJobVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsnJobVO.class, head.getPk_psnjob());
				DeptVO dept = (DeptVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, DeptVO.class, psnjob.getPk_dept());
				if (StringUtils.isNotBlank(dept.getPrincipal()) && (!"~".equals(dept.getPrincipal()))) {
					UserVO[] users = NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserVOsByPsnDocID(dept.getPrincipal());
					if (users != null && users.length > 0) {
						managerUserid = users[0].getCuserid();
					}
				}
				sendEmail(context, bill, null, EntryConst.ENTRY_MSG_RES_ENTRY_REMIND, managerUserid == null ? null : new String[] { managerUserid }, true);
			}
			//工作量统计(此处工作量统计放到EntrySendOfferWfGadget这个类中统计)
			//WorkLoadCountUtil.count(new Object[]{bill}, BusiActionConst.COMMITOFFER, EntrymngConst.BillTYPE_ENTRY);
		}
	}

	@Override
	public void noShow(AggEntryapplyVO bill, LoginContext context) throws BusinessException {
		EntryapplyVO head = (EntryapplyVO) bill.getParentVO();
		head.setWorkflow_state(EntryConst.BILL_STATUS_NOSHOW);
		bill = NCLocator.getInstance().lookup(IEntrymngManageService.class).updateBill(bill, false);
		disableUser(head);
		// 推流程
		HRYFWorkFlowHelper.driveWorkFlow(context, EntrymngConst.BillTYPE_ENTRY, bill);
	}

	@Override
	public void handleEntry(AggEntryapplyVO bill, LoginContext context, String psncode, String email, EntryMaterialVO[] materials, CtrtVO ctrt, boolean isCommit)
			throws BusinessException {
		EntryapplyVO head = (EntryapplyVO) bill.getParentVO();
		PsndocAggVO psndocAggVO = NCLocator.getInstance().lookup(IPsndocQryService.class).queryPsndocVOByPk(head.getPk_psndoc());
		if (StringUtils.isNotBlank(psncode)) {
			psndocAggVO.getParentVO().setCode(psncode);
		}
		if (StringUtils.isNotBlank(email)) {
			psndocAggVO.getParentVO().setEmail(email);
		}

		// 插入是否需要签合同,后续取值控制界面
		EntryMaterialVO vo = new EntryMaterialVO();
		vo.setPk_entry_material(null);
		vo.setPk_entryapply(head.getPk_entryapply());
		vo.setIsreceive(UFBoolean.valueOf(ctrt != null));
		vo.setPk_material(EntryMaterialVO.PK_SIGN_CTRT);
		vo.setPk_group(PubEnv.getPk_group());
		vo.setPk_org(head.getPk_org());
		vo.setCreationtime(new UFDateTime());
		vo.setCreator(PubEnv.getPk_user());
		vo.setStatus(VOStatus.NEW);
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).insertVO(null, vo, null);

		if (ctrt != null) {
			CtrtVO[] ctrtVOs = (CtrtVO[]) NCLocator.getInstance().lookup(IPsndocQryService.class).querySubVO(CtrtVO.class,
					"pk_psnorg='" + psndocAggVO.getParentVO().getPsnOrgVO().getPk_psnorg() + "'", "recordnum desc");
			// 找到对应主键的数据，改为删除态
			// CtrtVO oldVO = null;
			int oldIndex = -1;
			String subId = ctrt.getPk_psndoc_sub();
			for (int i = 0, j = ArrayUtils.getLength(ctrtVOs); i < j; i++) {
				if (!ctrtVOs[i].getPrimaryKey().equals(subId))
				{
					continue;
				}
				// oldVO = ctrtVOs[i];
				oldIndex = i;
				break;
			}

			if (oldIndex >= 0) {
				ctrtVOs[oldIndex] = ctrt;
				ctrtVOs[oldIndex].setStatus(VOStatus.UPDATED);
			} else {
				ctrt.setStatus(VOStatus.NEW);
				ctrtVOs = (CtrtVO[]) ArrayUtils.add(ctrtVOs, ctrt);
			}

			// if (oldVO != null) {
			// oldVO = ctrt;
			// oldVO.setStatus(VOStatus.UPDATED);
			// } else {
			// ctrt.setStatus(VOStatus.NEW);
			// ctrtVOs = (CtrtVO[]) ArrayUtils.add(ctrtVOs, ctrt);
			// }

			sortAndSetSubVOs(ctrtVOs);
			psndocAggVO.setTableVO(CtrtVO.getDefaultTableName(), ctrtVOs);

			// 设置为update
		}
		psndocAggVO.getParentVO().setStatus(VOStatus.UPDATED);

		//校验
		NCLocator.getInstance().lookup(IPsndocService.class).checkPsnUnique(psndocAggVO.getParentVO(), true);
		psndocAggVO = NCLocator.getInstance().lookup(IPsndocService.class).savePsndoc(psndocAggVO, false, false);

		// 删除旧的数据
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).executeSQLs(
				new String[] { "delete from hi_entry_material where pk_entryapply = '" + head.getPk_entryapply() + "' and pk_material <> '" + EntryMaterialVO.PK_SIGN_CTRT + "'" });
		if (materials != null && materials.length > 0) {
			for (int i = 0; i < materials.length; i++) {
				materials[i].setPk_entry_material(null);
				materials[i].setPk_entryapply(head.getPk_entryapply());
				materials[i].setPk_group(PubEnv.getPk_group());
				materials[i].setPk_org(head.getPk_org());
				materials[i].setCreationtime(new UFDateTime());
				materials[i].setCreator(PubEnv.getPk_user());
				materials[i].setStatus(VOStatus.NEW);
			}
			NCLocator.getInstance().lookup(IPersistenceUpdate.class).insertVOArray(null, materials, null);
		}

		if (!isCommit) {
			return;
		}

		boolean bl = NCLocator.getInstance().lookup(IHRLicenseChecker.class).checkPsnCountOnSwitchToDoc(1);
		if (bl) {
			throw new BusinessException(ResHelper.getString("6007psn", "06007psn0431") /* "单据执行失败:单据执行将导致系统员工数超过最大授权数!" */);
		}
		// 执行单据,推业务流
		// context.setPk_group(PubEnv.getPk_group());
		// context.setPk_org(head.getPk_org());
		// context.setPk_loginUser(PubEnv.getPk_user());
		// HashMap<String, Object> result = NCLocator.getInstance().lookup(IEntrymngManageService.class).execBills(new AggEntryapplyVO[] { bill }, context, true);
		// AggEntryapplyVO[] retObjs = (AggEntryapplyVO[]) result.get(EntrymngHelper.RESULT_BILLS);
		// String msg = (String) result.get(EntrymngHelper.RESULT_MSG);
		// if (retObjs == null || retObjs.length == 0) {
		// throw new BusinessException(msg);
		// }

		try {
			// 入职执行
			doPerfromBill(bill);
			// 工作量统计
			WorkLoadCountUtil.count(bill, BusiActionConst.ENTRYCONFIRM, EntrymngConst.BillTYPE_ENTRY);
			SatisfactSurveryUtil.fireSurvey(bill, BusiActionConst.ENTRYCONFIRM, EntrymngConst.BillTYPE_ENTRY);
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
			String billcode = (String) bill.getParentVO().getAttributeValue(EntryapplyVO.BILL_CODE);
			String msg = "";
			if (StringUtils.isEmpty(e.getMessage())) {
				msg = (0 + 1) + ResHelper.getString("6007entry", "06007entry0040")/* @res ":单据" */
						+ billcode + ResHelper.getString("6007entry", "06007entry0041")/* @res "由于如下未知异常[" */
						+ e.getMessage() + ResHelper.getString("6007entry", "06007entry0042")/* @res "]不能成功执行,具体异常信息请查看日志." */;
			} else {
				if (e.getMessage().indexOf(billcode) < 0) {
					// 如果异常信息中没有出现单据号,则重组异常信息
					msg = (0 + 1) + ResHelper.getString("6007entry", "06007entry0040")/* @res ":单据" */
							+ billcode + ResHelper.getString("6007entry", "06007entry0043")/* @res "由于如下异常[" */
							+ e.getMessage() + ResHelper.getString("6007entry", "06007entry0042")/* @res "]不能成功执行,具体异常信息请查看日志." */;
				} else {
					msg = (0 + 1) + ":" + e.getMessage()/* + "<br>" */;
				}
			}
			//
			throw new BusinessException(msg);
		}

		// 生成入职交接事项
		NCLocator.getInstance().lookup(IHandoverService.class).createHandoverList(head.getPk_entryapply(), 1);

		// 发送入职完成通知
		sendEmail(context, bill, null, EntryConst.ENTRY_MSG_RES_ENTRY, new String[] { head.getBillmaker() }, false);

		// 推流程
		bill = NCLocator.getInstance().lookup(IEntrymngQueryService.class).queryByPk(bill.getParentVO().getPrimaryKey());
		HRYFWorkFlowHelper.driveWorkFlow(context, EntrymngConst.BillTYPE_ENTRY, bill);
	}

	private void doPerfromBill(AggEntryapplyVO aggVO) throws BusinessException {
		if (aggVO == null)
		{
			return;
		}
		// 获取单据中人员数值
		EntryapplyVO vo = (EntryapplyVO) aggVO.getParentVO();

		PsnOrgVO[] orgVO = (PsnOrgVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, PsnOrgVO.class,
				" pk_psndoc = '" + vo.getPk_psndoc() + "' ");
		PsnOrgVO psnorgVO = new PsnOrgVO();
		// wanglqh获取值得时候需要按照下面条件获取，第一条记录不一定就是最新记录
		for (PsnOrgVO psnvo : orgVO) {
			if (psnvo.getEndflag() == UFBoolean.FALSE && psnvo.getLastflag() == UFBoolean.TRUE) {
				psnorgVO = psnvo;
			}
		}
		if (orgVO != null && orgVO.length > 0 && psnorgVO.getIndocflag() != null && psnorgVO.getIndocflag().booleanValue()) {
			PsndocVO psn = (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsndocVO.class, psnorgVO.getPk_psndoc());
			String name = MultiLangHelper.getName(psn);
			/* "人员[{0},{1}]已经转入人员档案,无法再次转入"; */
			throw new BusinessException(ResHelper.getString("6007psn", "06007psn0338", psn.getCode(), name));
		}

		// 转入人员档案
		boolean issyncwork = vo.getIssyncwork() == null ? false : vo.getIssyncwork().booleanValue();
		NCLocator.getInstance().lookup(IPsndocService.class).intoDoc(null, issyncwork, vo.getPk_org(), vo.getPk_psnjob());

		// 更新单据状态为已执行
		vo.setAttributeValue(EntryapplyVO.WORKFLOW_STATE, HRConstEnum.EXECUTED);
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVO(null, vo, new String[] { EntryapplyVO.WORKFLOW_STATE }, null);

		// 更新工作记录单据信息
		PsnJobVO jobVO = (PsnJobVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsnJobVO.class, vo.getPk_psnjob());
		String[] updateFields = { PsnJobVO.ORIBILLTYPE, PsnJobVO.ORIBILLPK };
		jobVO.setAttributeValue(updateFields[0], EntrymngConst.BillTYPE_ENTRY);
		jobVO.setAttributeValue(updateFields[1], vo.getPk_entryapply());
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVO(null, jobVO, updateFields, null);

		PsndocVO psndoc =  (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsndocVO.class, vo.getPk_psndoc());
		if(StringUtils.isBlank(psndoc.getEmail())){
			psndoc.setEmail(psndoc.getSecret_email());
			NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVO(null, psndoc, new String[]{PsndocVO.EMAIL}, null);
		}
		UserVO[] users = NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserVOsByPsnDocID(vo.getPk_psndoc());
		if(users!=null&&users.length>0){
			//确认入职后将用户上的邮箱去掉,使用基本信息上的email
			users[0].setEmail(null);
			NCLocator.getInstance().lookup(IUserManage.class).updateUser(users[0]);
		}
	}

	@Override
	public String[] queryBillPKs(String condition, String orderBy) throws BusinessException {
		String sql = " select " + EntryapplyVO.PK_ENTRYAPPLY + " from " + new EntryapplyVO().getTableName() + " where " + condition + " order by " + orderBy + " ";
		ArrayList list = (ArrayList) NCLocator.getInstance().lookup(IPersistenceHome.class).executeQuery(sql, new ColumnListProcessor());
		if (list == null || list.size() == 0) {
			return null;
		}
		String[] pks = new String[list.size()];
		for (int i = 0; i < list.size(); i++) {
			pks[i] = (String) list.get(i);
		}
		return pks;
	}

	private <T extends SuperVO> void sortAndSetSubVOs(T[] subVOs) {
		if (ArrayUtils.isEmpty(subVOs))
		{
			return;
		}
		Arrays.sort(subVOs, new Comparator<T>() {
			@Override
			public int compare(T o1, T o2) {
				Integer o1Num = (Integer) o1.getAttributeValue("recordnum");
				Integer o2Num = (Integer) o2.getAttributeValue("recordnum");
				if (o1Num == null)
				{
					o1Num = 9999;
				}
				if (o2Num == null)
				{
					o2Num = 9999;
				}
				return o1Num.compareTo(o2Num);
			}
		});
		int recordNum = 0;
		for (int i = subVOs.length - 1; i >= 0; i--) {
			if (VOStatus.DELETED == subVOs[i].getStatus())
			{
				continue;
			}
			subVOs[i].setAttributeValue("lastflag", UFBoolean.valueOf(recordNum == 0 || (subVOs[i]) instanceof EduVO));
			subVOs[i].setAttributeValue("recordnum", recordNum++);
		}
	}

	private boolean isFirstAcceptOffer(String pk_entryapply) throws BusinessException {
		int count = NCLocator.getInstance().lookup(IPersistenceRetrieve.class).getCountByCondition(new OfferHandItemVO().getTableName(),
				" pk_entryapply = '" + pk_entryapply + "'  and handtype = 2");
		return count == 1;
	}

	@Override
	public void confirmRecAll(AggEntryapplyVO vo, LoginContext context) throws BusinessException {
		EntryapplyVO head = (EntryapplyVO) vo.getParentVO();
		String sql = "update hi_entry_material set isreceive = 'Y' ,uncommit='N', receivedate='" + new UFLiteralDate().toStdString() + "' where uncommit='Y' and pk_entryapply='"
				+ head.getPk_entryapply() + "'";
		new BaseDAO().executeUpdate(sql);
	}

	@Override
	public void sendMissRemind(AggEntryapplyVO vo, LoginContext context) throws BusinessException {
		EntryapplyVO head = (EntryapplyVO) vo.getParentVO();
		String sql = "select " + getLangNameColume("c.name")
				+ " from hi_entry_material s inner join bd_defdoc c on s.pk_material=c.pk_defdoc where s.uncommit='Y' and s.pk_entryapply='" + head.getPk_entryapply() + "'";
		List list = (List) new BaseDAO().executeQuery(sql, new ColumnListProcessor());
		if (list == null || list.isEmpty()) {
			throw new BusinessException(ResHelper.getString("6008hryf", "06008hryf-0000044")/* "单据不存在缺件,不需要发送缺件提醒" */);
		}
		StringBuffer sb = new StringBuffer();
		sb.append("<ul>");
		for (Object absentFile : list) {
			sb.append("<li>");
			sb.append(absentFile);
			sb.append("</li>");
		}
		sb.append("</ul>");
		Hashtable<String, Object> var = new Hashtable<>();
		var.put("entryfilename", sb.toString());
		sendEmail(context, vo, var, EntryConst.ENTRY_MSG_RES_MISS_REMIND, null, true);
	}

	private String getLangNameColume(String nameField) {
		String multilangIndex = MultiLangUtil.getCurrentLangSeqSuffix();
		if (StringUtils.isBlank(multilangIndex)) {
			return nameField;
		}

		String currLangName = nameField + multilangIndex;
		return " isnull(" + currLangName + "," + nameField + ")";
	}

}
