1、查询单据所处的流程状态
nc.bs.wfengine.engine.EngineService的queryFlowStatus()方法
/*** 查询单据所处的流程状态* * @param billId* @param billType* @param result* @return* @throws DbException*/public int queryFlowStatus(String billId, String billType, int flowType, String taskResult) throws DbException {IFlowStatusService flowStatusService = AbstractFlowStatusService.getFlowStatusService(flowType);return flowStatusService.queryFlowStatus(billId, billType, taskResult);}
nc.bs.pub.wfengine.status.AbstractFlowStatusService
package nc.bs.pub.wfengine.status;import java.util.ArrayList;
import java.util.Iterator;import nc.jdbc.framework.JdbcSession;
import nc.jdbc.framework.PersistenceManager;
import nc.jdbc.framework.SQLParameter;
import nc.jdbc.framework.exception.DbException;
import nc.jdbc.framework.processor.ArrayListProcessor;
import nc.jdbc.framework.processor.ArrayProcessor;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.vo.pub.pf.IPfRetCheckInfo;
import nc.vo.wfengine.definition.WorkflowTypeEnum;
import nc.vo.wfengine.pub.WfTaskOrInstanceStatus;
import nc.vo.wfengine.pub.WfTaskType;public abstract class AbstractFlowStatusService implements IFlowStatusService {public static IFlowStatusService getFlowStatusService(int type) {WorkflowTypeEnum flowtype = WorkflowTypeEnum.fromIntValue(type);switch (flowtype) {case Approveflow:case SubApproveflow:return new ApproveflowStatusService();case Workflow:case SubWorkflow:return new WorkflowStatusService();case SubWorkApproveflow:return new SubWorkApproveflowStatusService();}return null;}public int queryFlowStatus(String billId, String billType, String taskResult)throws DbException{return 0;}protected int queryCurrentFlowStatus(String billId, String billType,int flowType) throws DbException {// 1.查询主流程实例的状态String sql = "select procstatus,procresult from pub_wf_instance"+ " where billversionpk=? and billtype=? and procstatus!="+ WfTaskOrInstanceStatus.Inefficient.getIntValue()+ " and ( isnull(cast(workflow_type as char),'~')='~' or workflow_type=?)";// 2.查询有无处于启动状态的修单任务String sql1 = "select b.pk_wf_task from pub_wf_task b,pub_wf_instance a"+ " where a.billversionpk=? and a.billtype=? and a.procstatus!="+ WfTaskOrInstanceStatus.Inefficient.getIntValue()+ " and (isnull(cast(a.workflow_type as char),'~')='~' or a.workflow_type=?)"+ " and b.pk_wf_instance=a.pk_wf_instance and b.tasktype="+ WfTaskType.Makebill.getIntValue() + " and b.taskstatus="+ WfTaskOrInstanceStatus.Started.getIntValue();// 3.查询有无已处于启动/完成状态的审批工作项String sql2 = "select a.approvestatus,b.pk_wf_task from pub_workflownote a,pub_wf_task b"+ " where a.pk_wf_task=b.pk_wf_task and b.tasktype=" + WfTaskType.Forward.getIntValue()+ " and a.approvestatus in(" + WfTaskOrInstanceStatus.Started.getIntValue() + ","+ WfTaskOrInstanceStatus.Finished.getIntValue() + ") and a.billversionpk=? and a.pk_billtype=?"+ " and (isnull(cast(a.workflow_type as char),'~')='~' or a.workflow_type=? or a.workflow_type = 3 or a.workflow_type = 5 or a.workflow_type = 6)"; PersistenceManager persist = null;try {persist = PersistenceManager.getInstance();JdbcSession jdbc = persist.getJdbcSession();SQLParameter para = new SQLParameter();para.addParam(billId);para.addParam(billType);para.addParam(flowType);Object[] objs = (Object[]) jdbc.executeQuery(sql, para, new ArrayProcessor());if (objs != null) {// 单据已经拥有流程实例int status = ((Integer) objs[0]).intValue();String result = String.valueOf(objs[1]);if (status != WfTaskOrInstanceStatus.Finished.getIntValue()) {// 流程未结束Object objTaskPK = jdbc.executeQuery(sql1, para, new ColumnProcessor(1));if (objTaskPK != null) {String pk_wf_task = String.valueOf(objTaskPK);if (pk_wf_task != null && pk_wf_task.trim().length() > 0) {// 如果有修改单据的任务,为自由态return IPfRetCheckInfo.NOSTATE;}}ArrayList alResult = (ArrayList) jdbc.executeQuery(sql2, para, new ArrayListProcessor());boolean hasFinishedItem = false;boolean hasStartedItem = false;for (Iterator iterator = alResult.iterator(); iterator.hasNext();) {Object[] results = (Object[]) iterator.next();String taskPK2 = (String) results[1];int approveStatus = (Integer) results[0];if (taskPK2 != null) {if (approveStatus == WfTaskOrInstanceStatus.Finished.getIntValue())hasFinishedItem = true;if (approveStatus == WfTaskOrInstanceStatus.Started.getIntValue())hasStartedItem = true;}}if (hasFinishedItem) {// 如果存在已完成的审批任务,则进行中return IPfRetCheckInfo.GOINGON;} else if (hasStartedItem) {// 如果存在启动的审批任务,则提交态return IPfRetCheckInfo.COMMIT;} else// 如果无启动/完成的审批任务,则自由态return IPfRetCheckInfo.NOSTATE;}// 流程已经结束if (result != null && result.equalsIgnoreCase("Y"))return IPfRetCheckInfo.PASSING;if (result != null && result.equalsIgnoreCase("N"))return IPfRetCheckInfo.NOPASS;}// 尚无流程实例,则为自由态return IPfRetCheckInfo.NOSTATE;} finally {if (persist != null)persist.release();}}
}
2、流程平台客户端工具类
package nc.ui.pub.pf;import java.awt.Container;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.Vector;import javax.swing.JDialog;
import javax.swing.SwingUtilities;import nc.bs.dao.DAOException;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.bs.pf.pub.BillTypeCacheKey;
import nc.bs.pf.pub.PfDataCache;
import nc.bs.pub.pf.PfUtilTools;
import nc.desktop.ui.WorkbenchEnvironment;
import nc.funcnode.ui.AbstractFunclet;
import nc.funcnode.ui.IFuncletWindow;
import nc.itf.uap.IUAPQueryBS;
import nc.itf.uap.pf.IPFConfig;
import nc.itf.uap.pf.IPFWorkflowQry;
import nc.itf.uap.pf.IPfExchangeService;
import nc.itf.uap.pf.IWorkflowDefine;
import nc.itf.uap.pf.IWorkflowMachine;
import nc.itf.uap.pf.IplatFormEntry;
import nc.itf.uap.pf.busiflow.PfButtonClickContext;
import nc.itf.uap.pf.metadata.IFlowBizItf;
import nc.message.Attachment;
import nc.message.vo.AttachmentVO;
import nc.uap.pf.metadata.PfMetadataTools;
import nc.ui.ml.NCLangRes;
import nc.ui.pf.change.PfUtilUITools;
import nc.ui.pf.clientutils.PfUtilClientAssistor;
import nc.ui.pf.pub.PFClientBizRetObj;
import nc.ui.pf.pub.PfUIDataCache;
import nc.ui.pf.workitem.ApproveFlowDispatchDialog;
import nc.ui.pf.workitem.ApproveWorkitemAcceptDlg;
import nc.ui.pf.workitem.BatchApproveModel;
import nc.ui.pf.workitem.BatchApproveWorkitemAcceptDlg;
import nc.ui.pf.workitem.WFStartDispatchDialog;
import nc.ui.pf.workitem.WorkflowWorkitemAcceptDlg;
import nc.ui.pf.workitem.beside.BesideApproveContext;
import nc.ui.pub.beans.MessageDialog;
import nc.ui.pub.beans.UIDialog;
import nc.ui.pub.bizflow.IBillReferQueryWithBusitype;
import nc.ui.pub.bizflow.IBillReferQueryWithScheme;
import nc.ui.pub.bizflow.IBillReferQueryWithTranstype;
import nc.ui.pub.workflowqry.WorkflowManageUtil;
import nc.ui.querytemplate.IBillReferQuery;
import nc.ui.querytemplate.QueryConditionDLG;
import nc.ui.querytemplate.querytree.IQueryScheme;
import nc.ui.wfengine.ext.ApplicationRuntimeAdjustContext;
import nc.ui.wfengine.ext.ApplicationRuntimeAdjustFactory;
import nc.ui.wfengine.ext.IApplicationRuntimeAdjust;
import nc.vo.jcom.lang.StringUtil;
import nc.vo.pf.change.ExchangeVO;
import nc.vo.pf.change.PfUtilBaseTools;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.billtype2.Billtype2VO;
import nc.vo.pub.billtype2.ExtendedClassEnum;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.pf.AssignableInfo;
import nc.vo.pub.pf.PfAddInfo;
import nc.vo.pub.pf.PfClientBizProcessContext;
import nc.vo.pub.pf.workflow.IPFActionName;
import nc.vo.pub.pfflow.BillactionVO;
import nc.vo.pub.pfflow01.BillbusinessVO;
import nc.vo.pub.template.ITemplateStyle;
import nc.vo.pub.workflownote.WorkflownoteVO;
import nc.vo.querytemplate.TemplateInfo;
import nc.vo.sm.UserVO;
import nc.vo.uap.pf.FlowDefNotFoundException;
import nc.vo.uap.pf.PFBusinessException;
import nc.vo.uap.pf.PFRuntimeException;
import nc.vo.uap.pf.PfProcessBatchRetObject;
import nc.vo.wfengine.core.parser.XPDLNames;
import nc.vo.wfengine.definition.IApproveflowConst;
import nc.vo.wfengine.definition.WorkflowDefinitionVO;
import nc.vo.wfengine.definition.WorkflowTypeEnum;
import nc.vo.wfengine.pub.WFTask;
import nc.vo.wfengine.pub.WfTaskType;/*** 流程平台客户端工具类* * @author fangj 2001-10* @modifier leijun 2005-5 取消单据类型UI类名必须以<Y>开头才可指派的限制* @modifier leijun 2006-7 送审时的指派对话框,如果用户点击取消,则不送审* @modifier leijun 2007-5 使用新的查询模板* @modifier leijun 2008-3 重构动作处理的API,进一步精简* @modifier dingxm 2009-7 参照制单对于按钮逻辑的处理挪到BusinessDelegator,参照制单中本类只提供信息,不处理按钮* @modifier zhouzhenga 20120107 部分逻辑挪到PfUtilClientAssistor*/
public class PfUtilClient {/*** 审批变量如果审批则true反之false;*/private static boolean m_checkFlag = true;// 当前单据类型private static String m_currentBillType = null;/** 当前审批节点的审批结果 */private static int m_iCheckResult = IApproveflowConst.CHECK_RESULT_PASS;private static boolean m_isOk = false;/** fgj2001-11-27 判断当前动作是否执行成功 */private static boolean m_isSuccess = true;/** 源单据类型 */private static String m_sourceBillType = null;private static AggregatedValueObject m_tmpRetVo = null;private static AggregatedValueObject[] m_tmpRetVos = null;// 单据自制标志public static boolean makeFlag = false;private static IPfExchangeService exchangeService;private static int m_classifyMode = PfButtonClickContext.NoClassify;private static boolean isOpenedInDialog = false;private static boolean isAutoCloseParentDialog = false;/*** 审批流定义查询服务*/private static IWorkflowDefine workflowDefService;private PfUtilClient() {// Noop!}/*** 提交单据时,需要的指派信息* <li>只有"SAVE","EDIT"动作才调用*/private static WorkflownoteVO checkOnSave(Container parent, String actionName, String billType, AggregatedValueObject billVo, Stack dlgResult, HashMap hmPfExParams) throws BusinessException {WorkflownoteVO worknoteVO = new WorkflownoteVO();// guowl+ 2010-5,如果是批处理,不用取指派信息,直接返回if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null)return worknoteVO;try {worknoteVO = NCLocator.getInstance().lookup(IWorkflowMachine.class).checkWorkFlow(actionName, billType, billVo, hmPfExParams);} catch (FlowDefNotFoundException e) {return worknoteVO;}// 在审批处理框显示之前,调用业务处理PFClientBizRetObj retObj = executeBusinessPlugin(parent, billVo, worknoteVO, true);if (retObj != null && retObj.isStopFlow()) {m_isSuccess = false;return null;}if (worknoteVO != null) {// 得到可指派的输入数据Vector assignInfos = worknoteVO.getTaskInfo().getAssignableInfos();if (assignInfos != null && assignInfos.size() > 0) {// 显示指派对话框并收集实际指派信息ApproveFlowDispatchDialog dlg = new ApproveFlowDispatchDialog(parent);dlg.getDisPatchPanel().initByWorknoteVO(worknoteVO);int iClose = dlg.showModal();if (iClose == UIDialog.ID_CANCEL)dlgResult.push(Integer.valueOf(iClose));}}return worknoteVO;}/*** 单据启动工作流时,需要的指派信息* <li>包括选择后继活动参与者、选择后继分支转移*/private static WorkflownoteVO checkOnStart(Container parent, String actionName, String billType, AggregatedValueObject billVo, Stack dlgResult, HashMap hmPfExParams) throws BusinessException {WorkflownoteVO wfVo = NCLocator.getInstance().lookup(IWorkflowMachine.class).checkWorkFlow(actionName, billType, billVo, hmPfExParams);// guowl+ 2010-5,如果是批处理,不用取指派信息,直接返回if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null)return wfVo;if (wfVo != null) {// 得到可指派的信息Vector assignInfos = wfVo.getTaskInfo().getAssignableInfos();Vector tSelectInfos = wfVo.getTaskInfo().getTransitionSelectableInfos();if (assignInfos.size() > 0 || tSelectInfos.size() > 0) {// 显示指派对话框并收集实际指派信息WFStartDispatchDialog wfdd = new WFStartDispatchDialog(parent, wfVo);int iClose = wfdd.showModal();if (iClose == UIDialog.ID_CANCEL)dlgResult.push(Integer.valueOf(iClose));}}return wfVo;}/*** 检查当前单据是否处于工作流程中或工作流的审批子流程中,并进行交互*/private static WorkflownoteVO checkWorkitemWhenSignal(Container parent, String actionCode, String billType, AggregatedValueObject billVo, HashMap hmPfExParams, int voAryLen) throws BusinessException {WorkflownoteVO noteVO = null;UIDialog dlg = null;if (voAryLen != 0) {if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE) != null) {noteVO = (WorkflownoteVO) hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE);m_checkFlag = true;return noteVO;}}try {// 检查当前用户的工作流工作项+审批子流程工作项noteVO = NCLocator.getInstance().lookup(IWorkflowMachine.class).checkWorkFlow(actionCode, billType, billVo, hmPfExParams);if (noteVO == null) {m_checkFlag = true;return noteVO;} else {// XXX:guowl+,检查是否弹出交互界面// 批量执行是按照每十条执行一次,当执行之后还剩下一条时,走单个执行方法,所以对工作项单独处理if (voAryLen == 0 && (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE) != null)) {WorkflownoteVO oldNoteVO = (WorkflownoteVO) hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE);noteVO.getTaskInfo().setTransitionSelectableInfos(oldNoteVO.getTaskInfo().getTransitionSelectableInfos());if (oldNoteVO.getTaskInfo().getTransitionSelectableInfos() != null && oldNoteVO.getTaskInfo().getTransitionSelectableInfos().size() > 0) {noteVO.getTaskInfo().setTransitionSelectableInfos(oldNoteVO.getTaskInfo().getTransitionSelectableInfos());}noteVO.setIscheck(oldNoteVO.getIscheck());noteVO.setApproveresult(oldNoteVO.getApproveresult());noteVO.setChecknote(oldNoteVO.getChecknote());if ("R".equals(oldNoteVO.getApproveresult()) && !noteVO.isAnyoneCanApprove()) {noteVO.getTaskInfo().getTask().setBackToFirstActivity(true);noteVO.getTaskInfo().getTask().setTaskType(WfTaskType.Backward.getIntValue());}Object value = noteVO.getRelaProperties().get(XPDLNames.ELECSIGNATURE);if (value != null && "true".equalsIgnoreCase(value.toString())) {noteVO.setCiphertext(oldNoteVO.getCiphertext());}return noteVO;}if (!PfUtilClientAssistor.isExchange(noteVO.getTaskInfo().getTask())) {m_checkFlag = true;noteVO.setApproveresult("Y");return noteVO;}if (noteVO.getWorkflow_type() == WorkflowTypeEnum.SubWorkApproveflow.getIntValue()) {// 工作流的审批子流程if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null) {dlg = new BatchApproveWorkitemAcceptDlg(parent, noteVO);BatchApproveModel batchApproveMode = new BatchApproveModel();batchApproveMode.setBillUI(true);batchApproveMode.setSingleBillSelected(true);batchApproveMode.setContainUnApproveBill(false);batchApproveMode.setBillItem(voAryLen);((BatchApproveWorkitemAcceptDlg) dlg).setBachApproveMode(batchApproveMode);} else {dlg = new ApproveWorkitemAcceptDlg(parent, noteVO, true);}} else// 工作流或工作子流程dlg = new WorkflowWorkitemAcceptDlg(parent, noteVO, PfUtilClientAssistor.isCanTransfer(noteVO.getTaskInfo().getTask()));if (dlg.showModal() == UIDialog.ID_OK) {// 返回处理后的工作项m_checkFlag = true;} else {// 用户取消m_checkFlag = false;noteVO = null;}if ((hmPfExParams != null && (!hmPfExParams.containsKey(PfUtilBaseTools.PARAM_WORKNOTE) || hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE) == null)) && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null) {hmPfExParams.put(PfUtilBaseTools.PARAM_WORKNOTE, noteVO);}}} finally {if (dlg != null) {nc.ui.pub.beans.UIComponentUtil.removeAllComponentRefrence(dlg);}}return noteVO;}/*** 检查当前单据是否处于审批流程中,并进行交互*/private static WorkflownoteVO checkWorkitemWhenApprove(Container parent, String actionName, String billType, Object billvos, HashMap hmPfExParams, int voAryLen) throws BusinessException {WorkflownoteVO noteVO = null;UIDialog dlg = null;if (voAryLen != 0) {if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE) != null) {noteVO = (WorkflownoteVO) hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE);m_checkFlag = true;return noteVO;}}// billvos传值为单值或者数组 qf@2015-1-22AggregatedValueObject billvo = null;AggregatedValueObject[] vos = null;if (billvos instanceof AggregatedValueObject) {billvo = (AggregatedValueObject) billvos;} else if (billvos instanceof AggregatedValueObject[]) {vos = (AggregatedValueObject[]) billvos;billvo = vos[0];}if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null) {Object notSilent = hmPfExParams.get(PfUtilBaseTools.PARAM_NOTSILENT);// 检查单据是否定义了审批流,如果没有定义,则不弹出,此处只简单检查第一张单据的单据类型上是否有流程定义if (notSilent == null && !hasApproveflowDef(billType, billvo)) {m_checkFlag = true;noteVO = new WorkflownoteVO();noteVO.setApproveresult("Y");Logger.debug("*checkWorkitemWhenApprove 1 billType.");return noteVO;} else {// 预算开发部要求批审时不管有没有流程定义,都弹出审批意见框noteVO = new WorkflownoteVO();// 判断是否需要CAList<String> billIdList = new ArrayList<String>();if (vos != null && vos.length != 0) {for (AggregatedValueObject vo : vos) {billIdList.add(vo.getParentVO().getPrimaryKey());}noteVO.getRelaProperties().put(XPDLNames.ELECSIGNATURE, NCLocator.getInstance().lookup(IPFWorkflowQry.class).isNeedCASign4Batch(PfUtilUITools.getLoginUser(), new String[] { billType }, billIdList.toArray(new String[0])));}BatchApproveModel batchApproveMode = new BatchApproveModel();batchApproveMode.setBillUI(true);batchApproveMode.setSingleBillSelected(true);batchApproveMode.setContainUnApproveBill(false);batchApproveMode.setBillItem(voAryLen);dlg = new BatchApproveWorkitemAcceptDlg(parent, noteVO);((BatchApproveWorkitemAcceptDlg) dlg).setBachApproveMode(batchApproveMode);Logger.debug("*checkWorkitemWhenApprove 2.");}} else {noteVO = NCLocator.getInstance().lookup(IWorkflowMachine.class).checkWorkFlow(actionName, billType, billvo, hmPfExParams);Logger.debug("*checkWorkitemWhenApprove 3.");if (noteVO != null && isBesideApprove(hmPfExParams)) {noteVO = BesideApprove(hmPfExParams, noteVO);} else {Object notSilent = null;if (hmPfExParams != null) {notSilent = hmPfExParams.get(PfUtilBaseTools.PARAM_NOTSILENT);}if (noteVO == null) {if (notSilent == null) {m_checkFlag = true;Logger.debug("*checkWorkitemWhenApprove 1 billType.");return noteVO;} else {noteVO = new WorkflownoteVO();}}PFClientBizRetObj retObj = executeBusinessPlugin(parent, billvo, noteVO, false);int workflowtype = noteVO.getWorkflow_type();boolean isInWorkflow = false;if (workflowtype == WorkflowTypeEnum.SubWorkApproveflow.getIntValue())isInWorkflow = true;dlg = new ApproveWorkitemAcceptDlg(parent, noteVO, billvo, isInWorkflow, isOpenedInDialog, retObj == null ? null : retObj.getHintMessage());ApproveWorkitemAcceptDlg acceptDlg = ((ApproveWorkitemAcceptDlg) dlg);if (retObj != null) {// yanke1 2012-02-22 根据前台业务处理的返回值来控制审批界面acceptDlg.setShowPass(retObj.isShowPass());
// acceptDlg.setShowNoPass(retObj.isShowNoPass());acceptDlg.setShowReject(retObj.isShowReject());}acceptDlg.setShowNoPass(!PfUtilClientAssistor.isHideNoPassing(noteVO.getTaskInfo().getTask()));Logger.debug("*checkWorkitemWhenApprove 4.");}}Logger.debug("*checkWorkitemWhenApprove 5.");if (!isBesideApprove(hmPfExParams)) {if (hmPfExParams == null) {hmPfExParams = new HashMap<String, Object>();}if (dlg.showModal() == UIDialog.ID_OK) { // 如果用户审批if (dlg instanceof ApproveWorkitemAcceptDlg) {isAutoCloseParentDialog = ((ApproveWorkitemAcceptDlg) dlg).isAutoCloseParentDialog();}m_checkFlag = true;} else { // 用户不审批m_checkFlag = false;noteVO = null;}if ((!hmPfExParams.containsKey(PfUtilBaseTools.PARAM_WORKNOTE) || hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE) == null) && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null) {hmPfExParams.put(PfUtilBaseTools.PARAM_WORKNOTE, noteVO);}}return noteVO;}/*** 侧边栏审批* * @throws BusinessException*/private static WorkflownoteVO BesideApprove(HashMap hmPfExParams, WorkflownoteVO noteVO) throws BusinessException {BesideApproveContext besideContext = (BesideApproveContext) hmPfExParams.get(PfUtilBaseTools.PARAM_BESIDEAPPROVE);m_checkFlag = true;if (besideContext.isNeedDispatch()) {// 填充指派信息ApproveFlowDispatchDialog disPatchDlg = new ApproveFlowDispatchDialog(null);disPatchDlg.getDisPatchPanel().initByWorknoteVO(noteVO, besideContext.getApproveResult().equalsIgnoreCase("Y") ? AssignableInfo.CRITERION_PASS : AssignableInfo.CRITERION_NOPASS);int result = disPatchDlg.showModal();if (result == UIDialog.ID_CANCEL) {// 如果指派对话框点击了取消,那么取消这次审批操作,重新回到审批面板 (changlx需求定义)modified by// zhangrui 2012-04-17noteVO = null;m_checkFlag = false;return noteVO;}}// 改派if (besideContext.getManagerContext() != null) {WorkflowManageUtil wfUtil = new WorkflowManageUtil();if (wfUtil.doAlterSend(null, besideContext.getManagerContext(), besideContext.getTransferList(), besideContext.getCheckNote())) {noteVO.getTaskInfo().getTask().setAppoint(true);} else {noteVO = null;m_isSuccess = false;return noteVO;}noteVO.setChecknote(besideContext.getCheckNote());}// 加签if (besideContext.isAddAssign()) {ApplicationRuntimeAdjustContext context = new ApplicationRuntimeAdjustContext();context.setStyle(besideContext.getAddAssignStyle());// style被去掉了context.setUserObject(besideContext.getAddAssignUserObj());// 记录加签发起人UserVO operator = WorkbenchEnvironment.getInstance().getLoginUser();noteVO.setSenderman(operator.getCuserid());noteVO.setChecknote(besideContext.getCheckNote());context.setWorkFlow(noteVO);IApplicationRuntimeAdjust runtimeObj = ApplicationRuntimeAdjustFactory.createAdjust(IApplicationRuntimeAdjust.ADJUST_TYPE_ADDASSIGN);try {runtimeObj.adjust(context);m_checkFlag = true;} catch (BusinessException e) {Logger.error(e.getMessage(), e);String message = e.getMessage();if (e.getCause() != null) {message = e.getCause().getMessage();}MessageDialog.showErrorDlg(null, null, message);m_isSuccess = false;noteVO = null;return noteVO;}}noteVO.setMailExtCpySenders(besideContext.getMailExtCpySenders());noteVO.setMsgExtCpySenders(besideContext.getMsgExtCpySenders());List<AttachmentVO> attchVOS = updateAttachment2DocServer(besideContext.getAttchlist());noteVO.setAttachmentSetting(attchVOS);noteVO.setApproveresult(besideContext.getApproveResult());noteVO.setChecknote(besideContext.getCheckNote());noteVO.setTrack(besideContext.isTracked());if (besideContext.getTaskType() != 0) {noteVO.getTaskInfo().getTask().setTaskType(besideContext.getTaskType());}noteVO.getTaskInfo().getTask().setBackToFirstActivity(besideContext.isBackToFirstActivity());noteVO.getTaskInfo().getTask().setJumpToActivity(besideContext.getJumpToActivity());m_checkFlag = true;m_isSuccess = true;return noteVO;}// 上传服务器,不影响流程private static List<AttachmentVO> updateAttachment2DocServer(List<Attachment> attchlist) throws BusinessException {List<AttachmentVO> vos = new ArrayList<AttachmentVO>();try {for (Attachment attachment : attchlist) {AttachmentVO vo = attachment.uploadToFileServer();vo.setFilesize(attachment.getSize());vo.setFilename(attachment.getName());vos.add(vo);}} catch (Exception e) {Logger.error(e.getMessage() + "上传附件失败!");throw new BusinessException(e.getMessage() + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("pfworkflow63", "Attachmentfile-0000")/** @res"上传附件失败!" */);}return vos;}private static boolean hasApproveflowDef(String billType, AggregatedValueObject billVo) throws BusinessException {IFlowBizItf fbi = PfMetadataTools.getBizItfImpl(billVo, IFlowBizItf.class);if (fbi == null)throw new PFRuntimeException(NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000000")/* 元数据实体没有提供业务接口IFlowBizItf的实现类 */);IWorkflowDefine wfDefine = NCLocator.getInstance().lookup(IWorkflowDefine.class);Logger.debug("查询流程定义: billType=" + billType + ";pkOrg=" + fbi.getPkorg() + ";userId=" + fbi.getBillMaker() + ";开始");return wfDefine.hasValidProcessDef(WorkbenchEnvironment.getInstance().getGroupVO().getPk_group(), billType, fbi.getPkorg(), fbi.getBillMaker(), fbi.getEmendEnum(), WorkflowTypeEnum.Approveflow.getIntValue());}/*** 参照来源单据,用于* <li>1.获取来源单据的查询对话框,并查询出来源单据* <li>2.显示来源单据,并进行选择* <li>3.获取选择的来源单据* * @param srcBillType 参照制单 选择的来源单据类型* @param pk_group* @param userId* @param currBillOrTranstype 当前单据或交易类型* @param parent* @param userObj* @param srcBillId 如果为空,则直接进入参照上游单据界面*/public static void childButtonClicked(String srcBillType, String pk_group, String userId, String currBillOrTranstype, Container parent, Object userObj, String srcBillId) {childButtonClickedWithBusi(srcBillType, pk_group, userId, currBillOrTranstype, parent, userObj, srcBillId, null);}public static void childButtonClickedNew(final PfButtonClickContext context) {makeFlag = false;if (context.getSrcBillType().toUpperCase().equals("MAKEFLAG")) {Logger.debug("******自制单据******");makeFlag = true;return;}Logger.debug("******参照来源单据******");m_classifyMode = context.getClassifyMode();try {final String funNode = PfUIDataCache.getBillType(new BillTypeCacheKey().buildBilltype(context.getSrcBillType()).buildPkGroup(context.getPk_group())).getNodecode();if (funNode == null || funNode.equals(""))throw new PFBusinessException(NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000001", null, new String[] { context.getSrcBillType() })/* 请注册单据{0}的功能节点号 */);// 查询交换信息,以便得到一些参照制单的定制信息String src_qrytemplate = null;String src_billui = null; // 来源单据的显示UI类String src_nodekey = null; // 用于查询来源单据的查询模板的节点标识ExchangeVO changeVO = getExchangeService().queryMostSuitableExchangeVO(context.getSrcBillType(), context.getCurrBilltype(), null, PfUtilUITools.getLoginGroup(), null);if (changeVO != null) {src_qrytemplate = changeVO.getSrc_qrytemplate();src_qrytemplate = src_qrytemplate == null ? null : src_qrytemplate.trim();src_billui = changeVO.getSrc_billui();src_nodekey = changeVO.getSrc_nodekey();}// a.获取来源单据的查询对话框,即为m_condition赋值IBillReferQuery qcDLG = null;if (StringUtil.isEmptyWithTrim(src_qrytemplate)) {Logger.debug("使用来源单据类型对应节点使用的查询模板对话框");src_qrytemplate = PfUtilUITools.getTemplateId(ITemplateStyle.queryTemplate, context.getPk_group(), funNode, context.getUserId(), src_nodekey);qcDLG = setConditionClient(src_qrytemplate, context.getParent(), context.getUserId(), funNode, context.getPk_group());} else if (src_qrytemplate.startsWith("<")) {Logger.debug("使用产品组定制的来源单据查询对话框");src_qrytemplate = src_qrytemplate.substring(1, src_qrytemplate.length() - 1);qcDLG = loadUserQuery(context.getParent(), src_qrytemplate, context.getPk_group(), context.getUserId(), funNode, context.getCurrBilltype(), context.getSrcBillType(), src_nodekey, context.getUserObj());} else {Logger.debug("使用注册的查询模板的查询对话框");qcDLG = setConditionClient(src_qrytemplate, context.getParent(), context.getUserId(), funNode, context.getPk_group());}// 给查询对话框设置业务类型,asked by scm-puqhif (context.getBusiTypes() != null && qcDLG instanceof IBillReferQueryWithBusitype)((IBillReferQueryWithBusitype) qcDLG).setBusitypes(context.getBusiTypes());// 给查询对话框设置交易类型,用于过滤上游单据,asked by scm-puqhif (context.getTransTypes() != null && qcDLG instanceof IBillReferQueryWithTranstype)((IBillReferQueryWithTranstype) qcDLG).setTranstypes(context.getTransTypes());if (context.getSrcBillId() == null) {// b.显示来源单据的查询对话框if (qcDLG.showModal() == UIDialog.ID_OK) {// c.显示来源单据,并进行选择refBillSource(context.getPk_group(), funNode, context.getUserId(), context.getCurrBilltype(), context.getParent(), context.getUserObj(), context.getSrcBillType(), src_qrytemplate, src_billui, src_nodekey, null, qcDLG);} else {m_isOk = false;return;}} else {// b'.直接显示来源单据refBillSource(context.getPk_group(), funNode, context.getUserId(), context.getCurrBilltype(), context.getParent(), context.getUserObj(), context.getSrcBillType(), src_qrytemplate, src_billui, src_nodekey, context.getSrcBillId(), qcDLG);return;}} catch (Exception ex) {Logger.error(ex.getMessage(), ex);MessageDialog.showErrorDlg(context.getParent(), "null", NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000002", null, new String[] { ex.getMessage() })/* 参照上游单据出现异常={0} */);}}/*** 参照来源单据,用于* <li>1.获取来源单据的查询对话框,并查询出来源单据* <li>2.显示来源单据,并进行选择* <li>3.获取选择的来源单据* * @param srcBillType 参照制单 选择的来源单据类型* @param pk_group* @param userId* @param currBillOrTranstype 当前单据或交易类型* @param parent* @param userObj* @param srcBillId 如果为空,则直接进入参照上游单据界面* @param busiTypes 如果不为空,表示查找指定业务流程中的单据*/public static void childButtonClickedWithBusi(String srcBillType, String pk_group, String userId, String currBillOrTranstype, Container parent, Object userObj, String srcBillId, List<String> busiTypes) {m_classifyMode = PfButtonClickContext.NoClassify;makeFlag = false;if (srcBillType.toUpperCase().equals("MAKEFLAG")) {Logger.debug("******自制单据******");makeFlag = true;return;}Logger.debug("******参照来源单据******");try {String funNode = PfUIDataCache.getBillType(new BillTypeCacheKey().buildBilltype(srcBillType).buildPkGroup(pk_group)).getNodecode();if (funNode == null || funNode.equals(""))throw new PFBusinessException(NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000001", null, new String[] { srcBillType })/* 请注册单据{0}的功能节点号 */);// 查询交换信息,以便得到一些参照制单的定制信息String src_qrytemplate = null;String src_billui = null; // 来源单据的显示UI类String src_nodekey = null; // 用于查询来源单据的查询模板的节点标识ExchangeVO changeVO = getExchangeService().queryMostSuitableExchangeVO(srcBillType, currBillOrTranstype, null, PfUtilUITools.getLoginGroup(), null);if (changeVO != null) {src_qrytemplate = changeVO.getSrc_qrytemplate();src_qrytemplate = src_qrytemplate == null ? null : src_qrytemplate.trim();src_billui = changeVO.getSrc_billui();src_nodekey = changeVO.getSrc_nodekey();}// a.获取来源单据的查询对话框,即为m_condition赋值IBillReferQuery qcDLG = null;if (StringUtil.isEmptyWithTrim(src_qrytemplate)) {Logger.debug("使用来源单据类型对应节点使用的查询模板对话框");src_qrytemplate = PfUtilUITools.getTemplateId(ITemplateStyle.queryTemplate, pk_group, funNode, userId, src_nodekey);qcDLG = setConditionClient(src_qrytemplate, parent, userId, funNode, pk_group);} else if (src_qrytemplate.startsWith("<")) {Logger.debug("使用产品组定制的来源单据查询对话框");src_qrytemplate = src_qrytemplate.substring(1, src_qrytemplate.length() - 1);qcDLG = loadUserQuery(parent, src_qrytemplate, pk_group, userId, funNode, currBillOrTranstype, srcBillType, src_nodekey, userObj);} else {Logger.debug("使用注册的查询模板的查询对话框");qcDLG = setConditionClient(src_qrytemplate, parent, userId, funNode, pk_group);}if (busiTypes != null && qcDLG instanceof IBillReferQueryWithBusitype)((IBillReferQueryWithBusitype) qcDLG).setBusitypes(busiTypes);if (srcBillId == null) {// b.显示来源单据的查询对话框if (qcDLG.showModal() == UIDialog.ID_OK) {// c.显示来源单据,并进行选择refBillSource(pk_group, funNode, userId, currBillOrTranstype, parent, userObj, srcBillType, src_qrytemplate, src_billui, src_nodekey, null, qcDLG);} else {m_isOk = false;return;}} else {// b'.直接显示来源单据refBillSource(pk_group, funNode, userId, currBillOrTranstype, parent, userObj, srcBillType, src_qrytemplate, src_billui, src_nodekey, srcBillId, qcDLG);return;}} catch (Exception ex) {Logger.error(ex.getMessage(), ex);MessageDialog.showErrorDlg(parent, NCLangRes.getInstance().getStrByID("pfworkflow1", "SplitRuleRegisterUI-000005")/* 错误 */, NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000002", null, new String[] { ex.getMessage() })/* 参照上游单据出现异常={0} */);}}/*** 参照制单时,显示来源单据;并进行VO交换*/private static void refBillSource(String pk_group, String funNode, String pkOperator, String currBillOrTranstype, Container parent, Object userObj, String billType, String strQueryTemplateId, String src_billui, String srcNodekey, String sourceBillId, IBillReferQuery qcDLG) throws Exception {// 获取主表的关键字段String pkField = PfUtilBaseTools.findPkField(billType);if (pkField == null || pkField.trim().length() == 0)throw new PFBusinessException(NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000003")/* 无法通过单据类型获取单据实体的主表PK字段 */);String whereString = null;IQueryScheme qryScheme = null;if (sourceBillId == null) {if (qcDLG instanceof IBillReferQueryWithScheme) {qryScheme = ((IBillReferQueryWithScheme) qcDLG).getQueryScheme();} elsewhereString = qcDLG.getWhereSQL();} elsewhereString = pkField + "='" + sourceBillId + "'";// 载入来源单据展现对话框,并显示BillSourceVar bsVar = new BillSourceVar();bsVar.setBillType(billType);bsVar.setCurrBillOrTranstype(currBillOrTranstype);bsVar.setFunNode(funNode);bsVar.setNodeKey(srcNodekey);bsVar.setPk_group(pk_group);bsVar.setPkField(pkField);bsVar.setQryTemplateId(strQueryTemplateId);bsVar.setUserId(pkOperator);bsVar.setUserObj(userObj);bsVar.setWhereStr(whereString);if (qryScheme != null)bsVar.setQueryScheme(qryScheme);AbstractBillSourceDLG bsDlg = null;if (!StringUtil.isEmptyWithTrim(src_billui)) {Logger.debug("产品组定制的来源单据展现对话框,必须继承自" + AbstractBillSourceDLG.class.getName());bsDlg = loadCustomBillSourceDLG(src_billui, bsVar, parent);} else {Logger.debug("使用通用的来源单据展现对话框");bsDlg = new BillSourceDLG(parent, bsVar);}bsDlg.setQueyDlg(qcDLG); // 放入查询模板对话框// 加载模版bsDlg.addBillUI();// 加载数据bsDlg.loadHeadData();if (bsDlg.showModal() == UIDialog.ID_OK) {m_sourceBillType = billType;m_currentBillType = currBillOrTranstype;m_tmpRetVo = bsDlg.getRetVo();m_tmpRetVos = bsDlg.getRetVos();m_isOk = true;} else {m_isOk = false;}}/*** 返回 当前审批节点的处理结果 lj+ 2005-1-20*/public static int getCurrentCheckResult() {return m_iCheckResult;}/*** 返回 用户选择的VO*/public static AggregatedValueObject getRetOldVo() {return m_tmpRetVo;}/*** 返回 用户选择VO数组.*/public static AggregatedValueObject[] getRetOldVos() {return m_tmpRetVos;}/*** 返回 用户选择的VO或交换过的VO* * @return*/public static AggregatedValueObject getRetVo() {try {// 需要进行VO交换m_tmpRetVo = getExchangeService().runChangeData(m_sourceBillType, m_currentBillType, m_tmpRetVo, null);jumpBusitype(m_tmpRetVo == null ? null : new AggregatedValueObject[] { m_tmpRetVo });} catch (Exception ex) {Logger.error(ex.getMessage(), ex);throw new PFRuntimeException(NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000004", null, new String[] { ex.getMessage() })/* VO交换错误:{0} */, ex);}return m_tmpRetVo;}/*** 返回 用户选择VO数组或交换过的VO数组* * @return* @throws BusinessException*/public static AggregatedValueObject[] getRetVos() throws BusinessException {// 默认根据业务流程进行VO交换return getRetVos(true);}/*** 返回 用户选择VO数组或交换过的VO数组* * @param exchangeByBusiType 是否根据业务流程进行交换,如果否,则在交换前将来源业务流程PK清除* @return* @throws BusinessException*/public static AggregatedValueObject[] getRetVos(boolean exchangeByBusiType) throws BusinessException {// 如果不根据业务流程进行交换,则将单据中的业务流程PK去掉(供应链的需求,来源单据有业务流程pK,但是想走的是另外的流程)if (!exchangeByBusiType && m_tmpRetVos != null) {for (int i = 0; i < m_tmpRetVos.length; i++) {AggregatedValueObject aggVO = m_tmpRetVos[i];IFlowBizItf fbi = PfMetadataTools.getBizItfImpl(aggVO, IFlowBizItf.class);if (fbi != null) {fbi.setBusitype(null);}}}// 需要进行VO交换m_tmpRetVos = changeVos(m_tmpRetVos, m_classifyMode);jumpBusitype(m_tmpRetVos);return m_tmpRetVos;}private static IPfExchangeService getExchangeService() {if (exchangeService == null)exchangeService = NCLocator.getInstance().lookup(IPfExchangeService.class);return exchangeService;}/*** 返回 用户选择的VO或交换过的VO* * @return*/private static AggregatedValueObject[] changeVos(AggregatedValueObject[] vos, int classifyMode) {AggregatedValueObject[] tmpRetVos = null;try {tmpRetVos = getExchangeService().runChangeDataAryNeedClassify(m_sourceBillType, m_currentBillType, vos, null, classifyMode);} catch (BusinessException ex) {Logger.error(ex.getMessage(), ex);throw new PFRuntimeException(NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000004", null, new String[] { ex.getMessage() })/* VO交换错误:{0} */, ex);}return tmpRetVos;}/*** 业务流跳转* * @throws BusinessException*/private static void jumpBusitype(AggregatedValueObject[] vos) throws BusinessException {if (vos == null || vos.length == 0)return;IFlowBizItf fbi = PfMetadataTools.getBizItfImpl(vos[0], IFlowBizItf.class);// 未实现业务流接口的单据或者未走流程直接returnif (fbi == null || StringUtil.isEmptyWithTrim(fbi.getBusitype()))return;BillbusinessVO condVO = new BillbusinessVO();condVO.setPk_businesstype(fbi.getBusitype());condVO.setJumpflag(UFBoolean.TRUE);// 得到单据类型编码String billtype = PfUtilBaseTools.getRealBilltype(m_currentBillType);condVO.setPk_billtype(billtype);condVO.setTranstype(fbi.getTranstype());try {Collection co = NCLocator.getInstance().lookup(IUAPQueryBS.class).retrieve(condVO, true);if (co.size() > 0) {HashMap<String, String> busitypeMaps = new HashMap<String, String>();for (AggregatedValueObject vo : vos) {String destBusitypePk = null;fbi = PfMetadataTools.getBizItfImpl(vo, IFlowBizItf.class);String transtype = fbi.getTranstype();String pk_org = fbi.getPkorg();String operator = PfUtilUITools.getLoginUser();if (StringUtil.isEmptyWithTrim(billtype)) {// 单据类型不能为空continue;}String key = billtype + (StringUtil.isEmptyWithTrim(transtype) ? "" : transtype) + (StringUtil.isEmptyWithTrim(pk_org) ? "" : pk_org) + operator;if (busitypeMaps.containsKey(key)) {destBusitypePk = busitypeMaps.get(key);} else {destBusitypePk = NCLocator.getInstance().lookup(IPFConfig.class).retBusitypeCanStart(billtype, transtype, pk_org, operator);}// 如果没有找到要跳转的业务流if (StringUtil.isEmptyWithTrim(destBusitypePk)) {continue;}fbi.setBusitype(destBusitypePk);}}} catch (DAOException e) {Logger.error(e.getMessage(), e);}}/*** 判断用户是否点击了"取消"按钮* * @return boolean leijun+*/public static boolean isCanceled() {return !m_checkFlag;}/*** 返回 参照单据是否正常关闭* * @return boolean*/public static boolean isCloseOK() {return m_isOk;}/*** 返回 当前单据动作执行是否成功* * @return boolean*/public static boolean isSuccess() {return m_isSuccess;}/*** 载入产品组注册的来源单据显示对话框*/private static AbstractBillSourceDLG loadCustomBillSourceDLG(String src_billui, BillSourceVar bsVar, Container parent) {Class c = null;try {c = Class.forName(src_billui);Class[] argCls = new Class[] { Container.class, BillSourceVar.class };Object[] args = new Object[] { parent, bsVar };// 实例化带参构造方法Constructor cc = c.getConstructor(argCls);return (AbstractBillSourceDLG) cc.newInstance(args);} catch (Exception ex) {Logger.error(ex.getMessage(), ex);MessageDialog.showErrorDlg(parent, null, NCLangRes.getInstance().getStrByID("pfworkflow1", "PfUtilClient-000005", null, new String[] { ex.getMessage() })/* 载入产品组注册的来源单据显示对话框 发生异常:{0} */);}return null;}private static IBillReferQuery loadUserQuery(Container parent, String src_qrytemplate, String pk_group, String userId, String FunNode, String currBillOrTranstype, String sourceBillType, String nodeKey, Object userObj) {Class c = null;try {// 先判定是否为新查询模板UI的子类String qtId = PfUtilUITools.getTemplateId(ITemplateStyle.queryTemplate, pk_group, FunNode, userId, nodeKey);TemplateInfo ti = new TemplateInfo();ti.setTemplateId(qtId);ti.setPk_Org(pk_group);ti.setUserid(userId);ti.setCurrentCorpPk(pk_group);ti.setFunNode(FunNode);ti.setNodekey(nodeKey);c = Class.forName(src_qrytemplate);Object retObj = c.getConstructor(new Class[] { Container.class, TemplateInfo.class }).newInstance(new Object[] { parent, ti });// 对查询模版对话框的一些定制初始化if (retObj instanceof IinitQueryData) {((IinitQueryData) retObj).initData(pk_group, userId, FunNode, currBillOrTranstype, sourceBillType, nodeKey, userObj);}return (IBillReferQuery) retObj;} catch (NoSuchMethodException e) {Logger.warn("找不到新查询模板UI的构造方法,继续判定是否有老查询模板的构造方法", e);try {// 应该为老查询模板UI的子类Object retObj = c.getConstructor(new Class[] { Container.class }).newInstance(new Object[] { parent });// 对查询模版对话框的一些定制初始化if (retObj instanceof IinitQueryData) {((IinitQueryData) retObj).initData(pk_group, userId, FunNode, currBillOrTranstype, sourceBillType, nodeKey, userObj);}return (IBillReferQuery) retObj;} catch (Exception ex) {Logger.error(ex.getMessage(), ex);}} catch (Exception e) {Logger.error(e.getMessage(), e);}return null;}private static IFuncletWindow getParentFuncletWindow(Container parent, String actionCode, String billType) {if (PfUtilBaseTools.isApproveAction(actionCode, billType)) {// yanke1+ 2011-9-8// 找到单据节点的IFuncletWindow// 判断打开方式是否为对话框if (parent instanceof AbstractFunclet) {AbstractFunclet func = (AbstractFunclet) parent;String funcCode = func.getFuncCode();IFuncletWindow[] windows = WorkbenchEnvironment.getInstance().getAllOpenedFuncletWindow();for (IFuncletWindow window : windows) {String windowCode = window.getFuncRegisterVO().getFuncode();if (windowCode.equals(funcCode)) {isOpenedInDialog = (window instanceof JDialog);return window;}}}}return null;}/*** 前台单据动作处理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;m_checkFlag = 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-5if (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() {@Overridepublic void run() {p.forceCloseWindow();}});}return retObj;}private static Object getParamFromMap(HashMap eParam, String paramKey) {return eParam == null ? null : eParam.get(paramKey);}/*** 工作流相关的交互处理* * @throws BusinessException*/private static WorkflownoteVO actionAboutWorkflow(Container parent, String actionName, String billType, AggregatedValueObject billvo, HashMap eParam, int voAryLen) throws BusinessException {WorkflownoteVO worknoteVO = null;if (PfUtilBaseTools.isStartAction(actionName, billType)) {Logger.debug("*启动动作=" + actionName + ",检查工作流");Stack dlgResult = new Stack();worknoteVO = checkOnStart(parent, actionName, billType, billvo, dlgResult, eParam);if (dlgResult.size() > 0) {m_isSuccess = false;Logger.debug("*用户指派时点击了取消,则停止启动工作流");}} else if (PfUtilBaseTools.isSignalAction(actionName, billType)) {Logger.debug("*执行动作=" + actionName + ",检查工作流");// 检查该单据是否处于工作流中worknoteVO = checkWorkitemWhenSignal(parent, actionName, billType, billvo, eParam, voAryLen);if (worknoteVO != null) {if ("Y".equals(worknoteVO.getApproveresult())) {m_iCheckResult = IApproveflowConst.CHECK_RESULT_PASS;} else if ("R".equals(worknoteVO.getApproveresult())) {// XXX::驳回也作为审批通过的一种,需要继续判断 lj+WFTask currTask = worknoteVO.getTaskInfo().getTask();if (currTask != null && currTask.getTaskType() == WfTaskType.Backward.getIntValue()) {if (currTask.isBackToFirstActivity())m_iCheckResult = IApproveflowConst.CHECK_RESULT_REJECT_FIRST;elsem_iCheckResult = IApproveflowConst.CHECK_RESULT_REJECT_LAST;}} elsem_iCheckResult = IApproveflowConst.CHECK_RESULT_NOPASS;} else if (!m_checkFlag) {m_isSuccess = false;Logger.debug("*用户驱动工作流时点击了取消,则停止执行工作流");}}return worknoteVO;}/*** 审批流相关的交互处理* * @throws BusinessException*/private static WorkflownoteVO actionAboutApproveflow(Container parent, String actionName, String billType, Object billvos, HashMap eParam, int voAryLen) throws BusinessException {WorkflownoteVO worknoteVO = null;if (PfUtilBaseTools.isSaveAction(actionName, billType)) {Logger.debug("*提交动作=" + actionName + ",检查审批流");// 如果为提交动作,可能需要收集提交人的指派信息,这里统一动作名称 lj@2005-4-8Stack dlgResult = new Stack();// billvos传值为单值或者数组 qf@2015-1-22AggregatedValueObject billvo = null;if (billvos instanceof AggregatedValueObject) {billvo = (AggregatedValueObject) billvos;} else if (billvos instanceof AggregatedValueObject[]) {AggregatedValueObject[] vos = (AggregatedValueObject[]) billvos;billvo = vos[0];}worknoteVO = checkOnSave(parent, IPFActionName.SAVE, billType, billvo, dlgResult, eParam);if (dlgResult.size() > 0) {m_isSuccess = false;Logger.debug("*用户指派时点击了取消,则停止送审");}} else if (PfUtilBaseTools.isApproveAction(actionName, billType)) {Logger.debug("*审批动作=" + actionName + ",检查审批流");// 检查该单据是否处于审批流中,并收集审批人的审批信息worknoteVO = checkWorkitemWhenApprove(parent, actionName, billType, billvos, eParam, voAryLen);if (worknoteVO != null) {if ("Y".equals(worknoteVO.getApproveresult())) {m_iCheckResult = IApproveflowConst.CHECK_RESULT_PASS;} else if ("R".equals(worknoteVO.getApproveresult())) {// XXX::驳回也作为审批通过的一种,需要继续判断 lj+WFTask currTask = worknoteVO.getTaskInfo().getTask();if (currTask != null && currTask.getTaskType() == WfTaskType.Backward.getIntValue()) {if (currTask.isBackToFirstActivity())m_iCheckResult = IApproveflowConst.CHECK_RESULT_REJECT_FIRST;elsem_iCheckResult = IApproveflowConst.CHECK_RESULT_REJECT_LAST;}} elsem_iCheckResult = IApproveflowConst.CHECK_RESULT_NOPASS;} else if (!m_checkFlag) {m_isSuccess = false;Logger.debug("*用户审批时点击了取消,则停止审批");}}return worknoteVO;}private static PFClientBizRetObj executeBusinessPlugin(Container parent, AggregatedValueObject billVo, WorkflownoteVO wfVo, boolean isMakeBill) {if (wfVo != null && wfVo.getApplicationArgs() != null && wfVo.getApplicationArgs().size() > 0) {String billtype = wfVo.getTaskInfo().getTask().getBillType();ArrayList<Billtype2VO> bt2VOs = PfDataCache.getBillType2Info(billtype, ExtendedClassEnum.PROC_CLIENT.getIntValue());// 实例化for (Iterator iterator = bt2VOs.iterator(); iterator.hasNext();) {Billtype2VO bt2VO = (Billtype2VO) iterator.next();try {Object obj = PfUtilTools.findBizImplOfBilltype(billtype, bt2VO.getClassname());PfClientBizProcessContext context = new PfClientBizProcessContext();context.setBillvo(billVo);context.setArgsList(wfVo.getApplicationArgs());context.setMakeBill(isMakeBill);return ((IPFClientBizProcess) obj).execute(parent, context);} catch (Exception e) {Logger.error("无法实例化前台业务插件类billType=" + billtype + ",className=" + bt2VO.getClassname(), e);}}}return null;}/*** @return 是否侧边栏审批*/private static boolean isBesideApprove(HashMap hmPfExParams) {return hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_BESIDEAPPROVE) != null;}// /**
// * 批审时的交互处理
// * @throws BusinessException
// */
// private static WorkflownoteVO batchActionAboutApproveflow(Container parent, String actionName,
// String billType, AggregatedValueObject[] voAry, HashMap eParam) throws BusinessException {
// WorkflownoteVO worknoteVO = null;
//
// if (PfUtilBaseTools.isSaveAction(actionName)) {
// Logger.debug("*提交动作=" + actionName + ",检查审批流");
// } else if (PfUtilBaseTools.isApproveAction(actionName)) {
// Logger.debug("*审批动作=" + actionName + ",检查审批流");
// // 检查该单据是否处于审批流中,并收集审批人的审批信息
// worknoteVO = checkWorkitemWhenApprove(parent, actionName, billType, null, eParam);
// if (worknoteVO != null) {
// if ("Y".equals(worknoteVO.getApproveresult())) {
// // XXX::驳回也作为审批通过的一种,需要继续判断 lj+
// WFTask currTask = worknoteVO.getTaskInfo().getTask();
// if (currTask.getTaskType() == WfTaskType.Backward.getIntValue()) {
// if (currTask.isBackToFirstActivity())
// m_iCheckResult = IApproveflowConst.CHECK_RESULT_REJECT_FIRST;
// else
// m_iCheckResult = IApproveflowConst.CHECK_RESULT_REJECT_LAST;
// } else
// m_iCheckResult = IApproveflowConst.CHECK_RESULT_PASS;
// } else
// m_iCheckResult = IApproveflowConst.CHECK_RESULT_NOPASS;
// } else if (!m_checkFlag) {
// m_isSuccess = false;
// Logger.debug("*用户审批时点击了取消,则停止审批");
// }
// }
// return worknoteVO;
// }/*** 日志一下动作处理的上下文参数*/private static void debugParams(String actionCode, String billType, Object billEntity, Object userObj) {Logger.debug("*********************************************");Logger.debug("* actionCode=" + actionCode);Logger.debug("* billType=" + billType);Logger.debug("* billEntity=" + billEntity);Logger.debug("* userObj=" + userObj);Logger.debug("*********************************************");}/*** 动作执行前提示*/private static boolean hintBeforeAction(Container parent, String actionName, String billType) {ActionClientParams acp = new ActionClientParams();acp.setUiContainer(parent);acp.setActionCode(actionName);acp.setBillType(billType);return PfUtilUITools.beforeAction(acp);}/*** 前台单据动作批处理API,算法如下:* <li>1.动作执行前提示以及事前处理,如果用户取消,则方法直接返回* <li>2.查看扩展参数,判断是否需要审批流相关处理。如果为提交动作,且单据VO数组中只有一张单据时可能需要收集提交人的指派信息;* 如果为审批动作,则针对第一张单据可能需要收集审批人的审批信息* <li>3.后台执行批动作。并返回动作执行结果。* * @param parent 父窗体* @param actionCode 动作编码,比如"SAVE"* @param billOrTranstype 单据类型(或交易类型)PK* @param voAry 单据聚合VO数组* @param userObjAry 用户自定义对象数组* @param eParam 扩展参数* @return 动作批处理的返回结果* @throws Exception* @since 5.5*/public static Object[] runBatch(Container parent, String actionCode, String billOrTranstype, AggregatedValueObject[] voAry, Object[] userObjAry, String strBeforeUIClass, HashMap eParam) throws Exception {eParam = initEParam(eParam);Logger.debug("*单据动作批处理 开始");debugParams(actionCode, billOrTranstype, voAry, userObjAry);long start = System.currentTimeMillis();if (isSingleDataRun(voAry, eParam)) {Object obj = runAction(parent, actionCode, billOrTranstype, voAry[0], userObjAry, strBeforeUIClass, null, eParam);Object[] ret = null;ret = PfUtilBaseTools.composeResultAry(obj, 1, 0, ret);return ret;}m_isSuccess = true;m_checkFlag = true;// 1.动作执行前提示以及事前处理boolean isContinue = beforeProcessBatchAction(parent, actionCode, billOrTranstype);if (!isContinue) {Logger.debug("*动作执行前提示以及事前处理,返回");m_isSuccess = false;return null;}WorkflownoteVO workflownote = null;// 2.查看扩展参数,是否要流程交互处理Object paramNoflow = getParamFromMap(eParam, PfUtilBaseTools.PARAM_NOFLOW);Object paramSilent = getParamFromMap(eParam, PfUtilBaseTools.PARAM_SILENTLY);if (paramNoflow == null && paramSilent == null) {// XXX:guowl,2010-5,批审时,审批处理对话框上只显示批准、不批准、驳回,故传入一个参数用于甄别// 如果传人的VO数组长度为1,同单个处理一样if (voAry != null && voAry.length > 1) {eParam = putParam(eParam, PfUtilBaseTools.PARAM_BATCH, PfUtilBaseTools.PARAM_BATCH);}if (PfUtilBaseTools.isSaveAction(actionCode, billOrTranstype) || PfUtilBaseTools.isApproveAction(actionCode, billOrTranstype)) {// 审批流交互处理workflownote = actionAboutApproveflow(parent, actionCode, billOrTranstype, voAry, eParam, voAry.length);if (!m_isSuccess)return null;} else if (PfUtilBaseTools.isStartAction(actionCode, billOrTranstype) || PfUtilBaseTools.isSignalAction(actionCode, billOrTranstype)) {// 工作流交互处理workflownote = actionAboutWorkflow(parent, actionCode, billOrTranstype, voAry[0], eParam, voAry.length);if (!m_isSuccess)return null;}}// 3.后台批处理动作Logger.debug("*后台动作批处理 开始");Object retObj = NCLocator.getInstance().lookup(IplatFormEntry.class).processBatch(actionCode, billOrTranstype, workflownote, voAry, userObjAry, eParam);if (retObj instanceof PfProcessBatchRetObject) {String errMsg = ((PfProcessBatchRetObject) retObj).getExceptionMsg();if (!StringUtil.isEmptyWithTrim(errMsg))MessageDialog.showErrorDlg(parent, null, errMsg);retObj = ((PfProcessBatchRetObject) retObj).getRetObj();}if (retObj != null && ((Object[]) retObj).length > 0) {// 批处理时,有一个成功的就认为成功m_isSuccess = true;}Logger.debug("*单据动作批处理 结束=" + (System.currentTimeMillis() - start) + "ms");return (Object[]) retObj;}private static HashMap initEParam(HashMap eParam) {eParam = eParam != null ? eParam : new HashMap();return eParam;}public static PfProcessBatchRetObject runBatchNew(Container parent, String actionCode, String billOrTranstype, AggregatedValueObject[] voAry, Object[] userObjAry, String strBeforeUIClass, HashMap eParam) throws Exception {eParam = initEParam(eParam);Logger.debug("*单据动作批处理 开始");debugParams(actionCode, billOrTranstype, voAry, userObjAry);long start = System.currentTimeMillis();if (isSingleDataRun(voAry, eParam)) {Object obj = runAction(parent, actionCode, billOrTranstype, voAry[0], userObjAry, strBeforeUIClass, null, eParam);Object[] retObj = null;retObj = PfUtilBaseTools.composeResultAry(obj, 1, 0, retObj);return new PfProcessBatchRetObject(retObj, null);}m_isSuccess = true;m_checkFlag = true;// 1.动作执行前提示以及事前处理boolean isContinue = beforeProcessBatchAction(parent, actionCode, billOrTranstype);if (!isContinue) {Logger.debug("*动作执行前提示以及事前处理,返回");m_isSuccess = false;return null;}// 2.查看扩展参数,是否要流程交互处理WorkflownoteVO workflownote = null;// (WorkflownoteVO)getParamFromMap(eParam, PfUtilBaseTools.PARAM_WORKNOTE);
// if(workflownote == null){Object paramNoflow = getParamFromMap(eParam, PfUtilBaseTools.PARAM_NOFLOW);Object paramSilent = getParamFromMap(eParam, PfUtilBaseTools.PARAM_SILENTLY);if (paramNoflow == null && paramSilent == null) {// XXX:guowl,2010-5,批审时,审批处理对话框上只显示批准、不批准、驳回,故传入一个参数用于甄别// 如果传人的VO数组长度为1,同单个处理一样if (voAry != null && voAry.length > 1) {eParam = putParam(eParam, PfUtilBaseTools.PARAM_BATCH, PfUtilBaseTools.PARAM_BATCH);}if (PfUtilBaseTools.isSaveAction(actionCode, billOrTranstype) || PfUtilBaseTools.isApproveAction(actionCode, billOrTranstype)) {// 审批流交互处理workflownote = actionAboutApproveflow(parent, actionCode, billOrTranstype, voAry, eParam, voAry.length);if (!m_isSuccess)return null;} else if (PfUtilBaseTools.isStartAction(actionCode, billOrTranstype) || PfUtilBaseTools.isSignalAction(actionCode, billOrTranstype)) {// 工作流交互处理workflownote = actionAboutWorkflow(parent, actionCode, billOrTranstype, voAry[0], eParam, voAry.length);if (!m_isSuccess)return null;}
// putParam(eParam, PfUtilBaseTools.PARAM_WORKNOTE, workflownote);}// }// 3.后台批处理动作Logger.debug("*后台动作批处理 开始");Object retObj = NCLocator.getInstance().lookup(IplatFormEntry.class).processBatch(actionCode, billOrTranstype, workflownote, voAry, userObjAry, eParam);Logger.debug("*单据动作批处理 结束=" + (System.currentTimeMillis() - start) + "ms");return (PfProcessBatchRetObject) retObj;}private static boolean isSingleDataRun(AggregatedValueObject[] voAry, HashMap eParam) {return voAry != null && voAry.length == 1 && eParam.get(PfUtilBaseTools.PARAM_WORKNOTE) == null;}private static HashMap putParam(HashMap eParam, String paramKey, Object value) {if (eParam == null) {eParam = new HashMap();}eParam.put(paramKey, value);return eParam;}/*** 动作执行前提示以及事前处理*/private static boolean beforeProcessBatchAction(Container parent, String actionName, String billType) throws Exception {ActionClientParams acp = new ActionClientParams();acp.setUiContainer(parent);acp.setActionCode(actionName);acp.setBillType(billType);return PfUtilUITools.beforeAction(acp);}/*** 返回某个单据或交易类型可使用的“新增”下拉菜单信息* <li>包括自制、来源单据* * @param billtype* @param transtype 如果没有交易类型,可空* @param pk_group 某集团PK* @param userId 某用户PK* @param includeBillType 是否包括单据类型的来源单据信息,只用于transtype非空的情况* @return* @throws BusinessException*/public static PfAddInfo[] retAddInfo(String billtype, String transtype, String pk_group, String userId, boolean includeBillType) throws BusinessException {return NCLocator.getInstance().lookup(IPFConfig.class).retAddInfo(billtype, transtype, pk_group, userId, includeBillType);}/*** 返回某个用户对某个单据或交易类型,在某组织下 可启动的业务流程* * @param billtype* @param transtype 如果没有交易类型,可空* @param pk_org 某组织PK* @param userId 某用户PK* @return* @throws BusinessException*/public static String retBusitypeCanStart(String billtype, String transtype, String pk_org, String userId) throws BusinessException {return NCLocator.getInstance().lookup(IPFConfig.class).retBusitypeCanStart(billtype, transtype, pk_org, userId);}/*** 返回某单据或交易类型配置的某动作组的所有单据动作* * @param billOrTranstype 单据或交易类型* @param actiongroupCode 动作组编码* @return*/public static BillactionVO[] getActionsOfActiongroup(String billOrTranstype, String actiongroupCode) {// 获得单据类型(或交易类型)的单据类型PKbillOrTranstype = PfUtilBaseTools.getRealBilltype(billOrTranstype);BillactionVO[] billActionVos = (BillactionVO[]) PfUIDataCache.getButtonByBillAndGrp(billOrTranstype, actiongroupCode);return billActionVos;}/*** 构造一个查询对话框,并为其设置查询模板* * @param templateId* @param parent* @param isRelationCorp* @param pkOperator* @param funNode*/private static IBillReferQuery setConditionClient(String templateId, Container parent, final String pkOperator, final String funNode, String pkCorp) {TemplateInfo ti = new TemplateInfo();ti.setTemplateId(templateId);ti.setPk_Org(pkCorp);ti.setUserid(pkOperator);ti.setCurrentCorpPk(pkCorp);ti.setFunNode(funNode);QueryConditionDLG qcDlg = new QueryConditionDLG(parent, ti);qcDlg.setVisibleNormalPanel(false);return qcDlg;}/*** 为NC预算提供的支持不同审批流的工作项批量处理的接口(只用于NC预算批量处理) add by liangyub 2014-04-21* * @param VOArrayMap map<审批流pk,审批的对象级(业务组聚合VO)>*/public static Map<String, PfProcessBatchRetObject> runBatchNewForNC(Container parent, String actionCode, Map<String, List<AggregatedValueObject>> VOArrayMap) throws Exception {Logger.debug("*单据动作批处理 runBatchNewForNC方法开始");// 批量处理逻辑m_isSuccess = true;m_checkFlag = true;Map<String, PfProcessBatchRetObject> result = new HashMap<String, PfProcessBatchRetObject>();// 查询所关联的流程定义String[] defPks = VOArrayMap.keySet().toArray(new String[0]);WorkflowDefinitionVO[] defVOs = getWorkflowDefService().findDefinitionsWithoutContentByPrimaryKeys(defPks);Map<String, String> billTypeMap = new HashMap<String, String>();for (WorkflowDefinitionVO def : defVOs) {billTypeMap.put(def.getPk_wf_def(), def.getBilltype());}// 处理单个逻辑if (VOArrayMap != null && VOArrayMap.size() == 1 && VOArrayMap.get(defPks[0]).size() == 1) {processForSingle(parent, actionCode, VOArrayMap, result, defPks, billTypeMap);return result;}long start = System.currentTimeMillis();Logger.debug("*后台动作批处理 开始");processForMultiple(parent, actionCode, VOArrayMap, result, defPks, billTypeMap);Logger.debug("*单据动作批处理 结束=" + (System.currentTimeMillis() - start) + "ms");return result;}private static IWorkflowDefine getWorkflowDefService() {if (workflowDefService == null) {workflowDefService = NCLocator.getInstance().lookup(IWorkflowDefine.class);}return workflowDefService;}/*** 处理单个任务*/private static void processForSingle(Container parent, String actionCode, Map<String, List<AggregatedValueObject>> VOArrayMap, Map<String, PfProcessBatchRetObject> result, String[] defPks, Map<String, String> billTypeMap) throws BusinessException {// 补全调用参数String billType = billTypeMap.get(defPks[0]);HashMap<String, Object> eParam = new HashMap<String, Object>();eParam.put(PfUtilBaseTools.PARAM_FLOWPK, defPks[0]);Object obj = runAction(parent, actionCode, billType, VOArrayMap.get(defPks[0]).get(0), new Object[] { Integer.valueOf(0) }, null, null, eParam);Object[] retObj = null;retObj = PfUtilBaseTools.composeResultAry(obj, 1, 0, retObj);result.put(defPks[0], new PfProcessBatchRetObject(retObj, null));}/*** 批量处理任务*/private static void processForMultiple(Container parent, String actionCode, Map<String, List<AggregatedValueObject>> VOArrayMap, Map<String, PfProcessBatchRetObject> result, String[] defPks, Map<String, String> billTypeMap) throws BusinessException, Exception {if (VOArrayMap.size() > 1) {processForSingleBillType(parent, actionCode, VOArrayMap, result, defPks, billTypeMap);} else {processForMultipleBillType(parent, actionCode, VOArrayMap, result, defPks, billTypeMap);}}/*** 如果只有一个流程,是属于相同流程的工作项批量处理(有动作执行前提示)*/private static void processForSingleBillType(Container parent, String actionCode, Map<String, List<AggregatedValueObject>> VOArrayMap, Map<String, PfProcessBatchRetObject> result, String[] defPks, Map<String, String> billTypeMap) throws Exception, BusinessException {// 1.动作执行前提示以及事前处理String billType = billTypeMap.get(defPks[0]);AggregatedValueObject[] voAry = VOArrayMap.get(defPks[0]).toArray(new AggregatedValueObject[0]);boolean isContinue = beforeProcessBatchAction(parent, actionCode, billType);if (!isContinue) {Logger.debug("*动作执行前提示以及事前处理,返回");m_isSuccess = false;}// 2.流程交互处理HashMap<String, Object> eParam = new HashMap<String, Object>();eParam.put(PfUtilBaseTools.PARAM_FLOWPK, defPks[0]);eParam.put(PfUtilBaseTools.PARAM_NOTSILENT, new Boolean(true));WorkflownoteVO workflownote = processForBatch(parent, actionCode, billType, voAry, eParam);// 3.后台批处理动作Object retObj = NCLocator.getInstance().lookup(IplatFormEntry.class).processBatch(actionCode, billType, workflownote, voAry, new Object[] { Integer.valueOf(1) }, eParam);result.put(defPks[0], (PfProcessBatchRetObject) retObj);}/*** 如果存在多个流程,是属于不同流程的工作项批量处理(有动作执行前提示)*/private static void processForMultipleBillType(Container parent, String actionCode, Map<String, List<AggregatedValueObject>> VOArrayMap, Map<String, PfProcessBatchRetObject> result, String[] defPks, Map<String, String> billTypeMap) throws BusinessException {// 取第一流程定义下的审批结果,用于补全剩余工作项String billType = billTypeMap.get(defPks[0]);AggregatedValueObject[] voAry = VOArrayMap.get(defPks[0]).toArray(new AggregatedValueObject[0]);HashMap<String, Object> eParam = new HashMap<String, Object>();eParam.put(PfUtilBaseTools.PARAM_FLOWPK, defPks[0]);eParam.put(PfUtilBaseTools.PARAM_NOTSILENT, new Boolean(true));WorkflownoteVO workflownote = processForBatch(parent, actionCode, billType, voAry, eParam);Object retObj = NCLocator.getInstance().lookup(IplatFormEntry.class).processBatch(actionCode, billType, workflownote, voAry, new Object[] { Integer.valueOf(1) }, eParam);result.put(defPks[0], (PfProcessBatchRetObject) retObj);for (int i = 1; i < defPks.length; i++) {String type = billTypeMap.get(defPks[i]);WorkflownoteVO noteVO = new WorkflownoteVO();completeWorkItemInfo(workflownote, noteVO);AggregatedValueObject[] ary = VOArrayMap.get(defPks[i]).toArray(new AggregatedValueObject[0]);HashMap<String, Object> param = new HashMap<String, Object>();eParam.put(PfUtilBaseTools.PARAM_FLOWPK, defPks[i]);Object ret = NCLocator.getInstance().lookup(IplatFormEntry.class).processBatch(actionCode, type, noteVO, ary, new Object[] { Integer.valueOf(1) }, param);result.put(defPks[i], (PfProcessBatchRetObject) ret);}}/*** 用于处理批量审批同一流程的多个工作项,并返回处理过的WorkflownoteVO<br/>*/@SuppressWarnings("unchecked")private static WorkflownoteVO processForBatch(Container parent, String actionCode, String billOrTranstype, AggregatedValueObject[] voAry, HashMap<String, Object> eParam) throws BusinessException {// 1.加入扩展承参数putElecsignatureValue(billOrTranstype, voAry, eParam);// 2.查看扩展参数,是否要流程交互处理WorkflownoteVO workflownote = null;Object paramNoflow = getParamFromMap(eParam, PfUtilBaseTools.PARAM_NOFLOW);Object paramSilent = getParamFromMap(eParam, PfUtilBaseTools.PARAM_SILENTLY);if (paramNoflow == null && paramSilent == null) {// 批审时,审批处理对话框上只显示批准、不批准、驳回,故传入一个参数用于甄别// 如果传人的VO数组长度为1,同单个处理一样if (voAry != null && voAry.length > 1) {eParam = putParam(eParam, PfUtilBaseTools.PARAM_BATCH, PfUtilBaseTools.PARAM_BATCH);}if (PfUtilBaseTools.isSaveAction(actionCode, billOrTranstype) || PfUtilBaseTools.isApproveAction(actionCode, billOrTranstype)) {// 审批流交互处理workflownote = actionAboutApproveflow(parent, actionCode, billOrTranstype, voAry[0], eParam, voAry.length);} else if (PfUtilBaseTools.isStartAction(actionCode, billOrTranstype) || PfUtilBaseTools.isSignalAction(actionCode, billOrTranstype)) {// 工作流交互处理workflownote = actionAboutWorkflow(parent, actionCode, billOrTranstype, voAry[0], eParam, voAry.length);}}return workflownote;}/*** 根据已有工作项,补全当前工作项信息 用于NC预算不同审批流的批量审批*/private static void completeWorkItemInfo(WorkflownoteVO baseVO, WorkflownoteVO toCompleteVO) {toCompleteVO.setChecknote(baseVO.getChecknote());if (baseVO.getApproveresult().equals("Y")) {// 批准toCompleteVO.setApproveresult("Y");} else if (baseVO.getApproveresult().equals("N")) {// 不批准toCompleteVO.setApproveresult("N");} else if (baseVO.getApproveresult().equals("R")) {// 驳回到制单人if (toCompleteVO.getTaskInfo().getTask() != null) {toCompleteVO.getTaskInfo().getTask().setTaskType(WfTaskType.Backward.getIntValue());toCompleteVO.getTaskInfo().getTask().setBackToFirstActivity(true);}toCompleteVO.setApproveresult("R");}toCompleteVO.setApproveresult(baseVO.getApproveresult());}/*** * @since 6.3 批审时候预先判断是否需要CA*/private static void putElecsignatureValue(String billOrTranstype, AggregatedValueObject[] voAry, HashMap eParam) throws BusinessException {// 判断是否需要CAList<String> billIdList = new ArrayList<String>();for (AggregatedValueObject vo : voAry) {billIdList.add(vo.getParentVO().getPrimaryKey());}boolean isNeedCASign = NCLocator.getInstance().lookup(IPFWorkflowQry.class).isNeedCASign4Batch(PfUtilUITools.getLoginUser(), new String[] { billOrTranstype }, billIdList.toArray(new String[0]));if (isNeedCASign) {putParam(eParam, XPDLNames.ELECSIGNATURE, "Y");}}}
流程平台客户端工具类中提交单据时,需要的指派信息方法:
/*** 提交单据时,需要的指派信息* <li>只有"SAVE","EDIT"动作才调用*/private static WorkflownoteVO checkOnSave(Container parent, String actionName, String billType, AggregatedValueObject billVo, Stack dlgResult, HashMap hmPfExParams) throws BusinessException {WorkflownoteVO worknoteVO = new WorkflownoteVO();// guowl+ 2010-5,如果是批处理,不用取指派信息,直接返回if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null)return worknoteVO;try {worknoteVO = NCLocator.getInstance().lookup(IWorkflowMachine.class).checkWorkFlow(actionName, billType, billVo, hmPfExParams);} catch (FlowDefNotFoundException e) {return worknoteVO;}// 在审批处理框显示之前,调用业务处理PFClientBizRetObj retObj = executeBusinessPlugin(parent, billVo, worknoteVO, true);if (retObj != null && retObj.isStopFlow()) {m_isSuccess = false;return null;}if (worknoteVO != null) {// 得到可指派的输入数据Vector assignInfos = worknoteVO.getTaskInfo().getAssignableInfos();if (assignInfos != null && assignInfos.size() > 0) {// 显示指派对话框并收集实际指派信息ApproveFlowDispatchDialog dlg = new ApproveFlowDispatchDialog(parent);dlg.getDisPatchPanel().initByWorknoteVO(worknoteVO);int iClose = dlg.showModal();if (iClose == UIDialog.ID_CANCEL)dlgResult.push(Integer.valueOf(iClose));}}return worknoteVO;}
如应收单保存时,弹出需要指派下个审批环节的参与者弹框就是调用该方法
3、检查当前单据是否处于审批流程中,并进行交互
审批弹框类:nc.ui.pf.workitem.ApproveWorkitemAcceptDlg
审批弹框调用的方法:
/*** 检查当前单据是否处于审批流程中,并进行交互*/private static WorkflownoteVO checkWorkitemWhenApprove(Container parent, String actionName, String billType, Object billvos, HashMap hmPfExParams, int voAryLen) throws BusinessException {WorkflownoteVO noteVO = null;UIDialog dlg = null;if (voAryLen != 0) {if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE) != null) {noteVO = (WorkflownoteVO) hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE);m_checkFlag = true;return noteVO;}}// billvos传值为单值或者数组 qf@2015-1-22AggregatedValueObject billvo = null;AggregatedValueObject[] vos = null;if (billvos instanceof AggregatedValueObject) {billvo = (AggregatedValueObject) billvos;} else if (billvos instanceof AggregatedValueObject[]) {vos = (AggregatedValueObject[]) billvos;billvo = vos[0];}if (hmPfExParams != null && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null) {Object notSilent = hmPfExParams.get(PfUtilBaseTools.PARAM_NOTSILENT);// 检查单据是否定义了审批流,如果没有定义,则不弹出,此处只简单检查第一张单据的单据类型上是否有流程定义if (notSilent == null && !hasApproveflowDef(billType, billvo)) {m_checkFlag = true;noteVO = new WorkflownoteVO();noteVO.setApproveresult("Y");Logger.debug("*checkWorkitemWhenApprove 1 billType.");return noteVO;} else {// 预算开发部要求批审时不管有没有流程定义,都弹出审批意见框noteVO = new WorkflownoteVO();// 判断是否需要CAList<String> billIdList = new ArrayList<String>();if (vos != null && vos.length != 0) {for (AggregatedValueObject vo : vos) {billIdList.add(vo.getParentVO().getPrimaryKey());}noteVO.getRelaProperties().put(XPDLNames.ELECSIGNATURE, NCLocator.getInstance().lookup(IPFWorkflowQry.class).isNeedCASign4Batch(PfUtilUITools.getLoginUser(), new String[] { billType }, billIdList.toArray(new String[0])));}BatchApproveModel batchApproveMode = new BatchApproveModel();batchApproveMode.setBillUI(true);batchApproveMode.setSingleBillSelected(true);batchApproveMode.setContainUnApproveBill(false);batchApproveMode.setBillItem(voAryLen);dlg = new BatchApproveWorkitemAcceptDlg(parent, noteVO);((BatchApproveWorkitemAcceptDlg) dlg).setBachApproveMode(batchApproveMode);Logger.debug("*checkWorkitemWhenApprove 2.");}} else {noteVO = NCLocator.getInstance().lookup(IWorkflowMachine.class).checkWorkFlow(actionName, billType, billvo, hmPfExParams);Logger.debug("*checkWorkitemWhenApprove 3.");if (noteVO != null && isBesideApprove(hmPfExParams)) {noteVO = BesideApprove(hmPfExParams, noteVO);} else {Object notSilent = null;if (hmPfExParams != null) {notSilent = hmPfExParams.get(PfUtilBaseTools.PARAM_NOTSILENT);}if (noteVO == null) {if (notSilent == null) {m_checkFlag = true;Logger.debug("*checkWorkitemWhenApprove 1 billType.");return noteVO;} else {noteVO = new WorkflownoteVO();}}PFClientBizRetObj retObj = executeBusinessPlugin(parent, billvo, noteVO, false);int workflowtype = noteVO.getWorkflow_type();boolean isInWorkflow = false;if (workflowtype == WorkflowTypeEnum.SubWorkApproveflow.getIntValue())isInWorkflow = true;dlg = new ApproveWorkitemAcceptDlg(parent, noteVO, billvo, isInWorkflow, isOpenedInDialog, retObj == null ? null : retObj.getHintMessage());ApproveWorkitemAcceptDlg acceptDlg = ((ApproveWorkitemAcceptDlg) dlg);if (retObj != null) {// yanke1 2012-02-22 根据前台业务处理的返回值来控制审批界面acceptDlg.setShowPass(retObj.isShowPass());
// acceptDlg.setShowNoPass(retObj.isShowNoPass());acceptDlg.setShowReject(retObj.isShowReject());}acceptDlg.setShowNoPass(!PfUtilClientAssistor.isHideNoPassing(noteVO.getTaskInfo().getTask()));Logger.debug("*checkWorkitemWhenApprove 4.");}}Logger.debug("*checkWorkitemWhenApprove 5.");if (!isBesideApprove(hmPfExParams)) {if (hmPfExParams == null) {hmPfExParams = new HashMap<String, Object>();}if (dlg.showModal() == UIDialog.ID_OK) { // 如果用户审批if (dlg instanceof ApproveWorkitemAcceptDlg) {isAutoCloseParentDialog = ((ApproveWorkitemAcceptDlg) dlg).isAutoCloseParentDialog();}m_checkFlag = true;} else { // 用户不审批m_checkFlag = false;noteVO = null;}if ((!hmPfExParams.containsKey(PfUtilBaseTools.PARAM_WORKNOTE) || hmPfExParams.get(PfUtilBaseTools.PARAM_WORKNOTE) == null) && hmPfExParams.get(PfUtilBaseTools.PARAM_BATCH) != null) {hmPfExParams.put(PfUtilBaseTools.PARAM_WORKNOTE, noteVO);}}return noteVO;}