nc65用友uap开发-人力资源模块合同审批流开发

nc65用友uap开发-人力资源模块合同审批流开发
1.需求:在人力资本模块下的人员合同管理支持审批流,而合同签订等节点使用的元数据属于合同处理中心元数据下的劳动合同,属于ncvo,而在产品设计流程中ncvo是不支持审批流的,无法达到审批流效果。
2.解决思路:在无法绕过产品按钮设计的情况下,选择了自己写代码,达到审批流效果(1.发消息,2.按钮状态改变)
3.产品实现过程:
3.1  PfUtilClient类下的runAction方法,获取WorkflownoteVO worknoteVO。主要方法如下:
/**
	 * 前台单据动作处理API,算法如下:
	 * <li>1.动作执行前提示以及事前处理,如果用户取消,则方法直接返回
	 * <li>2.查看扩展参数,判断是否需要审批流相关处理。如果为提交动作,则可能需要收集提交人的指派信息;
	 * 如果为审批动作,则可能需要收集审批人的审批信息
	 * <li>3.后台执行动作。并返回动作执行结果。 
	 * 
	 * @param parent 父窗体 -- 需要LoginContext.EntranceUI
	 * @param actionCode 动作编码,比如"SAVE"
	 * @param billOrTranstype 单据(或交易)类型PK
	 * @param billvo 单据聚合VO
	 * @param userObj 用户自定义对象
	 * @param checkVo 校验单据聚合VO
	 * @param eParam 扩展参数
	 * @return 动作处理的返回结果
	 * @throws BusinessException 
	 * @throws Exception
	 * @since 5.5
	 */
	public static Object runAction(Container parent, String actionCode, String billOrTranstype,
			AggregatedValueObject billvo, Object userObj, String strBeforeUIClass,
			AggregatedValueObject checkVo, HashMap eParam) throws BusinessException {
		eParam = initEParam(eParam);
		Logger.debug("*单据动作处理 开始");
		debugParams(actionCode, billOrTranstype, billvo, userObj);
		long start = System.currentTimeMillis();
		m_isSuccess = true;
		
		
		isOpenedInDialog = false;
		IFuncletWindow parentFuncletWindow = getParentFuncletWindow(parent, actionCode, billOrTranstype);
		
//TODO 先注释掉,目前的调用方式有问题,会增加远程调用次数,不应该在这个时机判断,后续如果有人提问题了再分析一下具体场景
//		if (PfUtilBaseTools.isStartAction(actionCode, billOrTranstype)) {
//			String actionSignlCode = actionCode.replace(IPFActionName.START,
//					IPFActionName.SIGNAL);
//			try {
//				WorkflownoteVO noteVO = NCLocator.getInstance().lookup(IWorkflowMachine.class).checkWorkFlow(actionSignlCode, billOrTranstype,billvo, eParam);
//				// 如果有代办任务
//				if (noteVO != null)
//					actionCode = actionSignlCode;
//			} catch (BusinessException be) {
//				Logger.error("工作流回退业务处理,找不到工作项即不用替换动作代码,继续执行即可");
//			}
//		}

		// 1.动作执行前提示
		boolean isContinue = hintBeforeAction(parent, actionCode, billOrTranstype);
		if (!isContinue) {
			Logger.debug("*动作执行前提示,返回");
			m_isSuccess = false;
			return null;
		}

		// 2.查看扩展参数,是否要流程交互处理
		WorkflownoteVO worknoteVO = null;///批量审批出错(WorkflownoteVO)getParamFromMap(eParam, PfUtilBaseTools.PARAM_WORKNOTE);
		Object paramSilent = getParamFromMap(eParam, PfUtilBaseTools.PARAM_SILENTLY);
		///if(worknoteVO == null){//批量审批出错
		Object paramNoflow = getParamFromMap(eParam,
				PfUtilBaseTools.PARAM_NOFLOW);
		if (paramNoflow == null && paramSilent == null) {
			// 需要交互处理
			if (PfUtilBaseTools.isSaveAction(actionCode, billOrTranstype)
					|| PfUtilBaseTools.isApproveAction(actionCode,
							billOrTranstype)) {
				// 审批流交互处理
				worknoteVO = actionAboutApproveflow(parent, actionCode,
						billOrTranstype, billvo, eParam,0);
				if (!m_isSuccess)
					return null;
			} else if (PfUtilBaseTools.isStartAction(actionCode,
					billOrTranstype)
					|| PfUtilBaseTools.isSignalAction(actionCode,
							billOrTranstype)) {
				// 工作流互处理
				worknoteVO = actionAboutWorkflow(parent, actionCode,
						billOrTranstype, billvo, eParam,0);
				if (!m_isSuccess)
					return null;
			}
			//putParam(eParam, PfUtilBaseTools.PARAM_WORKNOTE, worknoteVO);
		}
		///}//批量审批出错
		//如果用户在交互处理时候选择加签或者改派,则无需驱动流程@2009-5
		if (worknoteVO != null && PfUtilClientAssistor.isAddApproverOrAppoint(worknoteVO)) {
			//zhouhenga 此时返回原始的单据vo,使得侧边栏刷新
			//liangyub 通过侧边栏加签操作,成功后加以提示
			if(eParam != null && eParam.get(PfUtilBaseTools.PARAM_BESIDEAPPROVE) != null){
				if(eParam.get(PfUtilBaseTools.PARAM_BESIDEAPPROVE) instanceof BesideApproveContext){
					BesideApproveContext besideContext = (BesideApproveContext) eParam.get(PfUtilBaseTools.PARAM_BESIDEAPPROVE);
					if(besideContext.isAddAssign()){
			            	MessageDialog.showHintDlg(parent, 
			            			NCLangRes.getInstance().getStrByID("pfworkflow63","2PLATFORM-00082")/*操作成功*/,
			            			NCLangRes.getInstance().getStrByID("pfworkflow63","2PLATFORM-00083")/*单据加签成功*/);   
					}
				}
			}
			return billvo;
		}
		if (worknoteVO == null) {
			//检查不到工作项,则后台无需再次检查
			if (eParam == null)
				eParam = new HashMap<String, String>();
			if (paramSilent == null)
				eParam.put(PfUtilBaseTools.PARAM_NOTE_CHECKED, PfUtilBaseTools.PARAM_NOTE_CHECKED);
		}

		// 4.后台执行动作
		Object retObj = null;

		Logger.debug("*后台动作处理 开始");
		long start2 = System.currentTimeMillis();
		IplatFormEntry iIplatFormEntry = (IplatFormEntry) NCLocator.getInstance().lookup(
				IplatFormEntry.class.getName());
		retObj = iIplatFormEntry.processAction(actionCode, billOrTranstype, worknoteVO, billvo,
				userObj, eParam);
		Logger.debug("*后台动作处理 结束=" + (System.currentTimeMillis() - start2) + "ms");

		m_isSuccess = true;

		// 5.返回对象执行
		//retObjRun(parent, retObj);
		Logger.debug("*单据动作处理 结束=" + (System.currentTimeMillis() - start) + "ms");
		
		if(m_isSuccess && worknoteVO != null) {
			//更新消息的状态
			
			MessageProcessorContext.setHandledWithProcessor(worknoteVO);
		}
		
		
		if (m_isSuccess 
				&& isOpenedInDialog
				&& isAutoCloseParentDialog
				&& parentFuncletWindow != null
				&& PfUtilBaseTools.isApproveAction(actionCode, billOrTranstype)) {
			
			// 审批成功、单据为对话框打开、且审批时选择了自动关闭单据界面
			// yanke1 2012-7-18 那么关闭单据界面
			final IFuncletWindow p = parentFuncletWindow;
			
			// 放到swing线程里,否则界面会卡死掉
			SwingUtilities.invokeLater(new Runnable() {
				
				@Override
				public void run() {
					p.forceCloseWindow();					
				}
			});

		}

		return retObj;
	}
3.2 启动审批流主要类PFBusiAction中的processAction
public Object processAction(String actionName, String billOrTranstype, WorkflownoteVO workflowVo, AggregatedValueObject billvo, Object userObj, HashMap eParam) throws BusinessException {
		Logger.init("workflow");
		Logger.debug("*后台单据动作处理PFBusiAction.processAction开始");
		debugParams(actionName, billOrTranstype, workflowVo, billvo, userObj, eParam);
		long start = System.currentTimeMillis();

		Hashtable hashBilltypeToParavo = new Hashtable();
		Hashtable hashMethodReturn = new Hashtable();
		
		if (eParam == null) {
			eParam = new HashMap();
		}
		
		// -1. 如果为forcestart, 那么重置一下单据vo的审批状态
		if (eParam != null && eParam.get(PfUtilBaseTools.PARAM_FORCESTART) != null) {
			resetApproveStatus(billvo, IPfRetCheckInfo.NOSTATE);
		}
		
		// 0.处理工作项(上传附件)
		processWorknote(workflowVo);

		// 1.构造动作处理的参数VO
		AggregatedValueObject[] inVos = null;
		if (billvo != null) {
			inVos = PfUtilBaseTools.pfInitVos(billvo.getClass().getName(), 1);
			inVos[0] = billvo;
		}
		PfParameterVO paraVoOfBilltype = PfUtilBaseTools.getVariableValue(billOrTranstype, actionName, billvo, inVos, userObj, null, workflowVo, eParam, hashBilltypeToParavo);

		try {
			// 2.如果为删除动作,则删除流程信息
			if (PfUtilBaseTools.isDeleteAction(paraVoOfBilltype.m_actionName, paraVoOfBilltype.m_billType))
				deleteWorkFlow(paraVoOfBilltype);

			// 3.进行动作前约束检查
			IPFActionConstrict aConstrict = new PFActionConstrict();
			aConstrict.actionConstrictBefore(paraVoOfBilltype);

			// 4.执行动作脚本
			Object retObj = actionOnStep(paraVoOfBilltype.m_actionName, paraVoOfBilltype);

			// 5.进行动作后约束检查
			aConstrict.actionConstrictAfter(paraVoOfBilltype);

			// 6.脚本返回值的处理
			if (retObj instanceof nc.bs.pub.compiler.IWorkFlowRet) {
				// XXX::只有脚本调用procActionFlow@@,且在流程审批进行中时才返回该对象
				return ((nc.bs.pub.compiler.IWorkFlowRet) retObj).m_inVo;
			}

			try {
				Object[] tmpObj = (Object[]) retObj;
				Hashtable hasNoProc = null;
				// XXX::必须保证批量的动作脚本具有这样的返回值 lj
				if (tmpObj != null && tmpObj.length > 0 && tmpObj[0] instanceof IWorkflowBatch) {
					IWorkflowBatch wfBatch = (IWorkflowBatch) tmpObj[0];
					hasNoProc = wfBatch.getNoPassAndGoing();
					Object[] userObjs = (Object[]) wfBatch.getUserObj();
					retObj = userObjs[0];
				}
				if (hasNoProc != null && hasNoProc.containsKey("0"))
					return null;
			} catch (Exception e) {
				// FIXME::如果动作脚本返回值非数组或其他异常,都忽略之
			}

			// 7.上游消息处理
			backMsg(paraVoOfBilltype, retObj);

			// 8.动作驱动
			if (isDriveAction(paraVoOfBilltype.m_billType, paraVoOfBilltype.m_actionName)&&isNeedDriveAction(retObj)) {
				actiondrive(paraVoOfBilltype.m_preValueVo, userObj, hashBilltypeToParavo, hashMethodReturn, paraVoOfBilltype, eParam);
			}
			
			String src_billtypePK =paraVoOfBilltype.m_preValueVo!=null?StringUtil.isEmptyWithTrim(paraVoOfBilltype.m_preValueVo.getParentVO().getPrimaryKey())?"":paraVoOfBilltype.m_preValueVo.getParentVO().getPrimaryKey():"";

			// 9.如果动作为提交,尝试启动审批流或工作流
			if (PfUtilBaseTools.isSaveAction(paraVoOfBilltype.m_actionName, paraVoOfBilltype.m_billType)){
				retObj = startApproveFlowAfterAction(paraVoOfBilltype.m_billType, paraVoOfBilltype.m_preValueVo, userObj, retObj, eParam, hashBilltypeToParavo, hashMethodReturn,src_billtypePK)[1];
				sendMessageWhenStartWorkflow(paraVoOfBilltype,WorkflowTypeEnum.Approveflow.getIntValue());
			}				
			else if (PfUtilBaseTools.isStartAction(paraVoOfBilltype.m_actionName, paraVoOfBilltype.m_billType)){
				startWorkflowAfterAction(paraVoOfBilltype.m_billType, paraVoOfBilltype.m_preValueVo, userObj, retObj, eParam, hashBilltypeToParavo, hashMethodReturn,src_billtypePK);
				sendMessageWhenStartWorkflow(paraVoOfBilltype,WorkflowTypeEnum.Workflow.getIntValue());
			}
			//10 .如果业务流符合跳转的条件,执行流程的跳转
			jumpBusitype(lastParamVO);	

			// 清空引擎实例池中的数据,否则无法释放
			WfInstancePool.getInstance().clear();

			Logger.debug("*后台单据动作处理PFBusiAction.processAction结束,耗时" + (System.currentTimeMillis() - start) + "ms");

			return retObj;
		} catch (BusinessException ex) {
			logWorkflowExptInfo(ex, paraVoOfBilltype);
			throw ex;
		}
	}
其中审批和取消审批,收回在第四步发送消息,提交在第九步发送消息。
3.3 发送消息类 PfMessageUtil的sendMessageOfWorknote方法
public static void sendMessageOfWorknote(WorkflownoteVO workflownoteVO)
			throws BusinessException {
		if (workflownoteVO == null)
			return;

		if (checkmanIsVirtual(workflownoteVO))
			return;
		
		NCMessage ncMsg = transferToNCMessage(workflownoteVO);
		try {
			String[] msgpk = MessageCenter
					.sendMessage(new NCMessage[] { ncMsg });

			String pk_message = msgpk[0];
			WFTask task = getWFTask(workflownoteVO.getPk_wf_task());
			MessageMetaVO metavo = createMessageMeta(workflownoteVO, task, pk_message);
			
			NCLocator.getInstance().lookup(IPFMessageMetaService.class).insert(metavo);
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
			throw new BusinessException(e);
		}
	}
调用NCMessage ncMsg = transferToNCMessage(workflownoteVO);方法后调用fill(ncmsg, workflownote);

4.实现过程:
4.1:修改元数据,添加审批流字段属性,修改vo,修改数据库。
alter table hi_psndoc_ctrt add 
billid varchar(50) NULL add
billno varchar(50) NULL add
pkorg varchar(50) NULL add 
busitype varchar(50) NULL add 
billmaker varchar(50) NULL add 
approver varchar(50) NULL add 
approvestatus int NULL add 
approvenote varchar(50) NULL add 
approvedate char(19) NULL add 
transtype varchar(50) NULL add 
billtype varchar(50) NULL add 
transtypepk varchar(50) NULL add 
srcbilltype varchar(50) NULL add 
srcbillid varchar(50) NULL add 
emendenum int NULL add 
billversionpk varchar(50) NULL;
4.2   参考资料——审批流设置    在单据类型管理配置支持审批流和节点编号(对应功能编码),在单据动作管理添加动作代码
4.3  编写代码,实现按钮状态改变和发送消息。
@Override
	public void doAction(ActionEvent arg0) throws Exception {
		Integer[] row=this.model.getSelectedOperaRows();
		if (row.length>1) {
			MessageDialog.showErrorDlg(getModel().getContext().getEntranceUI(),"提示","请选择一行数据进行操作!");
			return;
		}
		
		CtrtVO tempData = (CtrtVO) this.model.getSelectedData();
		
		if (tempData==null) {
			MessageDialog.showErrorDlg(getModel().getContext().getEntranceUI(),"提示","请选中行后进行操作");
			return;
		}
		AggHRHeTongVO aggVo=new AggHRHeTongVO();
		aggVo.setParentVO(tempData);
		I6201Maintain service = NCLocator.getInstance().lookup(I6201Maintain.class);
		// 1.修改状态
		CtrtVO vo=(CtrtVO) tempData.clone();
		vo.setStatus(VOStatus.UNCHANGED);
//		通过按钮的名字《当前操作》来确定审批状态的变更写入
		int btnstatus=JudgementSubmissionStatus.isSubmit(this.getActionName());
		vo.setAttributeValue("approvestatus", btnstatus);//提交
		aggVo.setParentVO(vo);//更新后的VO
		
		// 2.发送消息
		AbstractFunclet funclet = (AbstractFunclet) getModel().getContext()
				.getEntranceUI();
		HashMap<String, Object> hmParam = new HashMap<String, Object>();
		hmParam.put("reload_vo", aggVo);
		String billtype=JudgementSubmissionStatus.getBillType(this.model.getContext().getNodeCode());
		WorkflownoteVO worknoteVO = MyAppActionScriptService.getWorkflownoteVO(funclet, "SAVE", billtype, aggVo, null, null, null, hmParam);
		Object obj=service.processAction(actionName, billType, worknoteVO, aggVo, null, null);
		service.update(vo);//修改状态
		getModel().directlyUpdate(vo);
		ShowStatusBarMsgUtil.showStatusBarMsg("所有单据操作成功!", this.getModel().getContext());
	}


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值