package nccloud.impl.hryf.psninfoapprove.impl;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.hr.frame.persistence.HrBatchService;
import nc.hr.utils.CommonUtils;
import nc.hr.utils.HRFileUtils;
import nc.hr.utils.PubEnv;
import nc.hr.utils.ResHelper;
import nc.hr.utils.StringPiecer;
import nc.itf.hi.IPersonRecordService;
import nc.itf.hi.IPsndocQryService;
import nc.itf.hi.IPsndocService;
import nc.itf.hr.frame.IPersistenceRetrieve;
import nc.itf.hr.frame.IPersistenceUpdate;
import nc.itf.hr.infoset.IInfoSetQry;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.generator.SequenceGenerator;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.md.innerservice.IMetaDataQueryService;
import nc.md.model.IAttribute;
import nc.md.model.IBean;
import nc.pub.tools.HiSQLHelper;
import nc.pub.tools.VOUtils;
import nc.ui.bd.ref.IRefConst;
import nc.vo.bd.address.AddressVO;
import nc.vo.bd.pub.NODE_TYPE;
import nc.vo.hi.psndoc.CapaVO;
import nc.vo.hi.psndoc.CertVO;
import nc.vo.hi.psndoc.CtrtVO;
import nc.vo.hi.psndoc.EnterQualCertVO;
import nc.vo.hi.psndoc.OtherCertVO;
import nc.vo.hi.psndoc.PartTimeVO;
import nc.vo.hi.psndoc.PsnJobVO;
import nc.vo.hi.psndoc.PsnOrgVO;
import nc.vo.hi.psndoc.PsnSuperVO;
import nc.vo.hi.psndoc.PsndocAggVO;
import nc.vo.hi.psndoc.PsndocVO;
import nc.vo.hi.psndoc.QulifyVO;
import nc.vo.hi.psndoc.TrainCertfileVO;
import nc.vo.hi.psndoc.TrainVO;
import nc.vo.hi.psndoc.WainfoVO;
import nc.vo.hr.infoset.InfoSetVO;
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.uif2.LoginContext;
import nc.vo.util.SqlWhereUtil;
import nccloud.commons.collections.CollectionUtils;
import nccloud.commons.collections.MapUtils;
import nccloud.commons.lang.ArrayUtils;
import nccloud.commons.lang.StringUtils;
import nccloud.dto.hryf.appconf.AppConfItemVO;
import nccloud.dto.hryf.appconf.AppConfSetVO;
import nccloud.dto.hryf.psninfo.PsnInfoApproveCheckEnum;
import nccloud.dto.hryf.psninfo.PsnInfoApproveVO;
import nccloud.itf.hryf.appconf.IAppconfService;
import nccloud.itf.hryf.psninfoapprove.IPsninfoApproveService;
import nccloud.vo.hr.json.HRJsonUtils;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 员工信息审核服务
 */
public class PsninfoApproveServiceImpl implements IPsninfoApproveService {

	private HrBatchService serviceTemplate;

	private HrBatchService getServiceTemplate() {
		if (serviceTemplate == null)
		{
			serviceTemplate = new HrBatchService("");
		}
		return serviceTemplate;
	}

	@Override
	public String[] queryPKsByCondition(String pk_org, String condition) throws BusinessException {
		StringBuffer sql = new StringBuffer();
		sql.append("select pk_psninfoapprove from hi_psninfoapp where 1=1 ");
		if (StringUtils.isNotBlank(pk_org)) {
			sql.append(" and pk_org = '" + pk_org + "' ");
		}
		if (StringUtils.isNotBlank(condition)) {
			sql.append(" and " + condition);
		}
		SqlWhereUtil sqlWhereUtil = new SqlWhereUtil(sql.toString());

		// 人员权限
		String psndocSql = HiSQLHelper.getPsnPowerSql(PubEnv.getPk_group(), "6007psnjob", IRefConst.DATAPOWEROPERATION_CODE,  "hi_psninfoapp");
		if (StringUtils.isNotBlank(psndocSql)) { 
			sqlWhereUtil.and(psndocSql);
		}
		String sqlCondition = sqlWhereUtil.getSQLWhere();
		@SuppressWarnings("unchecked")
		List<String> pkList = (List<String>) new BaseDAO().executeQuery(sqlCondition, new ColumnListProcessor());
		return CollectionUtils.isEmpty(pkList) ? null : pkList.toArray(new String[0]);
	}

	@Override
	public PsnInfoApproveVO[] queryByCondition(String condition) throws BusinessException {
		return getServiceTemplate().queryByCondition(PsnInfoApproveVO.class, condition);
	}

	@Override
	public PsnInfoApproveVO queryByPk(String pk) throws BusinessException {
		if (StringUtils.isBlank(pk))
		{
			return null;
		}
		return getServiceTemplate().queryByPk(PsnInfoApproveVO.class, pk);
	}

	@Override
	public PsnInfoApproveVO[] queryByPks(String[] pks) throws BusinessException {
		return getServiceTemplate().queryByPks(PsnInfoApproveVO.class, pks);
	}

	@Override
	public void delete(PsnInfoApproveVO[] vos) throws BusinessException {
		getServiceTemplate().delete(vos);
	}

	@Override
	public void deleteByPks(String[] pks) throws BusinessException {
		PsnInfoApproveVO[] vos = getServiceTemplate().queryByPks(PsnInfoApproveVO.class, pks);
		delete(vos);
	}
	
	@Override
	public void update(PsnInfoApproveVO[] vos, String[] selFields) throws BusinessException {
		NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, vos, selFields, null);
	}

	@Override
	public PsnInfoApproveVO[] doApprove(String[] pks, int checkstatus, String checknote) throws BusinessException {
		PsnInfoApproveVO[] vos = queryByPks(pks);
		if (ArrayUtils.isEmpty(vos))
		{
			return null;
		}
		// 查询人员
		String[] pk_psndocs = StringPiecer.getStrArrayDistinct(vos, PsnInfoApproveVO.PK_PSNJOB);
		PsndocAggVO[] psndocAggs = NCLocator.getInstance().lookup(IPsndocQryService.class).queryPsndocVOByPks(pk_psndocs);
		PsndocVO[] psndocVOs = CommonUtils.getParentVOArrayFromAggVOs(PsndocVO.class, psndocAggs);
		Map<String, PsndocVO> psndocMap = CommonUtils.toMap(PsndocVO.PK_PSNDOC, psndocVOs);
		// 赋值并保存人员信息 -- 因人员保存要逐个校验，所以在循环内保存
		IPersistenceUpdate psndocUpdateService = NCLocator.getInstance().lookup(IPersistenceUpdate.class);
		for (PsnInfoApproveVO vo : vos) {
			if (PsnInfoApproveCheckEnum.UNCHECK.getIndex() != vo.getCheckstatus())
			{
				throw new BusinessException(ResHelper.getString("6008hrgx", "06008hrgx0053")/* @res "记录已被审核，无法再次审核！" */);
			}
			vo.setPk_checkuser(PubEnv.getPk_user());
			vo.setCheckdate(PubEnv.getServerLiteralDate());
			vo.setCheckstatus(checkstatus);
			vo.setChecknote(checknote);
			vo.setModifier(PubEnv.getPk_user());
			vo.setModifiedtime(PubEnv.getServerTime());
			if(checkstatus == 2 ){
				//审批不通过
				continue;
			}
			// 收集修改后信息
			Object value = vo.getNewvalue();
			//收集修改前的信息
			Object oldvalue = vo.getOldvalue();
			if (value == null)
			{
				continue;
			}
			String voStr = new String((byte[]) value);
			String oldStr = new String((byte[]) oldvalue);
			InfoSetVO infoset = (InfoSetVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, InfoSetVO.class, vo.getPk_infoset());
			String tableCode = infoset.getInfoset_code();
			// 保存人员子表
			if (!PsndocVO.getDefaultTableName().equals(tableCode)) {
				IBean bean = NCLocator.getInstance().lookup(IMetaDataQueryService.class).getBeanByName("hrhi", tableCode);
				Class<?> clazz = null;
				try {
					clazz = Class.forName(bean.getFullClassName());
				} catch (ClassNotFoundException ex) {
					Logger.error(ex);
				}
				SuperVO[] subVOs = HRJsonUtils.fromJson(voStr, Array.newInstance(clazz, 1).getClass());
				updateSubPsnInfo(vo.getPk_psndoc(), vo.getPk_infoset(), vo.getPk_org(), subVOs);
				continue;
			}
			// 保存人员主表
			PsndocVO psndocVO = psndocMap.get(vo.getPk_psndoc());
			Map<String, Object> valueMap = HRJsonUtils.fromJson(voStr, Map.class);
			Map<String, Object> oldMap = HRJsonUtils.fromJson(oldStr, Map.class);
			if (oldMap.size() > valueMap.size()) {
				//变更后的值存在清空的情况
				for (String k : oldMap.keySet()) {
					for (String n : valueMap.keySet()) {
						if (!k.equals(n)) {
							valueMap.put(k, null);
						}
					}
				}
			}
			PsndocVO newPsndocVO = HRJsonUtils.fromJson(voStr, PsndocVO.class);
			String[] updateFlds =  valueMap.keySet().toArray(new String[0]);
			for (String key : valueMap.keySet()) {
				psndocVO.setAttributeValue(key, newPsndocVO.getAttributeValue(key));
				if(PsndocVO.PHOTO.equals(key)){
					//照片字段特殊处理
					if(newPsndocVO.getPhoto()!=null){
						if(newPsndocVO.getPhoto() instanceof String){
							psndocVO.setPhoto(HRFileUtils.base64Decode(psndocVO.getPhoto().toString().replaceAll("\r|\n", "")));
						}
						psndocVO.setPreviewphoto(VOUtils.transPreviewPhoto((byte[]) psndocVO.getPhoto()));
					}
					else{
						psndocVO.setPreviewphoto(null);
					}
					updateFlds = (String[]) ArrayUtils.add(updateFlds, PsndocVO.PREVIEWPHOTO);
				}
			}
			psndocUpdateService.updateVO(null, psndocVO, updateFlds, null);
		}
		// 保存
		return getServiceTemplate().update(true, vos);
	}

	@Override
	public String savePsndocVO(String pk_org, PsndocVO psndocVO, boolean needCheck) throws BusinessException {
		if (StringUtils.isBlank(pk_org) || psndocVO == null)
		{
			return null;
		}
		// 个人信息审核配置
		List<AppConfSetVO> setVOs = NCLocator.getInstance().lookup(IAppconfService.class).queryAppConfSetVOByCond(pk_org, PsndocVO.getDefaultTableName());
		if (CollectionUtils.isEmpty(setVOs))
		{
			return null;
		}
		// 原基本信息
		PsndocAggVO dbPsndocVOAgg = NCLocator.getInstance().lookup(IPsndocQryService.class).queryPsndocVOByPk(psndocVO.getPk_psndoc());
		if (dbPsndocVOAgg == null)
		{
			return null;
		}
		PsndocVO dbPsndocVO = dbPsndocVOAgg.getParentVO();
		AppConfSetVO setVO = setVOs.get(0);
		List<AppConfItemVO> itemList = setVO.getItemList();
		if (CollectionUtils.isEmpty(itemList))
		{
			return null;
		}
		Map<String, Object> oldValueMap = new HashMap<String, Object>();
		Map<String, Object> newValueMap = new HashMap<String, Object>();
		boolean hasDirectUpdate = false; // 是否有直接更新的数据
		boolean isIndoc = dbPsndocVO.getPsnOrgVO().getIndocflag() != null && dbPsndocVO.getPsnOrgVO().getIndocflag().booleanValue(); // 是否正式员工
		for (AppConfItemVO item : itemList) {
			String fieldCode = item.getInfoset_item_code();
			// 值相同不用处理
			if (isSameValue(psndocVO, dbPsndocVO, fieldCode))
			{
				continue;
			}
			// 是否需要审核 -- 未转档人员均不需要审核
			boolean isApprove = isIndoc && item.getEntry_approval() != null && item.getEntry_approval().booleanValue();
			if (!isApprove) {
				// 不需要审核直接更新数据库信息
				dbPsndocVO.setAttributeValue(fieldCode, psndocVO.getAttributeValue(fieldCode));
				if(PsndocVO.PHOTO.equals(fieldCode)){
					//照片字段特殊处理
					if(dbPsndocVO.getPhoto()!=null){
						if(dbPsndocVO.getPhoto() instanceof String){
							dbPsndocVO.setPhoto(HRFileUtils.base64Decode(dbPsndocVO.getPhoto().toString().replaceAll("\r|\n", "")));
						}
						dbPsndocVO.setPreviewphoto(VOUtils.transPreviewPhoto((byte[]) dbPsndocVO.getPhoto()));
					}
					else{
						dbPsndocVO.setPreviewphoto(null);
					}
				}
				hasDirectUpdate = true;
				continue;
			}
			// 需要审核的记录下来，后面处理
			if ("addr".equals(fieldCode) && dbPsndocVO.getAttributeValue(fieldCode) == null) {
				oldValueMap.put(fieldCode, null);
			} else {
				oldValueMap.put(fieldCode, "addr".equals(fieldCode) ? dbPsndocVO.getAttributeValue(fieldCode).toString().substring(0,16) + "ABCD" : dbPsndocVO.getAttributeValue(fieldCode));
			}
			newValueMap.put(fieldCode, psndocVO.getAttributeValue(fieldCode));
		}
		// 处理审核信息
		if (MapUtils.isNotEmpty(oldValueMap) || MapUtils.isNotEmpty(newValueMap)) {
			if (needCheck)
			{
				return "needCheck";
			}
			oldValueMap.put(PsndocVO.PK_PSNDOC, psndocVO.getPk_psndoc());
			newValueMap.put(PsndocVO.PK_PSNDOC, psndocVO.getPk_psndoc());
			for (String key : newValueMap.keySet()) {
				if (newValueMap.get(key) == null) {
					newValueMap.put(key, "");
				}
			}
			String oldValue = HRJsonUtils.toJson(oldValueMap);
			String newValue = HRJsonUtils.toJson(newValueMap);
			savePsnInfoApproveVO(oldValue, newValue, setVO, dbPsndocVO);
		}
		// 直接更新
		if (hasDirectUpdate) {
			NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVO(null, dbPsndocVO, null, null);
		}
		return null;
	}
	
	/**
	 * 比较两VO中指定属性值是否一致
	 * 
	 * @param vo1
	 * @param vo2
	 * @param fieldCode
	 * @return
	 */
	private boolean isSameValue(SuperVO vo1, SuperVO vo2, String fieldCode) {
		Object val1 = vo1.getAttributeValue(fieldCode);
		Object val2 = vo2.getAttributeValue(fieldCode);
		//家庭地址需要特殊处理
		if ("addr".equals(fieldCode) && val1 != null) {
			try {
				AddressVO oldAddressVO = (AddressVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, AddressVO.class, val1.toString().substring(0, 16) + "ABCD");
				AddressVO newAddressVO = (AddressVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, AddressVO.class, val1.toString());
				if (oldAddressVO != null && newAddressVO != null) {
					if (((oldAddressVO.getCountry() == null && newAddressVO.getCountry() == null) || (oldAddressVO.getCountry() != null && newAddressVO.getCountry() != null && (oldAddressVO.getCountry().equals(newAddressVO.getCountry()))))
							&& ((oldAddressVO.getProvince() == null && newAddressVO.getProvince() == null) || (oldAddressVO.getProvince() != null && newAddressVO.getProvince() != null && (oldAddressVO.getProvince().equals(newAddressVO.getProvince()))))
							&& ((oldAddressVO.getCity() == null && newAddressVO.getCity() == null) || (oldAddressVO.getCity() != null && newAddressVO.getCity() != null && (oldAddressVO.getCity().equals(newAddressVO.getCity()))))
							&& ((oldAddressVO.getVsection() == null && newAddressVO.getVsection() == null) || (oldAddressVO.getVsection() != null && newAddressVO.getVsection() != null && (oldAddressVO.getVsection().equals(newAddressVO.getVsection()))))
							&& ((oldAddressVO.getDetailinfo() == null && newAddressVO.getDetailinfo() == null) || (oldAddressVO.getDetailinfo() != null && newAddressVO.getDetailinfo() != null && (oldAddressVO.getDetailinfo().equals(newAddressVO.getDetailinfo()))))
							&& ((oldAddressVO.getPostcode() == null && newAddressVO.getPostcode() == null) || (oldAddressVO.getPostcode() != null && newAddressVO.getPostcode() != null && (oldAddressVO.getPostcode().equals(newAddressVO.getPostcode()))))) {
						return true;
					}
				}
				return false;
			} catch (BusinessException e) {
				e.printStackTrace();
			}
		}
		if (val1 instanceof byte[]) {
			val1 = HRFileUtils.base64Encode((byte[]) val1);
		}
		if (val2 instanceof byte[]) {
			val2 = HRFileUtils.base64Encode((byte[]) val2);
		}
		if (val1 == null && val2 == null)
		{
			return true;
		}
		return val1 != null && val1.equals(val2);
	}

	/**
	 * 保存员工基本信息--生成hi_psninfoapp记录
	 * 
	 * @param oldValue
	 * @param newValue
	 * @param appConfSet
	 * @param psndocVO
	 * @return
	 * @throws BusinessException
	 */
	private PsnInfoApproveVO savePsnInfoApproveVO(String oldValue, String newValue, AppConfSetVO appConfSet, PsndocVO psndocVO) throws BusinessException {
		PsnInfoApproveVO vo = new PsnInfoApproveVO();
		// 人员最新任职vo
		PsnJobVO psnJobVO = psndocVO.getPsnJobVO();
		vo.setPk_group(PubEnv.getPk_group());
		vo.setPk_org(psnJobVO != null ? psnJobVO.getPk_hrorg() : null);
		vo.setPk_psnjob(psnJobVO != null ? psnJobVO.getPk_psnjob() : null);
		vo.setPk_applicant(PubEnv.getPk_user()); // 申请人主键（用户主键）
		vo.setApplydate(new UFLiteralDate());
		vo.setCreator(PubEnv.getPk_user());
		vo.setCreationtime(new UFDateTime());
		vo.setPk_psndoc(psndocVO.getPk_psndoc()); // 变更职员主键
		vo.setSubmitdate(new UFLiteralDate());
		vo.setCheckstatus(PsnInfoApproveCheckEnum.UNCHECK.getIndex());
		vo.setReadstatus(0); // 预览状态 0-未读 1-已读
		vo.setPk_infoset(appConfSet.getPk_infoset());
		vo.setInfoset_code(appConfSet.getInfosetcode());
		vo.setInfoset_name(appConfSet.getInfosetname());
		vo.setTable_code(appConfSet.getTablecode());
		vo.setVo_class_name(appConfSet.getVo_class_name());
		vo.setOldvalue(StringUtils.isEmpty(oldValue) ? null : oldValue.getBytes());
		vo.setNewvalue(StringUtils.isEmpty(newValue) ? null : newValue.getBytes());
		return getServiceTemplate().insert(vo)[0];
	}

	@SuppressWarnings("deprecation")
	@Override
	public String savePsnSubInfo(String pk_org, PsndocVO psndocVO, SuperVO[] vos, boolean needCheck) throws BusinessException {
		if (ArrayUtils.isEmpty(vos) || StringUtils.isBlank(pk_org) || psndocVO == null)
		{
			return null;
		}
		// 个人信息审核配置
		List<AppConfSetVO> setVOs = NCLocator.getInstance().lookup(IAppconfService.class).queryAppConfSetVOByCond(pk_org, vos[0].getTableName());
		if (CollectionUtils.isEmpty(setVOs))
		{
			return null;
		}
		// 是否正式员工
		boolean isIndoc = psndocVO.getPsnOrgVO().getIndocflag() != null && psndocVO.getPsnOrgVO().getIndocflag().booleanValue();
		// 是否需要审核 -- 未转档人员均不需要审核
		AppConfSetVO setVO = setVOs.get(0);
		boolean isApprove = isIndoc && setVO.getEntry_approval() != null && setVO.getEntry_approval().booleanValue();
		if (!isApprove && needCheck) {
			// 第一次调用
			return null;
		}
		if (!isApprove && !needCheck) {
			// 第二次调用
			updateSubPsnInfo(psndocVO.getPk_psndoc(), setVO.getPk_infoset(), pk_org, vos);
			return null;
		}
		if (needCheck)
		{
			return "needCheck";
		}
		// 需要审核的保存到审核表
//		 vos = filterNoChangVO(vos);
		List<SuperVO> newValueList = new ArrayList<SuperVO>();
//		for(SuperVO vo : vos) {
//			if (VOStatus.UNCHANGED == vo.getStatus()) {
//				continue;
//			}
//			newValueList.add(vo);
//		}
		CollectionUtils.addAll(newValueList, vos);
		List<SuperVO> oldValueList = new ArrayList<SuperVO>();
		SuperVO[] dbSubVOs = queryPsnSubVOs(vos);
		if (!ArrayUtils.isEmpty(dbSubVOs)) {
			CollectionUtils.addAll(oldValueList, dbSubVOs);
		}
		String oldValue = HRJsonUtils.toJson(oldValueList);
		
		for(int i = 0; i < newValueList.size(); i++) {
			SuperVO vo = newValueList.get(i);
			String key = queryKeyByTableCode(vo.getTableName());
			if(key != null && (vo.getPrimaryKey() == null || "".equals(vo.getPrimaryKey()))){
				vo.setAttributeValue(key, "isnew");
				vo.setPrimaryKey(new SequenceGenerator().generate());
			}
		}
		
		String newValue = HRJsonUtils.toJson(newValueList);
		savePsnInfoApproveVO(oldValue, newValue, setVO, psndocVO);
		return null;
	}
	
	public String queryKeyByTableCode(String tablecode){
    	StringBuffer sqlstr=new StringBuffer("");
    	sqlstr.append("select item_code from hr_infoset_item").append("\r\n");
    	sqlstr.append("       left join hr_infoset").append("\r\n");
    	sqlstr.append("            on hr_infoset_item.pk_infoset = hr_infoset.pk_infoset").append("\r\n");
    	sqlstr.append("       where hr_infoset.table_code = '"+tablecode+"' and hr_infoset_item.item_name = '附件标识'"); 
    	String key = null;
		try {
			key = (String) NCLocator.getInstance().lookup(IUAPQueryBS.class).executeQuery(sqlstr.toString(),new ColumnProcessor());
		} catch (BusinessException e) {
			e.printStackTrace();
		}
    	return key;
    }

	/**
	 * 查询涉及到的子表数据
	 * 
	 * @param vos
	 * @return
	 * @throws BusinessException
	 */
	private SuperVO[] queryPsnSubVOs(SuperVO[] vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos))
		{
			return null;
		}
		// 组装所有主键数组
		List<String> pkList = new ArrayList<String>();
		for (SuperVO vo : vos) {
			if (VOStatus.NEW == vo.getStatus()) { // 新增的不需要再查了
				continue;
			}
			if (VOStatus.UNCHANGED == vo.getStatus()) {
				continue;
			}
			String pk = vo.getPrimaryKey();
			if (StringUtils.isBlank(pk))
			{
				continue;
			}
			pkList.add(pk);
		}
		if (CollectionUtils.isEmpty(pkList)){
			return null;
		}
		return getServiceTemplate().queryByPks(vos[0].getClass(), pkList.toArray(new String[0]));
	}

	/**
	 * 更新员工子集信息
	 * 
	 * @throws BusinessException
	 */
	private void updateSubPsnInfo(String pk_psndoc, String pk_infoset, String pk_org, SuperVO[] vos) throws BusinessException {
		InfoSetVO infoset = NCLocator.getInstance().lookup(IInfoSetQry.class).queryInfoSetByPk(pk_infoset);
		if (infoset == null) {
			throw new BusinessException(ResHelper.getString("6008hrgx", "06008hrgx0054")/* @res "没有找到对应信息集！" */);
		}
		IPersonRecordService recordService = NCLocator.getInstance().lookup(IPersonRecordService.class);
		IPsndocService psndocService = NCLocator.getInstance().lookup(IPsndocService.class);
		// 人员子集有排序和最新处理，必须一行一行处理
		for (SuperVO vo : vos) {
			if (vo.getStatus() == VOStatus.NEW) {
				vo.setAttributeValue(PsnSuperVO.CREATOR, PubEnv.getPk_user());
				vo.setAttributeValue(PsnSuperVO.CREATIONTIME, PubEnv.getServerTime());
				vo.setAttributeValue(PsndocVO.PK_GROUP, PubEnv.getPk_group());
				vo.setAttributeValue(PsndocVO.PK_ORG, pk_org);
				vo.setAttributeValue(PsndocVO.PK_PSNDOC, pk_psndoc);
				recordService.insertRecord(vo, infoset);
				continue;
			}
			// 子集每次保存都会刷新同表其他数据，导致ts不一致，此处暂时直接覆盖一下ts
			SuperVO tmpVO = getServiceTemplate().queryByPk(vo.getClass(), vo.getPrimaryKey());
			if (tmpVO == null)
			{
				continue;
			}
			vo.setAttributeValue("ts", tmpVO.getAttributeValue("ts"));
			if (vo.getStatus() == VOStatus.UPDATED) {
				recordService.updateRecord(vo);
			} else if (vo.getStatus() == VOStatus.DELETED) {
				psndocService.deleteSub(vo);
			}
		}

		//如果修改的是证件子集  需要将证件子集中默认的那一条回写到基本信息上
		if (CertVO.getDefaultTableName().equals(infoset.getInfoset_code())) {
			CertVO[] certs = (CertVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null,CertVO.class, " pk_psndoc = '" + pk_psndoc + "' and iseffect = 'Y' order by recordnum desc ");
			for (int i = 0; certs != null && i < certs.length; i++) {
				if (certs[i].getIsstart() != null && certs[i].getIsstart().booleanValue() && StringUtils.isNotBlank(certs[i].getIdtype())
						&& StringUtils.isNotBlank(certs[i].getId())) {
					PsndocVO psndoc = (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsndocVO.class, pk_psndoc);
					psndoc.setIdtype(certs[i].getIdtype());
					psndoc.setId(certs[i].getId());
					NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVO(null, psndoc, new String[] {PsndocVO.ID,PsndocVO.IDTYPE}, null);
					break;
				}
			}
		}

		// 子集更新后同步主表数据
		NCLocator.getInstance().lookup(IPsndocService.class).updateDataAfterSubDataChanged(infoset.getInfoset_code(), pk_psndoc);
	}

	@Override
	public Map<String, Object> queryPsnInfoByTableCode(String tableCode, String pk_psndoc, boolean isTeam) throws BusinessException {
		PsndocAggVO psndocAggVO = NCLocator.getInstance().lookup(IPsndocQryService.class).queryPsndocVOByPk(pk_psndoc);
		if (psndocAggVO == null)
		{
			return null;
		}
		Map<String, Object> resultMap = new HashMap<String, Object>();
		PsndocVO psndocVO = psndocAggVO.getParentVO();
		// 取人员所属组织
		String pk_org = psndocVO.getPsnJobVO().getPk_hrorg();
		// 查询未审核个人信息
		PsnInfoApproveVO approveVO = querySubmitPsnInfoByTableCode(pk_org, pk_psndoc, tableCode, false);
		// 如果是团队成员信息或没有待审核数据，直接返回
		if (isTeam) {
			if (PsndocVO.getDefaultTableName().equals(tableCode)) { // 基本信息表
				resultMap.put("vos", psndocVO);
			} else if (PsnJobVO.getDefaultTableName().equals(tableCode)) {
				//resultMap.put("vos", new PsnJobVO[] { psndocVO.getPsnJobVO() });
				IBean bean = NCLocator.getInstance().lookup(IMetaDataQueryService.class).getBeanByName("hrhi", tableCode);
				Class<?> clazz = null;
				try {
					clazz = Class.forName(bean.getFullClassName());
				} catch (ClassNotFoundException ex) {
					Logger.error(ex);
				}
				SuperVO[] subVOs = NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, PsnJobVO.class, " pk_psndoc = '" + pk_psndoc + "' order by begindate,enddate,recordnum desc ");
				subVOs = filterDeleteVOs(subVOs);
				resultMap.put("vos", subVOs);
			} else if (PsnOrgVO.getDefaultTableName().equals(tableCode)) {
				resultMap.put("vos", new PsnOrgVO[] { psndocVO.getPsnOrgVO() });
			} else {
				SuperVO[] subVOs = queryPsnShowSubVOsByTableCode(psndocVO, tableCode);
				resultMap.put("vos", subVOs);
			}
			resultMap.put("hasApprove", "N");
			return resultMap;
		}else if(approveVO == null){
			if (PsndocVO.getDefaultTableName().equals(tableCode)) { // 基本信息表
				resultMap.put("vos", psndocVO);
			} else if (PsnJobVO.getDefaultTableName().equals(tableCode)) {
				//resultMap.put("vos", new PsnJobVO[] { psndocVO.getPsnJobVO() });
				IBean bean = NCLocator.getInstance().lookup(IMetaDataQueryService.class).getBeanByName("hrhi", tableCode);
				Class<?> clazz = null;
				try {
					clazz = Class.forName(bean.getFullClassName());
				} catch (ClassNotFoundException ex) {
					Logger.error(ex);
				}
				SuperVO[] subVOs = NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, PsnJobVO.class, " pk_psndoc = '" + pk_psndoc + "' order by begindate,enddate,recordnum desc ");
				subVOs = filterDeleteVOs(subVOs);
				resultMap.put("vos", subVOs);
			} else if (PsnOrgVO.getDefaultTableName().equals(tableCode)) {
				resultMap.put("vos", new PsnOrgVO[] { psndocVO.getPsnOrgVO() });
			} else {
				SuperVO[] subVOs = queryPsnShowSubVOsByTableCode(psndocVO, tableCode);
				resultMap.put("vos", subVOs);
			}
			resultMap.put("hasApprove", "N");

			// 查询已审核个人信息
			PsnInfoApproveVO approvedVO = querySubmitPsnInfoByTableCode(pk_org, pk_psndoc, tableCode, true);
			if(null == approvedVO){
				return resultMap;
			}else{
				// readstatus：预览状态 0-未读 1-已读
				if(PsnInfoApproveCheckEnum.CHECK_SUCCESS.getIndex() == approvedVO.getReadstatus()){
					return resultMap;
				}
				// 审核通过
				if(PsnInfoApproveCheckEnum.CHECK_SUCCESS.getIndex() == approvedVO.getCheckstatus()){
					resultMap.put("isapproved", "Y");
				}// 审核不通过
				else if(PsnInfoApproveCheckEnum.CHECK_FAIL.getIndex() == approvedVO.getCheckstatus()){
					resultMap.put("isapproved", "N");
				}
				resultMap.put("pk_psninfoapprove", approvedVO.getPk_psninfoapprove());
			}
			return resultMap;
		}
		// 有待审核信息，直接返回前端转换VO--前端有转换器方便一些
		resultMap.put("vos", approveVO.getNewvalue());
		resultMap.put("pk_psninfoapprove", approveVO.getPk_psninfoapprove());
		if (PsndocVO.getDefaultTableName().equals(tableCode)) {
			Map<String, Object> valueMap = HRJsonUtils.fromJson(new String((byte[]) approveVO.getNewvalue()), Map.class);
			PsndocVO newPsndocVO = HRJsonUtils.fromJson(new String((byte[]) approveVO.getNewvalue()), PsndocVO.class);
			for (String key : valueMap.keySet()) {
				psndocVO.setAttributeValue(key, newPsndocVO.getAttributeValue(key));
			}
			resultMap.put("vos", psndocVO);
		} else {
			IBean bean = NCLocator.getInstance().lookup(IMetaDataQueryService.class).getBeanByName("hrhi", tableCode);
			Class<?> clazz = null;
			try {
				clazz = Class.forName(bean.getFullClassName());
			} catch (ClassNotFoundException ex) {
				Logger.error(ex);
			}
			SuperVO[] subVOs = HRJsonUtils.fromJson(new String((byte[]) approveVO.getNewvalue()), Array.newInstance(clazz, 1).getClass());
			subVOs = filterDeleteVOs(subVOs);
			resultMap.put("vos", subVOs);
		}
		resultMap.put("hasApprove", "Y");
		return resultMap;
	}

	@Override
	public Map<String, Object> queryAllSubmitInfo(String pk_psndoc, boolean checkstatus) throws BusinessException {
		PsndocAggVO psndocAggVO = NCLocator.getInstance().lookup(IPsndocQryService.class).queryPsndocVOByPk(pk_psndoc);
		if (psndocAggVO == null)
		{
			return null;
		}
		Map<String, Object> resultMap = new HashMap<String, Object>();
		PsndocVO psndocVO = psndocAggVO.getParentVO();
		// 取人员所属组织
		String pk_org = psndocVO.getPsnJobVO().getPk_hrorg();
		// 查询已审核个人信息
		LoginContext context = new LoginContext();
		context.setPk_group(PubEnv.getPk_group());
		context.setPk_org(pk_org);
		context.setNodeType(NODE_TYPE.ORG_NODE);
		String whereCond = null;
		if(checkstatus){
			whereCond = " pk_org = '" + pk_org + "' and checkstatus <> 0 and pk_psndoc = '" + pk_psndoc + "' order by ts desc";
		}else{
			whereCond = " pk_org = '" + pk_org + "' and checkstatus = 0 and pk_psndoc = '" + pk_psndoc + "' ";
		}
		PsnInfoApproveVO[] approvedVOs = queryByCondition(whereCond);
		if (ArrayUtils.isEmpty(approvedVOs)) {
			return resultMap;
		}else{
			ArrayList<Map<String, String>> list = new ArrayList<>();
			ArrayList<String> infosetPkList = new ArrayList<>();
			for (PsnInfoApproveVO approve : approvedVOs) {
				HashMap<String, String> map = new HashMap<>();
				// readstatus：预览状态 0-未读 1-已读
				if(PsnInfoApproveCheckEnum.CHECK_SUCCESS.getIndex() == approve.getReadstatus()){
					continue;
				}
				// 审核通过
				if(PsnInfoApproveCheckEnum.CHECK_SUCCESS.getIndex() == approve.getCheckstatus()){
					map.put("isapproved", "Y");
				}// 审核不通过
				else if(PsnInfoApproveCheckEnum.CHECK_FAIL.getIndex() == approve.getCheckstatus()){
					map.put("isapproved", "N");
				}
				map.put("area", approve.getPk_infoset());
				infosetPkList.add(approve.getPk_infoset());
				map.put("checknote", approve.getChecknote());
				map.put("pk_psninfoapprove", approve.getPk_psninfoapprove());
				list.add(map);
			}
			if (CollectionUtils.isEmpty(list)) {
				return resultMap;
			} else {
				// 此处根据信息区查出对应子集编码，方便前端处理
				String sql = " select pk_infoset, infoset_code from hr_infoset where pk_infoset in ( ";
				for (String pk_infoset : infosetPkList) {
					sql += "'" + pk_infoset + "',";
				}
				sql = sql.substring(0, sql.length() - 1) +  ")";
				List<Map<String, String>> infosetList = (List<Map<String, String>>) NCLocator.getInstance().lookup(IUAPQueryBS.class)
						.executeQuery(sql, new MapListProcessor());
				for (Map<String, String> map : list) {
					String pk_infoset = map.get("area");
					for (Map<String, String> m : infosetList) {
						if (pk_infoset.equals(m.get("pk_infoset"))) {
							map.put("area", m.get("infoset_code"));
							break;
						}
					}
				}
				resultMap.put("submitPsnInfos", list);
			}
		}
		return resultMap;
	}

	/**
	 * 过滤掉已删除的数据
	 * 
	 * @param subVOs
	 * @return
	 */
	private SuperVO[] filterDeleteVOs(SuperVO[] subVOs) {
		if (ArrayUtils.isEmpty(subVOs))
		{
			return null;
		}
		List<SuperVO> voList = new ArrayList<SuperVO>();
		for (SuperVO vo : subVOs) {
			if (VOStatus.DELETED == vo.getStatus())
			{
				continue;
			}
			voList.add(vo);
		}
		return CollectionUtils.isEmpty(voList) ? null : voList.toArray(new SuperVO[0]);
	}

	/**
	 * 查询待审核的个人信息
	 * @param pk_org
	 * @param pk_psndoc
	 * @param tableCode
	 * @param checkstatus : true-已审核， false-未审核
	 * @return
	 * @throws BusinessException
	 */
	private PsnInfoApproveVO querySubmitPsnInfoByTableCode(String pk_org, String pk_psndoc, String tableCode, boolean checkstatus) throws BusinessException {
		// 查询信息集配置
		String condition = " infoset_code = '" + tableCode + "'";
		LoginContext context = new LoginContext();
		context.setPk_group(PubEnv.getPk_group());
		context.setPk_org(pk_org);
		context.setNodeType(NODE_TYPE.ORG_NODE);
		InfoSetVO[] infosetVOs = NCLocator.getInstance().lookup(IInfoSetQry.class).queryInfoSet(context, condition);
		if (ArrayUtils.isEmpty(infosetVOs))
		{
			return null;
		}
		String whereCond = null;
		if(checkstatus){
			whereCond = " pk_org = '" + pk_org + "' and checkstatus <> 0 and pk_infoset = '" + infosetVOs[0].getPk_infoset() + "' and pk_psndoc = '" + pk_psndoc + "' order by ts desc";
		}else{
			whereCond = " pk_org = '" + pk_org + "' and checkstatus = 0 and pk_infoset = '" + infosetVOs[0].getPk_infoset() + "' and pk_psndoc = '" + pk_psndoc + "' ";
		}
		PsnInfoApproveVO[] approveVOs = queryByCondition(whereCond);
		return ArrayUtils.isEmpty(approveVOs) ? null : approveVOs[0];
	}

	/**
	 * 查询可显示的子集信息
	 * 
	 * @return
	 * @throws BusinessException
	 */
	private SuperVO[] queryPsnShowSubVOsByTableCode(PsndocVO psndocVO, String tableCode) throws BusinessException {
		String strAddtionalWhere = "";
		if (PsnJobVO.getDefaultTableName().equals(tableCode)) {
			strAddtionalWhere += " hi_psnjob.ismainjob='Y'";
		} else if (PartTimeVO.getDefaultTableName().equals(tableCode)) {
			strAddtionalWhere += " hi_psnjob.ismainjob='N'";
		} else if (CtrtVO.getDefaultTableName().equals(tableCode)) {
			// 在维护和信息节点合同只能看到生效的记录
			strAddtionalWhere += " hi_psndoc_ctrt.isrefer = 'Y' ";
		} else if (CapaVO.getDefaultTableName().equals(tableCode)) {
			strAddtionalWhere += " hi_psndoc_capa.lastflag = 'Y' ";
		} else if (TrainVO.getDefaultTableName().equals(tableCode)) {
			strAddtionalWhere += " hi_psndoc_train.pk_psnjob = '" + psndocVO.getPsnJobVO().getPk_psnjob() + "' ";
		}
		String strWhere = " pk_psndoc='" + psndocVO.getPk_psndoc() + "'";

		// 业务子集还要按照组织关系主键过滤
		if ((PsndocAggVO.hashBusinessInfoSet.contains(tableCode) || WainfoVO.getDefaultTableName().equals(tableCode))) {
			//
			String pk_org = psndocVO.getPsnJobVO().getPk_hrorg();
			String pk_psnorg = psndocVO.getPsnOrgVO().getPk_psnorg();
			if (PsnJobVO.getDefaultTableName().equals(tableCode)) {
				strWhere += " and pk_org = '" + pk_org + "' and pk_psnorg = '" + pk_psnorg + "'";
			} else if (PsndocAggVO.hashPsnJobInfoSet.contains(tableCode)) {
				strWhere += " and pk_psnjob in (select pk_psnjob from hi_psnjob where pk_org = '" + pk_org + "' and pk_psnorg = '" + pk_psnorg + "') ";
			} else {
				// 只显示当前组织关系的数据
				strWhere += " and pk_psnorg = '" + pk_psnorg + "'";
			}

			// 信息查询节点 单独处理主职/兼职记录
			UFBoolean ismainjob = psndocVO.getPsnJobVO().getIsmainjob();
			if (ismainjob == null || !ismainjob.booleanValue()) {
				// 兼职,除兼职外的业务子集不显示
				if (WainfoVO.getDefaultTableName().equals(tableCode)) {
					strWhere += " and pk_psnjob in (select pk_psnjob from hi_psnjob where pk_org = '" + pk_org + "' and pk_psnorg = '" + pk_psnorg + "' and ismainjob = 'N') ";
				} else if (PartTimeVO.getDefaultTableName().equals(tableCode)) {
					// 兼职页签显示任职组织下的兼职
					strWhere += " and pk_org = '" + pk_org + "' ";
				} else if (TrainVO.getDefaultTableName().equals(tableCode)) {
					strWhere += " and 1 = 1 ";
				} else {
					strWhere += " and 1 = 2 ";
				}
			}
		}

		if (strAddtionalWhere.length() > 0) {
			strWhere = strWhere + " and " + strAddtionalWhere;
		}

		IBean bean = NCLocator.getInstance().lookup(IMetaDataQueryService.class).getBeanByName("hrhi", tableCode);
		IAttribute attribute = bean.getAttributeByName("recordnum");
		String strOrder = attribute != null ? " recordnum desc" : null;// 此处根据不同情况构建order

		// 业务子集在非编辑态并且显示所有信息时,按照开始时间排序
		if (PsndocAggVO.hashBusinessInfoSet.contains(tableCode)) {
			if (QulifyVO.getDefaultTableName().equals(tableCode)) {
				strOrder = " authendate ";
			} else if (OtherCertVO.getDefaultTableName().equals(tableCode)
					|| TrainCertfileVO.getDefaultTableName().equals(tableCode)
					|| EnterQualCertVO.getDefaultTableName().equals(tableCode)) {
				// 证书子集按证书颁发时间排序
				strOrder = " firstdate ";
			} else {
				strOrder = " begindate ";
			}
		}
		Class<?> clazzVO = null;
		try {
			clazzVO = Class.forName(bean.getFullClassName());
		} catch (ClassNotFoundException ex) {
			Logger.error(ex);
		}
		SuperVO[] subVOs = NCLocator.getInstance().lookup(IPsndocQryService.class).querySubVO(clazzVO, strWhere, strOrder);
		return subVOs;
	}
}
