Browse Source

first commit

chenzhfa 4 years ago
parent
commit
6788947195
33 changed files with 8354 additions and 0 deletions
  1. 0 0
      README.md
  2. 19 0
      hrcm/.classpath
  3. 2 0
      hrcm/.module_prj
  4. 23 0
      hrcm/.project
  5. 7 0
      hrcm/META-INF/module.xml
  6. 137 0
      hrcm/src/client/nccloud/web/hrcm/contopinion/action/OpinionRemcSendMsgAction.java
  7. 818 0
      hrcm/src/private/nc/impl/hrcm/contopinion/ContopinionManageServiceImpl.java
  8. 89 0
      hrcm/src/public/nc/itf/hrcm/IContopinionManageService.java
  9. 21 0
      hrhi/.classpath
  10. 2 0
      hrhi/.module_prj
  11. 23 0
      hrhi/.project
  12. 7 0
      hrhi/META-INF/module.xml
  13. 137 0
      hrhi/src/client/nccloud/web/hrcm/contopinion/action/OpinionRemcSendMsgAction.java
  14. 126 0
      hrhi/src/client/nccloud/web/hrhi/psndoc/action/PsndocCreateUserInitAction.java
  15. 734 0
      hrhi/src/private/nc/impl/hrcm/contopinion/ContopinionManageServiceImpl.java
  16. 89 0
      hrhi/src/public/nc/itf/hrcm/IContopinionManageService.java
  17. 745 0
      hrhi/src/test/nc/impl/bd/psn/psndoc/PsndocServiceImpl.java
  18. 19 0
      hrjf/.classpath
  19. 2 0
      hrjf/.module_prj
  20. 23 0
      hrjf/.project
  21. 7 0
      hrjf/META-INF/module.xml
  22. 195 0
      hrjf/METADATA/dept/hrdept.bmf
  23. 91 0
      hrjf/METADATA/dept/hrdept_v.bmf
  24. 19 0
      hrtrn/.classpath
  25. 2 0
      hrtrn/.module_prj
  26. 23 0
      hrtrn/.project
  27. 7 0
      hrtrn/META-INF/module.xml
  28. 11 0
      hrtrn/META-INF/yytrn.upm
  29. 155 0
      hrtrn/src/client/nccloud/web/hryf/transapply/action/TransAddAction.java
  30. 2454 0
      hrtrn/src/private/nc/impl/trn/dimissionrds/DimissionrdsServiceImpl.java
  31. 2260 0
      hrtrn/src/private/nc/impl/trn/transmng/TransmngServiceImpl.java
  32. 86 0
      hrtrn/src/private/nc/impl/trn/transmng/TrnManageExServiceImpl.java
  33. 21 0
      hrtrn/src/public/nc/itf/trn/transmng/ITrnManageExService.java

+ 0 - 0
README.md


+ 19 - 0
hrcm/.classpath

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="out/public" path="src/public"/>
+	<classpathentry kind="src" output="out/private" path="src/private"/>
+	<classpathentry kind="src" output="out/client" path="src/client"/>
+	<classpathentry kind="src" output="out/test" path="src/test"/>
+	<classpathentry kind="src" output="out/resources" path="resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Ant_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Product_Common_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Middleware_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Framework_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Public_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Client_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Private_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Lang_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Generated_EJB"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 2 - 0
hrcm/.module_prj

@@ -0,0 +1,2 @@
+module.name=hrcm
+module.defConfig=module.xml

+ 23 - 0
hrcm/.project

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>hrcm</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>nc.uap.mde.ModuleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>nc.uap.mde.ModuleProjectNature</nature>
+	</natures>
+</projectDescription>

+ 7 - 0
hrcm/META-INF/module.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="gb2312"?>
+<module name="hrcm">
+    <public>
+    </public>
+    <private>
+    </private>
+</module>

+ 137 - 0
hrcm/src/client/nccloud/web/hrcm/contopinion/action/OpinionRemcSendMsgAction.java

@@ -0,0 +1,137 @@
+package nccloud.web.hrcm.contopinion.action;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import nc.hr.utils.ResHelper;
+import nc.itf.hrcm.IContopinionManageService;
+import nc.pub.tools.HRCMCommonValue;
+import nc.vo.hrcm.contopinion.ContopinionVO;
+import nc.vo.pub.BusinessException;
+import nc.vo.pub.BusinessRuntimeException;
+import nc.vo.uif2.LoginContext;
+import nccloud.commons.lang.ArrayUtils;
+import nccloud.commons.lang.StringUtils;
+import nccloud.framework.service.ServiceLocator;
+import nccloud.framework.web.container.IRequest;
+import nccloud.web.hr.pub.HRCommonAction;
+import nccloud.web.hr.pub.HRNccTemplateUtils;
+import nccloud.web.hr.pub.HRNccUtils;
+import nccloud.web.uapbd.commons.web.ParamUtils;
+
+/**
+ * 合同续签意见征询【发送续签征询消息】操作
+ * @author tianxfc
+ *
+ */
+public class OpinionRemcSendMsgAction extends HRCommonAction{
+	
+	private Integer	icntsucc = 0;	// 成功发送的消息数
+	
+	@Override
+	public <T> Object execute(IRequest request, T para) throws Exception {
+		ParamUtils param = new ParamUtils(request);
+		LoginContext context = HRNccUtils.getLoginContext(param);
+		
+		String pk_org = param.getString("pk_org", null);
+		if(StringUtils.isEmpty(pk_org)){
+			throw new BusinessRuntimeException(ResHelper.getString("6001uif2", "06001uif20070")/* @res 请先选择人力资源组织! */);
+		}
+		// 是否发送标识,第一次调用接口传N,第二次调用接口传Y
+		String sendCheckStr = param.getString("sendCheck", "Y");
+        boolean sendCheck = "Y".equals(sendCheckStr);
+		ContopinionVO[] selDatas = HRNccTemplateUtils.getVOFromGrid(ContopinionVO.class, OpinionCommon.getModelStr(param, "contopiniongrid"));
+		if(ArrayUtils.isEmpty(selDatas)){
+			throw new BusinessRuntimeException(ResHelper.getString("6011opin", "06011opin0025")/* @res"请选择要操作的记录!" */);
+		}
+		return sendContOpinion(selDatas, context, sendCheck);
+	}
+	
+	private String sendContOpinion(ContopinionVO[] contopinionVOs, LoginContext context, boolean sendCheck) throws Exception {
+		/**未征询或者未反馈续签意见*/
+		ArrayList<ContopinionVO> vtemp = new ArrayList<ContopinionVO>();
+		/**反馈中的续签意见*/
+		ArrayList<ContopinionVO> inFeedbackList = new ArrayList<ContopinionVO>();
+		for (int i = 0; i < contopinionVOs.length; i++) {
+			// conttype: 处理结果: 0=未征询,1=未反馈,2=反馈中,3=已反馈,4=已续签,5=已终止
+			if (contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_NOCONSULT) || contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_NOFEEDBACK)) {
+				vtemp.add(contopinionVOs[i]);
+			}
+			//modify by@chenzf 续签意见征询员工续签期限 2021-1-11 17:21:49 begin
+//			if(contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_INFEEDBACK)){
+//				inFeedbackList.add(contopinionVOs[i]);
+//			}
+			if(contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_INFEEDBACK) || contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_NOCONSULT) || contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_NOFEEDBACK)){
+				inFeedbackList.add(contopinionVOs[i]);
+			}
+			//modify by@chenzf 续签意见征询员工续签期限 2021-1-11 17:21:49 end
+		}
+		if (vtemp.size() < 1 && inFeedbackList.size() < 1) {
+			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0008")/* @res"只有未反馈、未征询、反馈中的人员才能发送通知!" */);
+		}
+		// 校验是否存在符合征询条件的记录
+		HashMap<String, Object> map = ServiceLocator.find(IContopinionManageService.class).getPsnjobDeptMap(vtemp.toArray(new ContopinionVO[0]));
+		String[] deptPKs = (String[]) map.get("pks");
+
+		String msg=null;
+		if(inFeedbackList.size()<1){
+			msg = (String) map.get("msg");
+			//当反馈中的数据为0,包含未反馈的数据,并且未征询和未反馈的都没有部门负责人时,不能征询意见
+			if(ArrayUtils.isEmpty(deptPKs)){
+				throw new BusinessException(ResHelper.getString("6011opin", "06011opin0019"));
+			}
+		}else if(ArrayUtils.isEmpty(deptPKs) || deptPKs.length < 1){
+			//只有反馈中
+			/*"您选中的部分人员的处理状态为“反馈中”,系统将给符合条件员工发送征询意见催办通知,确认发送吗?"*/;
+			msg = ResHelper.getString("6011opin", "06011opin0060");
+		}else{
+			//同时包含反馈中和未反馈
+			/*"您选中的人员的处理状态包含“未反馈”和“反馈中”,系统将给符合条件人员的部门负责人或员工发送征询意见通知,确认发送吗?"*/
+			msg = ResHelper.getString("6011opin", "06011opin0061");
+		}
+		
+		if(msg != null) {
+//			msg = "您好!您与公司的劳动合同即将到期,您满足签订无固定期限劳动合同的条件,请您反馈您的意向劳动合同期限类型。无固定期限/固定期限";
+		}
+		
+		// 是否发送标识,第一次调用接口false,第二次调用接口true
+		if(sendCheck){
+			return ResHelper.getString("6011opin", "06011opin0057")/* @res "确认发送" */ + "\n" + msg;
+//			return msg;
+		}
+		ContopinionVO[] vos = (ContopinionVO[]) map.get("vos");
+		HashMap<String, List<ContopinionVO>> contopMap = new HashMap<String, List<ContopinionVO>>();
+		HashMap<String, List<String>> psndeptMap = new HashMap<String, List<String>>();
+		if(!ArrayUtils.isEmpty(deptPKs)){			
+			for(int i = 0; i < deptPKs.length; i++){// 一个部门生成一个对应的通知
+				List<ContopinionVO> depttemp = new ArrayList<ContopinionVO>();
+				List<String> psndocList = new ArrayList<String>();
+				for(ContopinionVO vo : vos){
+					if(vo.getPk_dept().equals(deptPKs[i])){
+						depttemp.add(vo);
+						psndocList.add(vo.getPk_psnjob());
+					}
+				}
+				contopMap.put(deptPKs[i], depttemp);
+				psndeptMap.put(deptPKs[i], psndocList);
+			}
+		}
+
+		//modify by@chenzf 续签意见征询员工续签期限 2021-1-11 17:21:49 begin
+//		HashMap<String, Object> sendMsgMap = ServiceLocator.find(IContopinionManageService.class)
+//				.sendNoticeToDeptManager(psndeptMap, contopMap, context.getPk_group(), context.getPk_org(), vos, inFeedbackList);
+		HashMap<String, Object> sendMsgMap = ServiceLocator.find(IContopinionManageService.class)
+				.sendNoticeToPsn(psndeptMap, contopMap, context.getPk_group(), context.getPk_org(), vos, inFeedbackList);
+		//modify by@chenzf 续签意见征询员工续签期限 2021-1-11 17:21:49 end
+		icntsucc = (Integer) sendMsgMap.get("cnt");
+		if(icntsucc > 0){
+			// 提示发送成功信息
+			return ResHelper.getString("6011opin", "06011opin0010"/* @res "发送消息成功,共发送消息[{0}]条。" */, icntsucc.toString());
+		}else{
+			// 如果发送不成功,提示错误信息
+			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0011")/* @res "发送消息失败!" */);
+		}
+	}
+	
+}

+ 818 - 0
hrcm/src/private/nc/impl/hrcm/contopinion/ContopinionManageServiceImpl.java

@@ -0,0 +1,818 @@
+package nc.impl.hrcm.contopinion;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import nc.bs.dao.BaseDAO;
+import nc.bs.framework.common.NCLocator;
+import nc.bs.logging.Logger;
+import nc.bs.uif2.validation.ValidationException;
+import nc.bs.uif2.validation.ValidationFailure;
+import nc.hr.frame.persistence.HrBaseServiceImpl;
+import nc.hr.frame.persistence.SimpleDocServiceTemplate;
+import nc.hr.utils.HRCMTermUnitUtils;
+import nc.hr.utils.InSQLCreator;
+import nc.hr.utils.MultiLangHelper;
+import nc.hr.utils.PubEnv;
+import nc.hr.utils.ResHelper;
+import nc.itf.hi.IPsndocQryService;
+import nc.itf.hr.frame.IPersistenceRetrieve;
+import nc.itf.hr.hrss.IURLGenerator;
+import nc.itf.hr.managescope.ManagescopeFacade;
+import nc.itf.hr.message.IHRMessageSend;
+import nc.itf.hrcm.IContopinionManageService;
+import nc.itf.hrcm.IContopinionQueryService;
+import nc.itf.uap.rbac.IUserManageQuery;
+import nc.pub.tools.HRCMBusilogUtil;
+import nc.pub.tools.HRCMCommonValue;
+import nc.pubitf.rbac.IUserPubService;
+import nc.vo.bd.meta.BatchOperateVO;
+import nc.vo.hi.psndoc.PsnJobVO;
+import nc.vo.hi.psndoc.PsndocAggVO;
+import nc.vo.hi.psndoc.PsndocVO;
+import nc.vo.hr.managescope.ManagescopeBusiregionEnum;
+import nc.vo.hr.message.HRBusiMessageVO;
+import nc.vo.hrcm.contopinion.ContopinionVO;
+import nc.vo.hrcm.share.PsnSelListVO;
+import nc.vo.ml.LanguageVO;
+import nc.vo.ml.MultiLangContext;
+import nc.vo.om.hrdept.HRDeptVO;
+import nc.vo.pub.BusinessException;
+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.uif2.LoginContext;
+import nc.vo.util.BDVersionValidationUtil;
+import nccloud.commons.lang.ArrayUtils;
+import nccloud.commons.lang.StringUtils;
+
+/**
+ * 批量维护 Service实现
+ * 
+ * @author fengwei
+ */
+public class ContopinionManageServiceImpl extends HrBaseServiceImpl<ContopinionVO> implements IContopinionManageService
+{
+
+	private BaseDAO	baseDAO;
+
+	private BaseDAO getBaseDAO()
+	{
+		if (null == baseDAO)
+		{
+			baseDAO = new BaseDAO();
+		}
+		return baseDAO;
+	}
+
+	private final String				DOC_NAME	= "hrcm_contopinion";
+
+	private SimpleDocServiceTemplate	serviceTemplate;
+
+	private SimpleDocServiceTemplate getServiceTemplate()
+	{
+		if (null == serviceTemplate)
+		{
+			serviceTemplate = new SimpleDocServiceTemplate(DOC_NAME);
+		}
+		return serviceTemplate;
+	}
+
+	public ContopinionManageServiceImpl()
+	{
+		super("60e4471d-f208-4407-bdf7-682247ed0068");
+	}
+
+	@Override
+	public ContopinionVO[] batchSave(ContopinionVO[] vos) throws BusinessException {
+		if(vos == null || vos.length == 0){
+			return null;
+		}
+		//待修改的数据
+		List<ContopinionVO> updList = new ArrayList<ContopinionVO>();
+		//待删除的数据
+		List<ContopinionVO> delList = new ArrayList<ContopinionVO>();
+		for(ContopinionVO vo : vos){
+			if(vo.getStatus() == VOStatus.DELETED){
+				delList.add(vo);
+			}else{
+				updList.add(vo);
+			}
+		}
+		if(delList != null && !delList.isEmpty()){
+			deleteValidate(delList);
+			delete(delList.toArray(new ContopinionVO[0]));
+		}
+		if(updList != null && !updList.isEmpty()){
+			BatchOperateVO batchVO = new BatchOperateVO();
+			batchVO.setUpdObjs(updList.toArray());
+			BatchOperateVO returnObj = batchSave(batchVO, ContopinionVO.class);
+			return (ContopinionVO[]) returnObj.getUpdObjs();
+		}
+		return null;
+	}
+	
+	/**
+	 * 合同删除校验
+	 * @author tianxfc
+	 * @param vos
+	 * @throws ValidationException
+	 * @exception 异常描述
+	 */
+	public void deleteValidate(List<ContopinionVO> delList) throws ValidationException{
+		
+		List<ValidationFailure> failures = new ArrayList<ValidationFailure>();
+		for(ContopinionVO vo : delList){
+			int conttype = vo.getConttype();  //处理结果: 0=未征询,1=未反馈,2=反馈中,3=已反馈,4=已续签,5=已终止
+			if (HRCMCommonValue.STATE_NOCONSULT != conttype && HRCMCommonValue.STATE_NOFEEDBACK != conttype){
+				failures.add(new ValidationFailure(ResHelper.getString("6011opin", "06011opin0024")/* @res"只能删除状态为“未征询”和“未反馈”的征询记录!" */));
+				break;
+			}
+		}
+		if (!failures.isEmpty()){
+			throw new ValidationException(failures);
+		}
+	}
+
+	@Override
+	public HashMap<String, Object> sendNoticeToDeptManager(Map<String, List<String>> psndeptMap, Map<String, List<ContopinionVO>> contopMap,
+			String pk_group, String pk_org, ContopinionVO[] vos,ArrayList<ContopinionVO> inFeedbackList) throws BusinessException {
+		if(!ArrayUtils.isEmpty(vos)){
+			//时间戳校验
+			BDVersionValidationUtil.validateSuperVO(vos);
+		}
+		int icntsucc = 0;
+		IHRMessageSend messageSendService = NCLocator.getInstance().lookup(IHRMessageSend.class);
+		/**给部门负责人发送消息*/
+		if(!ArrayUtils.isEmpty(vos)){
+			Set<String> keySet = psndeptMap.keySet();
+			Iterator<String> it = keySet.iterator();
+			while (it.hasNext()) {
+				String pk_dept = it.next();// 部门主键
+				List<String> pk_psndocs = psndeptMap.get(pk_dept);// 部门内要续签的人员
+				List<ContopinionVO> opinionVOList = contopMap.get(pk_dept);// 部门内要续签人员的征询意见VO。
+				
+				// 续签人员列表
+				String employeeList = "";
+				InSQLCreator creator = new InSQLCreator();
+				
+				String inSQL = creator.getInSQL(pk_psndocs.toArray(new String[pk_psndocs.size()]));
+				ContopinionDAO dao = new ContopinionDAO();
+				List<String> nameList = dao.getPsnnameByPkjob(inSQL);
+				for (String name : nameList) {
+					employeeList += name + ", ";
+				}
+				
+				if (!StringUtils.isBlank(employeeList)) {
+					employeeList = employeeList.substring(0, employeeList.length() - 2);
+				}
+				
+				// 得到URL
+				//String url = getURL(pk_dept, opinionVOList);
+//				String url = SysinitAccessor.getInstance().getParaString(IOrgConst.GLOBEORG, "HR0002");
+//				if (StringUtils.isBlank(url)) {
+//					url = "";
+//				}
+				//url += "/nccloud/resources/hrcm/contractmgt/contopinion/main/index.html?appcode=60110313";
+				//url = "<a target='balck' href ='/nccloud/resources/hrcm/contractmgt/contopinion/main/index.html?appcode=60110313'>/nccloud/resources/hrcm/contractmgt/contopinion/main/index.html</a>";
+				String url = "请前往移动端【续签意见征询-经理】节点处理";
+				// 组织消息VO
+				HRBusiMessageVO messageInfoVO = new HRBusiMessageVO();
+				messageInfoVO.setBillVO(opinionVOList.get(0));// 关联元数据实体VO
+				messageInfoVO.setMsgrescode(HRCMCommonValue.DEPT_MSGTEMP_CODE);// 消息源编码
+				Hashtable<String, Object> transferValues = new Hashtable<String, Object>();
+				transferValues.put(HRCMCommonValue.EMPLOYEELIST, employeeList);
+				transferValues.put(HRCMCommonValue.URL, url);
+				messageInfoVO.setBusiVarValues(transferValues);// 业务函数值
+				messageInfoVO.setPkorgs(new String[] { opinionVOList.get(0).getPk_org() });
+				
+				setReciverInfo(messageInfoVO, pk_dept);
+				//征询意见-记录日志
+				HRCMBusilogUtil.writeContopinion(vos,"Contopin");
+				// 发送消息
+				//messageSendService.sendBuziMessage_RequiresNew(messageInfoVO, new String[] { getUserContentLangCode(PubEnv.getPk_user()) });
+				messageSendService.sendBuziMessage_RequiresNew(messageInfoVO);
+				icntsucc++;
+			}
+			
+			for(ContopinionVO vo : vos){
+				vo.setConttype(HRCMCommonValue.STATE_NOFEEDBACK);// 修改状态为未反馈
+				vo.setOpdate(PubEnv.getServerTime());// 征询时间为当前时间
+				vo.setIssendsuccess(UFBoolean.TRUE);
+			}
+			// 更新修改状态
+			vos = NCLocator.getInstance().lookup(IContopinionManageService.class).updateArray(vos);
+		}
+
+		/**如果需要发送催办消息的vo list 不为空  员工消息暂时不能发送*/
+		if(!inFeedbackList.isEmpty()){
+			int succ = sendMessageToEmp(inFeedbackList, pk_org, messageSendService);
+			icntsucc += succ;
+		}
+		HashMap<String, Object> map = new HashMap<String, Object>();
+		map.put("cnt", icntsucc);
+		return map;
+	}
+	
+	private String getUserContentLangCode(String userPk) throws BusinessException {
+		UserVO[] users = NCLocator.getInstance().lookup(IUserPubService.class).getUsersByPKs(new String[] { userPk });
+		if (ArrayUtils.isEmpty(users))
+			return null;
+		UserVO user = users[0];
+		String pk_langcode = user.getContentlang();
+		LanguageVO[] all = getAllEnabledLangVO();
+		if (ArrayUtils.isEmpty(all))
+			return null;
+		for (LanguageVO languageVO : all) {
+			if (languageVO.getPk_multilang().equals(pk_langcode))
+				return languageVO.getLangcode();
+		}
+		return null;
+
+	}
+
+	private static LanguageVO[] getAllEnabledLangVO() {
+		LanguageVO[] langvos = MultiLangContext.getInstance().getEnableLangVOs();
+		if (ArrayUtils.isEmpty(langvos))
+			return null;
+		return langvos;
+	}
+	
+	/**
+	 * 给员工发送征询催办消息
+	 * 2019-09-02 下午02:07:30
+	 * tianxfc
+	 * @param inFeedbackList
+	 * @param pk_org
+	 * @param messageSendService
+	 * @return
+	 * @throws BusinessException
+	 */
+	@SuppressWarnings("rawtypes")
+	private int sendMessageToEmp(ArrayList<ContopinionVO> inFeedbackList, String pk_org, IHRMessageSend messageSendService) throws BusinessException{
+		/**征询意见的工作记录主键*/
+		String[] psnjobPks = new String[inFeedbackList.size()];
+		for(int i=0; i<psnjobPks.length; i++){
+			psnjobPks[i] = inFeedbackList.get(i).getPk_psnjob();
+		}
+		/**查询每个工作记录主键所对应的aggVO*/
+		IPsndocQryService is = NCLocator.getInstance().lookup(IPsndocQryService.class);
+		PsndocAggVO[] psnaggVos = is.queryPsndocVOByPks(psnjobPks);
+		/**工作记录主键为KEY,aggVO为VALUE*/
+		HashMap<String,PsndocAggVO> psnMap = new HashMap<String, PsndocAggVO>();
+		/**K:pk_psndoc, V:pk_psnjob*/
+		HashMap<String,String> psndocPkMap = new HashMap<String, String>();
+		for (PsndocAggVO vo : psnaggVos) {// 缓存人员信息
+			String psndocPk = vo.getParentVO().getPk_psndoc();
+			String psnjobPk = vo.getParentVO().getPsnJobVO().getPk_psnjob();
+			psnMap.put(psnjobPk, vo);
+			psndocPkMap.put(psndocPk, psnjobPk);
+		}
+		/**人员主键*/
+		String[] psndocPks = new String[psnaggVos.length];
+		for (int i = 0; i < psnaggVos.length; i++) {
+			psndocPks[i] = psnaggVos[i].getParentVO().getPk_psndoc();
+		}
+		
+		InSQLCreator isc1 = new InSQLCreator();
+		String docInSql = isc1.getInSQL(psndocPks);
+		String userCondition = " pk_base_doc in ("+docInSql+") and base_doc_type = " + UserIdentityTypeEnumFactory.TYPE_PERSON + " ";
+		/**自助用户*/
+		UserVO[] uservos = (UserVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, UserVO.class, userCondition);
+		/**K:工作记录主键,V:UserVO的Cuserid*/
+		HashMap<String,String> userMap = new HashMap<String, String>();
+		if(ArrayUtils.isEmpty(uservos)){
+			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0064")/*"当前员工未设置自助用户不能发送催办消息"*/);
+		}
+		for(int i=0; i<uservos.length; i++){
+			String pk_psndoc = uservos[i].getPk_base_doc();
+			String psnjobPk = psndocPkMap.get(pk_psndoc);
+			userMap.put(psnjobPk, uservos[i].getCuserid());
+		}
+		int icntsucc = 0;
+		//组装消息VO
+		for (Iterator iterator = inFeedbackList.iterator(); iterator.hasNext();) {
+			ContopinionVO contopinionVO = (ContopinionVO) iterator.next();
+			HRBusiMessageVO messageInfoVO = new HRBusiMessageVO();
+			messageInfoVO.setMsgrescode(HRCMCommonValue.EMPLOYEE_MSGTEMP_CODE);// 消息源编码
+			messageInfoVO.setPkorgs(new String[] { pk_org });
+			setReciverInfoForEmp(messageInfoVO, contopinionVO, psnMap, userMap);
+			// 发送消息
+			messageSendService.sendBuziMessage_RequiresNew(messageInfoVO);
+			icntsucc++;
+		}
+		return icntsucc;
+	}
+	
+	private void setReciverInfoForEmp(HRBusiMessageVO messageInfoVO,ContopinionVO contopinionVO,HashMap<String,PsndocAggVO> psnMap,HashMap<String,String> userMap) throws BusinessException{
+		String psnjobPk = contopinionVO.getPk_psnjob();
+		PsndocVO psndocVO = psnMap.get(psnjobPk).getParentVO();
+		String[] emails = { psndocVO.getEmail() };
+		String[] mobiles = { psndocVO.getMobile() };
+		String userPk = userMap.get(psnjobPk);
+		String[] userpks = { userPk };
+		messageInfoVO.setReceiverEmails(emails);
+		messageInfoVO.setReceiverMobiles(mobiles);
+		messageInfoVO.setReceiverPkUsers(userpks);
+		messageInfoVO.setBillVO(contopinionVO);// 关联元数据实体VO
+		
+		Hashtable<String, Object> transferValues = new Hashtable<String, Object>();
+		String url = "请前往移动端【续签意见征询-员工】节点处理";
+		transferValues.put(HRCMCommonValue.URL, url);
+		messageInfoVO.setBusiVarValues(transferValues);// 业务函数值
+		
+//		//添加URL
+//		SSOInfo ssinfo = new SSOInfo();
+//		ssinfo.setUserPK(userPk);
+//		UFDateTime ut = new UFDateTime();
+//		ssinfo.setTtl(ut.getDateTimeAfter(30));
+//		ssinfo.setLocation("/portal/app/MyContopinApp?nodecode=E20200704&pk_opinion=" + contopinionVO.getPk_opinion());
+//		ssinfo.setWindowType(SSOInfo.WINDOW_TYPE_CURRENT);
+//		IURLGenerator IurlDirect = OpinionHrssUtils.getUrlDirect();
+//		if(IurlDirect!=null){			
+//			Hashtable<String, Object> transferValues = new Hashtable<String, Object>();
+//			transferValues.put(HRCMCommonValue.URL, IurlDirect.buildURLString(ssinfo));
+//			messageInfoVO.setBusiVarValues(transferValues);// 业务函数值
+//		}
+	}
+	
+	private IURLGenerator getUrlDirect() {
+		try {
+//			return ServiceLocator.lookup(IURLGenerator.class);
+			return null;
+		} catch (Throwable e) {
+			Logger.error(e.getMessage(), e);
+		}
+		return null;
+	}
+	
+	private void setReciverInfo(HRBusiMessageVO messageInfoVO, String pk_dept) throws BusinessException{
+		PsndocVO psndocVO = this.getDeptManager(pk_dept);
+		String[] emails = { psndocVO.getEmail() };
+		String[] mobiles = { psndocVO.getMobile() };
+		messageInfoVO.setReceiverEmails(emails);
+		messageInfoVO.setReceiverMobiles(mobiles);
+		UserVO uservo = getUserManageQuery(psndocVO.getPk_psndoc());
+		if(uservo != null){
+			String[] userpks = { uservo.getCuserid() };
+			messageInfoVO.setReceiverPkUsers(userpks);
+		}
+	}
+
+	private UserVO getUserManageQuery(String pk_psndoc) throws BusinessException{
+		return NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserVOByPsnDocID(pk_psndoc);
+	}
+
+	private PsndocVO getDeptManager(String pk_dept) throws BusinessException{
+		HRDeptVO deptVO = (HRDeptVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, HRDeptVO.class, pk_dept);
+		String pk_managerPk = deptVO.getPrincipal();
+		PsndocVO psndocVO = (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsndocVO.class, pk_managerPk);
+		return psndocVO;
+	}
+
+//	private String getURL(String pk_dept, List<ContopinionVO> opinionVOList) throws BusinessException
+//	{
+//		IContopinionQueryService queryService = NCLocator.getInstance().lookup(IContopinionQueryService.class);
+//		HRDeptVO deptVO = queryService.queryDeptManagerByPK(pk_dept);// 得到部门负责人VO
+//		// 部门负责人主键
+//		String principal = deptVO.getPrincipal();
+//		if (principal == null)
+//		{
+//			return null;
+//		}
+//
+//		// 续签人员主键
+//		String pk_opinionList = "";
+//		for (ContopinionVO opinionVO : opinionVOList)
+//		{
+//			pk_opinionList += opinionVO.getPk_opinion() + ", ";
+//		}
+//		if (!StringUtils.isBlank(pk_opinionList))
+//		{
+//			pk_opinionList = pk_opinionList.substring(0, pk_opinionList.length() - 2);
+//		}
+//
+//		// 得到部门负责人输信息
+//		GeneralVO vo = queryService.getDeptManagerInfo(principal);
+//
+//		// 得到部门负责人对应的用户
+//		String pk_psndoc = (String) vo.getAttributeValue("pk_psndoc");
+//		UserVO user = NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserVOByPsnDocID(pk_psndoc);
+//
+//		SSOInfo info = new SSOInfo();
+//		info.setFuncode("E20400704");
+//		if(user==null){	
+//			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0063")/*"当前人员的部门负责人未设置自助用户,不能发送通知"*/);
+//		}
+//		info.setUserPK(user.getCuserid());
+//
+//		UFDateTime ut = new UFDateTime();
+//		info.setTtl(ut.getDateTimeAfter(30));
+//		info.addParam("pk_opinion", pk_opinionList);
+//		//String title = nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("6011opin", "06011opin0052")/* @res "员工续签意见征询" */;
+//		//String url = NCLocator.getInstance().lookup(IURLGenerator.class).buildHTML(info, title);
+//		String url = NCLocator.getInstance().lookup(IURLGenerator.class).buildURLString(info);
+//
+//		return url;
+//	}
+
+	@Override
+	public ContopinionVO[] updateArray(ContopinionVO[] vos) throws BusinessException
+	{
+		getBaseDAO().updateVOArray(vos);
+		/*
+		 * @hujr 添加 记录日志文件
+		 * 2015年10月9日14:45:17
+		 */
+		//记录日志
+        HRCMBusilogUtil.writeContopinion(vos,"Contopin");
+		return (ContopinionVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
+				.retrieveByClause(null, ContopinionVO.class, " pk_opinion in (" + new InSQLCreator().getInSQL(vos, ContopinionVO.PK_OPINION) + ")");
+	}
+
+	@Override
+	public void delete(ContopinionVO[] vos) throws BusinessException
+	{
+		//记录日志
+		HRCMBusilogUtil.writeContopinion(vos,"delete");
+		
+		getBaseDAO().deleteVOArray(vos);
+	}
+
+	/**
+	 * 根据部门主键,判断部门是否有负责人
+	 * 
+	 * @author fengwei on 2011-1-25
+	 * @param pk_dept
+	 * @return
+	 * @exception 异常描述
+	 * @see 需要参见的其它内容
+	 * @since 从类的V60版本,此方法被添加进来。(可选)
+	 */
+	public boolean hasDeptManager(String pk_dept)
+	{
+		if (pk_dept != null)
+		{
+			try
+			{
+				HRDeptVO deptVO = NCLocator.getInstance().lookup(IContopinionQueryService.class).queryDeptManagerByPK(pk_dept);
+				if (null == deptVO.getPrincipal())
+				{
+					return false;
+				}
+			}
+			catch (BusinessException e)
+			{
+				Logger.error(e.getMessage());
+			}
+		}
+		return true;
+	}
+
+	private Map<String, String> getPkpsnjob(PsnSelListVO[] psnSelListVOs) throws BusinessException
+	{
+		Map<String, String> pkjobMap = new HashMap<String, String>();
+		List<String> psndocList = new ArrayList<String>();
+		for (int i = 0; i < psnSelListVOs.length; i++)
+		{
+			psndocList.add(psnSelListVOs[i].getPk_psndoc());
+		}
+
+		InSQLCreator isc = new InSQLCreator();
+
+		String insql = isc.getInSQL(psndocList.toArray(new String[0]));
+		String condition = " pk_psndoc in (" + insql + ") and lastflag = 'Y' and ismainjob = 'Y' and endflag = 'N'";
+		PsnJobVO[] psnjobVOs = getServiceTemplate().queryByCondition(PsnJobVO.class, condition);
+		if (!ArrayUtils.isEmpty(psnjobVOs))
+		{
+			for (int i = 0; i < psnjobVOs.length; i++)
+			{
+				String pk_psndoc = psnjobVOs[i].getPk_psndoc();
+				pkjobMap.put(pk_psndoc, psnjobVOs[i].getPk_psnjob());
+				psndocList.remove(pk_psndoc);
+			}
+		}
+
+		if (!psndocList.isEmpty())
+		{
+			String psndocSql = isc.getInSQL(psndocList.toArray(new String[0]));
+			String cond = " pk_psndoc in (" + psndocSql + ")";
+			//PsndocVO[] psndocVOs = getServiceTemplate().queryByCondition(PsndocVO.class, cond);
+			PsndocVO[] psndocVOs = (PsndocVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, PsndocVO.class, cond);
+			StringBuffer nameBuf = new StringBuffer();
+			for (int i = 0; i < psndocVOs.length; i++)
+			{
+				PsndocVO psndocVO = psndocVOs[i];
+				nameBuf.append(",").append(MultiLangHelper.getName(psndocVO));
+			}
+			String psnNames = nameBuf.toString().substring(1);
+			if (!StringUtils.isEmpty(psnNames))
+			{
+				throw new BusinessException(ResHelper.getString("6011opin", "06011opin0053", psnNames)/* @res "[{0}]是已离职人员,不能进续签意见征询!" */);
+			}
+		}
+
+		return pkjobMap;
+	}
+
+	/**
+	 * 得到业务委托人员过滤sql
+	 * 
+	 * @return
+	 * @throws BusinessException
+	 * @throws BusinessException
+	 */
+	@SuppressWarnings("unused")
+	private String getYwwt(String pk_org) throws BusinessException
+	{
+		String ywwtsql;
+		// 当前组织人员
+		HashMap<String, String> orgPkToYwwtSqlMap = new HashMap<String, String>();
+		ywwtsql = orgPkToYwwtSqlMap.get(pk_org);
+		if (ywwtsql == null)
+		{
+			// ywwtsql =
+			// ManagescopeFacade.queryPsnjobPksSQLByHrorgAndBusiregion(
+			// pk_org, ManagescopeBusiregionEnum.psndoc);
+			ywwtsql = ManagescopeFacade.queryPkOrgsSQLByHrorgAndBusiregion(pk_org, ManagescopeBusiregionEnum.psndoc, false);
+			// orgPkToYwwtSqlMap.put(pk_org, ywwtsql);
+			orgPkToYwwtSqlMap.put(pk_org, ywwtsql);
+		}
+		return ywwtsql;
+	}
+
+	@Override
+	public ContopinionVO[] insertContOpVO(PsnSelListVO[] psnVOs, String remenddate, String remmonth, String pk_psndoc_sub, String termtype,
+			Integer termUnit, LoginContext context) throws BusinessException
+	{
+		String[] remenddates = null;
+		String[] remmonths = null;
+		if (remenddate != null)
+		{
+			remenddates = remenddate.split("_");
+			remmonths = remmonth.split("_");
+		}
+
+		String[] pk_psndoc_subs = null;
+		if (pk_psndoc_sub != null)
+		{
+			pk_psndoc_subs = pk_psndoc_sub.split("_");
+		}
+
+		Map<String, String> map = getPkpsnjob(psnVOs);
+		ContopinionVO[] contopinionVOs = new ContopinionVO[pk_psndoc_subs.length];
+		for (int i = 0; i < pk_psndoc_subs.length; i++)
+		{
+			for (int j = 0; j < psnVOs.length; j++)
+			{
+				if (!psnVOs[j].getPk_psndoc_sub().equals(pk_psndoc_subs[i]))
+				{
+					continue;
+				}
+				ContopinionVO vo = new ContopinionVO();
+				vo.setPk_psndoc_sub(pk_psndoc_subs[i]);
+				vo.setTermtype(termtype);
+				vo.setContopinion_unit(termUnit);
+				if (HRCMTermUnitUtils.TERM_TYPE_NONFIXED.equals(termtype) || HRCMTermUnitUtils.TERM_TYPE_TASK.equals(termtype))
+				{
+					vo.setSedenddate(null);
+					vo.setItermmonth(null);
+				}
+				else
+				{
+					vo.setSedenddate(remenddates[i] == null ? null : new UFLiteralDate(remenddates[i]));
+					vo.setItermmonth(remmonths[i].equals("null") ? null : new Integer(remmonths[i]));
+
+				}
+				vo.setConttype(HRCMCommonValue.STATE_NOCONSULT);
+				vo.setDeptopinion(null);
+				vo.setDeptdirection(null);
+				vo.setHropinion(null);
+				vo.setPk_psnjob(map.get(psnVOs[i].getPk_psndoc()));
+				vo.setPk_org(context.getPk_org());
+				vo.setPk_group(context.getPk_group());
+				vo.setOpdate(PubEnv.getServerTime());
+				vo.setCreator(context.getPk_loginUser());
+				vo.setCreationtime(PubEnv.getServerTime());
+				contopinionVOs[i] = vo;
+			}
+		}
+		String[] pks = new ContopinionDAO().insertContopVOs(contopinionVOs);
+		/**modify start:记录合同续签意见征询增加业务日志 yunana 2013-06-08*/	
+		HRCMBusilogUtil.writeContopinionAdd(contopinionVOs);
+		/**modify end:yunana 2013-06-08*/
+		InSQLCreator isc = new InSQLCreator();
+		return (ContopinionVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
+				.retrieveByClause(null, ContopinionVO.class, " pk_opinion in (" + isc.getInSQL(pks) + ")");
+	}
+
+	
+
+	
+	@Override
+	public HashMap<String, Object> getPsnjobDeptMap(ContopinionVO[] contopinionVOs) throws BusinessException
+	{
+		PsnJobVO[] job = (PsnJobVO[]) NCLocator
+				.getInstance()
+				.lookup(IPersistenceRetrieve.class)
+				.retrieveByClause(null, PsnJobVO.class,
+						" pk_psnjob in (" + new InSQLCreator().getInSQL(contopinionVOs, ContopinionVO.PK_PSNJOB) + ")");
+		HashMap<String, String> map = new HashMap<String, String>();
+		for (int i = 0; job != null && i < job.length; i++)
+		{
+			map.put(job[i].getPk_psnjob(), job[i].getPk_dept());
+		}
+
+		for (int i = 0; i < contopinionVOs.length; i++)
+		{
+			String pk_dept = map.get(contopinionVOs[i].getPk_psnjob());
+			if (StringUtils.isBlank(pk_dept))
+			{
+				continue;
+			}
+			contopinionVOs[i].setPk_dept(pk_dept);
+		}
+
+		ArrayList<String> temp = new ArrayList<String>();// 部门id集合
+		for (ContopinionVO vo : contopinionVOs)
+		{
+			String pk_dept = vo.getPk_dept();
+			if (!temp.contains(pk_dept))
+			{
+				temp.add(pk_dept);
+			}
+		}
+		
+		/**拥有部门负责人的部门的主键*/
+		String[] deptPKs = getDeptHasPrincipal(temp.toArray(new String[0]));
+		HashMap<String, Object> result = new HashMap<String, Object>();
+		// 如果不存在部门没有负责人的情况,则提示用户是否继续进行操作
+		String msg = ResHelper.getString("6011opin", "06011opin0009")/* @res "即将向您所选人员的部门负责人发送通知,征询部门续签意见,确认发送吗?" */;
+		// 如果所有人员的所属部门都没有部门负责人,直接返回null
+		if (deptPKs == null || deptPKs.length == 0)
+		{
+			/* @res "您选中的人员的所属部门没有维护部门负责人,请维护部门负责人后再发送征询通知!" */
+			msg = ResHelper.getString("6011opin", "06011opin0019");
+			//throw new BusinessException(ResHelper.getString("6011opin", "06011opin0019"));
+			result.put("vos", null);
+			result.put("pks", null);
+			result.put("msg", msg);
+			return result;
+		}
+		
+		ArrayList<String> deptPkList = new ArrayList<String>();
+		for(int i=0; i<deptPKs.length;i++){
+			deptPkList.add(deptPKs[i]);
+		}
+		/**所在部门有负责人的征询意见*/
+		ArrayList<ContopinionVO> opinVOhasPrincipalList = new ArrayList<ContopinionVO>();
+		for(int i=0; i<contopinionVOs.length;i++){
+			if(!StringUtils.isEmpty(contopinionVOs[i].getPk_dept()) && deptPkList.contains(contopinionVOs[i].getPk_dept())){
+				opinVOhasPrincipalList.add(contopinionVOs[i]);
+			}
+		}
+
+		if (deptPKs.length < temp.size())
+		{
+			msg = ResHelper.getString("6011opin", "06011opin0020")/* @res"您选中的部分人员的所属部门没有维护部门负责人,系统将给符合条件人员的部门负责人发送征询通知!" */;
+		}
+
+		result.put("vos", opinVOhasPrincipalList.toArray(new ContopinionVO[0]));
+		result.put("pks", deptPKs);
+		result.put("msg", msg);
+
+		return result;
+	}
+
+	@Override
+	public String[] getDeptHasPrincipal(String[] deptPKs) throws BusinessException
+	{
+		if (deptPKs == null || deptPKs.length == 0)
+		{
+			return null;
+		}
+		HRDeptVO[] dept = (HRDeptVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
+				.retrieveByClause(null, HRDeptVO.class, " pk_dept in (" + new InSQLCreator().getInSQL(deptPKs) + ") and principal <> '~' ");
+
+		if (dept == null || dept.length == 0)
+		{
+			return null;
+		}
+		String[] result = new String[dept.length];
+		for (int i = 0; i < dept.length; i++)
+		{
+			result[i] = dept[i].getPk_dept();
+		}
+		return result;
+	}
+
+	@Override
+	public HashMap<String, Object> sendNoticeToPsn(Map<String, List<String>> psndeptMap,
+			Map<String, List<ContopinionVO>> contopMap, String pk_group, String pk_org, ContopinionVO[] vos,
+			ArrayList<ContopinionVO> inFeedbackList) throws BusinessException {
+		if(!ArrayUtils.isEmpty(vos)){
+			//时间戳校验
+			BDVersionValidationUtil.validateSuperVO(vos);
+		}
+		int icntsucc = 0;
+		IHRMessageSend messageSendService = NCLocator.getInstance().lookup(IHRMessageSend.class);
+		/** 员工消息发送*/
+		int succ = sendMessageToEmpEx(inFeedbackList, pk_org, messageSendService);
+		icntsucc += succ;
+		HashMap<String, Object> map = new HashMap<String, Object>();
+		map.put("cnt", icntsucc);
+		return map;
+	}
+	
+	/**
+	 * 给员工发送征询催办消息
+	 * 2019-09-02 下午02:07:30
+	 * tianxfc
+	 * @param inFeedbackList
+	 * @param pk_org
+	 * @param messageSendService
+	 * @return
+	 * @throws BusinessException
+	 */
+	@SuppressWarnings("rawtypes")
+	private int sendMessageToEmpEx(ArrayList<ContopinionVO> inFeedbackList, String pk_org, IHRMessageSend messageSendService) throws BusinessException{
+		/**征询意见的工作记录主键*/
+		String[] psnjobPks = new String[inFeedbackList.size()];
+		for(int i=0; i<psnjobPks.length; i++){
+			psnjobPks[i] = inFeedbackList.get(i).getPk_psnjob();
+		}
+		/**查询每个工作记录主键所对应的aggVO*/
+		IPsndocQryService is = NCLocator.getInstance().lookup(IPsndocQryService.class);
+		PsndocAggVO[] psnaggVos = is.queryPsndocVOByPks(psnjobPks);
+		/**工作记录主键为KEY,aggVO为VALUE*/
+		HashMap<String,PsndocAggVO> psnMap = new HashMap<String, PsndocAggVO>();
+		/**K:pk_psndoc, V:pk_psnjob*/
+		HashMap<String,String> psndocPkMap = new HashMap<String, String>();
+		for (PsndocAggVO vo : psnaggVos) {// 缓存人员信息
+			String psndocPk = vo.getParentVO().getPk_psndoc();
+			String psnjobPk = vo.getParentVO().getPsnJobVO().getPk_psnjob();
+			psnMap.put(psnjobPk, vo);
+			psndocPkMap.put(psndocPk, psnjobPk);
+		}
+		/**人员主键*/
+		String[] psndocPks = new String[psnaggVos.length];
+		for (int i = 0; i < psnaggVos.length; i++) {
+			psndocPks[i] = psnaggVos[i].getParentVO().getPk_psndoc();
+		}
+		
+		InSQLCreator isc1 = new InSQLCreator();
+		String docInSql = isc1.getInSQL(psndocPks);
+		String userCondition = " pk_base_doc in ("+docInSql+") and base_doc_type = " + UserIdentityTypeEnumFactory.TYPE_PERSON + " ";
+		/**自助用户*/
+		UserVO[] uservos = (UserVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, UserVO.class, userCondition);
+		/**K:工作记录主键,V:UserVO的Cuserid*/
+		HashMap<String,String> userMap = new HashMap<String, String>();
+		if(ArrayUtils.isEmpty(uservos)){
+			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0064")/*"当前员工未设置自助用户不能发送催办消息"*/);
+		}
+		for(int i=0; i<uservos.length; i++){
+			String pk_psndoc = uservos[i].getPk_base_doc();
+			String psnjobPk = psndocPkMap.get(pk_psndoc);
+			userMap.put(psnjobPk, uservos[i].getCuserid());
+		}
+		int icntsucc = 0;
+		//组装消息VO
+		for (Iterator iterator = inFeedbackList.iterator(); iterator.hasNext();) {
+			ContopinionVO contopinionVO = (ContopinionVO) iterator.next();
+			HRBusiMessageVO messageInfoVO = new HRBusiMessageVO();
+			messageInfoVO.setMsgrescode(HRCMCommonValue.EMPLOYEE_MSGTEMP_CODE);// 消息源编码
+			messageInfoVO.setPkorgs(new String[] { pk_org });
+			setReciverInfoForEmpEx(messageInfoVO, contopinionVO, psnMap, userMap);
+			// 发送消息
+			messageSendService.sendBuziMessage_RequiresNew(messageInfoVO);
+			icntsucc++;
+		}
+		return icntsucc;
+	}
+	
+	private void setReciverInfoForEmpEx(HRBusiMessageVO messageInfoVO,ContopinionVO contopinionVO,HashMap<String,PsndocAggVO> psnMap,HashMap<String,String> userMap) throws BusinessException{
+		String psnjobPk = contopinionVO.getPk_psnjob();
+		PsndocVO psndocVO = psnMap.get(psnjobPk).getParentVO();
+		String[] emails = { psndocVO.getEmail() };
+		String[] mobiles = { psndocVO.getMobile() };
+		String userPk = userMap.get(psnjobPk);
+		String[] userpks = { userPk };
+		messageInfoVO.setReceiverEmails(emails);
+		messageInfoVO.setReceiverMobiles(mobiles);
+		messageInfoVO.setReceiverPkUsers(userpks);
+		messageInfoVO.setBillVO(contopinionVO);// 关联元数据实体VO
+		
+		Hashtable<String, Object> transferValues = new Hashtable<String, Object>();
+		String url = "请前往移动端【续签意见征询-员工】节点处理";
+		transferValues.put(HRCMCommonValue.URL, url);
+		messageInfoVO.setBusiVarValues(transferValues);// 业务函数值
+		
+	}
+}

+ 89 - 0
hrcm/src/public/nc/itf/hrcm/IContopinionManageService.java

@@ -0,0 +1,89 @@
+package nc.itf.hrcm;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import nc.vo.hrcm.contopinion.ContopinionVO;
+import nc.vo.hrcm.share.PsnSelListVO;
+import nc.vo.pub.BusinessException;
+import nc.vo.uif2.LoginContext;
+
+/**
+ * 合同续签意见征询批量维护 Service接口
+ * @author fengwei
+ */
+public interface IContopinionManageService
+{
+
+	/**
+	 * 批量保存续签意见
+	 * @param batchVO
+	 * @return
+	 * @throws BusinessException
+	 */
+	ContopinionVO[] batchSave(ContopinionVO[] vos) throws BusinessException;
+
+	/**
+	 * 更新续签征询意见
+	 * @author fengwei on 2011-2-17
+	 * @param vos
+	 * @return 
+	 * @throws BusinessException
+	 * @exception 异常描述
+	 * @see 需要参见的其它内容
+	 * @since 从类的V60版本,此方法被添加进来。(可选)
+	 */
+	public ContopinionVO[] updateArray(ContopinionVO[] vos) throws BusinessException;
+
+	/**
+	 * 按照部门向部门负责人发送续签征询通知
+	 * @author fengwei on 2011-1-26
+	 * @param psndeptMap
+	 *             key:部门主键 value:部门下的人员
+	 * @param pk_group
+	 * @param pk_org
+	 * @param vos 
+	 * @param inFeedbackList 反馈中的续签意见,即部门反馈,个人还没有反馈的续签意见
+	 * @return
+	 * @exception 异常描述
+	 * @see 需要参见的其它内容
+	 * @since 从类的V60版本,此方法被添加进来。(可选)
+	 */
+	public HashMap<String, Object> sendNoticeToDeptManager(Map<String, List<String>> psndeptMap, Map<String, List<ContopinionVO>> contopMap, String pk_group,
+			String pk_org, ContopinionVO[] vos,ArrayList<ContopinionVO> inFeedbackList) throws BusinessException;
+
+	/**
+	 * 删除续签征询记录
+	 * @author fengwei on 2011-4-13
+	 * @param vos
+	 * @throws BusinessException
+	 * @exception 异常描述
+	 * @see 需要参见的其它内容
+	 * @since 从类的V60版本,此方法被添加进来。(可选)
+	 */
+	public void delete(ContopinionVO[] vos) throws BusinessException;
+
+	public ContopinionVO[] insertContOpVO(PsnSelListVO[] psnVOs, String remenddate, String remmonth, String pk_psndoc_sub, String termtype,
+			Integer termUnit, LoginContext context) throws BusinessException;
+
+	public HashMap<String, Object> getPsnjobDeptMap(ContopinionVO[] contopinionVOs) throws BusinessException;
+
+	public String[] getDeptHasPrincipal(String[] deptPKs) throws BusinessException;
+	
+	/**
+	 * 发送个人消息
+	 * @param psndeptMap
+	 * @param contopMap
+	 * @param pk_group
+	 * @param pk_org
+	 * @param vos
+	 * @param inFeedbackList
+	 * @return
+	 * @throws BusinessException
+	 */
+	public HashMap<String, Object> sendNoticeToPsn(Map<String, List<String>> psndeptMap, Map<String, List<ContopinionVO>> contopMap, String pk_group,
+			String pk_org, ContopinionVO[] vos,ArrayList<ContopinionVO> inFeedbackList) throws BusinessException; 
+
+}

+ 21 - 0
hrhi/.classpath

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="out/public" path="src/public"/>
+	<classpathentry kind="src" output="out/private" path="src/private"/>
+	<classpathentry kind="src" output="out/client" path="src/client"/>
+	<classpathentry kind="src" output="out/test" path="src/test"/>
+	<classpathentry kind="src" output="out/resources" path="resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Ant_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Product_Common_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Middleware_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Framework_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Public_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Client_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Private_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Lang_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Generated_EJB"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/hrcm"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/hrtrn"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 2 - 0
hrhi/.module_prj

@@ -0,0 +1,2 @@
+module.name=hrhi
+module.defConfig=module.xml

+ 23 - 0
hrhi/.project

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>hrhi</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>nc.uap.mde.ModuleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>nc.uap.mde.ModuleProjectNature</nature>
+	</natures>
+</projectDescription>

+ 7 - 0
hrhi/META-INF/module.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="gb2312"?>
+<module name="hrhi">
+    <public>
+    </public>
+    <private>
+    </private>
+</module>

+ 137 - 0
hrhi/src/client/nccloud/web/hrcm/contopinion/action/OpinionRemcSendMsgAction.java

@@ -0,0 +1,137 @@
+package nccloud.web.hrcm.contopinion.action;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import nc.hr.utils.ResHelper;
+import nc.itf.hrcm.IContopinionManageService;
+import nc.pub.tools.HRCMCommonValue;
+import nc.vo.hrcm.contopinion.ContopinionVO;
+import nc.vo.pub.BusinessException;
+import nc.vo.pub.BusinessRuntimeException;
+import nc.vo.uif2.LoginContext;
+import nccloud.commons.lang.ArrayUtils;
+import nccloud.commons.lang.StringUtils;
+import nccloud.framework.service.ServiceLocator;
+import nccloud.framework.web.container.IRequest;
+import nccloud.web.hr.pub.HRCommonAction;
+import nccloud.web.hr.pub.HRNccTemplateUtils;
+import nccloud.web.hr.pub.HRNccUtils;
+import nccloud.web.uapbd.commons.web.ParamUtils;
+
+/**
+ * 合同续签意见征询【发送续签征询消息】操作
+ * @author tianxfc
+ *
+ */
+public class OpinionRemcSendMsgAction extends HRCommonAction{
+	
+	private Integer	icntsucc = 0;	// 成功发送的消息数
+	
+	@Override
+	public <T> Object execute(IRequest request, T para) throws Exception {
+		ParamUtils param = new ParamUtils(request);
+		LoginContext context = HRNccUtils.getLoginContext(param);
+		
+		String pk_org = param.getString("pk_org", null);
+		if(StringUtils.isEmpty(pk_org)){
+			throw new BusinessRuntimeException(ResHelper.getString("6001uif2", "06001uif20070")/* @res 请先选择人力资源组织! */);
+		}
+		// 是否发送标识,第一次调用接口传N,第二次调用接口传Y
+		String sendCheckStr = param.getString("sendCheck", "Y");
+        boolean sendCheck = "Y".equals(sendCheckStr);
+		ContopinionVO[] selDatas = HRNccTemplateUtils.getVOFromGrid(ContopinionVO.class, OpinionCommon.getModelStr(param, "contopiniongrid"));
+		if(ArrayUtils.isEmpty(selDatas)){
+			throw new BusinessRuntimeException(ResHelper.getString("6011opin", "06011opin0025")/* @res"请选择要操作的记录!" */);
+		}
+		return sendContOpinion(selDatas, context, sendCheck);
+	}
+	
+	private String sendContOpinion(ContopinionVO[] contopinionVOs, LoginContext context, boolean sendCheck) throws Exception {
+		/**未征询或者未反馈续签意见*/
+		ArrayList<ContopinionVO> vtemp = new ArrayList<ContopinionVO>();
+		/**反馈中的续签意见*/
+		ArrayList<ContopinionVO> inFeedbackList = new ArrayList<ContopinionVO>();
+		for (int i = 0; i < contopinionVOs.length; i++) {
+			// conttype: 处理结果: 0=未征询,1=未反馈,2=反馈中,3=已反馈,4=已续签,5=已终止
+			if (contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_NOCONSULT) || contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_NOFEEDBACK)) {
+				vtemp.add(contopinionVOs[i]);
+			}
+			//modify by@chenzf 续签意见征询员工续签期限 2021-1-11 17:21:49 begin
+//			if(contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_INFEEDBACK)){
+//				inFeedbackList.add(contopinionVOs[i]);
+//			}
+			if(contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_INFEEDBACK) || contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_NOCONSULT) || contopinionVOs[i].getConttype().equals(HRCMCommonValue.STATE_NOFEEDBACK)){
+				inFeedbackList.add(contopinionVOs[i]);
+			}
+			//modify by@chenzf 续签意见征询员工续签期限 2021-1-11 17:21:49 end
+		}
+		if (vtemp.size() < 1 && inFeedbackList.size() < 1) {
+			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0008")/* @res"只有未反馈、未征询、反馈中的人员才能发送通知!" */);
+		}
+		// 校验是否存在符合征询条件的记录
+		HashMap<String, Object> map = ServiceLocator.find(IContopinionManageService.class).getPsnjobDeptMap(vtemp.toArray(new ContopinionVO[0]));
+		String[] deptPKs = (String[]) map.get("pks");
+
+		String msg=null;
+		if(inFeedbackList.size()<1){
+			msg = (String) map.get("msg");
+			//当反馈中的数据为0,包含未反馈的数据,并且未征询和未反馈的都没有部门负责人时,不能征询意见
+			if(ArrayUtils.isEmpty(deptPKs)){
+				throw new BusinessException(ResHelper.getString("6011opin", "06011opin0019"));
+			}
+		}else if(ArrayUtils.isEmpty(deptPKs) || deptPKs.length < 1){
+			//只有反馈中
+			/*"您选中的部分人员的处理状态为“反馈中”,系统将给符合条件员工发送征询意见催办通知,确认发送吗?"*/;
+			msg = ResHelper.getString("6011opin", "06011opin0060");
+		}else{
+			//同时包含反馈中和未反馈
+			/*"您选中的人员的处理状态包含“未反馈”和“反馈中”,系统将给符合条件人员的部门负责人或员工发送征询意见通知,确认发送吗?"*/
+			msg = ResHelper.getString("6011opin", "06011opin0061");
+		}
+		
+		if(msg != null) {
+			msg = "您好!您与公司的劳动合同即将到期,您满足签订无固定期限劳动合同的条件,请您反馈您的意向劳动合同期限类型。无固定期限/固定期限";
+		}
+		
+		// 是否发送标识,第一次调用接口false,第二次调用接口true
+		if(sendCheck){
+//			return ResHelper.getString("6011opin", "06011opin0057")/* @res "确认发送" */ + "\n" + msg;
+			return msg;
+		}
+		ContopinionVO[] vos = (ContopinionVO[]) map.get("vos");
+		HashMap<String, List<ContopinionVO>> contopMap = new HashMap<String, List<ContopinionVO>>();
+		HashMap<String, List<String>> psndeptMap = new HashMap<String, List<String>>();
+		if(!ArrayUtils.isEmpty(deptPKs)){			
+			for(int i = 0; i < deptPKs.length; i++){// 一个部门生成一个对应的通知
+				List<ContopinionVO> depttemp = new ArrayList<ContopinionVO>();
+				List<String> psndocList = new ArrayList<String>();
+				for(ContopinionVO vo : vos){
+					if(vo.getPk_dept().equals(deptPKs[i])){
+						depttemp.add(vo);
+						psndocList.add(vo.getPk_psnjob());
+					}
+				}
+				contopMap.put(deptPKs[i], depttemp);
+				psndeptMap.put(deptPKs[i], psndocList);
+			}
+		}
+
+		//modify by@chenzf 续签意见征询员工续签期限 2021-1-11 17:21:49 begin
+//		HashMap<String, Object> sendMsgMap = ServiceLocator.find(IContopinionManageService.class)
+//				.sendNoticeToDeptManager(psndeptMap, contopMap, context.getPk_group(), context.getPk_org(), vos, inFeedbackList);
+		HashMap<String, Object> sendMsgMap = ServiceLocator.find(IContopinionManageService.class)
+				.sendNoticeToPsn(psndeptMap, contopMap, context.getPk_group(), context.getPk_org(), vos, inFeedbackList);
+		//modify by@chenzf 续签意见征询员工续签期限 2021-1-11 17:21:49 end
+		icntsucc = (Integer) sendMsgMap.get("cnt");
+		if(icntsucc > 0){
+			// 提示发送成功信息
+			return ResHelper.getString("6011opin", "06011opin0010"/* @res "发送消息成功,共发送消息[{0}]条。" */, icntsucc.toString());
+		}else{
+			// 如果发送不成功,提示错误信息
+			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0011")/* @res "发送消息失败!" */);
+		}
+	}
+	
+}

+ 126 - 0
hrhi/src/client/nccloud/web/hrhi/psndoc/action/PsndocCreateUserInitAction.java

@@ -0,0 +1,126 @@
+package nccloud.web.hrhi.psndoc.action;
+
+import nc.bs.logging.Logger;
+import nc.hr.utils.ResHelper;
+import nc.itf.bd.psn.psndoc.IPsndocQueryService;
+import nc.itf.hi.IPsndocService;
+import nc.itf.hr.frame.IPersistenceRetrieve;
+import nc.md.persist.framework.IMDPersistenceQueryService;
+import nc.vo.bd.psn.PsndocVO;
+import nc.vo.hi.psndoc.PsnCreateVO;
+import nc.vo.hi.psndoc.PsnJobVO;
+import nc.vo.pub.BusinessException;
+import nc.vo.pub.BusinessRuntimeException;
+import nc.vo.sm.UserVO;
+import nc.vo.uif2.LoginContext;
+import nccloud.framework.service.ServiceLocator;
+import nccloud.framework.web.container.IRequest;
+import nccloud.itf.hrhi.pub.IHRHITempletConst;
+import nccloud.web.hr.pub.HRCommonAction;
+import nccloud.web.hr.pub.HRNccTemplateUtils;
+import nccloud.web.hr.pub.HRNccUtils;
+import nccloud.web.uapbd.commons.web.ParamUtils;
+import nccloud.commons.lang.StringUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 生成用户初始化对话框
+ * 
+ * @author sunpeng
+ *
+ */
+public class PsndocCreateUserInitAction extends HRCommonAction {
+
+	@Override
+	public <T> Object execute(IRequest request, T para) throws Exception {
+
+		ParamUtils param = new ParamUtils(request);
+		LoginContext context = HRNccUtils.getLoginContext(param);
+
+		// hr组织id,
+		if (StringUtils.isBlank(context.getPk_org())) {
+			throw new BusinessRuntimeException("Parameter Error!");
+		}
+
+		// 只有维护节点有这个按钮
+		String pageCode = IHRHITempletConst.TEMPLET_EMPLOYEE;
+
+		String paramStr = param.getString("param_str", null);
+		if (StringUtils.isBlank(paramStr)) {
+			throw new BusinessException(ResHelper.getString("6007psn", "06007psn0103")/* @res "请选择要批改的人员!" */);
+		}
+
+		String[] psnjobPks = paramStr.split(",");
+		Object[] objects = ServiceLocator.find(IMDPersistenceQueryService.class).queryBillOfVOByPKsWithOrder(PsnJobVO.class, psnjobPks, true);
+		if (objects == null || objects.length == 0) {
+			return null;
+		}
+
+		ArrayList<String> docPK = new ArrayList<String>();
+		for (int i = 0; i < objects.length; i++) {
+			if(objects[i]==null){
+				continue;
+			}
+			if (!docPK.contains(((PsnJobVO) objects[i]).getPk_psndoc())) {
+				docPK.add(((PsnJobVO) objects[i]).getPk_psndoc());
+			}
+
+		}
+		PsndocVO[] vos = ServiceLocator.find(IPsndocQueryService.class).queryPsndocByPks(docPK.toArray(new String[0]));
+
+		ArrayList<PsndocVO> al = new ArrayList<PsndocVO>();
+
+		for (int i = 0; vos != null && i < vos.length; i++) {
+			if (vos[i].getPsnjobs() == null || vos[i].getPsnjobs().length == 0) {
+				continue;
+			}
+			al.add(vos[i]);
+		}
+
+		vos = al.toArray(new PsndocVO[0]);
+
+		PsnCreateVO[] psnCreateVOs = psndocVO2PsnCreateVO(vos);
+
+		return HRNccTemplateUtils.getGridWithArea(pageCode, "createuser", psnCreateVOs);
+	}
+
+	public PsnCreateVO[] psndocVO2PsnCreateVO(PsndocVO[] psndocvos) throws BusinessException {
+		if (psndocvos == null || psndocvos.length == 0)
+			return null;
+		PsnCreateVO[] result = new PsnCreateVO[psndocvos.length];
+
+		ArrayList<String> al = new ArrayList<String>();
+		for (int i = 0; i < psndocvos.length; i++) {
+			if (!al.contains(psndocvos[i].getPrimaryKey())) {
+				al.add(psndocvos[i].getPrimaryKey());
+			}
+		}
+		List<String> list = new ArrayList<String>();
+		try {
+			list = ServiceLocator.find(IPsndocService.class).queryUserDocPK(al.toArray(new String[0]));
+		} catch (BusinessException e) {
+			Logger.error(e.getMessage(), e);
+		}
+
+		for (int i = 0; i < psndocvos.length; i++) {
+			if (list.contains(psndocvos[i].getPk_psndoc())) {
+				UserVO[] userVO = getUserVO(psndocvos[i].getPk_psndoc());
+				result[i] = new PsnCreateVO(psndocvos[i].getPk_psndoc(), userVO[0].getUser_code(), psndocvos[i].getName(), true);
+			} else {
+				//modify by@chenzf 修改用户编码为手机号 2021-1-5 11:39:12 begin
+//				result[i] = new PsnCreateVO(psndocvos[i].getPk_psndoc(), psndocvos[i].getCode(), psndocvos[i].getName(), false);
+				result[i] = new PsnCreateVO(psndocvos[i].getPk_psndoc(), psndocvos[i].getMobile(), psndocvos[i].getName(), false);
+				//modify by@chenzf 修改用户编码为手机号 2021-1-5 11:39:12 end
+			}
+		}
+		return result;
+	}
+
+	private UserVO[] getUserVO(String pk_psndoc) throws BusinessException {
+		String cond = " pk_base_doc = '"+pk_psndoc+"'";
+		return (UserVO[]) ServiceLocator.find(IPersistenceRetrieve.class).retrieveByClause(null, UserVO.class, cond);
+	}
+
+}

+ 734 - 0
hrhi/src/private/nc/impl/hrcm/contopinion/ContopinionManageServiceImpl.java

@@ -0,0 +1,734 @@
+package nc.impl.hrcm.contopinion;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import nc.bs.dao.BaseDAO;
+import nc.bs.framework.common.NCLocator;
+import nc.bs.logging.Logger;
+import nc.bs.uif2.validation.ValidationException;
+import nc.bs.uif2.validation.ValidationFailure;
+import nc.hr.frame.persistence.HrBaseServiceImpl;
+import nc.hr.frame.persistence.SimpleDocServiceTemplate;
+import nc.hr.utils.HRCMTermUnitUtils;
+import nc.hr.utils.InSQLCreator;
+import nc.hr.utils.MultiLangHelper;
+import nc.hr.utils.PubEnv;
+import nc.hr.utils.ResHelper;
+import nc.itf.hi.IPsndocQryService;
+import nc.itf.hr.frame.IPersistenceRetrieve;
+import nc.itf.hr.hrss.IURLGenerator;
+import nc.itf.hr.managescope.ManagescopeFacade;
+import nc.itf.hr.message.IHRMessageSend;
+import nc.itf.hrcm.IContopinionManageService;
+import nc.itf.hrcm.IContopinionQueryService;
+import nc.itf.uap.rbac.IUserManageQuery;
+import nc.pub.tools.HRCMBusilogUtil;
+import nc.pub.tools.HRCMCommonValue;
+import nc.pubitf.rbac.IUserPubService;
+import nc.vo.bd.meta.BatchOperateVO;
+import nc.vo.hi.psndoc.PsnJobVO;
+import nc.vo.hi.psndoc.PsndocAggVO;
+import nc.vo.hi.psndoc.PsndocVO;
+import nc.vo.hr.managescope.ManagescopeBusiregionEnum;
+import nc.vo.hr.message.HRBusiMessageVO;
+import nc.vo.hrcm.contopinion.ContopinionVO;
+import nc.vo.hrcm.share.PsnSelListVO;
+import nc.vo.ml.LanguageVO;
+import nc.vo.ml.MultiLangContext;
+import nc.vo.om.hrdept.HRDeptVO;
+import nc.vo.pub.BusinessException;
+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.uif2.LoginContext;
+import nc.vo.util.BDVersionValidationUtil;
+import nccloud.commons.lang.ArrayUtils;
+import nccloud.commons.lang.StringUtils;
+
+/**
+ * 批量维护 Service实现
+ * 
+ * @author fengwei
+ */
+public class ContopinionManageServiceImpl extends HrBaseServiceImpl<ContopinionVO> implements IContopinionManageService
+{
+
+	private BaseDAO	baseDAO;
+
+	private BaseDAO getBaseDAO()
+	{
+		if (null == baseDAO)
+		{
+			baseDAO = new BaseDAO();
+		}
+		return baseDAO;
+	}
+
+	private final String				DOC_NAME	= "hrcm_contopinion";
+
+	private SimpleDocServiceTemplate	serviceTemplate;
+
+	private SimpleDocServiceTemplate getServiceTemplate()
+	{
+		if (null == serviceTemplate)
+		{
+			serviceTemplate = new SimpleDocServiceTemplate(DOC_NAME);
+		}
+		return serviceTemplate;
+	}
+
+	public ContopinionManageServiceImpl()
+	{
+		super("60e4471d-f208-4407-bdf7-682247ed0068");
+	}
+
+	@Override
+	public ContopinionVO[] batchSave(ContopinionVO[] vos) throws BusinessException {
+		if(vos == null || vos.length == 0){
+			return null;
+		}
+		//待修改的数据
+		List<ContopinionVO> updList = new ArrayList<ContopinionVO>();
+		//待删除的数据
+		List<ContopinionVO> delList = new ArrayList<ContopinionVO>();
+		for(ContopinionVO vo : vos){
+			if(vo.getStatus() == VOStatus.DELETED){
+				delList.add(vo);
+			}else{
+				updList.add(vo);
+			}
+		}
+		if(delList != null && !delList.isEmpty()){
+			deleteValidate(delList);
+			delete(delList.toArray(new ContopinionVO[0]));
+		}
+		if(updList != null && !updList.isEmpty()){
+			BatchOperateVO batchVO = new BatchOperateVO();
+			batchVO.setUpdObjs(updList.toArray());
+			BatchOperateVO returnObj = batchSave(batchVO, ContopinionVO.class);
+			return (ContopinionVO[]) returnObj.getUpdObjs();
+		}
+		return null;
+	}
+	
+	/**
+	 * 合同删除校验
+	 * @author tianxfc
+	 * @param vos
+	 * @throws ValidationException
+	 * @exception 异常描述
+	 */
+	public void deleteValidate(List<ContopinionVO> delList) throws ValidationException{
+		
+		List<ValidationFailure> failures = new ArrayList<ValidationFailure>();
+		for(ContopinionVO vo : delList){
+			int conttype = vo.getConttype();  //处理结果: 0=未征询,1=未反馈,2=反馈中,3=已反馈,4=已续签,5=已终止
+			if (HRCMCommonValue.STATE_NOCONSULT != conttype && HRCMCommonValue.STATE_NOFEEDBACK != conttype){
+				failures.add(new ValidationFailure(ResHelper.getString("6011opin", "06011opin0024")/* @res"只能删除状态为“未征询”和“未反馈”的征询记录!" */));
+				break;
+			}
+		}
+		if (!failures.isEmpty()){
+			throw new ValidationException(failures);
+		}
+	}
+
+	@Override
+	public HashMap<String, Object> sendNoticeToDeptManager(Map<String, List<String>> psndeptMap, Map<String, List<ContopinionVO>> contopMap,
+			String pk_group, String pk_org, ContopinionVO[] vos,ArrayList<ContopinionVO> inFeedbackList) throws BusinessException {
+		if(!ArrayUtils.isEmpty(vos)){
+			//时间戳校验
+			BDVersionValidationUtil.validateSuperVO(vos);
+		}
+		int icntsucc = 0;
+		IHRMessageSend messageSendService = NCLocator.getInstance().lookup(IHRMessageSend.class);
+		/**给部门负责人发送消息*/
+		if(!ArrayUtils.isEmpty(vos)){
+			Set<String> keySet = psndeptMap.keySet();
+			Iterator<String> it = keySet.iterator();
+			while (it.hasNext()) {
+				String pk_dept = it.next();// 部门主键
+				List<String> pk_psndocs = psndeptMap.get(pk_dept);// 部门内要续签的人员
+				List<ContopinionVO> opinionVOList = contopMap.get(pk_dept);// 部门内要续签人员的征询意见VO。
+				
+				// 续签人员列表
+				String employeeList = "";
+				InSQLCreator creator = new InSQLCreator();
+				
+				String inSQL = creator.getInSQL(pk_psndocs.toArray(new String[pk_psndocs.size()]));
+				ContopinionDAO dao = new ContopinionDAO();
+				List<String> nameList = dao.getPsnnameByPkjob(inSQL);
+				for (String name : nameList) {
+					employeeList += name + ", ";
+				}
+				
+				if (!StringUtils.isBlank(employeeList)) {
+					employeeList = employeeList.substring(0, employeeList.length() - 2);
+				}
+				
+				// 得到URL
+				//String url = getURL(pk_dept, opinionVOList);
+//				String url = SysinitAccessor.getInstance().getParaString(IOrgConst.GLOBEORG, "HR0002");
+//				if (StringUtils.isBlank(url)) {
+//					url = "";
+//				}
+				//url += "/nccloud/resources/hrcm/contractmgt/contopinion/main/index.html?appcode=60110313";
+				//url = "<a target='balck' href ='/nccloud/resources/hrcm/contractmgt/contopinion/main/index.html?appcode=60110313'>/nccloud/resources/hrcm/contractmgt/contopinion/main/index.html</a>";
+				String url = "请前往移动端【续签意见征询-经理】节点处理";
+				// 组织消息VO
+				HRBusiMessageVO messageInfoVO = new HRBusiMessageVO();
+				messageInfoVO.setBillVO(opinionVOList.get(0));// 关联元数据实体VO
+				messageInfoVO.setMsgrescode(HRCMCommonValue.DEPT_MSGTEMP_CODE);// 消息源编码
+				Hashtable<String, Object> transferValues = new Hashtable<String, Object>();
+				transferValues.put(HRCMCommonValue.EMPLOYEELIST, employeeList);
+				transferValues.put(HRCMCommonValue.URL, url);
+				messageInfoVO.setBusiVarValues(transferValues);// 业务函数值
+				messageInfoVO.setPkorgs(new String[] { opinionVOList.get(0).getPk_org() });
+				
+				setReciverInfo(messageInfoVO, pk_dept);
+				//征询意见-记录日志
+				HRCMBusilogUtil.writeContopinion(vos,"Contopin");
+				// 发送消息
+				//messageSendService.sendBuziMessage_RequiresNew(messageInfoVO, new String[] { getUserContentLangCode(PubEnv.getPk_user()) });
+				messageSendService.sendBuziMessage_RequiresNew(messageInfoVO);
+				icntsucc++;
+			}
+			
+			for(ContopinionVO vo : vos){
+				vo.setConttype(HRCMCommonValue.STATE_NOFEEDBACK);// 修改状态为未反馈
+				vo.setOpdate(PubEnv.getServerTime());// 征询时间为当前时间
+				vo.setIssendsuccess(UFBoolean.TRUE);
+			}
+			// 更新修改状态
+			vos = NCLocator.getInstance().lookup(IContopinionManageService.class).updateArray(vos);
+		}
+
+		/**如果需要发送催办消息的vo list 不为空  员工消息暂时不能发送*/
+		if(!inFeedbackList.isEmpty()){
+			int succ = sendMessageToEmp(inFeedbackList, pk_org, messageSendService);
+			icntsucc += succ;
+		}
+		HashMap<String, Object> map = new HashMap<String, Object>();
+		map.put("cnt", icntsucc);
+		return map;
+	}
+	
+	private String getUserContentLangCode(String userPk) throws BusinessException {
+		UserVO[] users = NCLocator.getInstance().lookup(IUserPubService.class).getUsersByPKs(new String[] { userPk });
+		if (ArrayUtils.isEmpty(users))
+			return null;
+		UserVO user = users[0];
+		String pk_langcode = user.getContentlang();
+		LanguageVO[] all = getAllEnabledLangVO();
+		if (ArrayUtils.isEmpty(all))
+			return null;
+		for (LanguageVO languageVO : all) {
+			if (languageVO.getPk_multilang().equals(pk_langcode))
+				return languageVO.getLangcode();
+		}
+		return null;
+
+	}
+
+	private static LanguageVO[] getAllEnabledLangVO() {
+		LanguageVO[] langvos = MultiLangContext.getInstance().getEnableLangVOs();
+		if (ArrayUtils.isEmpty(langvos))
+			return null;
+		return langvos;
+	}
+	
+	/**
+	 * 给员工发送征询催办消息
+	 * 2019-09-02 下午02:07:30
+	 * tianxfc
+	 * @param inFeedbackList
+	 * @param pk_org
+	 * @param messageSendService
+	 * @return
+	 * @throws BusinessException
+	 */
+	@SuppressWarnings("rawtypes")
+	private int sendMessageToEmp(ArrayList<ContopinionVO> inFeedbackList, String pk_org, IHRMessageSend messageSendService) throws BusinessException{
+		/**征询意见的工作记录主键*/
+		String[] psnjobPks = new String[inFeedbackList.size()];
+		for(int i=0; i<psnjobPks.length; i++){
+			psnjobPks[i] = inFeedbackList.get(i).getPk_psnjob();
+		}
+		/**查询每个工作记录主键所对应的aggVO*/
+		IPsndocQryService is = NCLocator.getInstance().lookup(IPsndocQryService.class);
+		PsndocAggVO[] psnaggVos = is.queryPsndocVOByPks(psnjobPks);
+		/**工作记录主键为KEY,aggVO为VALUE*/
+		HashMap<String,PsndocAggVO> psnMap = new HashMap<String, PsndocAggVO>();
+		/**K:pk_psndoc, V:pk_psnjob*/
+		HashMap<String,String> psndocPkMap = new HashMap<String, String>();
+		for (PsndocAggVO vo : psnaggVos) {// 缓存人员信息
+			String psndocPk = vo.getParentVO().getPk_psndoc();
+			String psnjobPk = vo.getParentVO().getPsnJobVO().getPk_psnjob();
+			psnMap.put(psnjobPk, vo);
+			psndocPkMap.put(psndocPk, psnjobPk);
+		}
+		/**人员主键*/
+		String[] psndocPks = new String[psnaggVos.length];
+		for (int i = 0; i < psnaggVos.length; i++) {
+			psndocPks[i] = psnaggVos[i].getParentVO().getPk_psndoc();
+		}
+		
+		InSQLCreator isc1 = new InSQLCreator();
+		String docInSql = isc1.getInSQL(psndocPks);
+		String userCondition = " pk_base_doc in ("+docInSql+") and base_doc_type = " + UserIdentityTypeEnumFactory.TYPE_PERSON + " ";
+		/**自助用户*/
+		UserVO[] uservos = (UserVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, UserVO.class, userCondition);
+		/**K:工作记录主键,V:UserVO的Cuserid*/
+		HashMap<String,String> userMap = new HashMap<String, String>();
+		if(ArrayUtils.isEmpty(uservos)){
+			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0064")/*"当前员工未设置自助用户不能发送催办消息"*/);
+		}
+		for(int i=0; i<uservos.length; i++){
+			String pk_psndoc = uservos[i].getPk_base_doc();
+			String psnjobPk = psndocPkMap.get(pk_psndoc);
+			userMap.put(psnjobPk, uservos[i].getCuserid());
+		}
+		int icntsucc = 0;
+		//组装消息VO
+		for (Iterator iterator = inFeedbackList.iterator(); iterator.hasNext();) {
+			ContopinionVO contopinionVO = (ContopinionVO) iterator.next();
+			HRBusiMessageVO messageInfoVO = new HRBusiMessageVO();
+			messageInfoVO.setMsgrescode(HRCMCommonValue.EMPLOYEE_MSGTEMP_CODE);// 消息源编码
+			messageInfoVO.setPkorgs(new String[] { pk_org });
+			setReciverInfoForEmp(messageInfoVO, contopinionVO, psnMap, userMap);
+			// 发送消息
+			messageSendService.sendBuziMessage_RequiresNew(messageInfoVO);
+			icntsucc++;
+		}
+		return icntsucc;
+	}
+	
+	private void setReciverInfoForEmp(HRBusiMessageVO messageInfoVO,ContopinionVO contopinionVO,HashMap<String,PsndocAggVO> psnMap,HashMap<String,String> userMap) throws BusinessException{
+		String psnjobPk = contopinionVO.getPk_psnjob();
+		PsndocVO psndocVO = psnMap.get(psnjobPk).getParentVO();
+		String[] emails = { psndocVO.getEmail() };
+		String[] mobiles = { psndocVO.getMobile() };
+		String userPk = userMap.get(psnjobPk);
+		String[] userpks = { userPk };
+		messageInfoVO.setReceiverEmails(emails);
+		messageInfoVO.setReceiverMobiles(mobiles);
+		messageInfoVO.setReceiverPkUsers(userpks);
+		messageInfoVO.setBillVO(contopinionVO);// 关联元数据实体VO
+		
+		Hashtable<String, Object> transferValues = new Hashtable<String, Object>();
+		String url = "请前往移动端【续签意见征询-员工】节点处理";
+		transferValues.put(HRCMCommonValue.URL, url);
+		messageInfoVO.setBusiVarValues(transferValues);// 业务函数值
+		
+//		//添加URL
+//		SSOInfo ssinfo = new SSOInfo();
+//		ssinfo.setUserPK(userPk);
+//		UFDateTime ut = new UFDateTime();
+//		ssinfo.setTtl(ut.getDateTimeAfter(30));
+//		ssinfo.setLocation("/portal/app/MyContopinApp?nodecode=E20200704&pk_opinion=" + contopinionVO.getPk_opinion());
+//		ssinfo.setWindowType(SSOInfo.WINDOW_TYPE_CURRENT);
+//		IURLGenerator IurlDirect = OpinionHrssUtils.getUrlDirect();
+//		if(IurlDirect!=null){			
+//			Hashtable<String, Object> transferValues = new Hashtable<String, Object>();
+//			transferValues.put(HRCMCommonValue.URL, IurlDirect.buildURLString(ssinfo));
+//			messageInfoVO.setBusiVarValues(transferValues);// 业务函数值
+//		}
+	}
+	
+	private IURLGenerator getUrlDirect() {
+		try {
+//			return ServiceLocator.lookup(IURLGenerator.class);
+			return null;
+		} catch (Throwable e) {
+			Logger.error(e.getMessage(), e);
+		}
+		return null;
+	}
+	
+	private void setReciverInfo(HRBusiMessageVO messageInfoVO, String pk_dept) throws BusinessException{
+		PsndocVO psndocVO = this.getDeptManager(pk_dept);
+		String[] emails = { psndocVO.getEmail() };
+		String[] mobiles = { psndocVO.getMobile() };
+		messageInfoVO.setReceiverEmails(emails);
+		messageInfoVO.setReceiverMobiles(mobiles);
+		UserVO uservo = getUserManageQuery(psndocVO.getPk_psndoc());
+		if(uservo != null){
+			String[] userpks = { uservo.getCuserid() };
+			messageInfoVO.setReceiverPkUsers(userpks);
+		}
+	}
+
+	private UserVO getUserManageQuery(String pk_psndoc) throws BusinessException{
+		return NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserVOByPsnDocID(pk_psndoc);
+	}
+
+	private PsndocVO getDeptManager(String pk_dept) throws BusinessException{
+		HRDeptVO deptVO = (HRDeptVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, HRDeptVO.class, pk_dept);
+		String pk_managerPk = deptVO.getPrincipal();
+		PsndocVO psndocVO = (PsndocVO) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByPk(null, PsndocVO.class, pk_managerPk);
+		return psndocVO;
+	}
+
+//	private String getURL(String pk_dept, List<ContopinionVO> opinionVOList) throws BusinessException
+//	{
+//		IContopinionQueryService queryService = NCLocator.getInstance().lookup(IContopinionQueryService.class);
+//		HRDeptVO deptVO = queryService.queryDeptManagerByPK(pk_dept);// 得到部门负责人VO
+//		// 部门负责人主键
+//		String principal = deptVO.getPrincipal();
+//		if (principal == null)
+//		{
+//			return null;
+//		}
+//
+//		// 续签人员主键
+//		String pk_opinionList = "";
+//		for (ContopinionVO opinionVO : opinionVOList)
+//		{
+//			pk_opinionList += opinionVO.getPk_opinion() + ", ";
+//		}
+//		if (!StringUtils.isBlank(pk_opinionList))
+//		{
+//			pk_opinionList = pk_opinionList.substring(0, pk_opinionList.length() - 2);
+//		}
+//
+//		// 得到部门负责人输信息
+//		GeneralVO vo = queryService.getDeptManagerInfo(principal);
+//
+//		// 得到部门负责人对应的用户
+//		String pk_psndoc = (String) vo.getAttributeValue("pk_psndoc");
+//		UserVO user = NCLocator.getInstance().lookup(IUserManageQuery.class).queryUserVOByPsnDocID(pk_psndoc);
+//
+//		SSOInfo info = new SSOInfo();
+//		info.setFuncode("E20400704");
+//		if(user==null){	
+//			throw new BusinessException(ResHelper.getString("6011opin", "06011opin0063")/*"当前人员的部门负责人未设置自助用户,不能发送通知"*/);
+//		}
+//		info.setUserPK(user.getCuserid());
+//
+//		UFDateTime ut = new UFDateTime();
+//		info.setTtl(ut.getDateTimeAfter(30));
+//		info.addParam("pk_opinion", pk_opinionList);
+//		//String title = nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("6011opin", "06011opin0052")/* @res "员工续签意见征询" */;
+//		//String url = NCLocator.getInstance().lookup(IURLGenerator.class).buildHTML(info, title);
+//		String url = NCLocator.getInstance().lookup(IURLGenerator.class).buildURLString(info);
+//
+//		return url;
+//	}
+
+	@Override
+	public ContopinionVO[] updateArray(ContopinionVO[] vos) throws BusinessException
+	{
+		getBaseDAO().updateVOArray(vos);
+		/*
+		 * @hujr 添加 记录日志文件
+		 * 2015年10月9日14:45:17
+		 */
+		//记录日志
+        HRCMBusilogUtil.writeContopinion(vos,"Contopin");
+		return (ContopinionVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
+				.retrieveByClause(null, ContopinionVO.class, " pk_opinion in (" + new InSQLCreator().getInSQL(vos, ContopinionVO.PK_OPINION) + ")");
+	}
+
+	@Override
+	public void delete(ContopinionVO[] vos) throws BusinessException
+	{
+		//记录日志
+		HRCMBusilogUtil.writeContopinion(vos,"delete");
+		
+		getBaseDAO().deleteVOArray(vos);
+	}
+
+	/**
+	 * 根据部门主键,判断部门是否有负责人
+	 * 
+	 * @author fengwei on 2011-1-25
+	 * @param pk_dept
+	 * @return
+	 * @exception 异常描述
+	 * @see 需要参见的其它内容
+	 * @since 从类的V60版本,此方法被添加进来。(可选)
+	 */
+	public boolean hasDeptManager(String pk_dept)
+	{
+		if (pk_dept != null)
+		{
+			try
+			{
+				HRDeptVO deptVO = NCLocator.getInstance().lookup(IContopinionQueryService.class).queryDeptManagerByPK(pk_dept);
+				if (null == deptVO.getPrincipal())
+				{
+					return false;
+				}
+			}
+			catch (BusinessException e)
+			{
+				Logger.error(e.getMessage());
+			}
+		}
+		return true;
+	}
+
+	private Map<String, String> getPkpsnjob(PsnSelListVO[] psnSelListVOs) throws BusinessException
+	{
+		Map<String, String> pkjobMap = new HashMap<String, String>();
+		List<String> psndocList = new ArrayList<String>();
+		for (int i = 0; i < psnSelListVOs.length; i++)
+		{
+			psndocList.add(psnSelListVOs[i].getPk_psndoc());
+		}
+
+		InSQLCreator isc = new InSQLCreator();
+
+		String insql = isc.getInSQL(psndocList.toArray(new String[0]));
+		String condition = " pk_psndoc in (" + insql + ") and lastflag = 'Y' and ismainjob = 'Y' and endflag = 'N'";
+		PsnJobVO[] psnjobVOs = getServiceTemplate().queryByCondition(PsnJobVO.class, condition);
+		if (!ArrayUtils.isEmpty(psnjobVOs))
+		{
+			for (int i = 0; i < psnjobVOs.length; i++)
+			{
+				String pk_psndoc = psnjobVOs[i].getPk_psndoc();
+				pkjobMap.put(pk_psndoc, psnjobVOs[i].getPk_psnjob());
+				psndocList.remove(pk_psndoc);
+			}
+		}
+
+		if (!psndocList.isEmpty())
+		{
+			String psndocSql = isc.getInSQL(psndocList.toArray(new String[0]));
+			String cond = " pk_psndoc in (" + psndocSql + ")";
+			//PsndocVO[] psndocVOs = getServiceTemplate().queryByCondition(PsndocVO.class, cond);
+			PsndocVO[] psndocVOs = (PsndocVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class).retrieveByClause(null, PsndocVO.class, cond);
+			StringBuffer nameBuf = new StringBuffer();
+			for (int i = 0; i < psndocVOs.length; i++)
+			{
+				PsndocVO psndocVO = psndocVOs[i];
+				nameBuf.append(",").append(MultiLangHelper.getName(psndocVO));
+			}
+			String psnNames = nameBuf.toString().substring(1);
+			if (!StringUtils.isEmpty(psnNames))
+			{
+				throw new BusinessException(ResHelper.getString("6011opin", "06011opin0053", psnNames)/* @res "[{0}]是已离职人员,不能进续签意见征询!" */);
+			}
+		}
+
+		return pkjobMap;
+	}
+
+	/**
+	 * 得到业务委托人员过滤sql
+	 * 
+	 * @return
+	 * @throws BusinessException
+	 * @throws BusinessException
+	 */
+	@SuppressWarnings("unused")
+	private String getYwwt(String pk_org) throws BusinessException
+	{
+		String ywwtsql;
+		// 当前组织人员
+		HashMap<String, String> orgPkToYwwtSqlMap = new HashMap<String, String>();
+		ywwtsql = orgPkToYwwtSqlMap.get(pk_org);
+		if (ywwtsql == null)
+		{
+			// ywwtsql =
+			// ManagescopeFacade.queryPsnjobPksSQLByHrorgAndBusiregion(
+			// pk_org, ManagescopeBusiregionEnum.psndoc);
+			ywwtsql = ManagescopeFacade.queryPkOrgsSQLByHrorgAndBusiregion(pk_org, ManagescopeBusiregionEnum.psndoc, false);
+			// orgPkToYwwtSqlMap.put(pk_org, ywwtsql);
+			orgPkToYwwtSqlMap.put(pk_org, ywwtsql);
+		}
+		return ywwtsql;
+	}
+
+	@Override
+	public ContopinionVO[] insertContOpVO(PsnSelListVO[] psnVOs, String remenddate, String remmonth, String pk_psndoc_sub, String termtype,
+			Integer termUnit, LoginContext context) throws BusinessException
+	{
+		String[] remenddates = null;
+		String[] remmonths = null;
+		if (remenddate != null)
+		{
+			remenddates = remenddate.split("_");
+			remmonths = remmonth.split("_");
+		}
+
+		String[] pk_psndoc_subs = null;
+		if (pk_psndoc_sub != null)
+		{
+			pk_psndoc_subs = pk_psndoc_sub.split("_");
+		}
+
+		Map<String, String> map = getPkpsnjob(psnVOs);
+		ContopinionVO[] contopinionVOs = new ContopinionVO[pk_psndoc_subs.length];
+		for (int i = 0; i < pk_psndoc_subs.length; i++)
+		{
+			for (int j = 0; j < psnVOs.length; j++)
+			{
+				if (!psnVOs[j].getPk_psndoc_sub().equals(pk_psndoc_subs[i]))
+				{
+					continue;
+				}
+				ContopinionVO vo = new ContopinionVO();
+				vo.setPk_psndoc_sub(pk_psndoc_subs[i]);
+				vo.setTermtype(termtype);
+				vo.setContopinion_unit(termUnit);
+				if (HRCMTermUnitUtils.TERM_TYPE_NONFIXED.equals(termtype) || HRCMTermUnitUtils.TERM_TYPE_TASK.equals(termtype))
+				{
+					vo.setSedenddate(null);
+					vo.setItermmonth(null);
+				}
+				else
+				{
+					vo.setSedenddate(remenddates[i] == null ? null : new UFLiteralDate(remenddates[i]));
+					vo.setItermmonth(remmonths[i].equals("null") ? null : new Integer(remmonths[i]));
+
+				}
+				vo.setConttype(HRCMCommonValue.STATE_NOCONSULT);
+				vo.setDeptopinion(null);
+				vo.setDeptdirection(null);
+				vo.setHropinion(null);
+				vo.setPk_psnjob(map.get(psnVOs[i].getPk_psndoc()));
+				vo.setPk_org(context.getPk_org());
+				vo.setPk_group(context.getPk_group());
+				vo.setOpdate(PubEnv.getServerTime());
+				vo.setCreator(context.getPk_loginUser());
+				vo.setCreationtime(PubEnv.getServerTime());
+				contopinionVOs[i] = vo;
+			}
+		}
+		String[] pks = new ContopinionDAO().insertContopVOs(contopinionVOs);
+		/**modify start:记录合同续签意见征询增加业务日志 yunana 2013-06-08*/	
+		HRCMBusilogUtil.writeContopinionAdd(contopinionVOs);
+		/**modify end:yunana 2013-06-08*/
+		InSQLCreator isc = new InSQLCreator();
+		return (ContopinionVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
+				.retrieveByClause(null, ContopinionVO.class, " pk_opinion in (" + isc.getInSQL(pks) + ")");
+	}
+
+	
+
+	
+	@Override
+	public HashMap<String, Object> getPsnjobDeptMap(ContopinionVO[] contopinionVOs) throws BusinessException
+	{
+		PsnJobVO[] job = (PsnJobVO[]) NCLocator
+				.getInstance()
+				.lookup(IPersistenceRetrieve.class)
+				.retrieveByClause(null, PsnJobVO.class,
+						" pk_psnjob in (" + new InSQLCreator().getInSQL(contopinionVOs, ContopinionVO.PK_PSNJOB) + ")");
+		HashMap<String, String> map = new HashMap<String, String>();
+		for (int i = 0; job != null && i < job.length; i++)
+		{
+			map.put(job[i].getPk_psnjob(), job[i].getPk_dept());
+		}
+
+		for (int i = 0; i < contopinionVOs.length; i++)
+		{
+			String pk_dept = map.get(contopinionVOs[i].getPk_psnjob());
+			if (StringUtils.isBlank(pk_dept))
+			{
+				continue;
+			}
+			contopinionVOs[i].setPk_dept(pk_dept);
+		}
+
+		ArrayList<String> temp = new ArrayList<String>();// 部门id集合
+		for (ContopinionVO vo : contopinionVOs)
+		{
+			String pk_dept = vo.getPk_dept();
+			if (!temp.contains(pk_dept))
+			{
+				temp.add(pk_dept);
+			}
+		}
+		
+		/**拥有部门负责人的部门的主键*/
+		String[] deptPKs = getDeptHasPrincipal(temp.toArray(new String[0]));
+		HashMap<String, Object> result = new HashMap<String, Object>();
+		// 如果不存在部门没有负责人的情况,则提示用户是否继续进行操作
+		String msg = ResHelper.getString("6011opin", "06011opin0009")/* @res "即将向您所选人员的部门负责人发送通知,征询部门续签意见,确认发送吗?" */;
+		// 如果所有人员的所属部门都没有部门负责人,直接返回null
+		if (deptPKs == null || deptPKs.length == 0)
+		{
+			/* @res "您选中的人员的所属部门没有维护部门负责人,请维护部门负责人后再发送征询通知!" */
+			msg = ResHelper.getString("6011opin", "06011opin0019");
+			//throw new BusinessException(ResHelper.getString("6011opin", "06011opin0019"));
+			result.put("vos", null);
+			result.put("pks", null);
+			result.put("msg", msg);
+			return result;
+		}
+		
+		ArrayList<String> deptPkList = new ArrayList<String>();
+		for(int i=0; i<deptPKs.length;i++){
+			deptPkList.add(deptPKs[i]);
+		}
+		/**所在部门有负责人的征询意见*/
+		ArrayList<ContopinionVO> opinVOhasPrincipalList = new ArrayList<ContopinionVO>();
+		for(int i=0; i<contopinionVOs.length;i++){
+			if(!StringUtils.isEmpty(contopinionVOs[i].getPk_dept()) && deptPkList.contains(contopinionVOs[i].getPk_dept())){
+				opinVOhasPrincipalList.add(contopinionVOs[i]);
+			}
+		}
+
+		if (deptPKs.length < temp.size())
+		{
+			msg = ResHelper.getString("6011opin", "06011opin0020")/* @res"您选中的部分人员的所属部门没有维护部门负责人,系统将给符合条件人员的部门负责人发送征询通知!" */;
+		}
+
+		result.put("vos", opinVOhasPrincipalList.toArray(new ContopinionVO[0]));
+		result.put("pks", deptPKs);
+		result.put("msg", msg);
+
+		return result;
+	}
+
+	@Override
+	public String[] getDeptHasPrincipal(String[] deptPKs) throws BusinessException
+	{
+		if (deptPKs == null || deptPKs.length == 0)
+		{
+			return null;
+		}
+		HRDeptVO[] dept = (HRDeptVO[]) NCLocator.getInstance().lookup(IPersistenceRetrieve.class)
+				.retrieveByClause(null, HRDeptVO.class, " pk_dept in (" + new InSQLCreator().getInSQL(deptPKs) + ") and principal <> '~' ");
+
+		if (dept == null || dept.length == 0)
+		{
+			return null;
+		}
+		String[] result = new String[dept.length];
+		for (int i = 0; i < dept.length; i++)
+		{
+			result[i] = dept[i].getPk_dept();
+		}
+		return result;
+	}
+
+	@Override
+	public HashMap<String, Object> sendNoticeToPsn(Map<String, List<String>> psndeptMap,
+			Map<String, List<ContopinionVO>> contopMap, String pk_group, String pk_org, ContopinionVO[] vos,
+			ArrayList<ContopinionVO> inFeedbackList) throws BusinessException {
+		if(!ArrayUtils.isEmpty(vos)){
+			//时间戳校验
+			BDVersionValidationUtil.validateSuperVO(vos);
+		}
+		int icntsucc = 0;
+		IHRMessageSend messageSendService = NCLocator.getInstance().lookup(IHRMessageSend.class);
+		/** 员工消息发送*/
+		int succ = sendMessageToEmp(inFeedbackList, pk_org, messageSendService);
+		icntsucc += succ;
+		HashMap<String, Object> map = new HashMap<String, Object>();
+		map.put("cnt", icntsucc);
+		return map;
+	}
+
+}

+ 89 - 0
hrhi/src/public/nc/itf/hrcm/IContopinionManageService.java

@@ -0,0 +1,89 @@
+package nc.itf.hrcm;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import nc.vo.hrcm.contopinion.ContopinionVO;
+import nc.vo.hrcm.share.PsnSelListVO;
+import nc.vo.pub.BusinessException;
+import nc.vo.uif2.LoginContext;
+
+/**
+ * 合同续签意见征询批量维护 Service接口
+ * @author fengwei
+ */
+public interface IContopinionManageService
+{
+
+	/**
+	 * 批量保存续签意见
+	 * @param batchVO
+	 * @return
+	 * @throws BusinessException
+	 */
+	ContopinionVO[] batchSave(ContopinionVO[] vos) throws BusinessException;
+
+	/**
+	 * 更新续签征询意见
+	 * @author fengwei on 2011-2-17
+	 * @param vos
+	 * @return 
+	 * @throws BusinessException
+	 * @exception 异常描述
+	 * @see 需要参见的其它内容
+	 * @since 从类的V60版本,此方法被添加进来。(可选)
+	 */
+	public ContopinionVO[] updateArray(ContopinionVO[] vos) throws BusinessException;
+
+	/**
+	 * 按照部门向部门负责人发送续签征询通知
+	 * @author fengwei on 2011-1-26
+	 * @param psndeptMap
+	 *             key:部门主键 value:部门下的人员
+	 * @param pk_group
+	 * @param pk_org
+	 * @param vos 
+	 * @param inFeedbackList 反馈中的续签意见,即部门反馈,个人还没有反馈的续签意见
+	 * @return
+	 * @exception 异常描述
+	 * @see 需要参见的其它内容
+	 * @since 从类的V60版本,此方法被添加进来。(可选)
+	 */
+	public HashMap<String, Object> sendNoticeToDeptManager(Map<String, List<String>> psndeptMap, Map<String, List<ContopinionVO>> contopMap, String pk_group,
+			String pk_org, ContopinionVO[] vos,ArrayList<ContopinionVO> inFeedbackList) throws BusinessException;
+
+	/**
+	 * 删除续签征询记录
+	 * @author fengwei on 2011-4-13
+	 * @param vos
+	 * @throws BusinessException
+	 * @exception 异常描述
+	 * @see 需要参见的其它内容
+	 * @since 从类的V60版本,此方法被添加进来。(可选)
+	 */
+	public void delete(ContopinionVO[] vos) throws BusinessException;
+
+	public ContopinionVO[] insertContOpVO(PsnSelListVO[] psnVOs, String remenddate, String remmonth, String pk_psndoc_sub, String termtype,
+			Integer termUnit, LoginContext context) throws BusinessException;
+
+	public HashMap<String, Object> getPsnjobDeptMap(ContopinionVO[] contopinionVOs) throws BusinessException;
+
+	public String[] getDeptHasPrincipal(String[] deptPKs) throws BusinessException;
+	
+	/**
+	 * 发送个人消息
+	 * @param psndeptMap
+	 * @param contopMap
+	 * @param pk_group
+	 * @param pk_org
+	 * @param vos
+	 * @param inFeedbackList
+	 * @return
+	 * @throws BusinessException
+	 */
+	public HashMap<String, Object> sendNoticeToPsn(Map<String, List<String>> psndeptMap, Map<String, List<ContopinionVO>> contopMap, String pk_group,
+			String pk_org, ContopinionVO[] vos,ArrayList<ContopinionVO> inFeedbackList) throws BusinessException; 
+
+}

+ 745 - 0
hrhi/src/test/nc/impl/bd/psn/psndoc/PsndocServiceImpl.java

@@ -0,0 +1,745 @@
+package nc.impl.bd.psn.psndoc;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import nc.bs.bd.baseservice.busilog.IBDBusiLogUtil;
+import nc.bs.bd.baseservice.md.SingleBaseService;
+import nc.bs.bd.baseservice.validator.RefPkExistsValidator;
+import nc.bs.bd.psn.psndoc.validator.PsndocEmailValidator;
+import nc.bs.bd.psn.psndoc.validator.PsndocEnableValidator;
+import nc.bs.bd.psn.psndoc.validator.PsndocHREnableValidator;
+import nc.bs.bd.psn.psndoc.validator.PsndocNotNullValidator;
+import nc.bs.bd.psn.psndoc.validator.PsndocPartTimeJobDeleteValidator;
+import nc.bs.bd.psn.psndoc.validator.PsndocUniqueValidator;
+import nc.bs.bd.psn.psndoc.validator.PsnjobUniqueValidator;
+import nc.bs.bd.psn.psndoc.validator.PsnjobValidator;
+import nc.bs.businessevent.EventDispatcher;
+import nc.bs.businessevent.bd.BDCommonEvent;
+import nc.bs.dao.BaseDAO;
+import nc.bs.framework.common.NCLocator;
+import nc.bs.uif2.validation.ValidationException;
+import nc.bs.uif2.validation.Validator;
+import nc.itf.bd.config.uniquerule.UniqueRuleConst;
+import nc.itf.bd.psn.psndoc.IPsndocService;
+import nc.itf.uap.rbac.IRoleManage;
+import nc.itf.uap.rbac.IRoleManageQuery;
+import nc.itf.uap.rbac.IUserManage;
+import nc.itf.uap.rbac.IUserManageQuery;
+import nc.jdbc.framework.SQLParameter;
+import nc.jdbc.framework.processor.ColumnProcessor;
+import nc.md.persist.framework.IMDPersistenceQueryService;
+import nc.md.persist.framework.MDPersistenceService;
+import nc.pub.billcode.itf.IBillcodeManage;
+import nc.pub.billcode.vo.BillCodeContext;
+import nc.vo.bd.meta.BatchOperateVO;
+import nc.vo.bd.psn.IPsnConst;
+import nc.vo.bd.psn.PsndocExtend;
+import nc.vo.bd.psn.PsndocVO;
+import nc.vo.bd.psn.PsnjobVO;
+import nc.vo.ml.AbstractNCLangRes;
+import nc.vo.ml.LanguageVO;
+import nc.vo.ml.MultiLangContext;
+import nc.vo.ml.NCLangRes4VoTransl;
+import nc.vo.pub.BusinessException;
+import nc.vo.pub.SuperVO;
+import nc.vo.pub.lang.UFBoolean;
+import nc.vo.pub.lang.UFDate;
+import nc.vo.sm.UserVO;
+import nc.vo.uap.rbac.UserGroupVO;
+import nc.vo.uap.rbac.role.RoleVO;
+import nc.vo.util.BDVersionValidationUtil;
+import nccloud.commons.lang.ArrayUtils;
+import nccloud.commons.lang.StringUtils;
+
+public class PsndocServiceImpl extends SingleBaseService<PsndocVO>
+  implements IPsndocService
+{
+  private IBillcodeManage billcodeManage = null;
+  private IUserManage userManageSerivce = null;
+  private IRoleManage roleManageSercvice = null;
+  private IRoleManageQuery roleManageQuery = null;
+  private IUserManageQuery userManageQuery = null;
+  private BaseDAO dao = null;
+  private IPsndocService psndocService = null;
+
+  public PsndocServiceImpl()
+  {
+    super("40d39c26-a2b6-4f16-a018-45664cac1a1f", new String[] { "psnjobs" });
+  }
+
+  public void deletePsndoc(PsndocVO vo)
+    throws BusinessException
+  {
+    hrEnabledValidate(vo.getPk_org());
+    deleteVO(vo);
+    returnPsnCode(vo);
+    returnPsnjobCode(vo);
+  }
+
+  private void returnPsnCode(PsndocVO vo)
+    throws BusinessException
+  {
+    BillCodeContext billCodeContext = getBillcodeManage()
+      .getBillCodeContext("psndoc", vo
+      .getPk_group(), vo.getPk_org());
+
+    if (billCodeContext != null)
+      getBillcodeManage().returnBillCodeOnDelete("psndoc", vo
+        .getPk_group(), vo
+        .getPk_org(), vo.getCode(), vo);
+  }
+
+  private void returnPsnjobCode(PsndocVO vo)
+    throws BusinessException
+  {
+    BillCodeContext billCodeContext2 = getBillcodeManage()
+      .getBillCodeContext("psnjobs", vo
+      .getPk_group(), vo
+      .getPk_org());
+    PsnjobVO[] jobs = vo.getPsnjobs();
+
+    if ((billCodeContext2 != null) && (!(ArrayUtils.isEmpty(jobs))))
+      getBillcodeManage().returnBillCodeOnDelete("psnjobs", vo
+        .getPk_group(), vo.getPk_org(), jobs[0].getPsncode(), vo);
+  }
+
+  public PsndocVO insertPsndoc(PsndocVO vo, boolean isCheckRepeat)
+    throws BusinessException
+  {
+    if (vo == null)
+      return vo;
+    vo.setAttributeValue("isCheckRepeat", Boolean.valueOf(isCheckRepeat));
+    hrEnabledValidate(vo.getPk_org());
+
+    if (StringUtils.isNotBlank(vo.getId())) {
+      vo.setId(vo.getId().replaceAll(" ", ""));
+    }
+    syncPsnjobCodeWithFirst(vo);
+    vo = excuteWithAutoCode(vo, new IPsnAutoCodeExcute() {
+		@Override
+		public PsndocVO excute(PsndocVO vo) throws BusinessException {
+			return insertVO(vo);
+		}
+	});
+
+    return vo;
+  }
+
+  private void syncPsnjobCodeWithFirst(PsndocVO vo) {
+    PsnjobVO[] jobs = vo.getPsnjobs();
+    if (ArrayUtils.isEmpty(jobs)) {
+      return;
+    }
+    String psncode = jobs[0].getPsncode();
+    for (PsnjobVO psnjobVO : jobs)
+      psnjobVO.setPsncode(psncode);
+  }
+
+  private PsndocVO excuteWithAutoCode(PsndocVO vo, IPsnAutoCodeExcute excute)
+    throws BusinessException
+  {
+    BillCodeContext billCodeContext = getBillcodeManage()
+      .getBillCodeContext("psndoc", vo
+      .getPk_group(), vo.getPk_org());
+
+    BillCodeContext billCodeContext2 = getBillcodeManage()
+      .getBillCodeContext("psnjobs", vo
+      .getPk_group(), vo
+      .getPk_org());
+    PsnjobVO mainjob = getMainJob(vo);
+    boolean sucessed = false;
+	while (!sucessed) {
+		try {
+			if (billCodeContext != null && !billCodeContext.isPrecode()) {
+				String billcode = getBillcodeManage()
+						.getBillCode_RequiresNew(IPsnConst.PSNDOC_BILLCODE,
+								vo.getPk_group(), vo.getPk_org(), vo);
+				vo.setCode(billcode);
+			}
+			if (billCodeContext2 != null && !billCodeContext2.isPrecode()) {
+				String billcode2 = getBillcodeManage()
+						.getBillCode_RequiresNew(IPsnConst.PSNDOC_PSNJOB,
+								mainjob.getPk_group(), mainjob.getPk_org(),
+								mainjob);
+				for (PsnjobVO jobvo : vo.getPsnjobs()) {
+					jobvo.setPsncode(billcode2);
+				}
+			}
+			vo = excute.excute(vo);
+			sucessed = true;
+			break;
+		} catch (BusinessException e) {
+			if (billCodeContext != null
+					&& UniqueRuleConst.CODEBREAKUNIQUE.equals(e
+							.getErrorCodeString())) {
+				getBillcodeManage().AbandonBillCode_RequiresNew(
+						IPsnConst.PSNDOC_BILLCODE, vo.getPk_group(),
+						vo.getPk_org(), vo.getCode());
+				if (!billCodeContext.isPrecode()) {
+					continue;
+				}
+			} else if (PsnjobUniqueValidator.JOBCODE_UNIQUE_ERRCODE
+					.equals(e.getErrorCodeString())) {
+				getBillcodeManage().AbandonBillCode_RequiresNew(
+						IPsnConst.PSNDOC_PSNJOB, mainjob.getPk_group(),
+						mainjob.getPk_org(), mainjob.getPsncode());
+
+				if (!billCodeContext2.isPrecode())
+					continue;
+			}
+			throw e;
+		}
+	}
+    if ((billCodeContext != null) && (billCodeContext.isPrecode())) {
+      getBillcodeManage().commitPreBillCode("psndoc", vo
+        .getPk_group(), vo.getPk_org(), vo.getCode());
+    }
+    if ((billCodeContext2 != null) && (billCodeContext2.isPrecode())) {
+      mainjob = getMainJob(vo);
+      getBillcodeManage().commitPreBillCode("psnjobs", mainjob
+        .getPk_group(), mainjob.getPk_org(), mainjob
+        .getPsncode());
+    }
+    return vo;
+  }
+
+  private PsnjobVO getMainJob(PsndocVO vo) {
+    PsnjobVO mainjob = null;
+    PsnjobVO[] psnjobVOs = vo.getPsnjobs();
+    for (PsnjobVO jobvo : psnjobVOs) {
+      if (jobvo.getIsmainjob() == UFBoolean.TRUE) {
+        mainjob = jobvo;
+        break;
+      }
+    }
+    return mainjob;
+  }
+
+  protected String dbInsertVO(PsndocVO vo)
+    throws BusinessException
+  {
+    if ((vo.getPsnjobs() != null) && (vo.getPsnjobs().length > 0)) {
+      if (vo.getEnablestate().intValue() != 3)
+        vo.setEnablestate(Integer.valueOf(2));
+    }
+    else {
+      vo.setEnablestate(Integer.valueOf(3));
+    }
+    return super.dbInsertVO(vo);
+  }
+
+  protected Validator[] getInsertValidator()
+  {
+    PsndocNotNullValidator notNullValidator = new PsndocNotNullValidator();
+
+    PsndocEmailValidator emailValidator = new PsndocEmailValidator();
+
+    PsnjobValidator psnjobValidator = new PsnjobValidator(null);
+
+    PsndocUniqueValidator uniqueValidator = new PsndocUniqueValidator();
+
+    PsnjobUniqueValidator psnjobUniqueValidator = new PsnjobUniqueValidator();
+    RefPkExistsValidator refPkExistsValidator = new RefPkExistsValidator(new String[0]);
+    refPkExistsValidator.addChildAttrs("psnjobs", new String[] { "pk_psncl" });
+
+    PsndocHREnableValidator hrEnableValidator = new PsndocHREnableValidator();
+    return new Validator[] { notNullValidator, emailValidator, psnjobValidator, uniqueValidator, psnjobUniqueValidator, refPkExistsValidator, hrEnableValidator };
+  }
+
+  protected PsndocVO retrieveVO(String pk)
+    throws BusinessException
+  {
+    if (StringUtils.isBlank(pk)) {
+      return null;
+    }
+    PsndocVO newVO = (PsndocVO)getMDQueryService().queryBillOfVOByPK(PsndocVO.class, pk, false);
+
+    return newVO;
+  }
+
+  public PsndocVO updatePsndoc(PsndocVO vo, boolean isCheckRepeat)
+    throws BusinessException
+  {
+    if (vo == null)
+      return vo;
+    vo.setAttributeValue("isCheckRepeat", Boolean.valueOf(isCheckRepeat));
+
+    hrEnabledValidate(vo.getPk_org());
+
+    if (StringUtils.isNotBlank(vo.getId())) {
+      vo.setId(vo.getId().replaceAll(" ", ""));
+    }
+    syncPsnjobCodeWithFirst(vo);
+    return ((PsndocVO)updateVO(vo));
+  }
+
+  protected Validator[] getUpdateValidator(PsndocVO oldVO)
+  {
+    PsndocNotNullValidator notNullValidator = new PsndocNotNullValidator();
+
+    PsndocEmailValidator emailValidator = new PsndocEmailValidator();
+
+    PsnjobValidator psnjobValidator = new PsnjobValidator(oldVO);
+
+    PsndocPartTimeJobDeleteValidator parttimejobValidator = new PsndocPartTimeJobDeleteValidator(oldVO);
+
+    PsndocUniqueValidator uniqueValidator = new PsndocUniqueValidator();
+
+    PsnjobUniqueValidator psnjobUniqueValidator = new PsnjobUniqueValidator();
+    RefPkExistsValidator refPkExistsValidator = new RefPkExistsValidator(new String[0]);
+    refPkExistsValidator.addChildAttrs("psnjob", new String[] { "pk_psncl" });
+
+    PsndocHREnableValidator hrEnableValidator = new PsndocHREnableValidator();
+    return new Validator[] { notNullValidator, emailValidator, psnjobValidator, parttimejobValidator, uniqueValidator, psnjobUniqueValidator, refPkExistsValidator, hrEnableValidator };
+  }
+
+  public PsndocVO disEnablePsndoc(PsndocVO vo)
+    throws BusinessException
+  {
+    PsnjobVO[] vos = vo.getPsnjobs();
+    if ((vos != null) && (vos.length > 0)) {
+      getDao().updateVOList(Arrays.asList(vos));
+    }
+    return ((PsndocVO)super.disableSingleVO(vo));
+  }
+
+  protected Validator[] getDisableValidator()
+  {
+    PsnjobValidator psnjobValidator = new PsnjobValidator(null);
+    return new Validator[] { psnjobValidator };
+  }
+
+  public PsndocVO enablePsndoc(PsndocVO vo) throws BusinessException
+  {
+    return ((PsndocVO)super.enableSingleVO(vo));
+  }
+
+  protected Validator[] getEnableValidator()
+  {
+    PsndocEnableValidator enableValidator = new PsndocEnableValidator();
+    return new Validator[] { enableValidator };
+  }
+
+  protected void writeTransferBusiLog(PsndocVO vo)
+    throws BusinessException
+  {
+    getBusiLogUtil().writeBusiLog("Transfer", null, new SuperVO[] { vo });
+  }
+
+  public PsndocExtend[] createUser(PsndocExtend[] vos, String pk_userGroup, String passwordStrategy)
+    throws BusinessException
+  {
+    if ((vos == null) || (vos.length == 0)) {
+      return null;
+    }
+    List<PsndocExtend> errorList = new ArrayList<PsndocExtend>();
+	List<PsndocExtend> toCreateUserVOs = checkExistsUserData(vos, errorList);
+
+    UFDate enableDate = new UFDate(true);
+    UserGroupVO userGroupVo = (UserGroupVO)getDao().retrieveByPK(UserGroupVO.class, pk_userGroup, new String[] { "pk_org" });
+
+    Map groupid_rolevo_map = new HashMap();
+    BatchOperateVO batchvo = new BatchOperateVO();
+    List uservos = new ArrayList();
+    for (PsndocExtend psndocExtend : toCreateUserVOs) {
+      if (isWithSameCode(psndocExtend.getUser_code())) {
+        psndocExtend.setMessage(
+          NCLangRes4VoTransl.getNCLangRes().getStrByID("10140psn", "010140psn0097"), true);
+
+        errorList.add(psndocExtend);
+      }
+
+      UserVO uservo = createNewUservo(pk_userGroup, enableDate, userGroupVo, psndocExtend, passwordStrategy);
+
+      uservos.add(uservo);
+      getBusiLogUtil().writeBusiLog("CreateUser", null, new SuperVO[] { psndocExtend
+        .getPsnDocVo() });
+    }
+    batchvo.setAddObjs(uservos.toArray(new UserVO[0]));
+    batchvo = getUserManageSerivce().userbatchSave(batchvo);
+    for (int i = 0; i < batchvo.getAddObjs().length; ++i) {
+      UserVO uservo = (UserVO)batchvo.getAddObjs()[i];
+      RoleVO rolevo = (RoleVO)groupid_rolevo_map.get(uservo.getPk_group());
+      if (rolevo == null) {
+        rolevo = getIRoleManageQuery().queryRoleByCode("SF_Role", uservo
+          .getPk_group());
+        groupid_rolevo_map.put(uservo.getPk_group(), rolevo);
+      }
+      if (rolevo != null) {
+        getIRoleManage().assignRole2User(uservo.getCuserid(), new RoleVO[] { rolevo }, uservo
+          .getPk_org(), enableDate, null);
+      }
+
+    }
+
+    return ((errorList.size() == 0) ? null : 
+      (PsndocExtend[])errorList
+      .toArray(new PsndocExtend[0]));
+  }
+
+  private List<PsndocExtend> checkExistsUserData(PsndocExtend[] vos, List<PsndocExtend> errorList)
+    throws BusinessException
+  {
+    List toCreateUserVOs = filterExistsUserData(vos, errorList);
+
+    toCreateUserVOs = filterHRControlData(toCreateUserVOs, errorList);
+    return filterUserNameNull(toCreateUserVOs, errorList);
+  }
+
+  private List<PsndocExtend> filterExistsUserData(PsndocExtend[] vos, List<PsndocExtend> errorList) throws BusinessException
+  {
+    List notRelUserPsnVOs = new ArrayList();
+    for (PsndocExtend vo : vos) {
+      if (ArrayUtils.isEmpty(getIUserManageQuery()
+        .queryUserVOsByPsnDocID(vo
+        .getPsnDocVo().getPrimaryKey()))) {
+        notRelUserPsnVOs.add(vo);
+      } else {
+        vo.setMessage(NCLangRes4VoTransl.getNCLangRes()
+          .getStrByID("10140psn", "010140psn0027"), 
+          false);
+
+        errorList.add(vo);
+      }
+    }
+    return notRelUserPsnVOs;
+  }
+
+  private List<PsndocExtend> filterHRControlData(List<PsndocExtend> vos, List<PsndocExtend> errorList) throws BusinessException
+  {
+    Set pk_orgs = getPsndocOrgs(vos);
+
+    Map orgid_ishrenable = getPsndocService()
+      .isHREnabled((String[])pk_orgs
+      .toArray(new String[0]));
+
+    List toCreateUserVOs = new ArrayList();
+    for (PsndocExtend vo : vos) {
+      if ((orgid_ishrenable == null) || (orgid_ishrenable.size() == 0)) {
+        toCreateUserVOs.add(vo);
+      } else {
+        UFBoolean isHREnable = (UFBoolean)orgid_ishrenable.get(vo.getPsnDocVo()
+          .getPk_org());
+        if (isHREnable.booleanValue()) {
+          vo.setMessage(NCLangRes4VoTransl.getNCLangRes()
+            .getStrByID("10140psn", "010140psn0115"), 
+            false);
+        }
+        else
+        {
+          toCreateUserVOs.add(vo);
+        }
+      }
+    }
+    return toCreateUserVOs;
+  }
+
+  private List<PsndocExtend> filterUserNameNull(List<PsndocExtend> vos, List<PsndocExtend> errorList) throws BusinessException
+  {
+    List toCreateUserVOs = new ArrayList();
+    for (PsndocExtend vo : vos) {
+      if (StringUtils.isBlank(vo.getUser_code())) {
+        vo.setMessage(NCLangRes4VoTransl.getNCLangRes()
+          .getStrByID("10140psn", "010140psn0137"), 
+          true);
+
+        errorList.add(vo);
+      } else {
+        toCreateUserVOs.add(vo);
+      }
+    }
+    return toCreateUserVOs;
+  }
+
+  private Set<String> getPsndocOrgs(List<PsndocExtend> vos) {
+    Set orgIDs = new HashSet();
+    for (PsndocExtend vo : vos) {
+      orgIDs.add(vo.getPsnDocVo().getPk_org());
+    }
+    return orgIDs;
+  }
+
+  private UserVO createNewUservo(String pk_userGroup, UFDate enableDate, UserGroupVO userGroupVo, PsndocExtend psndocExtend, String passwordStrategy)
+  {
+    PsndocVO psndocVO = psndocExtend.getPsnDocVo();
+
+    LanguageVO currentLang = MultiLangContext.getInstance()
+      .getCurrentLangVO();
+    UserVO uservo = new UserVO();
+    uservo.setBase_doc_type(Integer.valueOf(0));
+    uservo.setPk_base_doc(psndocVO.getPk_psndoc());
+    uservo.setPk_group(psndocVO.getPk_group());
+    uservo.setPk_org((userGroupVo == null) ? null : userGroupVo.getPk_org());
+    //modify by@chenzf 修改用户编码为手机号 2021-1-5 11:39:12 begin
+//    uservo.setUser_code(psndocExtend.getUser_code());
+    uservo.setUser_code(psndocVO.getMobile());
+    //modify by@chenzf 修改用户编码为手机号 2021-1-5 11:39:12 end
+    uservo.setUser_name(psndocVO.getName());
+    uservo.setUser_name2(psndocVO.getName2());
+    uservo.setUser_name3(psndocVO.getName3());
+    uservo.setUser_name4(psndocVO.getName4());
+    uservo.setUser_name5(psndocVO.getName5());
+    uservo.setUser_name6(psndocVO.getName6());
+    uservo.setUser_type(Integer.valueOf(1));
+
+    uservo.setIdentityverifycode("staticpwd");
+    uservo.setContentlang(currentLang.getPk_multilang());
+    uservo.setPwdlevelcode("update");
+    uservo.setEnablestate(Integer.valueOf(2));
+    uservo.setPk_usergroupforcreate(pk_userGroup);
+    uservo.setFormat("FMT0Z000000000000000");
+    uservo.setAbledate(enableDate);
+
+    if (passwordStrategy.equals("password_default"))
+      uservo.setUser_password(null);
+    else if (passwordStrategy.equals("password_psnid")) {
+      uservo.setUser_password(getPasswordByPsnid(psndocVO.getId()));
+    }
+    return uservo;
+  }
+
+  private String getPasswordByPsnid(String id) {
+    if (StringUtils.isBlank(id)) {
+      return null;
+    }
+    if (id.length() <= 8) {
+      return StringUtils.rightPad(id, 8, "0");
+    }
+    return StringUtils.substring(id, id.length() - 8, id.length());
+  }
+
+  public PsndocVO deletePsnJob(PsndocVO vo, String pk_org)
+    throws BusinessException
+  {
+    if (vo == null)
+      return vo;
+    try
+    {
+      updatelockOperate(vo);
+
+      BDVersionValidationUtil.validateSuperVO(new SuperVO[] { vo });
+
+      PsndocVO oldVO = retrieveVO(vo.getPrimaryKey());
+
+      getDao().deleteByClause(PsnjobVO.class, "pk_org='" + pk_org + "' and pk_psndoc='" + vo
+        .getPk_psndoc() + "'");
+
+      setUpdateAuditInfo(vo);
+
+      fireBeforeDeleteJobEvent(oldVO, vo);
+
+      fireBeforeUpdateEvent(oldVO, vo);
+
+      notifyVersionChangeWhenDataUpdated(vo);
+
+      vo = retrieveVO(vo.getPrimaryKey());
+
+      fireAfterUpdateEvent(oldVO, vo);
+
+      writeUpdatedBusiLog(oldVO, vo);
+    } catch (ValidationException e) {
+      throw new BusinessException(e.getMessage());
+    }
+
+    return vo;
+  }
+
+  protected void fireBeforeDeleteJobEvent(PsndocVO oldVO, PsndocVO vo) throws BusinessException
+  {
+    EventDispatcher.fireEvent(new BDCommonEvent(getMDId(), "1097", new Object[] { oldVO }, vo ));
+  }
+
+  public void transferUser(PsndocVO vo, boolean innerGroup)
+    throws BusinessException
+  {
+    if (vo == null) {
+      return;
+    }
+    UserVO[] users = getIUserManageQuery().queryUserVOsByPsnDocID(vo
+      .getPk_psndoc());
+    if (ArrayUtils.isEmpty(users)) {
+      return;
+    }
+    if (innerGroup) {
+      for (UserVO userVO : users)
+      {
+        if (userVO.getEnablestate().intValue() != 3)
+          getUserManageSerivce().disableUser(userVO);
+      }
+    }
+    else
+      getUserManageSerivce().migrateUserToGroupWithDocRelation(users, vo
+        .getPk_group());
+  }
+
+  public void transferUserCrossGroup(PsndocVO vo, boolean ParamValue)
+    throws BusinessException
+  {
+    if (vo == null) {
+      return;
+    }
+    UserVO[] users = getIUserManageQuery().queryUserVOsByPsnDocID(vo
+      .getPk_psndoc());
+    if (ArrayUtils.isEmpty(users)) {
+      return;
+    }
+    if (ParamValue)
+    {
+      getUserManageSerivce().migrateUserToGroupWithDocRelation(users, vo
+        .getPk_group());
+    }
+    else
+      for (UserVO userVO : users)
+      {
+        if (userVO.getEnablestate().intValue() != 3)
+          getUserManageSerivce().disableUser(userVO);
+      }
+  }
+
+  public PsndocVO transferPsndoc(PsndocVO vo)
+    throws BusinessException
+  {
+    PsndocVO oldVO = retrieveVO(vo.getPrimaryKey());
+
+    if (!(oldVO.getPk_org().equals(vo.getPk_org()))) {
+      returnPsnCode(oldVO);
+      returnPsnjobCode(oldVO);
+    }
+    vo = excuteWithAutoCode(vo, new IPsnAutoCodeExcute() {
+		@Override
+		public PsndocVO excute(PsndocVO vo) throws BusinessException {
+			return updateVO(vo);
+		}
+	});
+
+    return vo;
+  }
+
+  private PsnjobVO getMainJobVO(PsndocVO vo)
+  {
+    PsnjobVO[] jobs = vo.getPsnjobs();
+    if (!(ArrayUtils.isEmpty(jobs))) {
+      for (PsnjobVO psnjobVO : jobs) {
+        if (psnjobVO.getIsmainjob().booleanValue()) {
+          return psnjobVO;
+        }
+      }
+    }
+    return null;
+  }
+
+  private PsnjobVO getJobVOByID(PsndocVO vo, String pk) {
+    if (StringUtils.isBlank(pk)) {
+      return null;
+    }
+    PsnjobVO[] jobs = vo.getPsnjobs();
+    if (!(ArrayUtils.isEmpty(jobs))) {
+      for (PsnjobVO psnjobVO : jobs) {
+        if (pk.equals(psnjobVO.getPrimaryKey())) {
+          return psnjobVO;
+        }
+      }
+    }
+    return null;
+  }
+
+  private IMDPersistenceQueryService getMDQueryService() {
+    return MDPersistenceService.lookupPersistenceQueryService();
+  }
+
+  private boolean isWithSameCode(String code) throws BusinessException
+  {
+    if (code == null)
+      return false;
+    String sql = "select 1 from sm_user where user_code=?";
+    SQLParameter param = new SQLParameter();
+    param.addParam(code);
+
+    Object uservo = getDao()
+      .executeQuery(sql, param, new ColumnProcessor());
+
+    return (uservo != null);
+  }
+
+  private IBillcodeManage getBillcodeManage() {
+    if (this.billcodeManage == null) {
+      this.billcodeManage = ((IBillcodeManage)NCLocator.getInstance().lookup(IBillcodeManage.class));
+    }
+
+    return this.billcodeManage;
+  }
+
+  private IUserManage getUserManageSerivce() {
+    if (this.userManageSerivce == null) {
+      this.userManageSerivce = ((IUserManage)NCLocator.getInstance().lookup(IUserManage.class));
+    }
+    return this.userManageSerivce;
+  }
+
+  private IRoleManage getIRoleManage()
+  {
+    if (this.roleManageSercvice == null) {
+      this.roleManageSercvice = ((IRoleManage)NCLocator.getInstance().lookup(IRoleManage.class));
+    }
+    return this.roleManageSercvice;
+  }
+
+  private IRoleManageQuery getIRoleManageQuery() {
+    if (this.roleManageQuery == null) {
+      this.roleManageQuery = ((IRoleManageQuery)NCLocator.getInstance().lookup(IRoleManageQuery.class));
+    }
+    return this.roleManageQuery;
+  }
+
+  private IUserManageQuery getIUserManageQuery()
+  {
+    if (this.userManageQuery == null) {
+      this.userManageQuery = ((IUserManageQuery)NCLocator.getInstance().lookup(IUserManageQuery.class));
+    }
+    return this.userManageQuery;
+  }
+
+  private BaseDAO getDao() {
+    if (this.dao == null)
+      this.dao = new BaseDAO();
+    return this.dao;
+  }
+
+  public boolean isHREnabled(String pk_org)
+    throws BusinessException
+  {
+    return false;
+  }
+
+  public Map<String, UFBoolean> isHREnabled(String[] pk_orgs)
+    throws BusinessException
+  {
+    Map map = new HashMap();
+    for (String pk_org : pk_orgs) {
+      map.put(pk_org, 
+        UFBoolean.valueOf(getPsndocService().isHREnabled(pk_org)));
+    }
+    return map;
+  }
+
+  private void hrEnabledValidate(String pk_org) throws BusinessException
+  {
+    if (!(getPsndocService().isHREnabled(pk_org)))
+      return;
+    throw new BusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("10140psn", "010140psn0103"));
+  }
+
+  private IPsndocService getPsndocService()
+  {
+    if (this.psndocService == null) {
+      this.psndocService = ((IPsndocService)NCLocator.getInstance().lookup(IPsndocService.class));
+    }
+
+    return this.psndocService;
+  }
+}

+ 19 - 0
hrjf/.classpath

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="out/public" path="src/public"/>
+	<classpathentry kind="src" output="out/private" path="src/private"/>
+	<classpathentry kind="src" output="out/client" path="src/client"/>
+	<classpathentry kind="src" output="out/test" path="src/test"/>
+	<classpathentry kind="src" output="out/resources" path="resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Ant_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Product_Common_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Middleware_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Framework_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Public_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Client_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Private_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Lang_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Generated_EJB"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 2 - 0
hrjf/.module_prj

@@ -0,0 +1,2 @@
+module.name=hrjf
+module.defConfig=module.xml

+ 23 - 0
hrjf/.project

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>hrjf</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>nc.uap.mde.ModuleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>nc.uap.mde.ModuleProjectNature</nature>
+	</natures>
+</projectDescription>

+ 7 - 0
hrjf/META-INF/module.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="gb2312"?>
+<module name="hrjf">
+    <public>
+    </public>
+    <private>
+    </private>
+</module>

File diff suppressed because it is too large
+ 195 - 0
hrjf/METADATA/dept/hrdept.bmf


File diff suppressed because it is too large
+ 91 - 0
hrjf/METADATA/dept/hrdept_v.bmf


+ 19 - 0
hrtrn/.classpath

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="out/public" path="src/public"/>
+	<classpathentry kind="src" output="out/private" path="src/private"/>
+	<classpathentry kind="src" output="out/client" path="src/client"/>
+	<classpathentry kind="src" output="out/test" path="src/test"/>
+	<classpathentry kind="src" output="out/resources" path="resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Ant_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Product_Common_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Middleware_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Framework_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Public_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Client_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Private_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Module_Lang_Library"/>
+	<classpathentry kind="con" path="nc.uap.mde.library.container/Generated_EJB"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 2 - 0
hrtrn/.module_prj

@@ -0,0 +1,2 @@
+module.name=hrtrn
+module.defConfig=module.xml

+ 23 - 0
hrtrn/.project

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>hrtrn</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>nc.uap.mde.ModuleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>nc.uap.mde.ModuleProjectNature</nature>
+	</natures>
+</projectDescription>

+ 7 - 0
hrtrn/META-INF/module.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="gb2312"?>
+<module name="hrtrn">
+    <public>
+    </public>
+    <private>
+    </private>
+</module>

+ 11 - 0
hrtrn/META-INF/yytrn.upm

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module name="yytrn">
+  <public>
+     <component  priority="0" singleton="false" remote="true" tx = "CMT" supportAlias="false">
+      <interface>nc.itf.trn.transmng.ITrnManageExService</interface>
+      <implementation>nc.impl.trn.transmng.TrnManageExServiceImpl</implementation>
+    </component>
+  </public>
+  <private>
+  </private>
+</module>

+ 155 - 0
hrtrn/src/client/nccloud/web/hryf/transapply/action/TransAddAction.java

@@ -0,0 +1,155 @@
+package nccloud.web.hryf.transapply.action;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import nccloud.commons.lang.StringUtils;
+
+import nc.bs.framework.common.NCLocator;
+import nc.bs.uif2.validation.ValidationFailure;
+import nc.hr.utils.ResHelper;
+import nc.itf.hi.seqcontrol.ISeqcontrolManageService;
+import nc.itf.hr.frame.IPersistenceRetrieve;
+import nc.itf.trn.IItemSetAdapter;
+import nc.vo.hi.psndoc.CtrtVO;
+import nc.vo.hi.seqcontrol.SeqcontrolSetVO;
+import nc.vo.hi.trnstype.TrnstypeFlowVO;
+import nc.vo.pub.AggregatedValueObject;
+import nc.vo.pub.BusinessException;
+import nc.vo.pub.SuperVO;
+import nc.vo.pub.billtype.BilltypeVO;
+import nc.vo.pub.lang.UFBoolean;
+import nc.vo.pub.pf.IPfRetCheckInfo;
+import nc.vo.trn.partmng.PartApplyVO;
+import nc.vo.trn.pub.TRNConst;
+import nc.vo.trn.transmng.StapplyVO;
+import nc.vo.uif2.LoginContext;
+import nccloud.dto.hryf.tools.HRYFConst;
+import nccloud.framework.service.ServiceLocator;
+import nccloud.framework.web.container.IRequest;
+import nccloud.framework.web.ui.meta.FormItemMeta;
+import nccloud.framework.web.ui.meta.FormMeta;
+import nccloud.framework.web.ui.meta.PageMeta;
+import nccloud.web.hr.pub.HRNccPubEnv;
+import nccloud.web.hr.pub.HRNccTemplateUtils;
+import nccloud.web.hr.pub.HRNccUtils;
+import nccloud.web.uapbd.commons.web.ParamUtils;
+
+/**
+ * 调配办理-新增按钮
+ * @author lbt 20190330
+ *
+ */
+public class TransAddAction extends TransBaseAction {
+
+	@Override
+	public <T> Object execute(IRequest request, T para) throws Exception {
+		ParamUtils param = new ParamUtils(request);
+		LoginContext context = HRNccUtils.getLoginContext(param);
+		// 1:校验数据并返回所有项目设置数据
+		IItemSetAdapter[] items = super.transtypeNotNullValidate(param, context);
+		AggregatedValueObject  aggvo = super.getDefaultValue(context, param,false);
+		//调配方式
+		Integer transMode = param.getInt("transMode", null);
+		if(transMode==null){
+			return new ValidationFailure(ResHelper.getString("6009tran", "06009tran0129")/* @res "当前选择的调配方式为空,不能进行后续操作!" */);
+		}
+		((StapplyVO)aggvo.getParentVO()).setStapply_mode(transMode);
+		((StapplyVO) aggvo.getParentVO()).setWorkflow_state(IPfRetCheckInfo.NOSTATE);
+		String transType = param.getString("transType", null);//调配业务类型
+		((StapplyVO)aggvo.getParentVO()).setPk_trnstype(transType);
+		TrnstypeFlowVO[] flow =  (TrnstypeFlowVO[]) ServiceLocator.find(IPersistenceRetrieve.class).retrieveByClause(null, TrnstypeFlowVO.class,
+                        " pk_group = '" + HRNccPubEnv.getPk_group() + "' and pk_trnstype = '" + transType + "'");
+		if (flow != null && flow.length > 0) {
+			 ((StapplyVO) aggvo.getParentVO()).setTranstypeid(flow[0].getPk_transtype());
+			 ((StapplyVO) aggvo.getParentVO()).setTranstype(null);
+             if (StringUtils.isNotEmpty(flow[0].getPk_transtype())){
+                 BilltypeVO billtype = (BilltypeVO) ServiceLocator.find(IPersistenceRetrieve.class) .retrieveByPk(null, BilltypeVO.class, flow[0].getPk_transtype());
+                 ((StapplyVO) aggvo.getParentVO()).setTranstype(billtype.getPk_billtypecode());
+             }
+             ((StapplyVO) aggvo.getParentVO()).setBusiness_type(flow[0].getPk_businesstype());
+        }
+		
+		//返回前后项目模板
+		PageMeta pm = showAllSetItems(context, HRYFConst.APPCODE_TRANAPPLY, HRYFConst.PAGECODE_TRANAPPLY, true, items, false);
+        ((FormMeta) pm.getAreaMeta(TRNConst.TRNS_NEWINFO_TAB)).getItemByCode(StapplyVO.NEWPK_POSTSERIES).setDisabled(false);
+        ((FormMeta) pm.getAreaMeta(TRNConst.TRNS_NEWINFO_TAB)).getItemByCode(StapplyVO.NEWPK_JOBGRADE).setDisabled(true);// 调配申请新增时职级不可编辑
+		// 人员信息
+		FormMeta fm_psninfo = (FormMeta) pm.getAreaMeta(TRNConst.TRNS_PSNINFO_TAB);
+		fm_psninfo.getItemByCode(StapplyVO.PK_PSNJOB).setDisabled(false);
+		fm_psninfo.getItemByCode(StapplyVO.PK_PSNJOB).setRequired(true);
+		fm_psninfo.getItemByCode(StapplyVO.STAPPLY_MODE).setDisabled(true);		
+		fm_psninfo.getItemByCode(StapplyVO.STAPPLY_MODE).setRequired(false);	
+		fm_psninfo.getItemByCode(StapplyVO.PK_TRNSTYPE).setDisabled(true);		
+		fm_psninfo.getItemByCode(StapplyVO.PK_TRNSTYPE).setRequired(false);
+		fm_psninfo.getItemByCode(StapplyVO.SREASON).setDisabled(false);
+		fm_psninfo.getItemByCode(StapplyVO.SREASON).setRequired(true);
+		fm_psninfo.getItemByCode(StapplyVO.EFFECTDATE).setDisabled(false);
+		fm_psninfo.getItemByCode(StapplyVO.EFFECTDATE).setRequired(true);
+		// 跟试用相关
+		fm_psninfo.getItemByCode(StapplyVO.TRIALDAYS).setDisabled(true);		
+		fm_psninfo.getItemByCode(StapplyVO.TRIALDAYS).setRequired(false);		
+		fm_psninfo.getItemByCode(StapplyVO.TRIAL_UNIT).setDisabled(true);		
+		fm_psninfo.getItemByCode(StapplyVO.TRIAL_UNIT).setRequired(false);		
+		fm_psninfo.getItemByCode(StapplyVO.TRIALBEGINDATE).setDisabled(true);		
+		fm_psninfo.getItemByCode(StapplyVO.TRIALBEGINDATE).setRequired(false);		
+		fm_psninfo.getItemByCode(StapplyVO.TRIALENDDATE).setDisabled(true);		
+		fm_psninfo.getItemByCode(StapplyVO.TRIALENDDATE).setRequired(false);
+		// 合同信息
+		CtrtVO ctrt = getCtrt((StapplyVO) aggvo.getParentVO());
+		if (ctrt == null) {
+			// 最新的合同记录不是签订/变更/续签三个状态(未签订合同或者合同已经解除/终止),不需要勾选和编辑
+			((StapplyVO) aggvo.getParentVO()).setIsrelease(UFBoolean.FALSE);
+			((StapplyVO) aggvo.getParentVO()).setIsend(UFBoolean.FALSE);
+			((FormMeta) pm.getAreaMeta("contract_mng_org")).getItemByCode(StapplyVO.ISRELEASE).setDisabled(true);
+			((FormMeta) pm.getAreaMeta("contract_mng_org")).getItemByCode(StapplyVO.ISEND).setDisabled(true);
+		}
+        if (TRNConst.TRANSMODE_CROSS_OUT == transMode ) {
+            // 调出,或变更离职后HR组织
+            ((FormMeta) pm.getAreaMeta("stapply_mng_org")).getItemByCode(StapplyVO.PK_HI_ORG).setDisabled(false);
+            ((StapplyVO)aggvo.getParentVO()).setPk_hi_org(null);
+        } else {
+            // 组织内、调入、不变更离职后组织都是当前HR组织
+    		((FormMeta) pm.getAreaMeta("contract_mng_org")).getItemByCode(StapplyVO.PK_HRCM_ORG).setDisabled(true);		
+    		((FormMeta) pm.getAreaMeta("stapply_mng_org")).getItemByCode(StapplyVO.PK_HI_ORG).setDisabled(true);
+    		((FormMeta) pm.getAreaMeta("contract_mng_org")).getItemByCode(StapplyVO.ISRELEASE).setDisabled(true);	
+    		((FormMeta) pm.getAreaMeta("contract_mng_org")).getItemByCode(StapplyVO.ISEND).setDisabled(true);	
+        }
+		// 是否是审批节点
+     	boolean isapprove = param.getBoolean("isapprove", false);
+		if (isapprove) {
+             // 审批节点不能修改流程类型与业务类型
+             ((FormMeta) pm.getAreaMeta("card")).getItemByCode(StapplyVO.TRANSTYPEID).setDisabled(true);
+             ((FormMeta) pm.getAreaMeta("card")).getItemByCode(StapplyVO.BUSINESS_TYPE).setDisabled(true);
+        } else {
+             ((FormMeta) pm.getAreaMeta("card")).getItemByCode(StapplyVO.BILL_CODE).setDisabled(true);
+        }
+		if (isapprove)  {
+		    ((FormMeta) pm.getAreaMeta("card")).getItemByCode(StapplyVO.BILL_CODE).setDisabled(true);
+			((FormMeta) pm.getAreaMeta("card")).getItemByCode(StapplyVO.BUSINESS_TYPE).setDisabled(true);
+			((FormMeta) pm.getAreaMeta("card")).getItemByCode(StapplyVO.TRANSTYPEID).setDisabled(true);
+			((FormMeta) pm.getAreaMeta("card")).getItemByCode(StapplyVO.APPLY_DATE).setDisabled(true);
+			// 审批节点不能修改解除和终止
+			((FormMeta) pm.getAreaMeta("contract_mng_org")).getItemByCode(StapplyVO.ISRELEASE).setDisabled(true);
+			((FormMeta) pm.getAreaMeta("contract_mng_org")).getItemByCode(StapplyVO.ISEND).setDisabled(true);
+        }
+		//返回页面默认数据
+		Map result = new HashMap<>();
+		result.put("formData",HRNccTemplateUtils.getFormWithArea(HRYFConst.PAGECODE_TRANAPPLY, "card", (SuperVO) aggvo.getParentVO()));
+		result.put("isBillCodeEditable",  super.isBillCodeEditable(context));
+		result.put(TRNConst.TRNS_OLDINFO_TAB, pm.getAreaMeta(TRNConst.TRNS_OLDINFO_TAB));
+		result.put(TRNConst.TRNS_NEWINFO_TAB, pm.getAreaMeta(TRNConst.TRNS_NEWINFO_TAB));
+		result.put(TRNConst.TRNS_PSNINFO_TAB, pm.getAreaMeta(TRNConst.TRNS_PSNINFO_TAB));
+		result.put("contract_mng_org", pm.getAreaMeta("contract_mng_org"));
+		result.put("stapply_mng_org", pm.getAreaMeta("stapply_mng_org"));
+		result.put("card", pm.getAreaMeta("card"));
+		FormItemMeta psnItemMeta = ((FormMeta)pm.getAreaMeta(TRNConst.TRNS_PSNINFO_TAB)).getItemByCode(StapplyVO.PK_PSNJOB);
+		// 查询当前逐级管控模式,如果有管控
+		if(getQuerySeq()){
+			psnItemMeta.setRefcode("hrhi/refer/hiref/PsnjobRefTreeGridRef/index");
+		}
+		return result;
+	}
+	
+
+}

File diff suppressed because it is too large
+ 2454 - 0
hrtrn/src/private/nc/impl/trn/dimissionrds/DimissionrdsServiceImpl.java


File diff suppressed because it is too large
+ 2260 - 0
hrtrn/src/private/nc/impl/trn/transmng/TransmngServiceImpl.java


+ 86 - 0
hrtrn/src/private/nc/impl/trn/transmng/TrnManageExServiceImpl.java

@@ -0,0 +1,86 @@
+package nc.impl.trn.transmng;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import nc.bs.framework.common.NCLocator;
+import nc.bsutil.mmpub.dpub.SysParamUtil;
+import nc.hr.frame.persistence.SimpleDocServiceTemplate;
+import nc.itf.hr.frame.IPersistenceUpdate;
+import nc.itf.hr.wa.IPsndocwadocManageService;
+import nc.itf.trn.transmng.ITrnManageExService;
+import nc.vo.hi.psndoc.PsnJobVO;
+import nc.vo.hi.wadoc.PsndocWadocVO;
+import nc.vo.pub.BusinessException;
+import nc.vo.pub.lang.UFBoolean;
+import nc.vo.trn.transmng.AggStapply;
+import nc.vo.trn.transmng.StapplyVO;
+
+/**
+ * 调配业务扩展实现
+ * @date 2021-1-5 20:04:14
+ * @author chenzf
+ *
+ */
+public class TrnManageExServiceImpl extends SimpleDocServiceTemplate implements ITrnManageExService {
+
+	public TrnManageExServiceImpl() {
+		super("TrnManageEx");
+	}
+
+	private IPersistenceUpdate getPersistenceUpdate() {
+        return NCLocator.getInstance().lookup(IPersistenceUpdate.class);
+    }
+	
+	private IPsndocwadocManageService getIPsndocwadocManageService() {
+		return NCLocator.getInstance().lookup(IPsndocwadocManageService.class);
+	}
+	
+	@Override
+	public Boolean updatePsn(AggStapply[] vos) throws BusinessException {
+        String[] updateFields = {PsnJobVO.PK_POST,"jobglbdef6"};
+        List<PsnJobVO> jobList = new ArrayList();
+        //是否生成定调资信息
+        boolean check = SysParamUtil.getParamValueAsBoolean(((StapplyVO) vos[0].getParentVO()).getPk_org(), "TRN0099");
+		List<PsndocWadocVO> wadocList = new ArrayList();
+        for(AggStapply vo : vos) {
+			StapplyVO stapplyVO = (StapplyVO) vo.getParentVO();
+			//更新工作信息  薪等薪级jobglbdef6 pk_post岗位
+			Object jobglbdef6 = stapplyVO.getAttributeValue("newjobglbdef6");
+			PsnJobVO jobVO = queryByPk(PsnJobVO.class, stapplyVO.getPk_psnjob());
+			jobVO.setPk_post(stapplyVO.getNewpk_post());
+			jobVO.setAttributeValue("jobglbdef6", jobglbdef6);
+			jobList.add(jobVO);
+			//生成定调资信息hi_psndoc_wadoc
+			if(check) {
+				if(jobglbdef6 != null && !"".equals(jobglbdef6.toString())) {
+					stapplyVO.setEffectdate(jobVO.getBegindate());
+					PsndocWadocVO wadocVO = createWadocVO(stapplyVO);
+					wadocList.add(wadocVO);
+				}
+			}
+			
+		}
+		if(jobList.size() > 0) {
+			getPersistenceUpdate().updateVOArray(null, jobList.toArray(new PsnJobVO[0]), updateFields, null);
+		}
+		if(wadocList.size() > 0) {
+			getIPsndocwadocManageService().insertArray(wadocList.toArray(new PsndocWadocVO[0]));
+		}
+		
+		return null;
+	}
+	
+	public PsndocWadocVO createWadocVO(StapplyVO stapplyVO) {
+		PsndocWadocVO wadocVO = new PsndocWadocVO();
+		wadocVO.setPk_group(stapplyVO.getPk_group());
+		wadocVO.setPk_org(stapplyVO.getPk_org());
+		wadocVO.setPk_psnjob(stapplyVO.getPk_psnjob());
+		wadocVO.setPk_psndoc(stapplyVO.getPk_psndoc());
+		wadocVO.setAssgid(stapplyVO.getAssgid());
+		wadocVO.setLastflag(UFBoolean.TRUE);
+		wadocVO.setBegindate(stapplyVO.getEffectdate());
+		return wadocVO;
+	}
+
+}

+ 21 - 0
hrtrn/src/public/nc/itf/trn/transmng/ITrnManageExService.java

@@ -0,0 +1,21 @@
+package nc.itf.trn.transmng;
+
+import nc.vo.pub.BusinessException;
+import nc.vo.trn.transmng.AggStapply;
+
+/**
+ * 调配业务扩展更新接口
+ * @date 2021-1-5 20:04:14
+ * @author chenzf
+ *
+ */
+public interface ITrnManageExService {
+
+	/**
+	 * 定岗定薪业务类型,更新工作信息和生成定调薪信息
+	 * @param vos
+	 * @return
+	 * @throws BusinessException
+	 */
+	public Boolean updatePsn(AggStapply[] vos)throws BusinessException;
+}