package nc.impl.hr.pub;

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

import nc.bs.bd.baseservice.ArrayClassConvertUtil;
import nc.bs.bd.baseservice.md.SingleBaseService;
import nc.bs.bd.util.DBAUtil;
import nc.bs.businessevent.IEventType;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.bs.sec.esapi.NCESAPI;
import nc.hr.frame.persistence.SimpleDocServiceTemplate;
import nc.hr.utils.InSQLCreator;
import nc.hr.utils.MultiLangHelper;
import nc.hr.utils.PubEnv;
import nc.hr.utils.ResHelper;
import nc.hr.utils.SQLHelper;
import nc.impl.hi.psndoc.PsndocDAO;
import nc.itf.hi.IPersonRecordService;
import nc.itf.hi.IPsndocService;
import nc.itf.hr.frame.IPersistenceHome;
import nc.itf.hr.frame.IPersistenceRetrieve;
import nc.itf.hr.frame.IPersistenceUpdate;
import nc.itf.uap.IUAPQueryBS;
import nc.itf.uap.rbac.IUserManage;
import nc.itf.uap.rbac.IUserManageQuery;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.md.persist.framework.MDPersistenceService;
import nc.pub.tools.HiCacheUtils;
import nc.pub.tools.HiSQLHelper;
import nc.pub.tools.VOUtils;
import nc.ui.pub.bill.IBillItem;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.bd.meta.BatchOperateVO;
import nc.vo.bd.pub.IPubEnumConst;
import nc.vo.hi.psndoc.AssVO;
import nc.vo.hi.psndoc.BminfoVO;
import nc.vo.hi.psndoc.CapaVO;
import nc.vo.hi.psndoc.CertVO;
import nc.vo.hi.psndoc.CtrtVO;
import nc.vo.hi.psndoc.EduVO;
import nc.vo.hi.psndoc.PartTimeVO;
import nc.vo.hi.psndoc.PsnChgVO;
import nc.vo.hi.psndoc.PsnJobVO;
import nc.vo.hi.psndoc.PsnOrgVO;
import nc.vo.hi.psndoc.PsndocVO;
import nc.vo.hi.psndoc.QulifyVO;
import nc.vo.hi.psndoc.RetireVO;
import nc.vo.hi.psndoc.TrialVO;
import nc.vo.hi.psndoc.WainfoVO;
import nc.vo.hi.psndoc.WorkVO;
import nc.vo.hi.pub.HICommonValue;
import nc.vo.hi.pub.HiBatchEventValueObject;
import nc.vo.hi.pub.HiEventValueObject;
import nc.vo.hi.pub.IHiEventType;
import nc.vo.hr.infoset.InfoSetVO;
import nc.vo.hr.tools.pub.GeneralVO;
import nc.vo.hr.tools.pub.GeneralVOProcessor;
import nc.vo.om.job.JobVO;
import nc.vo.om.post.PostVO;
import nc.vo.org.AdminOrgVO;
import nc.vo.org.DeptVO;
import nc.vo.org.OrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.SuperVO;
import nc.vo.pub.SuperVOUtil;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFLiteralDate;
import nc.vo.sm.UserVO;
import nc.vo.sm.enumfactory.UserIdentityTypeEnumFactory;
import nc.vo.util.BDVersionValidationUtil;

import nccloud.commons.lang.ArrayUtils;
import nccloud.commons.lang.StringUtils;

public class PersonRecordImpl extends SingleBaseService<PsndocVO> implements IPersonRecordService
{
    
    public PersonRecordImpl()
    {
        super(HICommonValue.MD_ID_PSNDOC);
    }
    
    public PsnJobVO addNewDimission(PsnJobVO dimission, String pkHrorg, boolean isDisablePsn) throws BusinessException
    {
        
        checkClerkCodeUnique(dimission);
        
        String pk_psnorg = dimission.getPk_psnorg();
        PsnJobVO before = getLastVO(PsnJobVO.class, pk_psnorg, 1);
        if (dimission.getPsntype() != null && dimission.getPsntype() == 0)
        {
            // 相关人员不发送事件
            fireEvent(before, null, pkHrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_BEFORE);
        }
        // 1)终止组织关系
        PsnOrgVO psnorg = getServiceTemplate().queryByPk(PsnOrgVO.class, pk_psnorg);
        if(null == psnorg.getBegindate()){
        	throw new BusinessException("此人的组织关系进入日期不能为空！");
        }
        psnorg.setPk_hrorg(pkHrorg);// 离职后同步组织关系中HR组织
        updateEndflagAndEnddate(psnorg, dimission.getBegindate());
        // 2)终止当前组织关系下所有任职/兼职
        PsnJobVO[] psnjobs =
            getServiceTemplate().queryByCondition(PsnJobVO.class,
                " pk_psnorg = '" + pk_psnorg + "' and ( endflag = 'N' or " + SQLHelper.getNullSql("endflag") + " ) ");
        for (int i = 0; psnjobs != null && i < psnjobs.length; i++)
        {
            updateEndflagAndEnddate(psnjobs[i], dimission.getBegindate());
            endWork(psnjobs[i], dimission);
        }
        // 4)增加一条离职记录,同时更新其他记录的recordnum与lastflag
        PsnJobVO[] oldVOs = getServiceTemplate().queryByCondition(PsnJobVO.class, " pk_psnorg = '" + pk_psnorg + "' and assgid = 1 ");
        updateRecordnumAndLastflag(oldVOs);
        
        // 5)结束试用
        TrialVO[] trial =
            getServiceTemplate().queryByCondition(TrialVO.class,
                " pk_psnorg = '" + pk_psnorg + "' and  ( endflag = 'N' or " + SQLHelper.getNullSql("endflag") + " ) ");
        for (int i = 0; trial != null && i < trial.length; i++)
        {
            updateEndflagAndEnddate(trial[i], dimission.getBegindate());
        }
        // 试用同步人员基本信息
        getIPsndocService().updateDataAfterSubDataChanged(TrialVO.getDefaultTableName(), dimission.getPk_psndoc());
        // 5)end
        // 6)同步基本信息的pk_org
        synPkorgOfPsndoc(dimission.getPk_org(), dimission.getPk_psndoc());
        // 同步离退休日期
        if (dimission.getTrnstype() != null
            && (dimission.getTrnstype().equals("1002Z710000000008GSV") || dimission.getTrnstype().equals("1002Z710000000008GSW")))
        {
            // 异动类型为离休或退休的
            String sql =
                " update bd_psndoc set retiredate = '" + dimission.getBegindate() + "' where pk_psndoc = '" + dimission.getPk_psndoc()
                    + "' ";
            NCLocator.getInstance().lookup(IPersistenceUpdate.class).executeSQLs(new String[]{sql});
        }
        
        // 离职结束最新的流动情况
        PsnChgVO lastVO = getLastVO(PsnChgVO.class, pk_psnorg, null);
        if (lastVO != null && lastVO.getEnddate() == null)
        {
            if (lastVO.getBegindate() != null && lastVO.getBegindate().compareTo(dimission.getBegindate()) >= 0)
            {
                lastVO.setEnddate(lastVO.getBegindate());
            }
            else
            {
                lastVO.setEnddate(dimission.getBegindate().getDateBefore(1));
            }
            getServiceTemplate().update(lastVO, false);
            getIPsndocService().updateDataAfterSubDataChanged(PsnChgVO.getDefaultTableName(), lastVO.getPk_psndoc());
        }
        // 插入离职记录
        dimission.setPk_hrorg(pkHrorg);// 同步HR组织
        PsnJobVO after = getServiceTemplate().insert(dimission);
        // 7)同步人员基本信息
        getIPsndocService().updateDataAfterSubDataChanged(PsnJobVO.getDefaultTableName(), after.getPk_psndoc());
        
        // fengwei 2012-12-24 停用离职人员
        if (isDisablePsn)
        {
            PsndocVO psndocVO =
                (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
                    .retrieveByPk(null, PsndocVO.class, dimission.getPk_psndoc());
            // PsndocVO psndocVO = getServiceTemplate().queryByPk(PsndocVO.class, dimission.getPk_psndoc());
            disableSingleVO(psndocVO);
        }
        
        // 人员离职后停用其对应的用户
        String pk_psndoc = after.getPk_psndoc();
        String condition =
            " base_doc_type = " + UserIdentityTypeEnumFactory.TYPE_PERSON + " and pk_base_doc = '" + pk_psndoc + "' and enablestate = "
                + IPubEnumConst.ENABLESTATE_ENABLE;
        
        UserVO[] users = NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserByClause(condition);
        if (users != null && users.length > 0)
        {
            for (UserVO user : users)
            {
                NCLocator.getInstance().lookup(IUserManage.class).disableUser(user);
            }
        }
        
        // 发送事件--终止劳动合同，确定薪资结算日期
        if (dimission.getPsntype() != null && dimission.getPsntype() == 0)
        {
            // 相关人员不发送事件
            fireEvent(before, after, pkHrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_AFTER);
            HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        }
        
        // 同步缓存
        HiCacheUtils.synCache(PsndocVO.getDefaultTableName(), PsnJobVO.getDefaultTableName(), PsnOrgVO.getDefaultTableName());
        
        return after;
    }
    
    public PsnJobVO addNewDimission(PsnJobVO dimission, String pkHrorg, boolean isDisablePsn, String pk_hrcm_org) throws BusinessException
    {
        
        checkClerkCodeUnique(dimission);
        
        String pk_psnorg = dimission.getPk_psnorg();
        PsnJobVO before = getLastVO(PsnJobVO.class, pk_psnorg, 1);
        if (dimission.getPsntype() != null && dimission.getPsntype() == 0)
        {
            // 相关人员不发送事件
            fireEvent(before, null, pkHrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_BEFORE);
        }
        // 1)终止组织关系
        PsnOrgVO psnorg = getServiceTemplate().queryByPk(PsnOrgVO.class, pk_psnorg);
        psnorg.setPk_hrorg(pkHrorg);// 离职后同步组织关系中HR组织
        updateEndflagAndEnddate(psnorg, dimission.getBegindate());
        // 2)终止当前组织关系下所有任职/兼职
        PsnJobVO[] psnjobs =
            getServiceTemplate().queryByCondition(PsnJobVO.class,
                " pk_psnorg = '" + pk_psnorg + "' and ( endflag = 'N' or " + SQLHelper.getNullSql("endflag") + " ) ");
        for (int i = 0; psnjobs != null && i < psnjobs.length; i++)
        {
            updateEndflagAndEnddate(psnjobs[i], dimission.getBegindate());
            endWork(psnjobs[i], dimission);
        }
        // 4)增加一条离职记录,同时更新其他记录的recordnum与lastflag
        PsnJobVO[] oldVOs = getServiceTemplate().queryByCondition(PsnJobVO.class, " pk_psnorg = '" + pk_psnorg + "' and assgid = 1 ");
        updateRecordnumAndLastflag(oldVOs);
        
        // 5)结束试用
        TrialVO[] trial =
            getServiceTemplate().queryByCondition(TrialVO.class,
                " pk_psnorg = '" + pk_psnorg + "' and  ( endflag = 'N' or " + SQLHelper.getNullSql("endflag") + " ) ");
        for (int i = 0; trial != null && i < trial.length; i++)
        {
            updateEndflagAndEnddate(trial[i], dimission.getBegindate());
        }
        // 试用同步人员基本信息
        getIPsndocService().updateDataAfterSubDataChanged(TrialVO.getDefaultTableName(), dimission.getPk_psndoc());
        // 5)end
        // 6)同步基本信息的pk_org
        synPkorgOfPsndoc(dimission.getPk_org(), dimission.getPk_psndoc());
        // 同步离退休日期
        if (dimission.getTrnstype() != null
            && (dimission.getTrnstype().equals("1002Z710000000008GSV") || dimission.getTrnstype().equals("1002Z710000000008GSW")))
        {
            // 异动类型为离休或退休的
            String sql =
                " update bd_psndoc set retiredate = '" + dimission.getBegindate() + "' where pk_psndoc = '" + dimission.getPk_psndoc()
                    + "' ";
            NCLocator.getInstance().lookup(IPersistenceUpdate.class).executeSQLs(new String[]{sql});
        }
        
        // 离职结束最新的流动情况
        PsnChgVO lastVO = getLastVO(PsnChgVO.class, pk_psnorg, null);
        if (lastVO != null && lastVO.getEnddate() == null)
        {
            if (lastVO.getBegindate() != null && lastVO.getBegindate().compareTo(dimission.getBegindate()) >= 0)
            {
                lastVO.setEnddate(lastVO.getBegindate());
            }
            else
            {
                lastVO.setEnddate(dimission.getBegindate().getDateBefore(1));
            }
            getServiceTemplate().update(lastVO, false);
            getIPsndocService().updateDataAfterSubDataChanged(PsnChgVO.getDefaultTableName(), lastVO.getPk_psndoc());
        }
        // 插入离职记录
        dimission.setPk_hrorg(pkHrorg);// 同步HR组织
        PsnJobVO after = getServiceTemplate().insert(dimission);
        // 7)同步人员基本信息
        getIPsndocService().updateDataAfterSubDataChanged(PsnJobVO.getDefaultTableName(), after.getPk_psndoc());
        
        // fengwei 2012-12-24 停用离职人员
        if (isDisablePsn)
        {
            PsndocVO psndocVO =
                (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
                    .retrieveByPk(null, PsndocVO.class, dimission.getPk_psndoc());
            // PsndocVO psndocVO = getServiceTemplate().queryByPk(PsndocVO.class, dimission.getPk_psndoc());
            disableSingleVO(psndocVO);
        }
        
        // 人员离职后停用其对应的用户
        String pk_psndoc = after.getPk_psndoc();
        String condition =
            " base_doc_type = " + UserIdentityTypeEnumFactory.TYPE_PERSON + " and pk_base_doc = '" + pk_psndoc + "' and enablestate = "
                + IPubEnumConst.ENABLESTATE_ENABLE;
        
        UserVO[] users = NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserByClause(condition);
        if (users != null && users.length > 0)
        {
            for (UserVO user : users)
            {
                NCLocator.getInstance().lookup(IUserManage.class).disableUser(user);
            }
        }
        
        if (StringUtils.isNotBlank(pk_hrcm_org)) after.setAttributeValue("pk_hrcm_org", pk_hrcm_org);
        
        // 发送事件--终止劳动合同，确定薪资结算日期
        if (dimission.getPsntype() != null && dimission.getPsntype() == 0)
        {
            // 相关人员不发送事件
            fireEvent(before, after, pkHrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_AFTER);
            HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        }
        
        // 同步缓存
        HiCacheUtils.synCache(PsndocVO.getDefaultTableName(), PsnJobVO.getDefaultTableName(), PsnOrgVO.getDefaultTableName());
        
        return after;
    }
    
    @Override
    public void addNewPsnjobs(PsnJobVO[] psnjobs, boolean isSyncWork, String[] hrOrgs) throws BusinessException
    {
        
        if (psnjobs == null || psnjobs.length == 0)
        {
            return;
        }
        
        BaseDAO dao = new BaseDAO();
        IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        IPersistenceUpdate update = NCLocator.getInstance().lookup(IPersistenceUpdate.class);
        
        // 检查部门岗位是否为撤销
        ArrayList<String> pkDept = new ArrayList<String>();
        ArrayList<String> pkPost = new ArrayList<String>();
        for (int i = 0; i < psnjobs.length; i++)
        {
            if (psnjobs[i] != null && psnjobs[i].getEndflag() != null && psnjobs[i].getEndflag().booleanValue())
            {
                continue;
            }
            if (psnjobs[i].getPk_dept() != null && !pkDept.contains(psnjobs[i].getPk_dept()))
            {
                pkDept.add(psnjobs[i].getPk_dept());
            }
            if (psnjobs[i].getPk_post() != null && !pkPost.contains(psnjobs[i].getPk_post()))
            {
                pkPost.add(psnjobs[i].getPk_post());
            }
        }
        
        String[] pk_psnorg = new String[psnjobs.length];
        for (int i = 0; i < psnjobs.length; i++)
        {
            pk_psnorg[i] = psnjobs[i].getPk_psnorg();
        }
        InSQLCreator ttu = null;
        try
        {
            ttu = new InSQLCreator();
            
            if (pkDept.size() > 0)
            {
                String sql1 =
                    " select count(*) from org_dept where hrcanceled = 'Y' and pk_dept in ( " + ttu.getInSQL(pkDept.toArray(new String[0]))
                        + " ) ";
                Object obj = dao.executeQuery(sql1, new ColumnProcessor());
                if (obj != null && ((Integer) obj) > 0)
                {
                    throw new BusinessException(ResHelper.getString("6007psn", "06007psn0323"/*
                                                                                              * @res
                                                                                              * "任职职未结束,部门不能为撤销部门"
                                                                                              */));
                }
                
            }
            
            if (pkPost.size() > 0)
            {
                String sql2 =
                    " select count(*) from om_post where hrcanceled ='Y' and pk_post in ( " + ttu.getInSQL(pkPost.toArray(new String[0]))
                        + " ) ";
                Object obj = dao.executeQuery(sql2, new ColumnProcessor());
                if (obj != null && ((Integer) obj) > 0)
                {
                    throw new BusinessException(ResHelper.getString("6007psn", "06007psn0324"/*
                                                                                              * @res
                                                                                              * "任职职未结束,岗位不能为撤销岗位"
                                                                                              */));
                }
            }
            // checkDeptPostCanceled(saveData);
            
            String psnorgInSql = ttu.getInSQL(pk_psnorg);
            
            // 时间校验
            String validateSql =
                " select count(*) from hi_psnjob where lastflag = 'Y' and assgid = 1 and pk_psnorg in (" + psnorgInSql
                    + ") and ( ( isnull(enddate,'~')<>'~' and enddate>='" + psnjobs[0].getBegindate()
                    + "' ) or (isnull(enddate,'~')='~' and isnull(begindate,'~')<>'~' and begindate>='" + psnjobs[0].getBegindate()
                    + "' ) )";
            Object obj = dao.executeQuery(validateSql, new ColumnProcessor());
            if (obj != null && ((Integer) obj) > 0)
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0276")/*
                                                                                           * @res
                                                                                           * "当前操作将导致当前操作的人员的最新业务关系记录开始时间早于其上一条业务关系记录开始时间."
                                                                                           */);
            }
            
            HashMap<String, PsnJobVO> afterMap = new HashMap<String, PsnJobVO>();
            for (int i = 0; i < psnjobs.length; i++)
            {
                afterMap.put(psnjobs[i].getPk_psnorg(), psnjobs[i]);
            }
            
            String queryCond = " pk_psnorg in (" + psnorgInSql + ") and assgid = 1 and lastflag = 'Y' ";
            
            PsnJobVO[] temp = (PsnJobVO[]) retrieve.retrieveByClause(null, PsnJobVO.class, queryCond);
            if (temp == null || temp.length != psnjobs.length)
            {
                throw new BusinessException(BDVersionValidationUtil.getUpdateInfo());
            }
            
            HashMap<String, PsnJobVO> beforeMap = new HashMap<String, PsnJobVO>();
            for (int i = 0; i < temp.length; i++)
            {
                beforeMap.put(temp[i].getPk_psnorg(), temp[i]);
            }
            
            PsnJobVO[] lastVOs = new PsnJobVO[psnjobs.length];
            for (int i = 0; i < lastVOs.length; i++)
            {
                lastVOs[i] = beforeMap.get(psnjobs[i].getPk_psnorg());
            }
            
            ArrayList<String> al = new ArrayList<String>();// 人员主键,去掉重复的
            for (int i = 0; i < psnjobs.length; i++)
            {
                if (!al.contains(psnjobs[i].getPk_psndoc()))
                {
                    al.add(psnjobs[i].getPk_psndoc());
                }
            }
            HiBatchEventValueObject.fireEvent(lastVOs, null, hrOrgs, HICommonValue.PSNJOBSOURCEID, IHiEventType.TYPE_INSERT_BEFORE);
            
            // 校验员工号
            checkClerkCodeUnique(psnjobs);
            // for (int i = 0; i < psnjobs.length; i++)
            // {
            // checkClerkCodeUnique(psnjobs[i]);
            // }
            
            // 回写上一条的Endflag与Enddate
            UFLiteralDate enddate = psnjobs[0].getBegindate().getDateBefore(1);
            String updateSql1 =
                " update hi_psnjob set enddate = '" + enddate + "',endflag='Y',poststat ='N' where pk_psnorg in (" + psnorgInSql
                    + ") and assgid = 1 and lastflag = 'Y' and isnull(enddate,'~') = '~' ";
            dao.executeUpdate(updateSql1);
            
            // 同步结束对应的履历
            if (isSyncWork)
            {
                PsnJobVO[] linshi = (PsnJobVO[]) retrieve.retrieveByClause(null, PsnJobVO.class, queryCond);
                
                ArrayList<String> sqlList = new ArrayList<String>();
                for (int i = 0; linshi != null && i < linshi.length; i++)
                {
                    String s =
                        " update hi_psndoc_work set enddate = ( case when begindate <='" + linshi[i].getEnddate() + "' then '"
                            + linshi[i].getEnddate() + "' else begindate end ) where pk_psnjob = '" + linshi[i].getPk_psnjob() + "' ";
                    sqlList.add(s);
                }
                if (sqlList.size() > 0)
                {
                    update.executeSQLs(sqlList.toArray(new String[0]));
                }
                
            }
            
            // 更新历史记录的lastflg&recordnum
            String updateSql2 =
                " update hi_psnjob set lastflag ='N',recordnum = recordnum + 1 where pk_psnorg in (" + psnorgInSql + ") and assgid = 1 ";
            dao.executeUpdate(updateSql2);
            
            // 如果当前生效的试用记录未结束且新增的工作记录为转正则结束这条试用记录;否则回写工作记录
            TrialVO[] lastTrailVOs =
                (TrialVO[]) retrieve.retrieveByClause(null, TrialVO.class, " pk_psnorg in (" + psnorgInSql + ") and lastflag = 'Y' ");
            for (int i = 0; lastTrailVOs != null && i < lastTrailVOs.length; i++)
            {
                PsnJobVO job = afterMap.get(lastTrailVOs[i].getPk_psnorg());
                if (lastTrailVOs[i].getEndflag() != null && !lastTrailVOs[i].getEndflag().booleanValue())
                {
                    
                    if (job.getTrnsevent() != null && job.getTrnsevent() == 2)
                    {
                        lastTrailVOs[i].setEndflag(UFBoolean.TRUE);
                        lastTrailVOs[i].setTrialresult(1);
                        lastTrailVOs[i].setRegulardate(psnjobs[0].getBegindate());
                        if (lastTrailVOs[i].getEnddate() == null)
                        {
                            lastTrailVOs[i].setEnddate(psnjobs[0].getBegindate());
                        }
                        lastTrailVOs[i].setStatus(VOStatus.UPDATED);
                    }
                    else
                    {
                        job.setTrial_flag(UFBoolean.TRUE);
                        job.setTrial_type(lastTrailVOs[i].getTrial_type());
                    }
                    
                }
                else
                {
                    // 未结束的试用 ,新增的工作记录的是否试用为是,试用类型为试用类型
                    job.setTrial_flag(UFBoolean.FALSE);
                    job.setTrial_type(null);
                }
            }
            
            dao.updateVOArray(lastTrailVOs, new String[]{TrialVO.ENDFLAG, TrialVO.TRIALRESULT, TrialVO.REGULARDATE, TrialVO.ENDDATE});
            
            for (int i = 0; i < psnjobs.length; i++)
            {
                psnjobs[i].setPk_hrorg(hrOrgs[i]);
            }
            insert4SubVOs(psnjobs);
            
            // 得到插入后的工作记录数组
            PsnJobVO[] afterList = (PsnJobVO[]) retrieve.retrieveByClause(null, PsnJobVO.class, queryCond);
            if (afterList == null || afterList.length != psnjobs.length)
            {
                throw new BusinessException(BDVersionValidationUtil.getUpdateInfo());
            }
            
            // PsnJobVO[] after = new PsnJobVO[psnjobs.length];
            
            HashMap<String, PsnJobVO> afterSaveMap = new HashMap<String, PsnJobVO>();
            for (int i = 0; i < afterList.length; i++)
            {
                afterSaveMap.put(afterList[i].getPk_psnorg(), afterList[i]);
            }
            
            PsnJobVO[] afterVOs = new PsnJobVO[psnjobs.length];
            for (int i = 0; i < afterVOs.length; i++)
            {
                afterVOs[i] = afterSaveMap.get(psnjobs[i].getPk_psnorg());
            }
            
            // for (int i = 0; afterList != null && i < afterList.length; i++) {
            // 同步流动情况
            // addPsnChg(afterList[i], false);
            // }
            // 同步流动情况
            batchAddPsnChg(lastVOs, afterVOs);
            
            // 同步工作履历
            if (isSyncWork)
            {
                // 4)isSynWork为true时,同步工作履历记录;
                batchAddWorkWhenPsnjobAdd(afterVOs);
                // addWorkWithoutSynPsndoc((PsnJobVO) afterList[i]);
            }
            
            ArrayList<String> updateSqls = new ArrayList<String>();
            for (int i = 0; i < afterVOs.length; i++)
            {
                // 6 )同步基本信息的pk_org
                updateSqls.add(" update bd_psndoc set pk_org = '" + afterVOs[i].getPk_org() + "' where pk_psndoc = '"
                    + afterVOs[i].getPk_psndoc() + "' ");
                // 同步psnorg中的pk_hrorg
                updateSqls.add(" update hi_psnorg set pk_hrorg = '" + afterVOs[i].getPk_hrorg() + "' where pk_psnorg = '"
                    + afterVOs[i].getPk_psnorg() + "' ");
            }
            if (updateSqls.size() > 0)
            {
                update.executeSQLs(updateSqls.toArray(new String[0]));
            }
            
            // 5)根据信息项设置的同步关系同步人员基础信息,处理信息项的同步; 未实现
            getIPsndocService().updateDataAfterSubDataChanged(WorkVO.getDefaultTableName(), al.toArray(new String[0]));
            getIPsndocService().updateDataAfterSubDataChanged(TrialVO.getDefaultTableName(), al.toArray(new String[0]));
            getIPsndocService().updateDataAfterSubDataChanged(PsnChgVO.getDefaultTableName(), al.toArray(new String[0]));
            getIPsndocService().updateDataAfterSubDataChanged(PsnJobVO.getDefaultTableName(), al.toArray(new String[0]));
            
            // 发送事件-修改薪资数据,修改委托关系
            HiBatchEventValueObject.fireEvent(lastVOs, afterVOs, hrOrgs, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_AFTER);
            HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        }
        catch (Exception e)
        {
            Logger.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        }
        finally
        {
            if (ttu != null)
            {
                
                ttu.clear();
                
            }
        }
        // 同步缓存
        HiCacheUtils.synCache(PsndocVO.getDefaultTableName(), PsnJobVO.getDefaultTableName(), PsnOrgVO.getDefaultTableName());
        
    }
    
    /**
     * @param lastVOs
     * @param afterVOs
     */
    private void batchAddPsnChg(PsnJobVO[] lastVOs, PsnJobVO[] afterVOs) throws BusinessException
    {
        
        ArrayList<String> orgPKList = new ArrayList<String>();
        for (int i = 0; i < afterVOs.length; i++)
        {
            if (lastVOs[i].getPk_org() != null && !orgPKList.contains(lastVOs[i].getPk_org()))
            {
                orgPKList.add(lastVOs[i].getPk_org());
            }
            
            if (afterVOs[i].getPk_org() != null && !orgPKList.contains(afterVOs[i].getPk_org()))
            {
                orgPKList.add(afterVOs[i].getPk_org());
            }
        }
        
        // 创建临时表
        String id = DBAUtil.getIdGenerator().generate();
        String tableName = DBAUtil.createTempTable("temp" + id.substring(9), " pk_org varchar(20) ", "pk_org");
        String[] insertSql = new String[orgPKList.size()];
        
        for (int i = 0; i < insertSql.length; i++)
        {
            insertSql[i] = " insert into " + tableName + " values ( '" + orgPKList.get(i) + "' )";
        }
        DBAUtil.execBatchSql(insertSql);
        
        // 得到组织与公司的对应
        String corpsql =
            " select  hr_orgs1.pk_corp pk_corp , hr_orgs2.pk_org                         "
                + " from (select corp.pk_corp,                                                    "
                + "        a.innercode aos_innercode ,                                               "
                + tableName
                + ".pk_org pkorg                                               "
                + "       from org_adminorg a                                                       "
                + "        inner join org_corp corp                                                       "
                + "        on a.pk_adminorg = corp.pk_corp                                             "
                + "        inner join org_adminorg b                                                "
                + "        on a.innercode = substring ( b.innercode, 1, len( a.innercode ) )         "
                + "        inner join "
                + tableName
                + "        on b.pk_adminorg = "
                + tableName
                + ".pk_org                                       "
                + "       where corp.enablestate =2                                              "
                + "  )                                                                               "
                + "  hr_orgs1                                                                        "
                + "   inner join (select max ( len(a.innercode) ) inlength ,                         "
                + "                "
                + tableName
                + ".pk_org                                             "
                + "               from org_adminorg a                                               "
                + "                inner join org_corp corp                                               "
                + "                on a.pk_adminorg = corp.pk_corp                                     "
                + "                inner join org_adminorg b                                        "
                + "                on a.innercode = substring ( b.innercode, 1, len( a.innercode ) ) "
                + "                inner join "
                + tableName
                + "                on b.pk_adminorg = "
                + tableName
                + ".pk_org                               "
                + "               where corp.enablestate = 2                                      "
                + "               group by "
                + tableName
                + ".pk_org                                     "
                + "   )                                                                              "
                + "   hr_orgs2                                                                       "
                + "   on hr_orgs1.pkorg = hr_orgs2.pk_org                                            "
                + " where len( hr_orgs1.aos_innercode ) = hr_orgs2.inlength                          ";
        
        BaseDAO dao = new BaseDAO();
        GeneralVO[] corpVOs = (GeneralVO[]) dao.executeQuery(corpsql, new GeneralVOProcessor<GeneralVO>(GeneralVO.class));
        HashMap<String, String> corpMap = new HashMap<String, String>();
        for (int i = 0; corpVOs != null && i < corpVOs.length; i++)
        {
            corpMap.put((String) corpVOs[i].getAttributeValue("pk_org"), (String) corpVOs[i].getAttributeValue("pk_corp"));
        }
        
        if (DBAUtil.isExist(" select 1 from " + tableName))
        {
            // 如果临时表还存在删除临时表
            DBAUtil.execBatchSql(new String[]{" delete  from  " + tableName});
        }
        
        // 得到公司名称的对应
        IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        String[] corpPK = corpMap.keySet().toArray(new String[0]);
        HashMap<String, String> corpNameMap = new HashMap<String, String>();
        InSQLCreator isc = null;
        try
        {
            isc = new InSQLCreator();
            OrgVO[] vos = (OrgVO[]) retrieve.retrieveByClause(null, OrgVO.class, " pk_org in ( " + isc.getInSQL(corpPK) + " )");
            
            for (int i = 0; vos != null && i < vos.length; i++)
            {
                corpNameMap.put(vos[i].getPk_org(), MultiLangHelper.getName(vos[i]));
            }
        }
        finally
        {
            if (isc != null)
            {
                isc.clear();
            }
        }
        
        ArrayList<PsnJobVO> al = new ArrayList<PsnJobVO>();
        for (int i = 0; i < afterVOs.length; i++)
        {
            // 如果为跨业务单元的调配并且单据上的属性勾上,要增加流动记录
            String pk_oldorg = lastVOs[i].getPk_org();// 如果当前只有一条工作记录,调配前的org为空,那么为转人员档案是触发的同步操作
            String pk_neworg = afterVOs[i].getPk_org();
            String pk_oldcorp = corpMap.get(pk_oldorg);
            String pk_newcorp = corpMap.get(pk_neworg);
            if (pk_oldcorp != null && pk_newcorp != null && !pk_oldcorp.equals(pk_newcorp))
            {
                al.add(afterVOs[i]);
            }
        }
        
        if (al.size() == 0)
        {
            return;
        }
        
        String[] psnorgPk = new String[al.size()];
        for (int i = 0; i < al.size(); i++)
        {
            psnorgPk[i] = al.get(i).getPk_psnorg();
        }
        InSQLCreator ttc = null;
        try
        {
            ttc = new InSQLCreator();
            
            String psnorgInSql = ttc.getInSQL(psnorgPk);
            
            // 当前行的开始日期
            UFLiteralDate beginDate = al.get(0).getBegindate();
            // 时间校验
            String validateSql =
                " select count(*) from hi_psndoc_psnchg where lastflag = 'Y' and pk_psnorg in (" + psnorgInSql
                    + ") and ( ( isnull(enddate,'~')<>'~' and enddate>='" + beginDate
                    + "' ) or (isnull(enddate,'~')='~' and isnull(begindate,'~')<>'~' and begindate>='" + beginDate + "' ) )";
            Object obj = dao.executeQuery(validateSql, new ColumnProcessor());
            if (obj != null && ((Integer) obj) > 0)
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0271")/*
                                                                                           * @res
                                                                                           * "同步流动情况子集异常:进入日期不能早于等于上一记录的离开日期！"
                                                                                           */);
            }
            
            PsnChgVO[] hisVOs =
                (PsnChgVO[]) retrieve.retrieveByClause(null, PsnChgVO.class, " lastflag = 'Y' and pk_psnorg in (" + psnorgInSql + ") ");
            if (hisVOs == null || hisVOs.length != al.size())
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0350")/* "当前操作涉及的人员中存在没有流动情况子集数据的人员,请补录人员流动情况信息后再进行操作." */);
            }
            
            HashMap<String, PsnChgVO> hisMap = new HashMap<String, PsnChgVO>();
            for (PsnChgVO vo : hisVOs)
            {
                hisMap.put(vo.getPk_psnorg(), vo);
            }
            
            ArrayList<PsnChgVO> updateHisVO = new ArrayList<PsnChgVO>();
            ArrayList<PsnChgVO> newVO = new ArrayList<PsnChgVO>();
            
            for (int i = 0; i < al.size(); i++)
            {
                String preToCorpName = corpNameMap.get(corpMap.get(al.get(i).getPk_org()));// 上一条记录的去向单位是当前的任职单位
                PsnChgVO last = hisMap.get(al.get(i).getPk_psnorg());
                last.setTocorpname(preToCorpName);
                last.setEnddate(beginDate.getDateBefore(1));
                updateHisVO.add(last);
                
                // 添加新纪录
                PsnChgVO psnchg = new PsnChgVO();
                psnchg.setRecordnum(0);
                psnchg.setLastflag(UFBoolean.TRUE);
                psnchg.setPk_group(al.get(i).getPk_hrgroup());
                psnchg.setPk_org(al.get(i).getPk_hrorg());
                psnchg.setPk_psndoc(al.get(i).getPk_psndoc());
                psnchg.setPk_psnorg(al.get(i).getPk_psnorg());
                psnchg.setAssgid(al.get(i).getAssgid());
                psnchg.setBegindate(al.get(i).getBegindate());
                psnchg.setComecorpname(corpNameMap.get(last.getPk_corp()));
                psnchg.setTocorpname(null);
                psnchg.setPk_corp(corpMap.get(al.get(i).getPk_org()));
                psnchg.setCreator(PubEnv.getPk_user());
                psnchg.setCreationtime(PubEnv.getServerTime());
                newVO.add(psnchg);
            }
            
            String updateSql =
                " update hi_psndoc_psnchg set lastflag = 'N',recordnum = recordnum+1 where pk_psnorg in (" + psnorgInSql + ") ";
            dao.executeUpdate(updateSql);
            
            dao.updateVOArray(updateHisVO.toArray(new PsnChgVO[0]), new String[]{PsnChgVO.TOCORPNAME, PsnChgVO.ENDDATE});
            
            dao.insertVOArray(newVO.toArray(new PsnChgVO[0]));
            
        }
        catch (Exception e)
        {
            Logger.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        }
        finally
        {
            if (ttc != null)
            {
                
                ttc.clear();
                
            }
        }
        
    }
    
    public PsnJobVO addNewPsnjob(PsnJobVO saveData, boolean isSynWork, String pk_hrorg) throws BusinessException
    {
        
        // 校验员工号
        checkClerkCodeUnique(saveData);
        
        checkDeptPostCanceled(saveData);
        
        String pk_psnorg = saveData.getPk_psnorg();
        PsnJobVO last = getLastVO(PsnJobVO.class, pk_psnorg, 1);
        if (last != null
            && (last.getBegindate().afterDate(saveData.getBegindate()) || last.getBegindate().isSameDate(saveData.getBegindate())))
        {
            // throw new BusinessException( "当前人员的最新工作记录开始日期晚于或等于转正日期，不能进行后续处理！"
            // );
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0270")/*
                                                                                       * @res
                                                                                       * "当前操作将导致当前操作的人员的最新任职记录开始时间早于其上一条任职记录开始时间."
                                                                                       */);
        }
        fireEvent(last, null, pk_hrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_BEFORE);
        PsnJobVO[] hisVOs = getServiceTemplate().queryByCondition(PsnJobVO.class, " pk_psnorg = '" + pk_psnorg + "' and assgid = 1 ");
        for (int i = 0; hisVOs != null && i < hisVOs.length; i++)
        {
            if (hisVOs[i].getLastflag().booleanValue())
            {
                // 2回写开始日期的前一天到上一条记录的结束日期;结束掉上一条记录
                hisVOs[i] = (PsnJobVO) updateEndflagAndEnddate(hisVOs[i], saveData.getBegindate());
                if (isSynWork)
                {
                    endWork(hisVOs[i].getPk_psnjob(), hisVOs[i].getEnddate());
                }
            }
        }
        updateRecordnumAndLastflag(hisVOs);
        // 3如果当前生效的试用记录未结束且新增的工作记录为转正则结束这条试用记录;否则回写工作记录
        TrialVO trial = getLastVO(TrialVO.class, pk_psnorg, null);
        if (trial != null)
        {
            if (trial.getEndflag() != null && !trial.getEndflag().booleanValue())
            {
                if (saveData.getTrnsevent() != null && saveData.getTrnsevent() == 2)
                {
                    // 未结束的转岗试用,结束之
                    updateEndflagAndEnddate(trial, saveData.getBegindate());
                    // 试用同步人员基本信息
                    getIPsndocService().updateDataAfterSubDataChanged(TrialVO.getDefaultTableName(), saveData.getPk_psndoc());
                }
                else
                {
                    // 非转正
                    saveData.setTrial_flag(UFBoolean.TRUE);
                    saveData.setTrial_type(trial.getTrial_type());
                }
            }
            else
            {
                // 未结束的试用 ,新增的工作记录的是否试用为是,试用类型为试用类型
                saveData.setTrial_flag(UFBoolean.FALSE);
                saveData.setTrial_type(null);
            }
        }
        
        // 更新保存数据中的pk_hrorg
        saveData.setPk_hrorg(pk_hrorg);
        PsnJobVO retVO = getServiceTemplate().insert(saveData);
        if (isSynWork)
        {
            // 4)isSynWork为true时,同步工作履历记录;
            addWork(retVO);
        }
        // 同步流动情况
        addPsnChg(retVO, true);
        // 5)根据信息项设置的同步关系同步人员基础信息,处理信息项的同步; 未实现
        getIPsndocService().updateDataAfterSubDataChanged(PsnJobVO.getDefaultTableName(), retVO.getPk_psndoc());
        // 6 )同步基本信息的pk_org
        synPkorgOfPsndoc(retVO.getPk_org(), retVO.getPk_psndoc());
        
        // 同步psnorg中的pk_hrorg
        synPkhrorgOfPsnorg(retVO.getPk_psnorg(), retVO.getPk_hrorg());
        
        // 发送事件-修改薪资数据,修改委托关系
        fireEvent(last, retVO, pk_hrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_AFTER);
        HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        
        // 同步缓存
        HiCacheUtils.synCache(PsndocVO.getDefaultTableName(), PsnJobVO.getDefaultTableName(), PsnOrgVO.getDefaultTableName());
        
        return retVO;
    }
    
    public PsnJobVO addNewPsnjobTran(PsnJobVO saveData, boolean isSynWork, boolean isFinshPart, String pk_hrorg) throws BusinessException
    {
        
        // 校验员工号
        checkClerkCodeUnique(saveData);
        
        checkDeptPostCanceled(saveData);
        
        String pk_psnorg = saveData.getPk_psnorg();
        PsnJobVO last = getLastVO(PsnJobVO.class, pk_psnorg, 1);
        if (last != null
            && (last.getBegindate().afterDate(saveData.getBegindate()) || last.getBegindate().isSameDate(saveData.getBegindate())))
        {
            // throw new BusinessException( "当前人员的最新工作记录开始日期晚于或等于转正日期，不能进行后续处理！"
            // );
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0270")/*
                                                                                       * @res
                                                                                       * "当前操作将导致当前操作的人员的最新任职记录开始时间早于其上一条任职记录开始时间."
                                                                                       */);
        }
        fireEvent(last, null, pk_hrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_BEFORE);
        PsnJobVO[] hisVOs = getServiceTemplate().queryByCondition(PsnJobVO.class, " pk_psnorg = '" + pk_psnorg + "' and assgid = 1 ");
        for (int i = 0; hisVOs != null && i < hisVOs.length; i++)
        {
            if (hisVOs[i].getLastflag().booleanValue())
            {
                // 2回写开始日期的前一天到上一条记录的结束日期;结束掉上一条记录
                hisVOs[i] = (PsnJobVO) updateEndflagAndEnddate(hisVOs[i], saveData.getBegindate());
                if (isSynWork)
                {
                    endWork(hisVOs[i].getPk_psnjob(), hisVOs[i].getEnddate());
                }
            }
        }
        updateRecordnumAndLastflag(hisVOs);
        // 3如果当前生效的试用记录未结束且新增的工作记录为转正则结束这条试用记录;否则回写工作记录
        TrialVO trial = getLastVO(TrialVO.class, pk_psnorg, null);
        if (trial != null)
        {
            if (trial.getEndflag() != null && !trial.getEndflag().booleanValue())
            {
                if (saveData.getTrnsevent() != null && saveData.getTrnsevent() == 2)
                {
                    // 未结束的转岗试用,结束之
                    updateEndflagAndEnddate(trial, saveData.getBegindate());
                    // 试用同步人员基本信息
                    getIPsndocService().updateDataAfterSubDataChanged(TrialVO.getDefaultTableName(), saveData.getPk_psndoc());
                }
                else
                {
                    // 非转正
                    saveData.setTrial_flag(UFBoolean.TRUE);
                    saveData.setTrial_type(trial.getTrial_type());
                }
            }
            else
            {
                // 未结束的试用 ,新增的工作记录的是否试用为是,试用类型为试用类型
                saveData.setTrial_flag(UFBoolean.FALSE);
                saveData.setTrial_type(null);
            }
        }
        
        // 更新保存数据中的pk_hrorg
        saveData.setPk_hrorg(pk_hrorg);
        PsnJobVO retVO = getServiceTemplate().insert(saveData);
        if (isSynWork)
        {
            // 4)isSynWork为true时,同步工作履历记录;
            addWork(retVO);
        }
        
        // 3-4)结束兼职
        if (isFinshPart)
        {
            // 结束当前组织关系下未结束的兼职记录
            PartTimeVO[] part =
                getServiceTemplate().queryByCondition(
                    PartTimeVO.class,
                    " pk_psnorg = '" + saveData.getPk_psnorg() + "' and assgid > 1 and ( " + SQLHelper.getNullSql("endflag")
                        + " or endflag = 'N' ) ");
            UFLiteralDate enddate = saveData.getBegindate();
            for (int i = 0; part != null && i < part.length; i++)
            {
                getIPersonRecordService().updateEndflagAndEnddate(part[i], enddate);
                
                if (isSynWork)
                {
                    // 同步工作履历结束兼职对应的工作履历
                    getIPersonRecordService().endWork(part[i].getPk_psnjob(), enddate.getDateBefore(1));
                }
            }
            // 更新人员基本信息
            // getIPsndocService().updateDataAfterSubDataChanged(PartTimeVO.getDefaultTableName(),
            // ((StapplyVO) bill.getParentVO()).getPk_psndoc());
        }
        
        // 同步流动情况
        addPsnChg(retVO, true);
        // 5)根据信息项设置的同步关系同步人员基础信息,处理信息项的同步; 未实现
        getIPsndocService().updateDataAfterSubDataChanged(PsnJobVO.getDefaultTableName(), retVO.getPk_psndoc());
        // 6 )同步基本信息的pk_org
        synPkorgOfPsndoc(retVO.getPk_org(), retVO.getPk_psndoc());
        
        // 同步psnorg中的pk_hrorg
        synPkhrorgOfPsnorg(retVO.getPk_psnorg(), retVO.getPk_hrorg());
        
        // 人员调配后，更新人员对应用户的所属组织
        updateUserOrg(retVO, pk_hrorg);
        
        // 发送事件-修改薪资数据,修改委托关系
        fireEvent(last, retVO, pk_hrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_AFTER);
        HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        
        // 同步缓存
        HiCacheUtils.synCache(PsndocVO.getDefaultTableName(), PsnJobVO.getDefaultTableName(), PsnOrgVO.getDefaultTableName());
        
        return retVO;
    }
    
    private IPersonRecordService getIPersonRecordService()
    {
        return NCLocator.getInstance().lookup(IPersonRecordService.class);
    }
    
    public PsnJobVO addNewPsnjob(PsnJobVO saveData, boolean isSynWork, String pk_hrorg, String pk_hrcm_org) throws BusinessException
    {
        
        // 校验员工号
        checkClerkCodeUnique(saveData);
        
        checkDeptPostCanceled(saveData);
        
        String pk_psnorg = saveData.getPk_psnorg();
        PsnJobVO last = getLastVO(PsnJobVO.class, pk_psnorg, 1);
        if (last != null
            && (last.getBegindate().afterDate(saveData.getBegindate()) || last.getBegindate().isSameDate(saveData.getBegindate())))
        {
            // throw new BusinessException( "当前人员的最新工作记录开始日期晚于或等于转正日期，不能进行后续处理！"
            // );
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0270")/*
                                                                                       * @res
                                                                                       * "当前操作将导致当前操作的人员的最新任职记录开始时间早于其上一条任职记录开始时间."
                                                                                       */);
        }
        fireEvent(last, null, pk_hrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_BEFORE);
        PsnJobVO[] hisVOs = getServiceTemplate().queryByCondition(PsnJobVO.class, " pk_psnorg = '" + pk_psnorg + "' and assgid = 1 ");
        for (int i = 0; hisVOs != null && i < hisVOs.length; i++)
        {
            if (hisVOs[i].getLastflag().booleanValue())
            {
                // 2回写开始日期的前一天到上一条记录的结束日期;结束掉上一条记录
                hisVOs[i] = (PsnJobVO) updateEndflagAndEnddate(hisVOs[i], saveData.getBegindate());
                if (isSynWork)
                {
                    endWork(hisVOs[i].getPk_psnjob(), hisVOs[i].getEnddate());
                }
            }
        }
        updateRecordnumAndLastflag(hisVOs);
        // 3如果当前生效的试用记录未结束且新增的工作记录为转正则结束这条试用记录;否则回写工作记录
        TrialVO trial = getLastVO(TrialVO.class, pk_psnorg, null);
        if (trial != null)
        {
            if (trial.getEndflag() != null && !trial.getEndflag().booleanValue())
            {
                if (saveData.getTrnsevent() != null && saveData.getTrnsevent() == 2)
                {
                    // 未结束的转岗试用,结束之
                    updateEndflagAndEnddate(trial, saveData.getBegindate());
                    // 试用同步人员基本信息
                    getIPsndocService().updateDataAfterSubDataChanged(TrialVO.getDefaultTableName(), saveData.getPk_psndoc());
                }
                else
                {
                    // 非转正
                    saveData.setTrial_flag(UFBoolean.TRUE);
                    saveData.setTrial_type(trial.getTrial_type());
                }
            }
            else
            {
                // 未结束的试用 ,新增的工作记录的是否试用为是,试用类型为试用类型
                saveData.setTrial_flag(UFBoolean.FALSE);
                saveData.setTrial_type(null);
            }
        }
        
        // 更新保存数据中的pk_hrorg
        saveData.setPk_hrorg(pk_hrorg);
        PsnJobVO retVO = getServiceTemplate().insert(saveData);
        if (isSynWork)
        {
            // 4)isSynWork为true时,同步工作履历记录;
            addWork(retVO);
        }
        // 同步流动情况
        addPsnChg(retVO, true);
        // 5)根据信息项设置的同步关系同步人员基础信息,处理信息项的同步; 未实现
        getIPsndocService().updateDataAfterSubDataChanged(PsnJobVO.getDefaultTableName(), retVO.getPk_psndoc());
        // 6 )同步基本信息的pk_org
        synPkorgOfPsndoc(retVO.getPk_org(), retVO.getPk_psndoc());
        
        // 同步psnorg中的pk_hrorg
        synPkhrorgOfPsnorg(retVO.getPk_psnorg(), retVO.getPk_hrorg());
        
        //
        if (StringUtils.isNotBlank(pk_hrcm_org)) retVO.setAttributeValue("pk_hrcm_org", pk_hrcm_org);
        
        // 人员调配后，更新人员对应用户的所属组织
        updateUserOrg(retVO, pk_hrorg);
        
        // 发送事件-修改薪资数据,修改委托关系
        fireEvent(last, retVO, pk_hrorg, HICommonValue.PSNJOBSOURCEID, IEventType.TYPE_INSERT_AFTER);
        HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        
        // 同步缓存
        HiCacheUtils.synCache(PsndocVO.getDefaultTableName(), PsnJobVO.getDefaultTableName(), PsnOrgVO.getDefaultTableName());
        
        return retVO;
    }
    
    // 人员调配后，更新人员对应用户的所属组织
    public void updateUserOrg(PsnJobVO retVO, String pk_hrorg) throws BusinessException
    {
        if (null == retVO || StringUtils.isBlank(pk_hrorg))
        {
            return;
        }
        UserVO[] uesrvo = getServiceTemplate().queryByCondition(UserVO.class, " pk_base_doc = '" + retVO.getPk_psndoc() + "' ");
        if (ArrayUtils.isEmpty(uesrvo))
        {
            return;
        }
        for (UserVO userVO : uesrvo)
        {
            userVO.setPk_org(pk_hrorg);
        }
        NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, uesrvo, null, null);
    }
    
    /**
     * 校验问结束的工作记录中部门/岗位是否撤销
     * 
     * @param psnJobVO
     * @throws BusinessException
     */
    public void checkDeptPostCanceled(PsnJobVO psnJobVO) throws BusinessException
    {
        
        if (psnJobVO != null && psnJobVO.getEndflag() != null && psnJobVO.getEndflag().booleanValue())
        {
            // 一结束的任职不用校验
            return;
        }
        
        IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        
        String pk_org = psnJobVO.getPk_org();
        AdminOrgVO org = StringUtils.isBlank(pk_org) ? null : (AdminOrgVO) retrieve.retrieveByPk(null, AdminOrgVO.class, pk_org);
        if (org != null && org.getEnablestate() != null && org.getEnablestate() != IPubEnumConst.ENABLESTATE_ENABLE)
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0477")/* "任职职未结束,任职组织不能为停用的行政组织" */);
        }
        
        String pk_dept = psnJobVO.getPk_dept();
        DeptVO dept = StringUtils.isBlank(pk_dept) ? null : (DeptVO) retrieve.retrieveByPk(null, DeptVO.class, pk_dept);
        if (dept != null && dept.getHrcanceled() != null && dept.getHrcanceled().booleanValue())
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0323"/* @res "任职未结束,部门不能为撤销部门" */));
        }
        
        if (dept != null && dept.getEnablestate() != null && dept.getEnablestate() != IPubEnumConst.ENABLESTATE_ENABLE)
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0372")/*
                                                                                       * @res
                                                                                       * "任职记录未结束,部门不能为停用部门"
                                                                                       */);
        }
        
        String pk_post = psnJobVO.getPk_post();
        PostVO post = StringUtils.isBlank(pk_post) ? null : (PostVO) retrieve.retrieveByPk(null, nc.vo.om.post.PostVO.class, pk_post);
        if (post != null && post.getHrcanceled() != null && post.getHrcanceled().booleanValue())
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0324"/*
                                                                                      * @res
                                                                                      * "任职记录未结束,岗位不能为撤销岗位"
                                                                                      */));
        }
        
        if (post != null && post.getEnablestate() != null && post.getEnablestate() != IPubEnumConst.ENABLESTATE_ENABLE)
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0373")/*
                                                                                       * @res
                                                                                       * "任职记录未结束,岗位不能为停用岗位"
                                                                                       */);
        }
        
        String pk_job = psnJobVO.getPk_job();
        JobVO job = StringUtils.isBlank(pk_job) ? null : (JobVO) retrieve.retrieveByPk(null, JobVO.class, pk_job);
        
        if (job != null && job.getEnablestate() != null && job.getEnablestate() != IPubEnumConst.ENABLESTATE_ENABLE)
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0374")/*
                                                                                       * @res
                                                                                       * "任职记录未结束,职务不能为停用职务"
                                                                                       */);
        }
        
    }
    
    /**
     * 同步psnorg中的pk_hrorg
     * 
     * @param pk_psnorg
     * @param pk_hrorg
     * @throws BusinessException
     */
    public void synPkhrorgOfPsnorg(String pk_psnorg, String pk_hrorg) throws BusinessException
    {
        String sql = " update hi_psnorg set pk_hrorg = '" + pk_hrorg + "' where pk_psnorg = '" + pk_psnorg + "' ";
        NCLocator.getInstance().lookup(IPersistenceUpdate.class).executeSQLs(new String[]{sql});
    }
    
    /**
     * 转档时增加流动记录
     * 
     * @param psnjobVO
     * @throws BusinessException
     */
    public void addPsnChgWhenIntoDoc(PsnJobVO psnjobVO) throws BusinessException
    {
        String pk_neworg = psnjobVO.getPk_org();
        String pk_newcorp = HiSQLHelper.getPkCorpByPkOrg(pk_neworg);
        // 没找到公司则不添加流动情况
        PsnChgVO lastVO = getLastVO(PsnChgVO.class, psnjobVO.getPk_psnorg(), null);
        if (lastVO != null)
        {
            // 当前行的开始日期
            UFLiteralDate beginDate = psnjobVO.getBegindate();
            // 前一条记录的开始日期
            UFLiteralDate preRowBegindate = lastVO.getBegindate();
            // 前一条记录的结束日期
            UFLiteralDate preRowEnddate = lastVO.getEnddate();
            
            if (preRowEnddate != null && (preRowEnddate.compareTo(beginDate) == 0 || preRowEnddate.afterDate(beginDate)))
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0271")/*
                                                                                           * @res
                                                                                           * "同步流动情况子集异常:到职日期不能早于等于上一记录的离职日期！"
                                                                                           */);
            }
            
            if (preRowBegindate != null && (preRowBegindate.compareTo(beginDate) == 0 || preRowBegindate.afterDate(beginDate)))
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0272")/*
                                                                                           * @res
                                                                                           * "同步流动情况子集异常:到职日期不能早于等于上一记录的离职日期！"
                                                                                           */);
            }
            // 回写上一条记录的结束日期
            updateEndflagAndEnddate(lastVO, beginDate);
            
            // 更新历史记录的recordnum&lastflag
            PsnChgVO[] his =
                getServiceTemplate().queryByCondition(PsnChgVO.class, " pk_psnorg = '" + psnjobVO.getPk_psnorg() + "' order by recordnum ");
            updateRecordnumAndLastflag(his);
            doAddPsnChg(psnjobVO, null, pk_newcorp, true);
        }
        else
        {
            doAddPsnChg(psnjobVO, null, pk_newcorp, true);
        }
    }
    
    private void doAddPsnChg(PsnJobVO psnjobVO, String comeCorpName, String pk_newcorp, boolean isSyncPsndoc) throws BusinessException
    {
        
        // 添加新纪录
        PsnChgVO psnchg = new PsnChgVO();
        psnchg.setRecordnum(0);
        psnchg.setLastflag(UFBoolean.TRUE);
        psnchg.setPk_group(psnjobVO.getPk_hrgroup());
        psnchg.setPk_org(psnjobVO.getPk_hrorg());
        psnchg.setPk_psndoc(psnjobVO.getPk_psndoc());
        psnchg.setPk_psnorg(psnjobVO.getPk_psnorg());
        psnchg.setAssgid(psnjobVO.getAssgid());
        psnchg.setBegindate(psnjobVO.getBegindate());
        psnchg.setComecorpname(comeCorpName);
        psnchg.setTocorpname(null);
        psnchg.setPk_corp(pk_newcorp);
        
        psnchg = new PsndocDAO().insert4SubSet(psnchg, true);
        if (isSyncPsndoc)
        {
            // 更新人员基本信息
            getIPsndocService().updateDataAfterSubDataChanged(PsnChgVO.getDefaultTableName(), psnchg.getPk_psndoc());
        }
    }
    
    /**
     * 新增工作记录,增加一条流动记录
     * 
     * @param psnjobVO
     * @throws BusinessException
     */
    @Override
    public void addPsnChg(PsnJobVO psnjobVO, boolean isSyncPsndoc) throws BusinessException
    {
        // 如果为跨业务单元的调配并且单据上的属性勾上,要增加流动记录
        String pk_oldorg = getPrePkOrg(psnjobVO);// 如果当前只有一条工作记录,调配前的org为空,那么为转人员档案是触发的同步操作
        String pk_neworg = psnjobVO.getPk_org();
        String pk_oldcorp = HiSQLHelper.getPkCorpByPkOrg(pk_oldorg);
        String pk_newcorp = HiSQLHelper.getPkCorpByPkOrg(pk_neworg);
        String preToCorpName = VOUtils.getDocName(OrgVO.class, pk_newcorp);// 上一条记录的去向单位是当前的任职单位
        String comeCorpName = "";// 当前的来源单位是上一条的任职单位
        // 不管是否为空，只要不同即新增一条，即只有两个都为空，或者两个相同时候不生成
        
        if (!(pk_oldcorp == null && pk_newcorp == null) && !StringUtils.equals(pk_oldcorp, pk_newcorp))
        {
            
            PsnChgVO lastVO = getLastVO(PsnChgVO.class, psnjobVO.getPk_psnorg(), null);
            // 校验记录间的开始结束日期关系
            if (lastVO != null)
            {
                // 当前行的开始日期
                UFLiteralDate beginDate = psnjobVO.getBegindate();
                // 前一条记录的开始日期
                UFLiteralDate preRowBegindate = lastVO.getBegindate();
                // 前一条记录的结束日期
                UFLiteralDate preRowEnddate = lastVO.getEnddate();
                
                if (preRowEnddate != null && (preRowEnddate.compareTo(beginDate) == 0 || preRowEnddate.afterDate(beginDate)))
                {
                    throw new BusinessException(ResHelper.getString("6007psn", "06007psn0271")/*
                                                                                               * @res
                                                                                               * "同步流动情况子集异常:进入日期不能早于等于上一记录的离开日期！"
                                                                                               */);
                }
                
                if (preRowBegindate != null && (preRowBegindate.compareTo(beginDate) == 0 || preRowBegindate.afterDate(beginDate)))
                {
                    throw new BusinessException(ResHelper.getString("6007psn", "06007psn0272")/*
                                                                                               * @res
                                                                                               * "同步流动情况子集异常:进入日期不能早于等于上一记录的进入日期！"
                                                                                               */);
                }
                if (StringUtils.isBlank(lastVO.getTocorpname()))
                {
                    // 回写上一条的去向单位
                    lastVO.setTocorpname(preToCorpName);
                }
                
                // 由于历史代码问题上一条记录的任职单位不一定是新确定需求的法人，这里给更新一下
                lastVO.setPk_corp(HiSQLHelper.getPkCorpByPkOrg(lastVO.getPk_corp()));
                
                // 回写上一条记录的结束日期
                updateEndflagAndEnddate(lastVO, beginDate);
                // 获得来源单位
                comeCorpName = VOUtils.getDocName(OrgVO.class, lastVO.getPk_corp());
            }
            
            // 更新历史记录的recordnum&lastflag
            PsnChgVO[] his =
                getServiceTemplate().queryByCondition(PsnChgVO.class, " pk_psnorg = '" + psnjobVO.getPk_psnorg() + "' order by recordnum ");
            updateRecordnumAndLastflag(his);
            
            doAddPsnChg(psnjobVO, comeCorpName, pk_newcorp, isSyncPsndoc);
        }
    }
    
    /**
     * 查找上一条工作记录的任职组织<br>
     * 如果当前只有一条工作记录,那么为转人员档案是触发的同步操作
     * 
     * @param vo
     * @return String
     * @throws BusinessException
     */
    private String getPrePkOrg(PsnJobVO vo) throws BusinessException
    {
        PsnJobVO[] preVO =
            getServiceTemplate().queryByCondition(
                PsnJobVO.class,
                " pk_psnorg = '" + vo.getPk_psnorg() + "' and assgid = " + vo.getAssgid().intValue() + "  and recordnum > "
                    + vo.getRecordnum().intValue() + "  order by recordnum ");
        if (preVO != null && preVO.length > 0)
        {
            return preVO[0].getPk_org();
        }
        return null;
    }
    
    public void addWork(PsnJobVO retVO) throws BusinessException
    {
        // 更新历史履历记录
        WorkVO[] vos = getServiceTemplate().queryByCondition(WorkVO.class, " pk_psndoc = '" + retVO.getPk_psndoc() + "'");
        updateRecordnumAndLastflag(vos);// 更新lastflag&recordnum
        // 删除此pk_psnjob之前对应的工作履历的对应关系并结束之
        WorkVO[] wvo = getServiceTemplate().queryByCondition(WorkVO.class, " pk_psnjob = '" + retVO.getPk_psnjob() + "'");
        if (null != wvo && wvo.length > 0)
        {
            for (int i = 0; wvo != null && i < wvo.length; i++)
            {
                wvo[i].setPk_psnjob(null);
                if (wvo[i].getEnddate() == null)
                {
                    wvo[i].setEnddate(retVO.getBegindate() == null ? PubEnv.getServerLiteralDate() : retVO.getBegindate().getDateBefore(1));
                }
                // new PsndocDAO().update4SubSet(wvo[i], false, false);
            }
            NCLocator.getInstance().lookup(IPersistenceUpdate.class)
                .updateVOArray(null, wvo, new String[]{WorkVO.PK_PSNJOB, WorkVO.ENDDATE}, null);
        }
        // else
        // {// 有可能此pk_psnjob之前没有对应的工作履历 heqiaoa 20150604
        // for (int i = 0; vos != null && i < vos.length; i++)
        // {
        // if (vos[i].getEnddate() == null)
        // {
        // vos[i].setEnddate(retVO.getBegindate() == null ? PubEnv.getServerLiteralDate() :
        // retVO.getBegindate().getDateBefore(1));
        // }
        // }
        // if (null != vos && vos.length > 0)
        // {
        // NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, vos, new
        // String[]{WorkVO.ENDDATE}, null);
        // }
        // }
        
        // 根据新增的工作记录,生成一条新的履历记录,保存之
        WorkVO newWork = new WorkVO();
        newWork.setPk_group(retVO.getPk_group());
        newWork.setPk_org(retVO.getPk_hrorg());
        newWork.setPk_psndoc(retVO.getPk_psndoc());
        newWork.setPk_psnjob(retVO.getPk_psnjob());
        newWork.setRecordnum(0);
        newWork.setLastflag(UFBoolean.TRUE);
        newWork.setBegindate(retVO.getBegindate());
        newWork.setEnddate(retVO.getEnddate());
        newWork.setMemo(retVO.getMemo());
        // 组织
        newWork.setWorkcorp(VOUtils.getDocName(OrgVO.class, retVO.getPk_org()));
        // 部门
        newWork.setWorkdept(VOUtils.getDocName(DeptVO.class, retVO.getPk_dept()));
        // 岗位
        newWork.setWorkpost(VOUtils.getDocName(PostVO.class, retVO.getPk_post()));
        // 职务
        newWork.setWorkjob(VOUtils.getDocName(JobVO.class, retVO.getPk_job()));
        
        this.dealWorkSyncItem(newWork, retVO);
        
        newWork = new PsndocDAO().insert4SubSet(newWork, true);
        // 同步人员基本信息
        getIPsndocService().updateDataAfterSubDataChanged(WorkVO.getDefaultTableName(), newWork.getPk_psndoc());
    }
    
    public void addWorkWithoutSynPsndoc(PsnJobVO retVO) throws BusinessException
    {
        // 更新历史履历记录
        WorkVO[] vos =
            (WorkVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
                .retrieveByClause(null, WorkVO.class, " pk_psndoc = '" + retVO.getPk_psndoc() + "'");
        
        for (int i = 0; vos != null && i < vos.length; i++)
        {
            vos[i].setLastflag(UFBoolean.FALSE);
            vos[i].setRecordnum(vos[i].getRecordnum() + 1);
            if (retVO.getPk_psnjob().equals(vos[i].getPk_psnjob()))
            {
                vos[i].setPk_psnjob(null);
                if (vos[i].getEnddate() == null)
                {
                    vos[i].setEnddate(retVO.getBegindate() == null ? PubEnv.getServerLiteralDate() : retVO.getBegindate().getDateBefore(1));
                }
            }
        }
        
        new BaseDAO().updateVOArray(vos, new String[]{WorkVO.LASTFLAG, WorkVO.RECORDNUM, WorkVO.PK_PSNJOB, WorkVO.ENDDATE});
        
        // 根据新增的工作记录,生成一条新的履历记录,保存之
        WorkVO newWork = new WorkVO();
        newWork.setPk_group(retVO.getPk_group());
        newWork.setPk_org(retVO.getPk_hrorg());
        newWork.setPk_psndoc(retVO.getPk_psndoc());
        newWork.setPk_psnjob(retVO.getPk_psnjob());
        newWork.setRecordnum(0);
        newWork.setLastflag(UFBoolean.TRUE);
        newWork.setBegindate(retVO.getBegindate());
        newWork.setEnddate(retVO.getEnddate());
        newWork.setMemo(retVO.getMemo());
        // 组织
        newWork.setWorkcorp(VOUtils.getDocName(OrgVO.class, retVO.getPk_org()));
        // 部门
        newWork.setWorkdept(VOUtils.getDocName(DeptVO.class, retVO.getPk_dept()));
        // 岗位
        newWork.setWorkpost(VOUtils.getDocName(PostVO.class, retVO.getPk_post()));
        // 职务
        newWork.setWorkjob(VOUtils.getDocName(JobVO.class, retVO.getPk_job()));
        
        dealWorkSyncItem(newWork, retVO);
        
        new PsndocDAO().insert4SubSet(newWork, false);
    }
    
    private void dealWorkSyncItem(WorkVO newWork, PsnJobVO job) throws BusinessException
    {
        // 获得工作记录到履历信息同步字段映射
        PsndocDAO psnDao = new PsndocDAO();
        // 是主职
        HashMap<String, GeneralVO> syncMap =
            psnDao.getWorkSyncMap(job.getPk_hrorg(), job.getPk_group(), job.getIsmainjob() != null && job.getIsmainjob().booleanValue());
        // 根据映射关系同步工作记录到履历记录
        if (syncMap != null)
        {
            String[] jobItems = syncMap.keySet().toArray(new String[0]);
            for (String jobItem : jobItems)
            {
                // 验证两方同步字段是否都在使用，未使用则不同步
                String[] jobAttrSet = job.getAttributeNames();
                String[] workAttrSet = newWork.getAttributeNames();
                if (ArrayUtils.contains(jobAttrSet, jobItem)
                    && ArrayUtils.contains(workAttrSet, (String) syncMap.get(jobItem).getAttributeValue("workcode")))
                {
                    Integer jobDataType = (Integer) syncMap.get(jobItem).getAttributeValue("jobdatatype");
                    Integer workDataType = (Integer) syncMap.get(jobItem).getAttributeValue("workdatatype");
                    // 从参照同步到文本,需要将参照名称同步到文本字段,不能直接同步
                    if (IBillItem.UFREF == jobDataType && IBillItem.STRING == workDataType)
                    {
                        String pk_refinfo = (String) syncMap.get(jobItem).getAttributeValue("jobrefmodule");
                        Object value = job.getAttributeValue(jobItem);
                        String pk_infoset_item = (String) syncMap.get(jobItem).getAttributeValue("job_pk_infoset_item");
                        // 参照对应名称
                        String name = psnDao.getRefItemName(pk_refinfo, value, pk_infoset_item);
                        String workItemCode = (String) syncMap.get(jobItem).getAttributeValue("workcode");
                        newWork.setAttributeValue(workItemCode, name);
                    }
                    // 否则则直接同步
                    else
                    {
                        String workItemCode = (String) syncMap.get(jobItem).getAttributeValue("workcode");
                        newWork.setAttributeValue(workItemCode, job.getAttributeValue(jobItem));
                    }
                    
                }
            }
        }
    }
    
    /**
     * 结束工作履历,不同步基本信息
     * 
     * @param pk_psnjob
     * @param endDate
     * @throws BusinessException
     */
    public void endWorkWithoutSynPsndoc(String pk_psnjob, UFLiteralDate endDate) throws BusinessException
    {
        // 如果同步工作履历,则结束其对应的工作履历
        WorkVO[] work =
            (WorkVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
                .retrieveByClause(null, WorkVO.class, " pk_psnjob = '" + pk_psnjob + "' ");
        for (int j = 0; work != null && j < work.length; j++)
        {
            UFLiteralDate begin = work[j].getBegindate();
            if (begin != null && begin.afterDate(endDate))
            {
                // 如果开始日期大于结束日期,则将开始日期
                work[j].setEnddate(begin);
            }
            else
            {
                work[j].setEnddate(endDate);
            }
            // new PsndocDAO().update4SubSet(work[j], false, false);
        }
        NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, work, new String[]{WorkVO.ENDDATE}, null);
    }
    
    public void endWork(String pk_psnjob, UFLiteralDate endDate) throws BusinessException
    {
        // 如果同步工作履历,则结束其对应的工作履历
        WorkVO[] work = getServiceTemplate().queryByCondition(WorkVO.class, " pk_psnjob = '" + pk_psnjob + "' ");
        for (int j = 0; work != null && j < work.length; j++)
        {
            UFLiteralDate begin = work[j].getBegindate();
            if (begin != null && begin.afterDate(endDate))
            {
                // 如果开始日期大于结束日期,则将开始日期
                work[j].setEnddate(begin);
            }
            else
            {
                work[j].setEnddate(endDate);
            }
        }
        NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, work, new String[]{WorkVO.ENDDATE}, null);
        // 履历同步人员基本信息
        PsnJobVO pj = getServiceTemplate().queryByPk(PsnJobVO.class, pk_psnjob);
        getIPsndocService().updateDataAfterSubDataChanged(WorkVO.getDefaultTableName(), pj.getPk_psndoc());
    }
    
    private void endWork(PsnJobVO psnjob, PsnJobVO dimission) throws BusinessException
    {
        // 兼职
        if (psnjob.getIsmainjob() == null || !psnjob.getIsmainjob().booleanValue())
        {
            endWork(psnjob.getPk_psnjob(), dimission.getBegindate().getDateBefore(1));
        }
        else
        {
            // 主职
            // 如果同步工作履历,则结束其对应的工作履历
            WorkVO[] work = getServiceTemplate().queryByCondition(WorkVO.class, " pk_psnjob = '" + psnjob.getPk_psnjob() + "' ");
            for (int j = 0; work != null && j < work.length; j++)
            {
                UFLiteralDate begin = work[j].getBegindate();
                if (begin != null && begin.afterDate(dimission.getBegindate().getDateBefore(1)))
                {
                    // 如果开始日期大于结束日期,则将开始日期
                    work[j].setEnddate(begin);
                }
                else
                {
                    work[j].setEnddate(dimission.getBegindate().getDateBefore(1));
                }
                work[j].setDimission_reason(VOUtils.getDocName(DefdocVO.class, dimission.getTrnsreason()));
            }
            NCLocator.getInstance().lookup(IPersistenceUpdate.class)
                .updateVOArray(null, work, new String[]{WorkVO.ENDDATE, WorkVO.DIMISSION_REASON}, null);
            // 履历同步人员基本信息
            getIPsndocService().updateDataAfterSubDataChanged(WorkVO.getDefaultTableName(), psnjob.getPk_psndoc());
        }
    }
    
    /**
     * 发送事件
     * 
     * @param before
     * @param after
     * @param pk_hrorg
     * @param sourceID
     * @param eventType
     * @throws BusinessException
     */
    private void fireEvent(PsnJobVO before, PsnJobVO after, String pk_hrorg, String sourceID, String eventType) throws BusinessException
    {
        HiEventValueObject.fireEvent(before, after, pk_hrorg, sourceID, eventType);
    }
    
    private IPsndocService getIPsndocService()
    {
        return NCLocator.getInstance().lookup(IPsndocService.class);
    }
    
    public <T extends SuperVO> T getLastVO(Class<T> className, String pk_psnorg, Integer assgid) throws BusinessException
    {
        String where = " pk_psnorg = '" + pk_psnorg + "' and lastflag = 'Y' ";
        if (assgid != null)
        {
            where += " and assgid = " + assgid.intValue();
        }
        SuperVO[] vos = getServiceTemplate().queryByCondition(className, where);
        if (vos != null && vos.length > 0)
        {
            return (T) vos[0];
        }
        return null;
    }
    
    @Override
    public int getMaxAssgidByPsndoc(String pkPsndoc) throws BusinessException
    {
        String pk_psnorg = getPsnorgByPsndoc(pkPsndoc);
        String strSQL = "select max(assgid) as maxid from hi_psnjob where pk_psnorg = '" + pk_psnorg + "' ";
        HashMap hm = (HashMap) NCLocator.getInstance().lookup(IPersistenceHome.class).executeQuery(strSQL, new MapProcessor());
        if (hm == null || hm.get("maxid") == null || !(hm.get("maxid") instanceof Integer))
        {
            return 2;
        }
        return ((Integer) hm.get("maxid")).intValue() + 1;
    }
    
    @Override
    public String getNewPkpsnjob(String oldPkpsnjob) throws BusinessException
    {
        PsnJobVO oldvo = getServiceTemplate().queryByPk(PsnJobVO.class, oldPkpsnjob);
        PsnJobVO[] newvo =
            getServiceTemplate().queryByCondition(
                PsnJobVO.class,
                " pk_psnorg = '" + oldvo.getPk_psnorg() + "' and assgid = " + oldvo.getAssgid().intValue()
                    + " and ismainjob = 'Y' and lastflag = 'Y' ");
        if (newvo == null || newvo.length == 0)
        {
            return oldvo.getPk_psnjob();
        }
        return newvo[0].getPk_psnjob();
    }
    
    @Override
    public String getPsnjobByPsndoc(String pkPsndoc) throws BusinessException
    {
        String pk_psnorg = this.getPsnorgByPsndoc(pkPsndoc);
        PsnJobVO[] psnjob =
            getServiceTemplate().queryByCondition(PsnJobVO.class, " pk_psnorg = '" + pk_psnorg + "' and lastflag = 'Y' and assgid = 1 ");
        if (psnjob == null || psnjob.length == 0)
        {
            Logger.error("当前人员没有最新任职记录");
            return null;
        }
        if (psnjob.length > 1)
        {
            Logger.error("当前人员有多条最新的任职记录");
            return psnjob[0].getPk_psnjob();
        }
        return psnjob[0].getPk_psnjob();
    }
    
    @Override
    public String getPsnorgByPsndoc(String pkPsndoc) throws BusinessException
    {
        PsnOrgVO[] psnorg = getServiceTemplate().queryByCondition(PsnOrgVO.class, " pk_psndoc = '" + pkPsndoc + "' and lastflag = 'Y' ");
        if (psnorg == null || psnorg.length == 0)
        {
            Logger.error("当前人员没有最新组织关系记录");
            return null;
        }
        if (psnorg.length > 1)
        {
            Logger.error("当前人员有多条最新的组织关系记录");
            return psnorg[0].getPk_psnorg();
        }
        return psnorg[0].getPk_psnorg();
    }
    
    @Override
    public String getEmpPsnorgByPsndoc(String pk_psndoc) throws BusinessException
    {
        PsnOrgVO[] psnorg =
            getServiceTemplate().queryByCondition(PsnOrgVO.class, " pk_psndoc = '" + pk_psndoc + "' order by orgrelaid desc ");
        if (psnorg == null || psnorg.length == 0)
        {
            Logger.error("当前人员没有组织关系记录");
            return null;
        }
        
        for (PsnOrgVO org : psnorg)
        {
            if (org.getPsntype() != null && org.getPsntype() == 1)
            {
                continue;
            }
            return org.getPk_psnorg();
        }
        // 返回空说明没有人员类型的组织关系
        return null;
    }
    
    @Override
    public String getEmpPsnjobByPsndoc(String pk_psndoc) throws BusinessException
    {
        String pk_psnorg = getEmpPsnorgByPsndoc(pk_psndoc);
        if (StringUtils.isBlank(pk_psnorg))
        {
            // 人员没有了员工类型的组织关系
            return null;
        }
        PsnJobVO[] psnjob =
            getServiceTemplate().queryByCondition(PsnJobVO.class, " pk_psnorg = '" + pk_psnorg + "' and lastflag = 'Y' and assgid = 1 ");
        if (psnjob == null || psnjob.length == 0)
        {
            Logger.error("当前人员没有最新任职记录");
            return null;
        }
        if (psnjob.length > 1)
        {
            Logger.error("当前人员有多条最新的任职记录");
            return psnjob[0].getPk_psnjob();
        }
        return psnjob[0].getPk_psnjob();
    }
    
    private SimpleDocServiceTemplate getServiceTemplate()
    {
        SimpleDocServiceTemplate service = new SimpleDocServiceTemplate("PERSONRECORD");
        service.setLazyLoad(true);
        return service;
    }
    
    @Override
    public <T extends SuperVO> T insertRecord(T vo, InfoSetVO infoset) throws BusinessException
    {
        // 更新历史记录
        String condition = "";
        if (vo instanceof PsnJobVO || vo instanceof PartTimeVO)
        {
            // 工作记录/兼职记录
            String pk_psnorg = (String) vo.getAttributeValue("pk_psnorg");
            if (StringUtils.isBlank(pk_psnorg))
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0273")/* @res "组织关系PK为空" */);
            }
            Integer assgid = (Integer) vo.getAttributeValue("assgid");
            if (assgid == null)
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0274")/* @res "任职ID为空" */);
            }
            condition = " pk_psnorg = '" + pk_psnorg.trim() + "' and assgid = " + assgid.intValue();
        }
        else if (vo instanceof TrialVO || vo instanceof CtrtVO)
        {
            // 试用/合同
            String pk_psnorg = (String) vo.getAttributeValue("pk_psnorg");
            if (StringUtils.isBlank(pk_psnorg))
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0273")/* @res "组织关系PK为空" */);
            }
            condition = " pk_psnorg = '" + pk_psnorg.trim() + "' ";
        }
        else
        {
            // 其他非业务子集
            String pk_psndoc = (String) vo.getAttributeValue("pk_psndoc");
            if (StringUtils.isBlank(pk_psndoc))
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0275")/* @res "人员基本信息主键为空" */);
            }
            condition = " pk_psndoc = '" + pk_psndoc.trim() + "' ";
        }
        SuperVO[] hisVO = getServiceTemplate().queryByCondition(vo.getClass(), condition);
        if (infoset.getRecord_character() != null && infoset.getRecord_character() == 3)
        {
            // 同期记录
            for (int i = 0; hisVO != null && i < hisVO.length; i++)
            {
                hisVO[i].setAttributeValue("recordnum", (Integer) hisVO[i].getAttributeValue("recordnum") + 1);
                hisVO[i].setAttributeValue("lastflag", UFBoolean.TRUE);
                getServiceTemplate().update(hisVO[i], false);
            }
        }
        else
        {
            // 无规律变更
            updateRecordnumAndLastflag(hisVO);
        }
        // 插入新纪录
        vo.setAttributeValue("recordnum", 0);
        vo.setAttributeValue("lastflag", UFBoolean.TRUE);
        
        //add by@chenzf 如果带主键保存，则调用带主键保存动作 2022-1-6 19:56:07 begin
        if(StringUtils.isNotBlank(vo.getPrimaryKey())) {
        	String key = queryKeyByTableCode(vo.getTableName());
			if(key != null && vo.getPrimaryKey() != null && !"".equals(vo.getPrimaryKey())){
				vo.setAttributeValue(key, "");
				String pk = new BaseDAO().insertVOWithPK(vo);
				return (T) getServiceTemplate().queryByPk(vo.getClass(), pk);
			}
        }
        //add by@chenzf 如果带主键保存，则调用带主键保存动作 2022-1-6 19:56:07 end
        return getServiceTemplate().insert(vo);
    }
    
    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;
    }
    
    public void synPkorgOfPsndoc(String pk_org, String pk_psndoc) throws BusinessException
    {
        
        String sql = " update bd_psndoc set pk_org = '" + pk_org + "' where pk_psndoc = '" + pk_psndoc + "' ";
        NCLocator.getInstance().lookup(IPersistenceUpdate.class).executeSQLs(new String[]{sql});
    }
    
    public void updateAllRecordnumAndLastflag(SuperVO[] vos) throws BusinessException
    {
        String[] updFields = new String[]{"recordnum", "lastflag"};
        if (vos == null || vos.length == 0)
        {
            return;
        }
        for (int i = 0; i < vos.length; i++)
        {
            vos[i].setAttributeValue("recordnum", i);
            if (i == 0)
            {
                vos[i].setAttributeValue("lastflag", UFBoolean.TRUE);
                if( vos[i] instanceof WorkVO )
                {
                    vos[i].setAttributeValue("enddate", null);// 回滚履历时，回滚后最新的履历结束日期要置空
                    updFields = new String[]{"recordnum", "lastflag", "enddate"};
                }
                
            }
            else
            {
                vos[i].setAttributeValue("lastflag", UFBoolean.FALSE);
            }
        }
        NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, vos, updFields, null);
    }
    
    public SuperVO updateEndflagAndEnddate(SuperVO vo, UFLiteralDate date) throws BusinessException
    {
        vo.setAttributeValue("endflag", UFBoolean.TRUE);
        if (vo instanceof PsnJobVO)
        {
            // 工作记录在结束的时候,要将是否在岗置为false
            vo.setAttributeValue(PsnJobVO.POSTSTAT, UFBoolean.FALSE);
            if (vo.getAttributeValue("enddate") == null)
            {
                if (!((PsnJobVO) vo).getIsmainjob().booleanValue())
                {
                    // 兼职
                    UFLiteralDate begindate = ((PsnJobVO) vo).getBegindate();
                    if (begindate.compareTo(date) >= 0)
                    {
                        // 开始日期>=执行日期,则结束日期赋值为开始日期
                        vo.setAttributeValue("enddate", begindate);
                    }
                    else
                    {
                        vo.setAttributeValue("enddate", date.getDateBefore(1));
                    }
                }
                else
                {
                    // 任职/离职,只有在没有结束日期的时候才回写
                    vo.setAttributeValue("enddate", date.getDateBefore(1));
                }
            }
            else
            {
                UFLiteralDate enddate = ((PsnJobVO) vo).getEnddate();
                if (!((PsnJobVO) vo).getIsmainjob().booleanValue() && (enddate.afterDate(date) || enddate.isSameDate(date)))
                {
                    // 工作记录的结束日期>=执行日期,则以执行日期前一天结束工作记录
                    vo.setAttributeValue("enddate", date.getDateBefore(1));
                }
            }
        }
        else if (vo instanceof PsnOrgVO)
        {
            // 组织关系
            if (vo.getAttributeValue("enddate") == null)
            {
                UFLiteralDate begindate = ((PsnOrgVO) vo).getBegindate();
                if (begindate.compareTo(date) >= 0)
                {
                    // 开始日期>=执行日期,则结束日期赋值为开始日期
                    vo.setAttributeValue("enddate", begindate);
                }
                else
                {
                    vo.setAttributeValue("enddate", date.getDateBefore(1));
                }
            }
            else
            {
                UFLiteralDate enddate = ((PsnOrgVO) vo).getEnddate();
                if (enddate.afterDate(date) || enddate.isSameDate(date))
                {
                    // 结束日期>=执行日期,则以执行日期前一天结束工作记录
                    vo.setAttributeValue("enddate", date.getDateBefore(1));
                }
            }
        }
        else if (vo instanceof PsnChgVO || vo instanceof RetireVO)
        {
            // 流动情况或离退待遇
            if (vo.getAttributeValue("enddate") == null)
            {
                vo.setAttributeValue("enddate", date.getDateBefore(1));
            }
        }
        else if (vo instanceof TrialVO)
        {
            ((TrialVO) vo).setTrialresult(1);
            if (((TrialVO) vo).getEnddate() == null)
            {
                ((TrialVO) vo).setEnddate(date);
            }
            ((TrialVO) vo).setRegulardate(date);
        }
        return updateRecord(vo);
    }
    
    @Override
    public <T extends SuperVO> T updateRecord(T vo) throws BusinessException
    {
        return new PsndocDAO().update4SubSet(vo, false, true);
    }
    
    public void updateRecordnumAndLastflag(SuperVO[] vos) throws BusinessException
    {
        if (vos == null || vos.length == 0)
        {
            return;
        }
        for (int i = 0; i < vos.length; i++)
        {
            vos[i].setAttributeValue("recordnum", (Integer) vos[i].getAttributeValue("recordnum") + 1);
            vos[i].setAttributeValue("lastflag", UFBoolean.FALSE);
            // new PsndocDAO().update4SubSet(vo, false, false);
        }
        NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, vos, new String[]{"recordnum", "lastflag"}, null);
    }
    
    /**
     * 批量增加相关人员工作记录,用于部门合并、部门转移,所有记录的开始日期都是一样的
     * 
     * @param psnJobVO
     * @throws BusinessException
     */
    public void addPoiPsnjobs(PsnJobVO[] psnJobVO) throws BusinessException
    {
        if (psnJobVO == null || psnJobVO.length == 0)
        {
            return;
        }
        String[] pk_psnorg = new String[psnJobVO.length];
        for (int i = 0; i < psnJobVO.length; i++)
        {
            pk_psnorg[i] = psnJobVO[i].getPk_psnorg();
        }
        InSQLCreator ttu = null;
        try
        {
            ttu = new InSQLCreator();
            String psnorgInSql = ttu.getInSQL(pk_psnorg);
            
            BaseDAO dao = new BaseDAO();
            
            // 时间校验
            String validateSql =
                " select count(*) from hi_psnjob where lastflag = 'Y' and pk_psnorg in (" + psnorgInSql
                    + ") and ( ( isnull(enddate,'~')<>'~' and enddate>='" + psnJobVO[0].getBegindate()
                    + "' ) or (isnull(enddate,'~')='~' and isnull(begindate,'~')<>'~' and begindate>='" + psnJobVO[0].getBegindate()
                    + "' ) )";
            Object obj = dao.executeQuery(validateSql, new ColumnProcessor());
            if (obj != null && ((Integer) obj) > 0)
            {
                throw new BusinessException(ResHelper.getString("6007psn", "06007psn0276")/*
                                                                                           * @res
                                                                                           * "当前操作将导致当前操作的人员的最新业务关系记录开始时间早于其上一条业务关系记录开始时间."
                                                                                           */);
            }
            
            PsnJobVO[] before =
                getServiceTemplate().queryByCondition(PsnJobVO.class,
                    " pk_psnorg in (" + psnorgInSql + ") and lastflag = 'Y' order by pk_psnorg ");
            
            if (before == null || before.length != psnJobVO.length)
            {
                throw new BusinessException(BDVersionValidationUtil.getUpdateInfo());
            }
            
            String[] pkOrg = new String[before.length];
            for (int i = 0; i < before.length; i++)
            {
                pkOrg[i] = before[i].getPk_hrorg();
            }
            
            HiBatchEventValueObject.fireEvent(before, null, pkOrg, HICommonValue.MD_ID_PSNDOC, IHiEventType.SAVE_POI_BEFORE);
            
            // 回写最新一条记录的结束日期
            UFLiteralDate end = psnJobVO[0].getBegindate().getDateBefore(1);
            String sql1 =
                " update hi_psnjob set enddate = '" + end + "'  where lastflag = 'Y'  and pk_psnorg in (" + psnorgInSql
                    + ")  and  isnull(enddate,'~') = '~' ";
            dao.executeUpdate(sql1);
            
            // 回写lastflag&recordnum&poststate&endflag
            String sql2 =
                " update hi_psnjob set lastflag = 'N' ,recordnum = recordnum+1 ,poststat = 'N',endflag = 'Y' where  pk_psnorg in ("
                    + psnorgInSql + ") ";
            dao.executeUpdate(sql2);
            
            // 插入记录
            HashMap<String, PsnJobVO> hm = new HashMap<String, PsnJobVO>();
            for (PsnJobVO job : before)
            {
                hm.put(job.getPk_psnorg(), job);
            }
            
            String[] pkPsndoc = new String[psnJobVO.length];
            for (int i = 0; i < psnJobVO.length; i++)
            {
                String pkHrOrg =
                    hm.get(psnJobVO[i].getPk_psnorg()) == null ? psnJobVO[i].getPk_org() : hm.get(psnJobVO[i].getPk_psnorg()).getPk_hrorg();
                psnJobVO[i].setPk_hrorg(pkHrOrg);
                pkPsndoc[i] = psnJobVO[i].getPk_psndoc();
            }
            dao.insertVOArray(psnJobVO);
            
            PsnJobVO[] after =
                getServiceTemplate().queryByCondition(PsnJobVO.class,
                    " pk_psnorg in (" + psnorgInSql + ") and lastflag = 'Y' order by pk_psnorg ");
            
            if (after != null && before.length != after.length)
            {
                throw new BusinessException(BDVersionValidationUtil.getUpdateInfo());
            }
            
            // 5)根据信息项设置的同步关系同步人员基础信息,处理信息项的同步; 未实现
            getIPsndocService().updateDataAfterSubDataChanged(PsnJobVO.getDefaultTableName(), pkPsndoc);
            
            // 发送事件-修改薪资数据,修改委托关系
            HiBatchEventValueObject.fireEvent(before, after, pkOrg, HICommonValue.MD_ID_PSNDOC, IHiEventType.SAVE_POI_AFTER);
            HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        }
        catch (Exception e)
        {
            Logger.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        }
        finally
        {
            if (ttu != null)
            {
                
                ttu.clear();
                
            }
        }
        
        // 同步缓存
        HiCacheUtils.synCache(PsndocVO.getDefaultTableName(), PsnJobVO.getDefaultTableName(), PsnOrgVO.getDefaultTableName());
        
    }
    
    @Override
    public void addPoiPsnjob(PsnJobVO psnJobVO) throws BusinessException
    {
        String pk_psnorg = psnJobVO.getPk_psnorg();
        PsnJobVO last = getLastVO(PsnJobVO.class, pk_psnorg, 1);
        if (last != null
            && (last.getBegindate().afterDate(psnJobVO.getBegindate()) || last.getBegindate().isSameDate(psnJobVO.getBegindate())))
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0276")/*
                                                                                       * @res
                                                                                       * "当前操作将导致当前操作的人员的最新业务关系记录开始时间早于其上一条业务关系记录开始时间."
                                                                                       */);
        }
        fireEvent(last, psnJobVO, last.getPk_hrorg(), HICommonValue.MD_ID_PSNDOC, IHiEventType.SAVE_POI_BEFORE);
        PsnJobVO[] hisVOs = getServiceTemplate().queryByCondition(PsnJobVO.class, " pk_psnorg = '" + pk_psnorg + "' and assgid = 1 ");
        for (int i = 0; hisVOs != null && i < hisVOs.length; i++)
        {
            if (hisVOs[i].getLastflag().booleanValue())
            {
                // 2回写开始日期的前一天到上一条记录的结束日期;结束掉上一条记录
                hisVOs[i] = (PsnJobVO) updateEndflagAndEnddate(hisVOs[i], psnJobVO.getBegindate());
            }
        }
        updateRecordnumAndLastflag(hisVOs);
        psnJobVO.setPk_hrorg(last.getPk_hrorg());
        PsnJobVO retVO = getServiceTemplate().insert(psnJobVO);
        // 5)根据信息项设置的同步关系同步人员基础信息,处理信息项的同步; 未实现
        getIPsndocService().updateDataAfterSubDataChanged(PsnJobVO.getDefaultTableName(), retVO.getPk_psndoc());
        // 6 )同步基本信息的pk_org,相关人员不用同步主表pk_org
        // synPkorgOfPsndoc(retVO.getPk_org(), retVO.getPk_psndoc());
        
        // 发送事件-修改薪资数据,修改委托关系
        fireEvent(last, retVO, retVO.getPk_hrorg(), HICommonValue.MD_ID_PSNDOC, IHiEventType.SAVE_POI_AFTER);
        HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        
        // 同步缓存
        HiCacheUtils.synCache(PsndocVO.getDefaultTableName(), PsnJobVO.getDefaultTableName(), PsnOrgVO.getDefaultTableName());
    }
    
    @Override
    public PartTimeVO savePartchgInf(PartTimeVO partTimeVO, boolean isSynWork, String pk_hrorg) throws BusinessException
    {
        
        // 检查员工号
        checkClerkCodeUnique(partTimeVO);
        
        checkDeptPostCanceled(partTimeVO);
        
        // 结束上一条
        PartTimeVO last = getLastVO(PartTimeVO.class, partTimeVO.getPk_psnorg(), partTimeVO.getAssgid());
        fireEvent(last, null, pk_hrorg, HICommonValue.PARTSOURCEID, IHiEventType.PARTCHGBEFORE);
        if (last != null)
        {
            updateEndflagAndEnddate(last, partTimeVO.getBegindate());
            if (isSynWork)
            {
                // 同步工作履历,结束对应的履历
                endWork(last.getPk_psnjob(), last.getEnddate());
            }
        }
        // 更新历史
        PartTimeVO[] his =
            getServiceTemplate().queryByCondition(PartTimeVO.class,
                " pk_psnorg = '" + partTimeVO.getPk_psnorg() + "' and assgid = " + partTimeVO.getAssgid());
        updateRecordnumAndLastflag(his);
        // 保存新纪录
        PartTimeVO retVO = getServiceTemplate().insert(partTimeVO);
        fireEvent(last, retVO, pk_hrorg, HICommonValue.PARTSOURCEID, IHiEventType.PARTCHGAFTER);
        HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        if (isSynWork)
        {
            // 同步工作履历
            addWork(retVO);
        }
        // 同步人员基本信息
        getIPsndocService().updateDataAfterSubDataChanged(PartTimeVO.getDefaultTableName(), retVO.getPk_psndoc());
        return retVO;
    }
    
    /**
     * 批量进行兼职变更
     * 
     * @param partTimeVOs
     * @param isSynWork
     * @throws BusinessException
     */
    public void savePartchgInfo(PartTimeVO[] partTimeVOs, boolean isSynWork) throws BusinessException
    {
        
        BaseDAO dao = new BaseDAO();
        
        // 检查部门岗位是否为撤销
        ArrayList<String> pkDept = new ArrayList<String>();
        ArrayList<String> pkPost = new ArrayList<String>();
        for (int i = 0; i < partTimeVOs.length; i++)
        {
            if (partTimeVOs[i] != null && partTimeVOs[i].getEndflag() != null && partTimeVOs[i].getEndflag().booleanValue())
            {
                continue;
            }
            if (partTimeVOs[i].getPk_dept() != null && !pkDept.contains(partTimeVOs[i].getPk_dept()))
            {
                pkDept.add(partTimeVOs[i].getPk_dept());
            }
            if (partTimeVOs[i].getPk_post() != null && !pkPost.contains(partTimeVOs[i].getPk_post()))
            {
                pkPost.add(partTimeVOs[i].getPk_post());
            }
        }
        
        InSQLCreator ttu = null;
        try
        {
            ttu = new InSQLCreator();
            
            if (pkDept.size() > 0)
            {
                String sql1 =
                    " select count(*) from org_dept where hrcanceled = 'Y' and pk_dept in ( " + ttu.getInSQL(pkDept.toArray(new String[0]))
                        + " ) ";
                Object obj = dao.executeQuery(sql1, new ColumnProcessor());
                if (obj != null && ((Integer) obj) > 0)
                {
                    throw new BusinessException(ResHelper.getString("6007psn", "06007psn0323"/*
                                                                                              * @res
                                                                                              * "任职职未结束,部门不能为撤销部门"
                                                                                              */));
                }
                
            }
            
            if (pkPost.size() > 0)
            {
                String sql2 =
                    " select count(*) from om_post where hrcanceled ='Y' and pk_post in ( " + ttu.getInSQL(pkPost.toArray(new String[0]))
                        + " ) ";
                Object obj = dao.executeQuery(sql2, new ColumnProcessor());
                if (obj != null && ((Integer) obj) > 0)
                {
                    throw new BusinessException(ResHelper.getString("6007psn", "06007psn0324"/*
                                                                                              * @res
                                                                                              * "任职职未结束,岗位不能为撤销岗位"
                                                                                              */));
                }
            }
            
        }
        catch (Exception e)
        {
            Logger.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        }
        finally
        {
            if (ttu != null)
            {
                
                ttu.clear();
                
            }
        }
        // checkDeptPostCanceled(partTimeVO);
        
        // 创建组织关系&任职ID的临时表
        String id = DBAUtil.getIdGenerator().generate();
        String tempTable = DBAUtil.createTempTable("temp" + id.substring(9), " pk_psnorg varchar(20) ,assgid int ", "pk_psnorg , assgid");
        String[] insertSql = new String[partTimeVOs.length];
        
        for (int i = 0; i < partTimeVOs.length; i++)
        {
            insertSql[i] =
                " insert into " + tempTable + " values ('" + partTimeVOs[i].getPk_psnorg() + "'," + partTimeVOs[i].getAssgid() + ")";
        }
        DBAUtil.execBatchSql(insertSql);
        
        // 查询数据,按组织关系主键排序,后面查询的时候也按照pk_psnorg排序
        String querySql =
            " select hi_psnjob.* from hi_psnjob inner join " + tempTable + " on hi_psnjob.pk_psnorg = " + tempTable
                + ".pk_psnorg and hi_psnjob.assgid = " + tempTable
                + ".assgid  where hi_psnjob.lastflag = 'Y' order by hi_psnjob.pk_psnorg ";
        ArrayList beforeList = (ArrayList) dao.executeQuery(querySql, new BeanListProcessor(PartTimeVO.class));
        if (beforeList == null || beforeList.size() != partTimeVOs.length)
        {
            throw new BusinessException(BDVersionValidationUtil.getUpdateInfo());
        }
        PartTimeVO[] lastVOs = new PartTimeVO[partTimeVOs.length];// 变更前数组
        String[] pkOrg = new String[partTimeVOs.length];// hr组织数组
        ArrayList<String> al = new ArrayList<String>();// 人员主键,去掉重复的
        for (int i = 0; i < lastVOs.length; i++)
        {
            lastVOs[i] = (PartTimeVO) beforeList.get(i);
            pkOrg[i] = ((PartTimeVO) beforeList.get(i)).getPk_hrorg();
            if (!al.contains(((PartTimeVO) beforeList.get(i)).getPk_psndoc()))
            {
                al.add(((PartTimeVO) beforeList.get(i)).getPk_psndoc());
            }
        }
        
        HiBatchEventValueObject.fireEvent(lastVOs, null, pkOrg, HICommonValue.PARTSOURCEID, IHiEventType.PARTCHGBEFORE);
        
        for (int i = 0; i < partTimeVOs.length; i++)
        {
            
            // 检查员工号
            checkClerkCodeUnique(partTimeVOs[i]);
            
        }
        
        // 更新上一条的Endflag与Enddate
        UFLiteralDate begindate = partTimeVOs[0].getBegindate();// 下一条的开始日期
        UFLiteralDate enddate = begindate.getDateBefore(1);// 上一条的结束日期
        String updateSql1 =
            " update hi_psnjob set endflag='Y',poststat ='N',enddate = ( case when isnull(enddate,'~')<>'~' and enddate >='" + begindate
                + "' then '" + enddate + "' when  isnull( enddate,'~')='~' then (case when begindate >='" + begindate
                + "' then begindate else '" + enddate
                + "' end) end)  where pk_psnjob in (select hi_psnjob.pk_psnjob from hi_psnjob inner join " + tempTable
                + " on hi_psnjob.pk_psnorg = " + tempTable + ".pk_psnorg and hi_psnjob.assgid = " + tempTable
                + ".assgid  where hi_psnjob.lastflag = 'Y') ";
        dao.executeUpdate(updateSql1);
        
        // 同步履历,结束对应的履历
        if (isSynWork)
        {
            
            WorkVO[] hisWorkVOs =
                (WorkVO[]) NCLocator
                    .getInstance()
                    .lookup(IPersistenceRetrieve.class)
                    .retrieveByClause(
                        null,
                        WorkVO.class,
                        " pk_psnjob in ( select hi_psnjob.pk_psnjob from hi_psnjob inner join " + tempTable + " on hi_psnjob.pk_psnorg = "
                            + tempTable + ".pk_psnorg and hi_psnjob.assgid = " + tempTable + ".assgid  where hi_psnjob.lastflag = 'Y' ) ");
            
            ArrayList tempList = (ArrayList) dao.executeQuery(querySql, new BeanListProcessor(PartTimeVO.class));
            HashMap<String, PartTimeVO> map = new HashMap<String, PartTimeVO>();
            for (int i = 0; i < tempList.size(); i++)
            {
                map.put(((PartTimeVO) tempList.get(i)).getPk_psnjob(), (PartTimeVO) tempList.get(i));
            }
            
            for (int i = 0; hisWorkVOs != null && i < hisWorkVOs.length; i++)
            {
                PartTimeVO vo = map.get(hisWorkVOs[i].getPk_psnjob());
                if (vo == null)
                {
                    if (hisWorkVOs[i].getEnddate() == null)
                    {
                        hisWorkVOs[i].setEnddate(hisWorkVOs[i].getBegindate());
                    }
                    continue;
                }
                
                UFLiteralDate begin = hisWorkVOs[i].getBegindate();
                UFLiteralDate end = vo.getBegindate().getDateBefore(1);
                if (begin != null && begin.afterDate(end))
                {
                    // 如果开始日期大于结束日期,则将开始日期
                    hisWorkVOs[i].setEnddate(begin);
                }
                else
                {
                    hisWorkVOs[i].setEnddate(end);
                }
                
            }
            
            dao.updateVOArray(hisWorkVOs, new String[]{WorkVO.ENDDATE});
        }
        
        // 更新历史的lastflag与recordnum
        String updateSql2 =
            " update hi_psnjob set lastflag ='N',recordnum = recordnum + 1 where pk_psnjob in (select  hi_psnjob.pk_psnjob  from hi_psnjob inner join "
                + tempTable + " on hi_psnjob.pk_psnorg = " + tempTable + ".pk_psnorg and hi_psnjob.assgid = " + tempTable + ".assgid  ) ";
        dao.executeUpdate(updateSql2);
        
        // 插入数组
        insert4SubVOs(partTimeVOs);
        
        // 得到插入后的工作记录数组
        ArrayList afterList = (ArrayList) dao.executeQuery(querySql, new BeanListProcessor(PartTimeVO.class));
        if (afterList == null || afterList.size() != partTimeVOs.length)
        {
            throw new BusinessException(BDVersionValidationUtil.getUpdateInfo());
        }
        PartTimeVO[] after = new PartTimeVO[partTimeVOs.length];
        for (int i = 0; i < partTimeVOs.length; i++)
        {
            after[i] = (PartTimeVO) afterList.get(i);
        }
        
        if (isSynWork)
        {
            // 同步工作履历
            batchAddWorkWhenPsnjobAdd(after);
        }
        
        if (DBAUtil.isExist(" select 1 from " + tempTable))
        {
            // 如果临时表还存在删除临时表
            DBAUtil.execBatchSql(new String[]{" delete  from  " + tempTable});
        }
        
        HiBatchEventValueObject.fireEvent(lastVOs, after, pkOrg, HICommonValue.PARTSOURCEID, IHiEventType.PARTCHGAFTER);
        HiEventValueObject.fireDataPermChangeEvent(HICommonValue.MD_ID_PSNJOB);
        // 同步人员基本信息
        getIPsndocService().updateDataAfterSubDataChanged(PartTimeVO.getDefaultTableName(), al.toArray(new String[0]));
        getIPsndocService().updateDataAfterSubDataChanged(WorkVO.getDefaultTableName(), al.toArray(new String[0]));
        
    }
    
    /**
     * @param after
     * @throws Exception
     */
    private void batchAddWorkWhenPsnjobAdd(PsnJobVO[] after) throws BusinessException
    {
        
        InSQLCreator ttu = null;
        try
        {
            
            ArrayList<String> orgList = new ArrayList<String>();
            ArrayList<String> deptList = new ArrayList<String>();
            ArrayList<String> postList = new ArrayList<String>();
            ArrayList<String> jobList = new ArrayList<String>();
            
            for (int i = 0; i < after.length; i++)
            {
                if (after[i].getPk_org() != null && !orgList.contains(after[i].getPk_org()))
                {
                    orgList.add(after[i].getPk_org());
                }
                if (after[i].getPk_dept() != null && !deptList.contains(after[i].getPk_dept()))
                {
                    deptList.add(after[i].getPk_dept());
                }
                if (after[i].getPk_post() != null && !postList.contains(after[i].getPk_post()))
                {
                    postList.add(after[i].getPk_post());
                }
                if (after[i].getPk_job() != null && !jobList.contains(after[i].getPk_job()))
                {
                    jobList.add(after[i].getPk_job());
                }
            }
            
            ttu = new InSQLCreator();
            
            String orgSql = ttu.getInSQL(orgList.toArray(new String[0]));
            String deptSql = ttu.getInSQL(deptList.toArray(new String[0]));
            String postSql = ttu.getInSQL(postList.toArray(new String[0]));
            String jobSql = ttu.getInSQL(jobList.toArray(new String[0]));
            
            OrgVO[] orgVOs = null;
            DeptVO[] deptVOs = null;
            PostVO[] postVOs = null;
            JobVO[] jobVOs = null;
            
            IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
            
            if (orgSql != null)
            {
                orgVOs = (OrgVO[]) retrieve.retrieveByClause(null, OrgVO.class, " pk_org in ( " + orgSql + " ) ");
            }
            
            if (deptSql != null)
            {
                deptVOs = (DeptVO[]) retrieve.retrieveByClause(null, DeptVO.class, " pk_dept in ( " + deptSql + " ) ");
            }
            
            if (postSql != null)
            {
                postVOs = (PostVO[]) retrieve.retrieveByClause(null, PostVO.class, " pk_post in ( " + postSql + " ) ");
            }
            
            if (jobSql != null)
            {
                jobVOs = (JobVO[]) retrieve.retrieveByClause(null, JobVO.class, " pk_job in ( " + jobSql + " ) ");
            }
            
            HashMap<String, String> orgMap = new HashMap<String, String>();
            HashMap<String, String> deptMap = new HashMap<String, String>();
            HashMap<String, String> postMap = new HashMap<String, String>();
            HashMap<String, String> jobMap = new HashMap<String, String>();
            
            for (int i = 0; orgVOs != null && i < orgVOs.length; i++)
            {
                orgMap.put(orgVOs[i].getPk_org(), MultiLangHelper.getName(orgVOs[i]));
            }
            
            for (int i = 0; deptVOs != null && i < deptVOs.length; i++)
            {
                deptMap.put(deptVOs[i].getPk_dept(), MultiLangHelper.getName(deptVOs[i]));
            }
            
            for (int i = 0; postVOs != null && i < postVOs.length; i++)
            {
                postMap.put(postVOs[i].getPk_post(), MultiLangHelper.getName(postVOs[i]));
            }
            
            for (int i = 0; jobVOs != null && i < jobVOs.length; i++)
            {
                jobMap.put(jobVOs[i].getPk_job(), MultiLangHelper.getName(jobVOs[i]));
            }
            
            ArrayList<String> sqlList = new ArrayList<String>();
            ArrayList<WorkVO> voList = new ArrayList<WorkVO>();
            for (PsnJobVO vo : after)
            {
                // 更新历史履历记录
                String sql =
                    " update hi_psndoc_work set lastflag = 'N',recordnum = recordnum + 1 where pk_psndoc = '" + vo.getPk_psndoc() + "' ";
                sqlList.add(sql);
                // new BaseDAO().executeUpdate(sql);
                
                // 根据新增的工作记录,生成一条新的履历记录,保存之
                WorkVO newWork = new WorkVO();
                newWork.setPk_group(vo.getPk_group());
                newWork.setPk_org(vo.getPk_hrorg());
                newWork.setPk_psndoc(vo.getPk_psndoc());
                newWork.setPk_psnjob(vo.getPk_psnjob());
                newWork.setRecordnum(0);
                newWork.setLastflag(UFBoolean.TRUE);
                newWork.setBegindate(vo.getBegindate());
                newWork.setEnddate(vo.getEnddate());
                newWork.setMemo(vo.getMemo());
                // 组织
                newWork.setWorkcorp(vo.getPk_org() == null ? null : orgMap.get(vo.getPk_org()));
                // 部门
                newWork.setWorkdept(vo.getPk_dept() == null ? null : deptMap.get(vo.getPk_dept()));
                // 岗位
                newWork.setWorkpost(vo.getPk_post() == null ? null : postMap.get(vo.getPk_post()));
                // 职务
                newWork.setWorkjob(vo.getPk_job() == null ? null : jobMap.get(vo.getPk_job()));
                
                dealWorkSyncItem(newWork, vo);
                
                newWork.setCreator(PubEnv.getPk_user());
                newWork.setCreationtime(PubEnv.getServerTime());
                voList.add(newWork);
                // new BaseDAO().insertVO(newWork);
            }
            NCLocator.getInstance().lookup(IPersistenceUpdate.class).executeSQLs(sqlList.toArray(new String[0]));
            new BaseDAO().insertVOArray(voList.toArray(new WorkVO[0]));
            
        }
        catch (Exception e)
        {
            Logger.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        }
        finally
        {
            if (ttu != null)
            {
                
                ttu.clear();
                
            }
        }
    }
    
    /**
     * 新增工作记录同步履历
     * 
     * @param vo
     * @throws BusinessException
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public void addWorkWhenPsnjobAdd(PsnJobVO vo) throws BusinessException
    {
        // 更新历史履历记录
        String sql = " update hi_psndoc_work set lastflag = 'N',recordnum = recordnum + 1 where pk_psndoc = '" + vo.getPk_psndoc() + "' ";
        new BaseDAO().executeUpdate(sql);
        
        // 根据新增的工作记录,生成一条新的履历记录,保存之
        WorkVO newWork = new WorkVO();
        newWork.setPk_group(vo.getPk_group());
        newWork.setPk_org(vo.getPk_hrorg());
        newWork.setPk_psndoc(vo.getPk_psndoc());
        newWork.setPk_psnjob(vo.getPk_psnjob());
        newWork.setRecordnum(0);
        newWork.setLastflag(UFBoolean.TRUE);
        newWork.setBegindate(vo.getBegindate());
        newWork.setEnddate(vo.getEnddate());
        newWork.setMemo(vo.getMemo());
        // 组织
        newWork.setWorkcorp(VOUtils.getDocName(OrgVO.class, vo.getPk_org()));
        // 部门
        newWork.setWorkdept(VOUtils.getDocName(DeptVO.class, vo.getPk_dept()));
        // 岗位
        newWork.setWorkpost(VOUtils.getDocName(PostVO.class, vo.getPk_post()));
        // 职务
        newWork.setWorkjob(VOUtils.getDocName(JobVO.class, vo.getPk_job()));
        
        this.dealWorkSyncItem(newWork, vo);
        
        new PsndocDAO().insert4SubSet(newWork, false);
    }
    
    /**
     * 子集插入 ,不带唯一性校验,不发送事件
     * 
     * @param <T>
     * @param vo
     * @return
     * @throws BusinessException
     */
    private <T extends SuperVO> void insert4SubVOs(T[] vo) throws BusinessException
    {
        // 设置审计信息
        for (int i = 0; i < vo.length; i++)
        {
            vo[i].setStatus(VOStatus.NEW);
            SimpleDocServiceTemplate.setAuditInfoAndTs(vo[i], true);
        }
        MDPersistenceService.lookupPersistenceService().saveBill(vo);
    }
    
    /**
     * 检查日期
     * 
     * @param psnjobVO 当前组织关系下的最新工作记录
     * @param jobDate 工作记录开始日期
     * @param orgDate 组织关系开始日期
     * @throws BusinessException
     */
    @Override
    public void checkBeginDate(PsnJobVO psnjobVO, UFLiteralDate jobDate, UFLiteralDate orgDate) throws BusinessException
    {
        IPersistenceRetrieve service = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        PsndocVO docVO =
            psnjobVO == null || psnjobVO.getPk_psndoc() == null ? null : (PsndocVO) service.retrieveByPk(null, PsndocVO.class,
                psnjobVO.getPk_psndoc());
        if (docVO == null)
        {
            // 没有人员,第一次入职,不需要校验
            return;
        }
        
        PsnOrgVO preOrgVO = null;
        String orgCond = "";
        if (psnjobVO.getPk_psnorg() == null)
        {
            // 新增一个人员 ,查询数据库中最新的组织关系
            orgCond = " pk_psndoc = '" + psnjobVO.getPk_psndoc() + "' and lastflag = 'Y' ";
        }
        else
        {
            
            orgCond =
                " pk_psndoc = '" + psnjobVO.getPk_psndoc() + "' and orgrelaid = ( select orgrelaid - 1 from hi_psnorg where pk_psnorg = '"
                    + psnjobVO.getPk_psnorg() + "' ) ";
        }
        PsnOrgVO[] temp = getServiceTemplate().queryByCondition(PsnOrgVO.class, orgCond);
        if (temp != null && temp.length > 0)
        {
            preOrgVO = temp[0];
        }
        
        if (preOrgVO == null)
        {
            // 没有历史的组织关系不需要校验
            return;
        }
        
        // 如果orgDate为空,则查询数据库中的数据,只会在记录节点传入null,此时pk_psnorg不为空
        if (orgDate == null)
        {
            PsnOrgVO org = getServiceTemplate().queryByPk(PsnOrgVO.class, psnjobVO.getPk_psnorg());
            orgDate = org.getBegindate();
        }
        
        // modify at 20130108 for 港华 不再跟工作记录比 只与组织关系的结束日期比
        // PsnJobVO preJobVO = getLastVO(PsnJobVO.class, preOrgVO.getPk_psnorg(), 1);
        
        // 没有结束日期,就用开始日期,再加一天,方便比较
        UFLiteralDate preOrgDate = preOrgVO.getEnddate() == null ? preOrgVO.getBegindate() : preOrgVO.getEnddate();
        preOrgDate = preOrgDate.getDateAfter(1);
        // UFLiteralDate preJobDate = preJobVO.getEnddate() == null ? preJobVO.getBegindate() :
        // preJobVO.getEnddate();
        // preJobDate = preJobDate.getDateAfter(1);
        
        int curPsnType = psnjobVO.getPsntype();
        int prePsnType = preOrgVO.getPsntype();
        
        // 工作记录与工作记录比
        // if (preJobDate.afterDate(jobDate))
        // {
        // String curJobName = curPsnType == 0 ? ResHelper.getString("6007psn", "16007psn0014")/* @res "任职记录"
        // */: ResHelper.getString("6007psn",
        // "06007psn0277")/* @res "业务关系记录" */;
        // String preJobName = prePsnType == 0 ? ResHelper.getString("6007psn", "06007psn0278")/* @res
        // "组织关系的最新任职记录" */: ResHelper.getString(
        // "6007psn", "06007psn0279")/* @res "业务关系的最新记录" */;
        // throw new BusinessException(ResHelper.getString("6007psn", "06007psn0280"/*
        // * @res "人员[{0},{1}]第一条{2}的开始日期早于或等于上一次{3}的结束日期"
        // */, psnjobVO.getClerkcode(),
        // VOUtils.getDocName(PsndocVO.class, psnjobVO.getPk_psndoc()), curJobName, preJobName));
        // }
        
        // 组织关系与工作记录比
        if (preOrgDate.afterDate(jobDate))
        {
            String curJobName =
                curPsnType == 0 ? ResHelper.getString("6007psn", "16007psn0014")/* @res "任职记录" */: ResHelper.getString("6007psn",
                    "06007psn0277")/* @res "业务关系记录" */;
            String preOrgName =
                prePsnType == 0 ? ResHelper.getString("6007psn", "16007psn0012")/* @res "组织关系" */: ResHelper.getString("6007psn",
                    "16007psn0034")/* @res "业务关系" */;
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0281"/*
                                                                                      * @res
                                                                                      * "人员[{0},{1}]第一条{2}的开始日期早于或等于上一次{3}的退出日期"
                                                                                      */, psnjobVO.getClerkcode(),
                VOUtils.getDocName(PsndocVO.class, psnjobVO.getPk_psndoc()), curJobName, preOrgName));
        }
        
        // 工作记录与组织关系比
        // if (preJobDate.afterDate(orgDate))
        // {
        // String curOrgName = curPsnType == 0 ? ResHelper.getString("6007psn", "16007psn0012")/* @res "组织关系"
        // */: ResHelper.getString("6007psn",
        // "16007psn0034")/* @res "业务关系" */;
        // String preJobName = prePsnType == 0 ? ResHelper.getString("6007psn", "06007psn0278")/* @res
        // "组织关系的最新任职记录" */: ResHelper.getString(
        // "6007psn", "06007psn0279")/* @res "业务关系的最新记录" */;
        // throw new BusinessException(ResHelper.getString("6007psn", "06007psn0282"/*
        // * @res "人员[{0},{1}]当前{2}的进入日期早于或等于上一次{3}的结束日期"
        // */, psnjobVO.getClerkcode(),
        // VOUtils.getDocName(PsndocVO.class, psnjobVO.getPk_psndoc()), curOrgName, preJobName));
        // }
        
        // 组织关系与组织关系比
        if (preOrgDate.afterDate(orgDate))
        {
            String curOrgName =
                curPsnType == 0 ? ResHelper.getString("6007psn", "16007psn0012")/* @res "组织关系" */: ResHelper.getString("6007psn",
                    "16007psn0034")/* @res "业务关系" */;
            String preOrgName =
                prePsnType == 0 ? ResHelper.getString("6007psn", "16007psn0012")/* @res "组织关系" */: ResHelper.getString("6007psn",
                    "16007psn0034")/* @res "业务关系" */;
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0283"/*
                                                                                      * @res
                                                                                      * "人员[{0},{1}]当前{2}的进入日期早于或等于上一次{3}的退出日期"
                                                                                      */, psnjobVO.getClerkcode(),
                VOUtils.getDocName(PsndocVO.class, psnjobVO.getPk_psndoc()), curOrgName, preOrgName));
        }
        
    }
    
    /**
     * 校验员工号唯一
     * @param psnjobVOs
     * @throws BusinessException
     */
    public void checkClerkCodeUnique(PsnJobVO[] psnjobVOs) throws BusinessException
    {
        if (ArrayUtils.isEmpty(psnjobVOs)) return;
        String[] fields = {PsnJobVO.CLERKCODE, PsnJobVO.PK_ORG, PsnJobVO.PK_PSNDOC};
        String tmpTableName = new InSQLCreator().insertValues(PsnJobVO.getDefaultTableName() + "tmpu", fields, fields, psnjobVOs);
        String sql =
            " select t.clerkcode clerkcode, t.pk_org pk_org from " + tmpTableName + " t where exists(select 1 from "
                + PsnJobVO.getDefaultTableName() + " s where s.pk_org=t.pk_org and s.clerkcode=t.clerkcode and s.pk_psndoc<>t.pk_psndoc)";
        GeneralVO[] c = (GeneralVO[]) new BaseDAO().executeQuery(sql, new GeneralVOProcessor<GeneralVO>(GeneralVO.class));
        if (ArrayUtils.isEmpty(c)) return;
        throw new BusinessException(ResHelper.getString("6007psn", "06007psn0234"/*
                                                                                  * @res
                                                                                  * " 员工号[{0}]在组织[{1}]下已存在,请检查."
                                                                                  */, (String) c[0].getAttributeValue("clerkcode"),
            VOUtils.getDocName(OrgVO.class, (String) c[0].getAttributeValue("pk_org"))));
    }
    
    @Override
    public void checkClerkCodeUnique(PsnJobVO psnjobVO) throws BusinessException
    {
        String clerkCode = psnjobVO.getClerkcode();
        String pk_org = psnjobVO.getPk_org();
        String pk_psndoc = psnjobVO.getPk_psndoc();
        // 当前任职组织下其他人员存在相同的员工号
        String condition = " clerkcode = '" + NCESAPI.sqlEncode(clerkCode)+ "' and pk_org = '" + pk_org + "' and pk_psndoc <>'" + pk_psndoc + "' ";
        int count =
            NCLocator.getInstance().lookup(IPersistenceRetrieve.class).getCountByCondition(PsnJobVO.getDefaultTableName(), condition);
        if (count > 0)
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0234"/*
                                                                                      * @res
                                                                                      * " 员工号[{0}]在组织[{1}]下已存在,请检查."
                                                                                      */, clerkCode,
                VOUtils.getDocName(OrgVO.class, pk_org)));
        }
    }
    
    @Override
    public void checkPsnorg(String pk_psnjob) throws BusinessException
    {
        
        PsnJobVO job = getServiceTemplate().queryByPk(PsnJobVO.class, pk_psnjob);
        
        PsnOrgVO org = getServiceTemplate().queryByPk(PsnOrgVO.class, job.getPk_psnorg());
        
        // 查询当前人员下比当前组织关系晚的已转档的组织关系
        String sql = " pk_psndoc ='" + org.getPk_psndoc() + "' and indocflag = 'Y' and orgrelaid > " + org.getOrgrelaid();
        
        int count = NCLocator.getInstance().lookup(IPersistenceRetrieve.class).getCountByCondition("hi_psnorg", sql);
        if (count > 0)
        {
            throw new BusinessException(ResHelper.getString("6007psn", "06007psn0348")/* "当前选择人员所属组织关系不是该人员最新的有效组织关系,不能进行身故操作." */);
        }
        
    }
    
    @Override
    public void syncPsnWaInfo(Map<String, WainfoVO[]> wainfo) throws BusinessException
    {
        if (wainfo == null || wainfo.size() <= 0)
        {
            return;
        }
        
        IPersistenceUpdate update = NCLocator.getInstance().lookup(IPersistenceUpdate.class);
        IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        
        String[] docPKs = wainfo.keySet().toArray(new String[0]);
        
        InSQLCreator isc = new InSQLCreator();
        try
        {
            
            // 删除所有人得历史记录
            WainfoVO[] old =
                (WainfoVO[]) retrieve.retrieveByClause(null, WainfoVO.class, " pk_psndoc in ( " + isc.getInSQL(docPKs) + " ) ");
            if (old != null && old.length > 0)
            {
                update.deleteVOArray(null, old, null);
            }
            
        }
        finally
        {
            isc.clear();
        }
        
        ArrayList<WainfoVO> al = new ArrayList<WainfoVO>();
        
        for (String pk : docPKs)
        {
            // 没有数据说明这个人没有薪资信息
            WainfoVO[] vos = wainfo.get(pk);
            if (vos == null || vos.length == 0)
            {
                continue;
            }
            // 处理recordnum
            for (int i = 0; i < vos.length; i++)
            {
                vos[i].setPk_psndoc(pk);
                vos[i].setRecordnum(vos.length - 1 - i);
                vos[i].setCreationtime(PubEnv.getServerTime());
                vos[i].setCreator(PubEnv.getPk_user());
                vos[i].setStatus(VOStatus.NEW);
                al.add(vos[i]);
            }
        }
        if (al.size() > 0)
        {
            update.insertVOArray(null, al.toArray(new WainfoVO[0]), null);
        }
        getIPsndocService().updateDataAfterSubDataChanged(WainfoVO.getDefaultTableName(), docPKs);
        // 薪资没有记录人员组织关系主键，需要根据人员任职主键同步组织关系主键
        if (docPKs == null || docPKs.length == 0)
        {
            return;
        }
        InSQLCreator ttu = new InSQLCreator();
        String inSql = ttu.getInSQL(docPKs);
        
        String updateSQL =
            " update hi_psndoc_wainfo set pk_psnorg = (select pk_psnorg from hi_psnjob where hi_psnjob.pk_psnjob = hi_psndoc_wainfo.pk_psnjob) where pk_psndoc in ( "
                + inSql + " ) ";
        new BaseDAO().executeUpdate(updateSQL);
    }
    
    @Override
    public void syncPsnBmInfo(Map<String, BminfoVO> bminfo, String pk_insurance) throws BusinessException
    {
        if (bminfo == null || bminfo.size() <= 0 || StringUtils.isBlank(pk_insurance))
        {
            return;
        }
        
        IPersistenceUpdate update = NCLocator.getInstance().lookup(IPersistenceUpdate.class);
        IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        
        String[] docPKs = bminfo.keySet().toArray(new String[0]);
        ArrayList<String> noList = new ArrayList<String>();// 传过来是null的人员
        ArrayList<String> yesList = new ArrayList<String>();// 传过来不是null的人员
        for (String pk : docPKs)
        {
            BminfoVO vo = bminfo.get(pk);
            if (vo == null)
            {
                noList.add(pk);
            }
            else
            {
                yesList.add(pk);
            }
        }
        
        InSQLCreator isc = new InSQLCreator();
        try
        {
            // 传过来的社保信息是空的情况
            if (noList.size() > 0)
            {
                String noInsql = isc.getInSQL(noList.toArray(new String[0]));
                BminfoVO[] old =
                    (BminfoVO[]) retrieve.retrieveByClause(null, BminfoVO.class, " pk_psndoc in ( " + noInsql + " ) and pk_insurance = '"
                        + pk_insurance + "' ");
                if (old != null && old.length > 0)
                {
                    // 如果传过来的是null,则删除旧的信息
                    update.deleteVOArray(null, old, null);
                }
                
                // 删除之后更新recordnum与lastflag
                BminfoVO[] psnBm =
                    (BminfoVO[]) retrieve.retrieveByClause(null, BminfoVO.class, " pk_psndoc in ( " + noInsql + " ) order by recordnum ");
                
                HashMap<String, ArrayList<BminfoVO>> hm = new HashMap<String, ArrayList<BminfoVO>>();
                for (int i = 0; psnBm != null && i < psnBm.length; i++)
                {
                    if (hm.get(psnBm[i].getPk_psndoc()) == null)
                    {
                        hm.put(psnBm[i].getPk_psndoc(), new ArrayList<BminfoVO>());
                    }
                    hm.get(psnBm[i].getPk_psndoc()).add(psnBm[i]);
                }
                ArrayList<BminfoVO> al = new ArrayList<BminfoVO>();
                for (String key : hm.keySet())
                {
                    ArrayList<BminfoVO> vos = hm.get(key);
                    for (int i = 0; vos != null && i < vos.size(); i++)
                    {
                        vos.get(i).setRecordnum(i);
                        if (i == 0)
                        {
                            vos.get(i).setLastflag(UFBoolean.TRUE);
                        }
                        else
                        {
                            vos.get(i).setLastflag(UFBoolean.FALSE);
                        }
                    }
                    if (vos != null && vos.size() > 0)
                    {
                        al.addAll(vos);
                    }
                }
                update.updateVOList(null, al, new String[]{"recordnum", "lastflag"}, null);
                
            }
            
            // 传过来的社保信息不是空的情况
            if (yesList.size() > 0)
            {
                String yesInsql = isc.getInSQL(yesList.toArray(new String[0]));
                BminfoVO[] old =
                    (BminfoVO[]) retrieve.retrieveByClause(null, BminfoVO.class, " pk_psndoc in ( " + yesInsql + " ) and pk_insurance = '"
                        + pk_insurance + "' ");
                
                // 每个人原有的社保信息
                HashMap<String, BminfoVO> map = new HashMap<String, BminfoVO>();
                for (int i = 0; old != null && i < old.length; i++)
                {
                    if (map.containsKey(old[i].getPk_psndoc()))
                    {
                        continue;
                    }
                    
                    map.put(old[i].getPk_psndoc(), old[i]);
                    
                }
                
                ArrayList<String> wuList = new ArrayList<String>();// 无历史信息的人员
                ArrayList<String> youList = new ArrayList<String>();// 有历史信息的人员
                for (String pk : yesList)
                {
                    if (map.get(pk) != null)
                    {
                        youList.add(pk);
                    }
                    else
                    {
                        wuList.add(pk);
                    }
                }
                
                if (youList.size() > 0)
                {
                    ArrayList<BminfoVO> l = new ArrayList<BminfoVO>();
                    for (String pk : youList)
                    {
                        BminfoVO vo = bminfo.get(pk);
                        BminfoVO his = map.get(pk);
                        
                        // 如果该险种已经存在 则更新相关信息
                        vo.setPk_psndoc(his.getPk_psndoc());
                        vo.setPk_psndoc_sub(his.getPk_psndoc_sub());
                        vo.setRecordnum(his.getRecordnum());
                        vo.setLastflag(his.getLastflag());
                        vo.setCreationtime(his.getCreationtime());
                        vo.setCreator(his.getCreator());
                        vo.setStatus(VOStatus.UPDATED);
                        l.add(vo);
                    }
                    update.updateVOList(null, l, null, null);
                }
                
                if (wuList.size() > 0)
                {
                    
                    // 插入之前 更新已有记录的recordnum与lastflag
                    String wuInsql = isc.getInSQL(wuList.toArray(new String[0]));
                    BminfoVO[] psnBm = (BminfoVO[]) retrieve.retrieveByClause(null, BminfoVO.class, " pk_psndoc in ( " + wuInsql + " ) ");
                    for (int i = 0; psnBm != null && i < psnBm.length; i++)
                    {
                        psnBm[i].setRecordnum(psnBm[i].getRecordnum() + 1);
                        psnBm[i].setLastflag(UFBoolean.FALSE);
                    }
                    if (psnBm != null && psnBm.length > 0)
                    {
                        update.updateVOArray(null, psnBm, new String[]{"recordnum", "lastflag"}, null);
                    }
                    
                    // 如果该险种不存在 则插入相关信息
                    ArrayList<BminfoVO> bm = new ArrayList<BminfoVO>();
                    for (String pk : wuList)
                    {
                        BminfoVO vo = bminfo.get(pk);
                        // 如果该险种不存在 则插入相关信息
                        vo.setPk_psndoc(pk);
                        vo.setRecordnum(0);
                        vo.setLastflag(UFBoolean.TRUE);
                        vo.setCreationtime(PubEnv.getServerTime());
                        vo.setCreator(PubEnv.getPk_user());
                        vo.setStatus(VOStatus.NEW);
                        bm.add(vo);
                    }
                    
                    update.insertVOList(null, bm, null);
                    
                }
                
            }
            
        }
        finally
        {
            isc.clear();
        }
        
        getIPsndocService().updateDataAfterSubDataChanged(BminfoVO.getDefaultTableName(), docPKs);
    }
    
    @Override
    public void syncPsnCapaInfo(Map<String, CapaVO[]> capainfo) throws BusinessException
    {
        if (capainfo == null || capainfo.size() <= 0)
        {
            return;
        }
        
        IPersistenceUpdate update = NCLocator.getInstance().lookup(IPersistenceUpdate.class);
        IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        
        String[] jobPKs = capainfo.keySet().toArray(new String[0]);
        ArrayList<String> docPKList = new ArrayList<String>();
        for (String pk : jobPKs)
        {
            PsnJobVO job = (PsnJobVO) retrieve.retrieveByPk(null, PsnJobVO.class, pk);
            if (job == null)
            {
                continue;
            }
            
            CapaVO[] old =
                (CapaVO[]) retrieve.retrieveByClause(null, CapaVO.class,
                    "pk_psndoc = '" + job.getPk_psndoc() + "' and pk_psnorg = '" + job.getPk_psnorg() + "' ");
            if (old != null && old.length > 0)
            {
                update.deleteVOArray(null, old, null);
            }
            
            CapaVO[] vos = capainfo.get(pk);
            if (vos == null || vos.length == 0)
            {
                continue;
            }
            
            for (int i = 0; i < vos.length; i++)
            {
                vos[i].setPk_psndoc(job.getPk_psndoc());
                vos[i].setPk_psnorg(job.getPk_psnorg());
                vos[i].setRecordnum(vos.length - 1 - i);
                vos[i].setLastflag(UFBoolean.TRUE);
                vos[i].setCreationtime(PubEnv.getServerTime());
                vos[i].setCreator(PubEnv.getPk_user());
                vos[i].setStatus(VOStatus.NEW);
            }
            update.insertVOArray(null, vos, null);
            if (!docPKList.contains(job.getPk_psndoc()))
            {
                docPKList.add(job.getPk_psndoc());
            }
        }
        
        getIPsndocService().updateDataAfterSubDataChanged(CapaVO.getDefaultTableName(), docPKList.toArray(new String[0]));
    }
    
    @Override
    public void syncPsnPeInfo(Map<String, AssVO[]> peinfo) throws BusinessException
    {
        if (peinfo == null || peinfo.size() <= 0)
        {
            return;
        }
        
        IPersistenceUpdate update = NCLocator.getInstance().lookup(IPersistenceUpdate.class);
        IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        
        String[] jobPKs = peinfo.keySet().toArray(new String[0]);
        
        InSQLCreator isc = new InSQLCreator();
        try
        {
            String jobInsql = isc.getInSQL(jobPKs);
            
            PsnJobVO[] jobVOs = (PsnJobVO[]) retrieve.retrieveByClause(null, PsnJobVO.class, " pk_psnjob in (" + jobInsql + ") ");
            
            ArrayList<String> psnorgPKList = new ArrayList<String>();
            for (PsnJobVO job : jobVOs)
            {
                if (!psnorgPKList.contains(job.getPk_psnorg()))
                {
                    psnorgPKList.add(job.getPk_psnorg());
                }
            }
            
            String orgInsql = isc.getInSQL(psnorgPKList.toArray(new String[0]));
            AssVO[] allOld =
                (AssVO[]) retrieve.retrieveByClause(null, AssVO.class, " pk_psnorg in (" + orgInsql + ") order by recordnum desc ");
            
            // 每条组织关系下的考核信息列表，按recordnum倒序
            HashMap<String, ArrayList<AssVO>> hm = new HashMap<String, ArrayList<AssVO>>();
            for (int i = 0; allOld != null && i < allOld.length; i++)
            {
                if (hm.get(allOld[i].getPk_psnorg()) == null)
                {
                    hm.put(allOld[i].getPk_psnorg(), new ArrayList<AssVO>());
                }
                hm.get(allOld[i].getPk_psnorg()).add(allOld[i]);
            }
            ArrayList<AssVO> deleteList = new ArrayList<AssVO>();// 要删除的记录
            ArrayList<AssVO> updateListAll = new ArrayList<AssVO>();// 要更新的记录
            ArrayList<AssVO> insertList = new ArrayList<AssVO>();// 要插入的记录
            ArrayList<String> docPKList = new ArrayList<String>();// 人员主键类表
            
            for (PsnJobVO job : jobVOs)
            {
                String pk_psnjob = job.getPk_psnjob();
                
                AssVO[] vos = peinfo.get(pk_psnjob);
                if (vos == null || vos.length == 0)
                {
                    continue;
                }
                
                // 更新历史记录的recordnum和lastflag
                AssVO[] old = null;
                if (hm.get(job.getPk_psnorg()) != null)
                {
                    old = hm.get(job.getPk_psnorg()).toArray(new AssVO[0]);
                }
                ArrayList<AssVO> updateList = new ArrayList<AssVO>();// 要更新的记录
                for (int i = 0; old != null && i < old.length; i++)
                {
                    if (exist(old[i], vos))
                    {
                        // 如果历史的考核方案对应的记录在档次冻结时也存在,则删除
                        deleteList.add(old[i]);
                    }
                    updateList.add(old[i]);
                }
                
                if (updateList.size() > 0)
                {
                    for (int i = 0; i < updateList.size(); i++)
                    {
                        updateList.get(i).setRecordnum(updateList.size() - 1 - i + vos.length);
                        updateList.get(i).setLastflag(UFBoolean.FALSE);
                    }
                    updateListAll.addAll(updateList);
                }
                
                for (int i = 0; i < vos.length; i++)
                {
                    vos[i].setPk_psndoc(job.getPk_psndoc());
                    vos[i].setPk_psnorg(job.getPk_psnorg());
                    vos[i].setRecordnum(vos.length - 1 - i);
                    vos[i].setLastflag(UFBoolean.valueOf(vos[i].getRecordnum() == 0));
                    vos[i].setCreationtime(PubEnv.getServerTime());
                    vos[i].setCreator(PubEnv.getPk_user());
                    vos[i].setStatus(VOStatus.NEW);
                    insertList.add(vos[i]);
                }
                if (!docPKList.contains(job.getPk_psndoc()))
                {
                    docPKList.add(job.getPk_psndoc());
                }
            }
            
            if (deleteList.size() > 0)
            {
                update.deleteVOList(null, deleteList, null);
            }
            
            if (updateListAll.size() > 0)
            {
                update.updateVOList(null, updateListAll, new String[]{AssVO.RECORDNUM, AssVO.LASTFLAG}, null);
            }
            
            if (insertList.size() > 0)
            {
                update.insertVOList(null, insertList, null);
            }
            
            getIPsndocService().updateDataAfterSubDataChanged(AssVO.getDefaultTableName(), docPKList.toArray(new String[0]));
        }
        finally
        {
            isc.clear();
        }
        
    }
    
    private boolean exist(AssVO assVO, AssVO[] vos)
    {
        for (AssVO vo : vos)
        {
            if (vo.getSchemecode().equals(assVO.getSchemecode()))
            {
                return true;
            }
        }
        return false;
    }
    
    @Override
    public void delPsnPeInfo(String pk_scheme) throws BusinessException
    {
        AssVO[] ass =
            (AssVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
                .retrieveByClause(null, AssVO.class, " schemecode = '" + pk_scheme + "' ");
        
        ArrayList<String> list = new ArrayList<String>();
        ArrayList<String> docPKList = new ArrayList<String>();
        for (int i = 0; ass != null && i < ass.length; i++)
        {
            if (!list.contains(ass[i].getPk_psnorg()))
            {
                list.add(ass[i].getPk_psnorg());
            }
            
            if (!docPKList.contains(ass[i].getPk_psndoc()))
            {
                docPKList.add(ass[i].getPk_psndoc());
            }
        }
        
        if (ass != null && ass.length > 0)
        {
            NCLocator.getInstance().lookup(IPersistenceUpdate.class).deleteVOArray(null, ass, null);
            
            InSQLCreator isc = new InSQLCreator();
            try
            {
                String insql = isc.getInSQL(list.toArray(new String[0]));
                AssVO[] assVOs =
                    (AssVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
                        .retrieveByClause(null, AssVO.class, " pk_psnorg in (" + insql + ") ");
                
                HashMap<String, ArrayList<AssVO>> hm = new HashMap<String, ArrayList<AssVO>>();
                for (int i = 0; assVOs != null && i < assVOs.length; i++)
                {
                    if (!hm.containsKey(assVOs[i].getPk_psnorg()))
                    {
                        hm.put(assVOs[i].getPk_psnorg(), new ArrayList<AssVO>());
                    }
                    hm.get(assVOs[i].getPk_psnorg()).add(assVOs[i]);
                }
                
                AssVO[] update = new AssVO[0];
                
                if (hm.keySet().size() > 0)
                {
                    for (String key : hm.keySet())
                    {
                        AssVO[] a = hm.get(key).toArray(new AssVO[0]);
                        SuperVOUtil.sortByAttributeName(a, AssVO.RECORDNUM, true);
                        for (int i = 0; i < a.length; i++)
                        {
                            a[i].setAttributeValue("recordnum", i);
                            if (i == 0)
                            {
                                a[i].setAttributeValue("lastflag", UFBoolean.TRUE);
                            }
                            else
                            {
                                a[i].setAttributeValue("lastflag", UFBoolean.FALSE);
                            }
                            a[i].setStatus(VOStatus.UPDATED);
                        }
                        update = (AssVO[]) ArrayUtils.addAll(update, a);
                    }
                }
                
                if (update.length > 0)
                {
                    NCLocator.getInstance().lookup(IPersistenceUpdate.class).updateVOArray(null, update, null, null);
                }
                
            }
            finally
            {
                isc.clear();
            }
            
            getIPsndocService().updateDataAfterSubDataChanged(AssVO.getDefaultTableName(), docPKList.toArray(new String[0]));
        }
        
    }
    
    @Override
    public void updateRecordnumAndLastflagForHrss(Map<String, String[]> map) throws BusinessException
    {
        if (map == null || map.size() == 0)
        {
            return;
        }
        
        IPersistenceRetrieve retrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        for (String pkPsndoc : map.keySet())
        {
            String[] setPKs = map.get(pkPsndoc);
            InfoSetVO[] set =
                (InfoSetVO[]) retrieve.retrieveByClause(null, InfoSetVO.class, " pk_infoset in (" + SQLHelper.joinToInSql(setPKs, -1)
                    + ") ");
            for (int i = 0; set != null && i < set.length; i++)
            {
                try
                {
                    SuperVO vo = (SuperVO) Class.forName(set[i].getVo_class_name()).newInstance();
                    SuperVO[] vos =
                        retrieve.retrieveByClause(null, Class.forName(set[i].getVo_class_name()), " pk_psndoc = '" + pkPsndoc
                            + "' order by recordnum,ts desc");
                    if (vo instanceof EduVO || vo instanceof CertVO)
                    {
                        for (int j = 0; vos != null && j < vos.length; j++)
                        {
                            vos[j].setAttributeValue("recordnum", j);
                            vos[j].setAttributeValue("lastflag", UFBoolean.TRUE);
                        }
                        NCLocator.getInstance().lookup(IPersistenceUpdate.class)
                            .updateVOArray(null, vos, new String[]{"recordnum", "lastflag"}, null);
                    }
                    else
                    {
                        updateAllRecordnumAndLastflag(vos);
                    }
                }
                catch (Exception e)
                {
                    Logger.error(e.getMessage(), e);
                    throw new BusinessException(e);
                }
            }
        }
        
    }
    
    @Override
    public void syncPsnQulifyInfo(BatchOperateVO vo) throws BusinessException
    {
        
        if (vo == null)
        {
            return;
        }
        
        QulifyVO[] deledCurrtypeVOs = ArrayClassConvertUtil.convert(vo.getDelObjs(), QulifyVO.class);
        new BaseDAO().deleteVOArray(deledCurrtypeVOs);
        
        QulifyVO[] updatedCurrtypeVOs = ArrayClassConvertUtil.convert(vo.getUpdObjs(), QulifyVO.class);
        new BaseDAO().updateVOArray(updatedCurrtypeVOs);
        
        QulifyVO[] addedCurrObjects = ArrayClassConvertUtil.convert(vo.getAddObjs(), QulifyVO.class);
        new BaseDAO().insertVOArray(addedCurrObjects);
        
    }
    
    /**
     * 根据人员基本信息主键pk_psndoc查找当前员工所有的组织关系主键pk_psnorg
     * 
     * @param pk_psndoc
     * @return String
     * @throws BusinessException
     */
    public HashMap<String, String[]> getAllPsnorgByPsndoc(String[] pk_psndocs) throws BusinessException
    {
        HashMap<String, String[]> mappks = new HashMap<String, String[]>();
        
        InSQLCreator insql = new InSQLCreator();
        String conditon = " pk_psndoc in (" + insql.getInSQL(pk_psndocs) + ") ";
        PsnOrgVO[] psnorgs = getServiceTemplate().queryByCondition(PsnOrgVO.class, conditon);
        if (ArrayUtils.isEmpty(psnorgs))
        {
            Logger.error("当前人员没有最新组织关系记录");
            return null;
        }
        
        for (String pk_psndoc : pk_psndocs)
        {
            String[] pk_psnorgs = new String[psnorgs.length];
            for (int i = 0; i < psnorgs.length; i++)
            {
                if (StringUtils.isNotBlank(pk_psndoc) && pk_psndoc.equals(psnorgs[i].getPk_psndoc()))
                    pk_psnorgs[i] = psnorgs[i].getPk_psnorg();
            }
            mappks.put(pk_psndoc, pk_psnorgs);
        }
        
        return mappks;
    }
    
}
