package nccloud.web.hryf.pub.action;

import nc.bs.logging.Logger;
import nc.hr.utils.ResHelper;
import nc.itf.hi.IPsndocQryService;
import nc.itf.hr.frame.IHrBillCode;
import nc.itf.hr.frame.IPersistenceRetrieve;
import nc.itf.uap.busibean.SysinitAccessor;
import nc.itf.uap.pf.IPFWorkflowQry;
import nc.itf.uap.pf.metadata.IFlowBizItf;
import nc.md.data.access.NCObject;
import nc.md.persist.framework.IMDPersistenceQueryService;
import nc.pub.billcode.itf.IBillcodeManage;
import nc.pub.billcode.vo.BillCodeContext;
import nc.pub.tools.HiCacheUtils;
import nc.ui.querytemplate.querytree.FromWhereSQL;
import nc.ui.trade.businessaction.IPFACTION;
import nc.vo.hi.psndoc.PsndocVO;
import nc.vo.hi.pub.HICommonValue;
import nc.vo.hi.trnstype.TrnstypeVO;
import nc.vo.hr.message.HRBusiMessageVO;
import nc.vo.hr.tools.pub.HRConstEnum;
import nc.vo.pf.change.PfUtilBaseTools;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.BusinessRuntimeException;
import nc.vo.pub.SuperVO;
import nc.vo.pub.ValidationException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.pf.IPfRetCheckInfo;
import nc.vo.sm.UserVO;
import nc.vo.trn.transmng.AggStapply;
import nc.vo.uap.pf.PFBatchExceptionInfo;
import nc.vo.uap.pf.PfProcessBatchRetObject;
import nc.vo.uap.rbac.constant.INCSystemUserConst;
import nc.vo.uif2.LoginContext;
import nc.vo.wfengine.definition.WorkflowTypeEnum;
import nccloud.commons.lang.ArrayUtils;
import nccloud.commons.lang.StringUtils;
import nccloud.dto.hryf.tools.HRYFConst;
import nccloud.dto.hryf.tools.HRYFWorkFlowHelper;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.container.SessionContext;
import nccloud.framework.web.ui.config.Area;
import nccloud.framework.web.ui.config.Item;
import nccloud.framework.web.ui.config.PageTemplet;
import nccloud.framework.web.ui.meta.FormItemMeta;
import nccloud.pubitf.riart.pflow.CloudPFlowContext;
import nccloud.pubitf.riart.pflow.ICloudScriptPFlowService;
import nccloud.vo.pf.flowinstance.NCCFlowInstanceVO;
import nccloud.web.hr.pub.HRCommonAction;
import nccloud.web.hr.pub.HRNccPubEnv;
import nccloud.web.hr.pub.HRNccQueryHelper;
import nccloud.web.hryf.pub.utils.PsndocTempUtils;
import nccloud.web.uapbd.commons.web.ParamUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

public abstract class HrYfBaseAction extends HRCommonAction {

	protected abstract String getBillType();

	protected abstract Class<? extends AggregatedValueObject> getAggVOClass();

	protected abstract Class<? extends SuperVO> getHeadVOClass();

	protected boolean isAutoGenerateBillCode(LoginContext context) throws BusinessException {

		BillCodeContext bcc = ServiceLocator.find(IBillcodeManage.class).getBillCodeContext(getBillType(), context.getPk_group(), context.getPk_org());
		if (bcc == null) {
			// 用户没有配置,则不自动生成
			return false;
		}
		return true;
	}

	protected boolean isBillCodeEditable(LoginContext context) throws BusinessException {

		BillCodeContext bcc = ServiceLocator.find(IBillcodeManage.class).getBillCodeContext(getBillType(), context.getPk_group(), context.getPk_org());
		if (bcc == null) {
			return true;
		}
		// return false;
		// 暂时在自动生成时不允许修改单据号,后面有问题再修改
		return bcc.isEditable();
	}

	protected String getBillCode(LoginContext context) throws BusinessException {
		BillCodeContext bcc = ServiceLocator.find(IBillcodeManage.class).getBillCodeContext(getBillType(), context.getPk_group(), context.getPk_org());
	    //没有编码返回null
		if (bcc == null) {
			return null;
		}
		//前编码返回前编码
		if(bcc.isPrecode()) {
			return ServiceLocator.find(IHrBillCode.class).getBillCode(getBillType(), context.getPk_group(), context.getPk_org());
		}else {//后编码返回点
			return ".";
		}
	}

	protected AggregatedValueObject getDefaultValue(LoginContext context, boolean isBatch) throws BusinessException {
		SuperVO headVO = null;
		AggregatedValueObject aggVO = null;

		try {
			aggVO = getAggVOClass().newInstance();
			headVO = getHeadVOClass().newInstance();
		} catch (InstantiationException ex) {
			Logger.error(ex.getMessage(), ex);
		} catch (IllegalAccessException ex) {
			Logger.error(ex.getMessage(), ex);
		}

		if (aggVO == null || headVO == null) {
			return null;
		}

		aggVO.setParentVO(headVO);

		// 设置界面默认值
		String appcode = SessionContext.getInstance().getAppcode();
		String appcodeTemp =  appcode.length()>8?appcode.substring(0,8):appcode;
		String pagecode =appcodeTemp + "nccloud";
		PageTemplet pt = PsndocTempUtils.getPageTemp(context, appcode, pagecode);
		String headcode = pt.getHeadcode();
		for (Area area : pt.getAllAreas()) {
			if (headcode.equals(area.getCode()) || headcode.equals(area.getRelationcode())) {
				for (Item item : area.getItems()) {
					if (item.getInitialvalue() != null && item.getInitialvalue().getValue() != null) {
						headVO.setAttributeValue(item.getCode(), item.getInitialvalue().getValue());
					}
				}
			}
		}

		NCObject ncObj = NCObject.newInstance(headVO);

		IFlowBizItf itf = ncObj.getBizInterface(IFlowBizItf.class);

		if (!isBatch) {
			// 批量新增的时候不设置编码
			headVO.setAttributeValue(itf.getColumnName(IFlowBizItf.ATTRIBUTE_BILLNO), getBillCode(context));
		}
		headVO.setAttributeValue(itf.getColumnName(IFlowBizItf.ATTRIBUTE_BILLMAKER), context.getPk_loginUser());
		headVO.setAttributeValue(itf.getColumnName(IFlowBizItf.ATTRIBUTE_APPROVESTATUS), IPfRetCheckInfo.NOSTATE);
		headVO.setAttributeValue(itf.getColumnName(IFlowBizItf.ATTRIBUTE_BILLTYPE), getBillType());

		return aggVO;
	}
	
	protected AggregatedValueObject getDefaultValue(LoginContext context, boolean isBatch, String appcode,
			String pagecode) throws BusinessException {
		if (StringUtils.isBlank(appcode) || StringUtils.isBlank(pagecode)) {
			return getDefaultValue(context, isBatch);
		}

		SuperVO headVO = null;
		AggregatedValueObject aggVO = null;

		try {
			aggVO = getAggVOClass().newInstance();
			headVO = getHeadVOClass().newInstance();
		} catch (InstantiationException ex) {
			Logger.error(ex.getMessage(), ex);
		} catch (IllegalAccessException ex) {
			Logger.error(ex.getMessage(), ex);
		}

		if (aggVO == null || headVO == null) {
			return null;
		}

		aggVO.setParentVO(headVO);

		// 设置界面默认值
		PageTemplet pt = PsndocTempUtils.getPageTemp(context, appcode, pagecode);
		String headcode = pt.getHeadcode();
		for (Area area : pt.getAllAreas()) {
			if (headcode.equals(area.getCode()) || headcode.equals(area.getRelationcode())) {
				for (Item item : area.getItems()) {
					if (item.getInitialvalue() != null && item.getInitialvalue().getValue() != null) {
						headVO.setAttributeValue(item.getCode(), item.getInitialvalue().getValue());
					}
				}
			}
		}

		NCObject ncObj = NCObject.newInstance(headVO);

		IFlowBizItf itf = ncObj.getBizInterface(IFlowBizItf.class);

		if (!isBatch) {
			// 批量新增的时候不设置编码
			headVO.setAttributeValue(itf.getColumnName(IFlowBizItf.ATTRIBUTE_BILLNO), getBillCode(context));
		}
		headVO.setAttributeValue(itf.getColumnName(IFlowBizItf.ATTRIBUTE_BILLMAKER), context.getPk_loginUser());
		headVO.setAttributeValue(itf.getColumnName(IFlowBizItf.ATTRIBUTE_APPROVESTATUS), IPfRetCheckInfo.NOSTATE);
		headVO.setAttributeValue(itf.getColumnName(IFlowBizItf.ATTRIBUTE_BILLTYPE), getBillType());

		return aggVO;
	}

	protected AggregatedValueObject getDefaultValue(LoginContext context) throws BusinessException {
		return getDefaultValue(context, false);
	}

	/**
	 * 得到当前单选数据
	 *
	 * @return
	 * @throws BusinessException
	 */
	protected AggregatedValueObject getSelectedData(ParamUtils param) throws BusinessException {
		String billid = param.getString("billid", null);
		if (StringUtils.isBlank(billid)) {
			throw new BusinessException(ResHelper.getString("6008hrgx", "06008hrgx0031")
			/* @res "billid 没传！" */);
		}
		return ServiceLocator.find(IMDPersistenceQueryService.class).queryBillOfVOByPK(getAggVOClass(), billid, true);
	}

	/**
	 * 得到当前勾选数据(多选)
	 *
	 * @return
	 * @throws BusinessException
	 */
	protected AggregatedValueObject[] getSelectedDatas(ParamUtils param) throws BusinessException {
		String[] billids = param.getStrings("billids");
		if (ArrayUtils.isEmpty(billids)) {
			throw new BusinessException(ResHelper.getString("6008hrgx", "06008hrgx0032")
			/* @res "billids 没传！" */);
		}
		Object[] objs = ServiceLocator.find(IMDPersistenceQueryService.class).queryBillOfVOByPKsWithOrder(getAggVOClass(), billids, true);
		AggregatedValueObject[] aggs = new AggregatedValueObject[objs.length];
		for (int i = 0; i < objs.length; i++) {
			aggs[i] = (AggregatedValueObject) objs[i];
		}
		return aggs;
	}

	/**
	 * 提交校验,入职与离职使用
	 *
	 * @return
	 * @throws BusinessException
	 */
	protected PfProcessBatchRetObject submitValidation(AggregatedValueObject... pfAggVOs) throws BusinessException {
		PFBatchExceptionInfo exInfo = new PFBatchExceptionInfo();
		ArrayList<AggregatedValueObject> al = new ArrayList<AggregatedValueObject>();

		Map<String, AggregatedValueObject> mapDBVO = queryByPks(pfAggVOs);

		for (int i = 0; i < pfAggVOs.length; i++) {
			AggregatedValueObject dbVO = mapDBVO.get(pfAggVOs[i].getParentVO().getPrimaryKey());

			if (dbVO == null) {
				exInfo.putErrorMessage(i, pfAggVOs[i], ResHelper.getString("6001pf", "06001pf0053")
				/* @res "单据不存在" */);
				continue;
			}

			NCObject dbObj = NCObject.newInstance(dbVO);
			IFlowBizItf flowBiz = dbObj.getBizInterface(IFlowBizItf.class);

			if (IPfRetCheckInfo.NOSTATE != flowBiz.getApproveStatus()) {
				exInfo.putErrorMessage(i, dbVO, ResHelper.getString("6001pf", "06001pf0075")
				/* @res "单据的的状态不为自由态" */);
				continue;
			}

			String billtype = StringUtils.isBlank(flowBiz.getTranstype()) ? flowBiz.getBilltype() : flowBiz.getTranstype();
			String paramType = ("6115".equals(billtype))?"TRN0006":"HI0011";
			UFBoolean isApprove = SysinitAccessor.getInstance().getParaBoolean(flowBiz.getPkorg(), paramType);// 入职是否审批流参数
			int flowType = (isApprove != null && isApprove.booleanValue())? WorkflowTypeEnum.Approveflow.getIntValue():WorkflowTypeEnum.Workflow.getIntValue();
			boolean blExistWorkFlow = ServiceLocator.find(IPFWorkflowQry.class).isExistWorkflowDefinition(billtype, flowBiz.getPkorg(), flowBiz.getBillMaker(),
					flowType);


			if (!blExistWorkFlow) {
				String msg = (isApprove != null && isApprove.booleanValue())? ResHelper.getString("6008hrgx", "06008hrgx0063") :ResHelper.getString("6008hrgx", "06008hrgx0033");
				exInfo.putErrorMessage(i, dbVO, msg
				/* @res "没有针对当前提交人的工作流" */);
				continue;
			}
		
			
			
			
			al.add(pfAggVOs[i]);
		}

		return new PfProcessBatchRetObject(al.toArray(new AggregatedValueObject[0]), exInfo);
	}

	protected Map<String, AggregatedValueObject> queryByPks(AggregatedValueObject... pfAggVOs) throws BusinessException {
		List<String> strPks = new ArrayList<String>();

		for (int i = 0; i < pfAggVOs.length; i++) {
			strPks.add(pfAggVOs[i].getParentVO().getPrimaryKey());
		}

		ArrayList dbVOs = (ArrayList) ServiceLocator.find(IMDPersistenceQueryService.class).queryBillOfVOByPKs(pfAggVOs[0].getClass(), strPks.toArray(new String[strPks.size()]),
				true);

		Map<String, AggregatedValueObject> mapResult = new HashMap<String, AggregatedValueObject>();

		for (Object dbVO : dbVOs) {
			mapResult.put(((AggregatedValueObject) dbVO).getParentVO().getPrimaryKey(), (AggregatedValueObject) dbVO);
		}

		return mapResult;
	}

	protected boolean isBillCanEdit(SuperVO headVO) throws BusinessException {
		if (headVO == null) {
			return false;
		}
		Integer intApproveState = getApproveState(headVO);

		if (intApproveState == null) {
			return true;
		}

		// 如果是编写中，并且登录人是制单人，就可以修改单据
		if (IPfRetCheckInfo.NOSTATE == intApproveState && isBillMaker(headVO)) {
			return true;
		}

		// 审批进行中的单据，如果登录人是当前审批人，可以修改单据
		if (IPfRetCheckInfo.COMMIT == intApproveState || IPfRetCheckInfo.GOINGON == intApproveState) {
			return isCheckman(headVO);
		}

		return false;
	}

	protected Integer getApproveState(SuperVO headVO) {
		NCObject ncObj = NCObject.newInstance(headVO);
		IFlowBizItf itf = ncObj.getBizInterface(IFlowBizItf.class);
		Integer intApproveState = itf.getApproveStatus();
		return intApproveState;
	}

	/*********************************************************************************************************
	 * 检查是否是制单人<br>
	 * Created on 2006-11-22 12:40:32<br>
	 *
	 * @author Rocex Wang
	 * @param headVO
	 * @return boolean true：是制单人 或者 没有指定制单人字段名 或者 单据没有制单人
	 * @throws BusinessException
	 ********************************************************************************************************/
	protected boolean isBillMaker(SuperVO headVO) throws BusinessException {
		NCObject ncObj = NCObject.newInstance(headVO);
		IFlowBizItf itf = ncObj.getBizInterface(IFlowBizItf.class);
		if (itf.getBillMaker() == null) {
			return false;
		}
		return isBillMaker(itf.getBillMaker());
	}

	/***************************************************************************
	 * <br>
	 * Created on 2011-3-20 15:47:11<br>
	 *
	 * @param strBillMaker
	 *            制单人主键
	 * @return boolean true：是制单人 或者 没有指定制单人字段名 或者 单据没有制单人
	 * @author Rocex Wang
	 ***************************************************************************/
	protected boolean isBillMaker(String strBillMaker) {
		// 当前用户或系统用户
		return HRNccPubEnv.getPk_user().equals(strBillMaker) || INCSystemUserConst.NC_USER_PK.equals(strBillMaker);
	}

	/****************************************************************************
	 * 检查当前登录人是不是选定录用单的当前审批人
	 *
	 * @param headvo
	 * @return boolean
	 * @throws BusinessException
	 ***************************************************************************/
	protected boolean isCheckman(SuperVO headvo) throws BusinessException {
		// 如果是需要审批的，需要根据当前的审批人来决定是否可以修改单据
		NCObject ncObj = NCObject.newInstance(headvo);
		IFlowBizItf itf = ncObj.getBizInterface(IFlowBizItf.class);
		String billtype = StringUtils.isBlank(itf.getTranstype()) ? itf.getBilltype() : itf.getTranstype();
		return ServiceLocator.find(IPFWorkflowQry.class).isCheckman(itf.getBillId(), billtype, HRNccPubEnv.getPk_user());
	}

	/**
	 * 批量执行提交/收回/删除动作
	 *
	 * @param objs
	 * @param actionCode
	 * @throws BusinessException
	 */
	protected Object batchRunAction(ParamUtils param, AggregatedValueObject[] bills, String actionCode) throws BusinessException {
		if (!ArrayUtils.contains(new String[] { IPFACTION.RECALL, IPFACTION.START, IPFACTION.COMMIT, IPFACTION.DELETE }, actionCode)) {
			return "success";
		}
		PfProcessBatchRetObject validateRetObj = actionValidation(bills);

		if (validateRetObj == null) {
			return "success";
		}

		if (validateRetObj.getRetObj() == null || validateRetObj.getRetObj().length == 0) {
			// 状态校验都没有通过
			String errStr = validateRetObj.getExceptionMsg();
			if (StringUtils.isEmpty(errStr)) {
				return "success";
			}
			throw new ValidationException(errStr);
		}

		AggregatedValueObject[] passObjs = null;
		if (validateRetObj.getRetObj() != null && validateRetObj.getRetObj().length > 0) {
			passObjs = (AggregatedValueObject[]) validateRetObj.getRetObj();
		}

		String message = "";
		PfProcessBatchRetObject validateRetObj2 = null;
		HashMap result = new HashMap<>();
		try {
			CloudPFlowContext flowContext = new CloudPFlowContext();
			flowContext.setActionName(actionCode);
			flowContext.setBillType(getBillType());
			flowContext.setBillVos(passObjs);
			flowContext.setTrantype((String) bills[0].getParentVO().getAttributeValue("transtype"));
			HashMap<Object, Object> eParam = new HashMap<Object, Object>();
			Object content = null;
			if (IPFACTION.COMMIT.equals(actionCode) || IPFACTION.START.equals(actionCode)) {
				content = param.get("content");
				if (content != null) {
					eParam.put("content", content);
				}
			}
			flowContext.seteParam(eParam);
			ICloudScriptPFlowService service = ServiceLocator.find(ICloudScriptPFlowService.class);
			Object[] objs = service.exeScriptPFlow(flowContext);
			Object obj = objs[0];
			if ((IPFACTION.COMMIT.equals(actionCode) || IPFACTION.START.equals(actionCode)) && content == null) {
				if (obj instanceof Map && ((Map<?, ?>) obj).get(PfUtilBaseTools.PARAM_WORKFLOWTYPE) != null
						&& (PfUtilBaseTools.PARAM_APPROVEFLOW.equals(String.valueOf(((Map<?, ?>) obj).get(PfUtilBaseTools.PARAM_WORKFLOWTYPE)))
								|| PfUtilBaseTools.PARAM_WORKFLOW.equals(String.valueOf(((Map<?, ?>) obj).get(PfUtilBaseTools.PARAM_WORKFLOWTYPE))))) {
					Map<String, Object> map = (Map<String, Object>) obj;
					if (map.get(PfUtilBaseTools.PARAM_WORKFLOWTYPE) != null) {
						result.put("content", map);
						return result;
					}
				}
			}

			if (obj instanceof PfProcessBatchRetObject) {
				validateRetObj2 = (PfProcessBatchRetObject) obj;
			}
		} catch (Exception e) {
			Logger.error(message, e);
			message = e.getMessage();
			if (message == null && e.getCause() != null) {
				message = e.getCause().getMessage();
				if (message == null && e.getCause().getCause() != null) {
					message = e.getCause().getCause().getMessage();
					if (message == null && e.getCause().getCause().getCause() != null) {
						message = e.getCause().getCause().getCause().getMessage();
					}
				}
			}
		}

		String errMsg = "";
		String msg1 = validateRetObj.getExceptionMsg();
		String msg3 = validateRetObj2 == null ? "" : validateRetObj2.getExceptionMsg();
		String msg2 = message;

		if ((StringUtils.isNotBlank(msg1)) || (StringUtils.isNotBlank(msg2)) || (StringUtils.isNotBlank(msg3))) {
			errMsg = new StringBuilder().append((StringUtils.isBlank(msg1)) ? "" : (msg1 + '\n')).append((StringUtils.isBlank(msg3)) ? "" : (msg3 + '\n'))
					.append((StringUtils.isBlank(msg2)) ? "" : msg2).toString();
		}

		if (StringUtils.isBlank(errMsg)) {
			// 返回提交后状态为提交的数据
			return "success";
		}

		result.put("errorMsg", errMsg);
		return result;
	}
	/**
	 * 批量执行提交/收回/删除动作（此方法解决流程中提交至驳回环节问题）
	 *
	 * @param objs
	 * @param actionCode
	 * @throws BusinessException
	 */
	protected Object batchRunAction2Rebut(ParamUtils param, AggregatedValueObject[] bills, String actionCode) throws BusinessException {
		if (!ArrayUtils.contains(new String[] { IPFACTION.RECALL, IPFACTION.START, IPFACTION.COMMIT, IPFACTION.DELETE }, actionCode)) {
			return "success";
		}
		PfProcessBatchRetObject validateRetObj = actionValidation(bills);

		if (validateRetObj == null) {
			return "success";
		}

		if (validateRetObj.getRetObj() == null || validateRetObj.getRetObj().length == 0) {
			// 状态校验都没有通过
			String errStr = validateRetObj.getExceptionMsg();
			if (StringUtils.isEmpty(errStr)) {
				return "success";
			}
			throw new ValidationException(errStr);
		}

		AggregatedValueObject[] passObjs = null;
		if (validateRetObj.getRetObj() != null && validateRetObj.getRetObj().length > 0) {
			passObjs = (AggregatedValueObject[]) validateRetObj.getRetObj();
		}
        String totalRetMsg = "";
        HashMap result = new HashMap<>();
		for(int i=0;i<passObjs.length;i++) {
			//校验是否是驳回单据
			Boolean rebutFlag =  HRYFWorkFlowHelper.isRebutBill(passObjs[i],actionCode);
			//根据标志返回动作编码
			String pActionCode = HRYFWorkFlowHelper.getActionCodeByIsRebut(rebutFlag, actionCode);
			String message = "";
			PfProcessBatchRetObject validateRetObj2 = null;
			
			try {
				CloudPFlowContext flowContext = new CloudPFlowContext();
				flowContext.setActionName(pActionCode);
				flowContext.setBillType(getBillType());
				flowContext.setBillVos(passObjs);
				flowContext.setTrantype((String) bills[0].getParentVO().getAttributeValue("transtype"));
				HashMap<Object, Object> eParam = new HashMap<Object, Object>();
				Object content = null;
				if (IPFACTION.COMMIT.equals(pActionCode) || IPFACTION.START.equals(pActionCode)) {
					content = param.get("content");
					if (content != null) {
						eParam.put("content", content);
					}
				}
				flowContext.seteParam(eParam);
				ICloudScriptPFlowService service = ServiceLocator.find(ICloudScriptPFlowService.class);
				Object[] objs = service.exeScriptPFlow(flowContext);
				Object obj = objs[0];
				if ((IPFACTION.COMMIT.equals(pActionCode) || IPFACTION.START.equals(pActionCode)) && content == null) {
					if (obj instanceof Map && ((Map<?, ?>) obj).get(PfUtilBaseTools.PARAM_WORKFLOWTYPE) != null
							&& (PfUtilBaseTools.PARAM_APPROVEFLOW.equals(String.valueOf(((Map<?, ?>) obj).get(PfUtilBaseTools.PARAM_WORKFLOWTYPE)))
									|| PfUtilBaseTools.PARAM_WORKFLOW.equals(String.valueOf(((Map<?, ?>) obj).get(PfUtilBaseTools.PARAM_WORKFLOWTYPE))))) {
						Map<String, Object> map = (Map<String, Object>) obj;
						// 如果是指派并且是多个单据时，给出提示，需要逐个提交不能批量提交
						if (map.get(PfUtilBaseTools.PARAM_WORKFLOWTYPE) != null ) {
							if(passObjs.length >1) {
								result.put("errorMsg",
										ResHelper.getString("6008hryf", "06008hryf-0000060"))/* 此流程支持指派，请逐个提交！ */;
								return result;
							}
							result.put("content", map);
							return result;
						}
					}
				}
	
				if (obj instanceof PfProcessBatchRetObject) {
					validateRetObj2 = (PfProcessBatchRetObject) obj;
				}
			} catch (Exception e) {
				Logger.error(message, e);
				message = e.getMessage();
				if (message == null && e.getCause() != null) {
					message = e.getCause().getMessage();
					if (message == null && e.getCause().getCause() != null) {
						message = e.getCause().getCause().getMessage();
						if (message == null && e.getCause().getCause().getCause() != null) {
							message = e.getCause().getCause().getCause().getMessage();
						}
					}
				}
			}
	
			String errMsg = "";
			String msg1 = validateRetObj.getExceptionMsg();
			String msg3 = validateRetObj2 == null ? "" : validateRetObj2.getExceptionMsg();
			String msg2 = message;
	
			if ((StringUtils.isNotBlank(msg1)) || (StringUtils.isNotBlank(msg2)) || (StringUtils.isNotBlank(msg3))) {
				errMsg = new StringBuilder().append((StringUtils.isBlank(msg1)) ? "" : (msg1 + '\n')).append((StringUtils.isBlank(msg3)) ? "" : (msg3 + '\n'))
						.append((StringUtils.isBlank(msg2)) ? "" : msg2).toString();
			}
	
			if(StringUtils.isNotBlank(errMsg)) {
				totalRetMsg+=errMsg;
			}
			
		}
		result.put("errorMsg", totalRetMsg);
		return result;
	}

	
	/**
	 * 动作执行前校验
	 *
	 * @param bills
	 * @return
	 */
	protected PfProcessBatchRetObject actionValidation(AggregatedValueObject[] bills) throws BusinessException {
		// 提交/收回/删除 需要重写此方法校验数据
		return null;
	}

	/**
	 * 发送通知-入职/离职/调配/兼职/转正
	 *
	 * @param Msgrescode
	 * @return
	 * @throws ValidationException
	 */
	protected Object sendMsgAction(AggregatedValueObject[] selData, String msgRescode) throws BusinessException {

		String errMsg = ResHelper.getString("6007entry", "06007entry0026");/* "发送通知失败:下列单据的状态不是审批通过、已执行或审批不通过,不能发送通知." */
		String billno = "";
		for (AggregatedValueObject agg : selData) {
			NCObject ncObj = NCObject.newInstance(agg);
			IFlowBizItf itf = ncObj.getBizInterface(IFlowBizItf.class);

			if ((HICommonValue.msgcode_trns.equals(msgRescode) /* || HICommonValue.msgcode_dimission.equals(msgRescode) */ || HICommonValue.msgcode_part.equals(msgRescode))
					&& (HRConstEnum.EXECUTED != itf.getApproveStatus() && IPfRetCheckInfo.PASSING != itf.getApproveStatus()) && IPfRetCheckInfo.NOPASS != itf.getApproveStatus()) {
				// 调配离职兼职执行后或审批不通过发送通知
				billno += '\n' + itf.getBillNo();
			} else if ((/* HICommonValue.msgcode_entry.equals(msgRescode) || */ HICommonValue.msgcode_zhuanzheng.equals(msgRescode))
					&& (HRConstEnum.EXECUTED != itf.getApproveStatus() && IPfRetCheckInfo.PASSING != itf.getApproveStatus()) && IPfRetCheckInfo.NOPASS != itf.getApproveStatus()) {
				// 入职转正执行后或审批不通过发送通知
				billno += '\n' + itf.getBillNo();
			}
		}
		if (!StringUtils.isBlank(billno)) {
			throw new ValidationException(errMsg + billno);
		}
		// 给HRBusiMessageVO赋值，消息信息从此处取
		HRBusiMessageVO[] msgInfoVOs = new HRBusiMessageVO[selData.length];

		for (int i = 0; i < selData.length; i++) {
			msgInfoVOs[i] = new HRBusiMessageVO();
			msgInfoVOs[i].setBillVO((Object) selData[i].getParentVO());
			msgInfoVOs[i].setMsgrescode(msgRescode);
			msgInfoVOs[i].setPkorgs(new String[] { (String) selData[i].getParentVO().getAttributeValue("pk_org") });
			msgInfoVOs[i].setSender(HRNccPubEnv.getPk_user());
			msgInfoVOs[i].setSendtime(HRNccPubEnv.getBizTime());

			String pk_psndoc = (String)selData[i].getParentVO().getAttributeValue("pk_psndoc");
			// 设置发送邮箱
			UserVO[] userVO = (UserVO[])  ServiceLocator.find(IPersistenceRetrieve.class).retrieveByClause(null, UserVO.class, " pk_base_doc = '" + pk_psndoc+"'" );
			if(userVO == null || userVO.length == 0){
				return null;
			}
			msgInfoVOs[i].setReceiverPkUsers(new String[]{userVO[0].getPrimaryKey()});
			PsndocVO psndocVO = (PsndocVO)  ServiceLocator.find(IPersistenceRetrieve.class).retrieveByPk(null, PsndocVO.class, pk_psndoc);
			if(psndocVO==null){
				return null;
			}
			String email = StringUtils.isEmpty(psndocVO.getEmail())?psndocVO.getSecret_email():psndocVO.getEmail();
			if (!StringUtils.isEmpty(email)) {
				msgInfoVOs[i].setReceiverEmails(new String[]{email});
			}
			msgInfoVOs[i].setBusiVarValues(createBusiVarValues(selData));
		}
		try {

			nc.itf.hr.message.IHRMessageSend messageSendService = ServiceLocator.find(nc.itf.hr.message.IHRMessageSend.class);
			messageSendService.sendBuziMessage_RequiresNew(msgInfoVOs);
			return ResHelper.getString("6001msgtmp", "06001msgtmp0033");/* @res "消息已发送！" */
		} catch (Exception ex) {
			String errMsgEx = ResHelper.getString("6001msgtmp", "06001msgtmp0044"/* @res "发送失败！" */);
			throw new BusinessRuntimeException(errMsgEx + "\r\n" + ex.getMessage(), ex);
		}
	}

	protected Hashtable<String, Object> createBusiVarValues(AggregatedValueObject[] aggvos) {
		return null;
	};

	protected String getBatchAddInSql(HRNccQueryHelper queryHelper) throws BusinessException {
		// 下面的代码原来有问题,改成调配记录查询的逻辑,再有问题再说
		FromWhereSQL fws = queryHelper.getQueryScheme().getTableJoinFromWhereSQL();
		String whereSql = fws.getWhere();
		String fromSql = fws.getFrom();

		fromSql = StringUtils.isBlank(fromSql) ? (" bd_psndoc inner join hi_psnjob on bd_psndoc.pk_psndoc = hi_psnjob.pk_psndoc ") : fromSql;

		fromSql = fromSql.indexOf("hi_psnjob") < 0 ? (fromSql + " inner join hi_psnjob on bd_psndoc.pk_psndoc = hi_psnjob.pk_psndoc ") : fromSql;

		if (StringUtils.isBlank(whereSql)) {
			whereSql = " 1 = 1 ";
		}

		LoginContext context = new LoginContext();
		context.setPk_group(HRNccPubEnv.getPk_group());
		if (!ServiceLocator.find(IPsndocQryService.class).getValueOFParaDeployCadre(context)) {
			whereSql += " and bd_psndoc.iscadre != 'Y'";
		}

		String jobAlias = fws.getTableAliasByAttrpath("hi_psnjob");
		jobAlias = StringUtils.isBlank(jobAlias) ? "hi_psnjob" : jobAlias;

		String insql = " select " + jobAlias + ".pk_psnjob from " + fromSql + " where " + whereSql;
		return insql;
	}

	/**
	 * 将变动的字段转为前端喜欢的格式
	 *
	 * @param itemList
	 * @return
	 */
	protected Map getItemMap(List<FormItemMeta> itemList) {
		Map<String, Boolean> visibleMap = new HashMap<String, Boolean>();
		Map<String, Boolean> requiredMap = new HashMap<String, Boolean>();
		Map<String, Boolean> disableMap = new HashMap<String, Boolean>();
		Map<String, Object> returnMap = new HashMap<String, Object>();
		if (itemList != null && itemList.size() > 0) {
			for (FormItemMeta item : itemList) {
				visibleMap.put(item.getAttrcode(), item.isVisible());
				requiredMap.put(item.getAttrcode(), item.isRequired());
				disableMap.put(item.getAttrcode(), item.isDisabled());
			}
		}
		returnMap.put("visible", visibleMap);
		returnMap.put("required", requiredMap);
		returnMap.put("disable", disableMap);
		return returnMap;
	}
	/**
	 * 检测入离职是否是审批流接口
	 *
	 */
	protected Boolean CheckIsApprFlowAction(ParamUtils param,LoginContext context) throws Exception {
        // 入离职是否审批流参数【HI0011，TRN0006】，默认是入职   60092010（入职），60092060（离职）
		String appCode = param.getString("appCode", null);
		String billid = param.getString("billid", null);
		if(appCode ==null || billid==null){
			throw new BusinessException(ResHelper.getString("6008hrgx", "06008hrgx0064")/* @res "appCode参数错误错误！" */);
		}
		
		AggregatedValueObject agg =  ServiceLocator.find(IMDPersistenceQueryService.class).queryBillOfVOByPK(AggStapply.class , billid, true);
		Integer approve_state = (Integer)agg.getParentVO().getAttributeValue("approve_state");
		if(IPfRetCheckInfo.NOSTATE == approve_state){
			String isApproveParam ="";
			if(appCode.startsWith(HRYFConst.APPCODE_ENTRYAPPLY)){
				isApproveParam = "HI0011";
			}else if(appCode.startsWith(HRYFConst.APPCODE_DIMISSAPPLY)){
				isApproveParam = "TRN0006";
			}else{
				throw new BusinessException(ResHelper.getString("6008hrgx", "06008hrgx0064")/* @res "appCode参数错误错误！" */);
			}
			UFBoolean isApprove = SysinitAccessor.getInstance().getParaBoolean(context.getPk_org(), isApproveParam);
			return  isApprove.booleanValue();
		}else{
			String condition = " 1=1 ";
			condition += " and  billid = '" +billid +"'  and workflow_type in ('2','4')   order by startts desc ";
			NCCFlowInstanceVO[] ins = (NCCFlowInstanceVO[]) ServiceLocator.find(IPersistenceRetrieve.class).retrieveByClause(null, NCCFlowInstanceVO.class, condition);
			String workflow_type = ins[0].getWorkflow_type();
			if(WorkflowTypeEnum.Approveflow.getStrValue().equals(workflow_type)){
				return true;
			}else{
				return false;
			}
		}
	}
	
//	protected String isApproveEdit(AggregatedValueObject obj) throws BusinessException{
//		String billtype = (String)obj.getParentVO().getAttributeValue("pk_billtype");
//		TrnstypeVO vo = null;
//		if("6111".equals(billtype)){
//			 vo = (TrnstypeVO)ServiceLocator.find(IPersistenceRetrieve.class).retrieveByPk(null, TrnstypeVO.class,"1002Z710000000008GSF");
//		}else if("6113".equals(billtype)){
//			String pk_trnstype = (String)obj.getParentVO().getAttributeValue("pk_trnstype");
//			if(StringUtils.isNotEmpty(pk_trnstype)){
//				 vo = (TrnstypeVO)ServiceLocator.find(IPersistenceRetrieve.class).retrieveByPk(null, TrnstypeVO.class,pk_trnstype);
//			}
//		}else if("6117".equals(billtype)){
//			vo = null;
//		}
//		if (vo==null || vo.getIsapproveedit() ==null){
//			return "N";
//		}else{
//			return vo.getIsapproveedit().toString();
//		}
//	}
	/**
	 * 返回是否是前编码（在确定有编码规则的情况下使用）
	 * @param billType
	 * @param pk_group
	 * @param pk_org
	 * @return
	 * @throws BusinessException
	 */
	protected boolean checkIsPreBillCode(String billType, String pk_group, String pk_org) throws BusinessException {
		BillCodeContext billCodeContext = HiCacheUtils.getBillCodeContext(billType, pk_group, pk_org);
		return billCodeContext.isPrecode();
	}
}
