NC31审批流程开发文档_v1.2

更新时间:2023-05-23 16:40:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

NC31审批流程开发文档_v1.2

NC31审批流程开发文档

版本:V1.2

发布日期:2005年6月 部门:NC_UAP NC31的流程平台包括业务流程和审批流程两个部分。NC31对审批流程进行了较大的改进,而业务流程还是沿用NC30版本的应用模式和功能。本文是对NC31的审批流程开发进行的规范说明。

参考文档:

1. 《NC30审批流培训文档》 2. 《NC31审批流使用文档》 3. 《NC31业务流程开发文档》

NC31审批流程开发文档_v1.2

一、 概述

NC31审批流程平台为NC各种单据的审批处理提供了一个统一的平台机制。

原有审批流应用模型(NC30版本)在一定程度上满足不了日益复杂的业务需求,定义模型也存在混淆难以理解的弊病。NC31审批流使用了新的工作流执行引擎,它要求有严格的流程定义。基于任务驱动的执行引擎使得流程流转与用户交互分离开来,具有更强的健壮性。在业务客户端应用模式上,NC31还是沿袭NC30审批流中的单据动作驱动,即通过单据动作(比如提交、审批、弃审、驳回等)来驱动流程流转。在开发模式上,完善并规范了原有的一些开发规范。本文将详细进行阐述。

二、 系统结构

三、 开发步骤

3.1

注册单据类型

单据类型是NC系统中比较重要的数据,注册在表《NC31业务流程开发文档》2.2节。

这里列出了几个与审批流相关的属性字段: bd_billtype

中,业务操作都需要用到它。参见

NC31审批流程开发文档_v1.2

单据类型编码

NC31扩展了编码最大长度为4个字符,由NC设计部统一规划和命名。一般由系统安装时预置,也可由用户自定义。

单据UI类名 语法结构如下:

从语法图可知,UI类名称一般注册为以下几种形式:

<Y>nc.ui.card.test.TestBillCardUI <Y><P>nc.ui.card.test.TestBillCardUI <N><PK>00014375433109252871 <Y><PK>0001AA00000000000494 <N>nc.ui.fa.BillCardUI nc.ui.rc.audit.CardAuditUI <P>nc.ui.fi.fiapply.FIApplyMange

注:如果某单据类型希望走审批流,建议UI类名注册为以<Y>开头。

非<PK>方式的UI类名必须实现接口nc.ui.pf.query.ICheckRetVO,参见4.8.6节。

审批流检查类 需要执行审批流的单据类型都必须注册该信息,一般由DMO或BO类实现,主要用途如下:

NC31审批流程开发文档_v1.2

1. 用于回写单据的审批状态。 2. 用于过滤活动的实际执行者。

审批流检查类需要实现的接口参见4.8节。 功能编码 对于需要执行审批流的单据类型,一般都关联有且仅有一个功能节点编码。一个用户对某单据类型拥有权限,实际上是对该功能节点拥有权限。功能编码还可用于获取查询模板。对于UI类名注册为<P>模式的单据类型,其UI类名最好与功能编码表示的功能点的UI类名保持一致。

自定义项def1

该项用于注册业务类型调整后的处理类,即单据类型与业务类型的关联关系被修改后的业务处理类。被nc.bs.pub.pf.PfSaveAfterBusi.adjustAfterBusiOp()实例化后调用。如果该项未注册,但该登录公司启用了“PO采购管理”模块,则默认处理类为nc.bs.pu.po.PoToPfDMO。

自定义项def3 动作执行前的UI端处理,被nc.ui.pub.pf.PfUtilClient.processAction()实例化后调用。该类必须实现nc.ui.pub.pf.IUIBeforeProcAction接口(参见《NC31业务流程开发文档》3.6.1节)。如果该项未注册,但单据类型编码以“D”、“E”、“F”开头,则默认为nc.ui.ep.dj.Arap_ProcAction类。

3.2开发业务单据

业务单据的开发主要包括:数据库设计、数据访问DMO、单据聚合VO、单据UI、单据动作及其执行脚本、单据动作组、单据状态组、单据函数注册、单据组件注册、VO对照表。当然还有查询模板和打印模板等。更详细的请参考UAP组织编写的《UI工厂文档——模式化快速开发手册》。 这里只对两点进行重提: 1.VO对照表pub_votable 与单据VO相互间的数据交换规则(参考NC31业务流程开发文档)不同,这里的VO对照表是用以详细描述某单据类型的。主要包括单据主子表的VO对象类名、主子表的表名等信息。其中

注:每一个需要走审批流的单据类型,其数据库表和主表聚合VO中都应该包含这几个属性字段,并将其字段名称在此注册。

NC31审批流程开发文档_v1.2

3.3定义审批流程

利用NC31的审批流设计器,根据实际业务需求设计审批流程。 参考《NC31审批流使用文档》

四、 开发指导

4.1动作处理

动作处理时序图1:

NC31审批流程开发文档_v1.2

业务

图 1非审批类动作处理

动作处理时序图2:

NC31审批流程开发文档_v1.2

图 2审批类动作处理

4.1.1 UI端调用-PfUtilClient

1. 单据动作处理(非"APPROVE")

Object nc.ui.pub.pf.PfUtilClient.processAction(Container parent,

String actionName, String billType, String currentDate, AggregatedValueObject vo, Object userObj,

String strBeforeUIClass, AggregatedValueObject checkVo ) throws Exception

功能:

1. 判断是否进行动作前提示

NC31审批流程开发文档_v1.2

2. 动作执行前的事前处理

3. 如果是新增单据后保存(动作为SAVE),或修改单据后保存(动作为SAVE或EDIT),而且单

据类型的注册类名以<Y>开头,则可能需要指派信息 4. 后台执行动作处理- PfUtilBO.processAction(…)

5. 如果动作执行的返回值为IProcActionRetObject,则进行事后前台处理

6. 如果上述过程发生异常,且异常为IPfRetException,则判断异常是否需要进行业务处

理后继续执行事后处理

7. 判断返回对象是否为PfUtilActionVO,然后前台显示

2. 单据动作处理,但不启动审批流

Object nc.ui.pub.pf.PfUtilClient. processActionNoSendMessage (

Container parent, String actionName, String billType, String currentDate, AggregatedValueObject vo, Object userObj,

String strBeforeUIClass, AggregatedValueObject checkVo ) throws Exception

功能:

1. 判断是否进行动作前提示 2. 动作执行前的事前处理

3. 后台执行动作处理-PfUtilBO.processAction(…)

4. 如果动作执行的返回值为IProcActionRetObject,则进行事后前台处理

5. 如果上述过程发生异常,且异常为IPfRetException,则判断异常是否需要进行业务处

理后继续执行事后处理

6. 判断返回对象是否为PfUtilActionVO,然后前台显示

NC31审批流程开发文档_v1.2

3. 单据动作处理("APPROVE")

Object nc.ui.pub.pf.PfUtilClient.processActionFlow(Container parent,

String actionName, String billType, String currentDate, AggregatedValueObject vo, Object userObj,

String strBeforeUIClass ) throws Exception

功能:

1. 判断是否进行动作前提示 2. 动作执行前的事前处理

3. 如果单据动作以"APPROVE"开头,检查该单据是否处于审批流中并打开审批对话框 4. 后台执行动作处理- PfUtilBO.processAction(…)

5. 如果动作执行的返回值为IProcActionRetObject,则进行事后前台处理

6. 如果上述过程发生异常,且异常为IPfRetException,则判断异常是否需要进行业务处

理后继续执行事后处理

7. 判断返回对象是否为PfUtilActionVO,然后前台显示

4. 单据动作批处理(非"APPROVE")

NC31审批流程开发文档_v1.2

Object[] nc.ui.pub.pf.PfUtilClient.processBatch(Container parent,

String actionName, String billType, String currentDate,

AggregatedValueObject[] voAry, Object[] userObjAry, String strBeforeUIClass ) throws Exception

功能:

1. 判断是否进行动作前提示 2. 动作执行前的事前处理

3. 后台执行动作处理- PfUtilBO.processBatch(…)

4. 如果返回对象为IProcActionRetObject,则按照事后业务进行处理

5. 如果上述过程发生异常,且异常为IPfRetException,则判断是否需要进行业务处理后

继续进行动作处理

参数说明:

5. 单据动作批处理("APPROVE")

Object[] nc.ui.pub.pf.PfUtilClient.processBatchFlow(Container parent,

String actionName, String billType, String currentDate,

AggregatedValueObject[] voAry, Object[] userObjAry ) throws Exception

功能:

1. 判断是否进行动作前提示 2. 动作执行前的事前处理

3. 如果单据动作以"APPROVE"开头,检查第一张单据是否可被当前操作员审批并打开审批对

话框

4. 后台执行批动作处理- PfUtilBO.processBatch(…)

NC31审批流程开发文档_v1.2

5. 如果动作执行的返回值为IProcActionRetObject,则进行事后前台处理

6. 如果上述过程发生异常,且异常为IPfRetException,则判断异常是否需要进行业务处

理后继续执行事后处理

7. 判断返回对象是否为PfUtilActionVO,然后前台显示

参数说明:

4.1.2 BS端调用-PfUtilBO

1. 单据动作处理

Object nc.bs.pub.pf.PfUtilBO.processAction(

String actionName, String billType, String currentDate,

PfUtilWorkFlowVO workFlow, AggregatedValueObject vo, Object userObj ) throws RemoteException

功能:

1. 数据加锁和一致性检查

2. 动作执行前的工作流处理(弃审或删除) 3. 进行动作约束检查

4. 执行动作脚本,并返回值

5. 如果返回值为IWorkFlowRet,则直接返回 6. 判断动作是否为最后一个动作,执行动作驱动

7. 如果动作编码以“SAVE”或“EDIT”结尾,则尝试启动审批流

NC31审批流程开发文档_v1.2

2. 单据动作批处理

Object[] nc.bs.pub.pf.PfUtilBO.processBatch(

String actionName, String billType, String currentDate,

AggregatedValueObject[] vos, Object[] userObjAry, PfUtilWorkFlowVO workflow ) throws RemoteException

功能:

1. 遍历一遍单据VO数组,进行动作执行前的工作流处理(弃审或删除)以及动作约束检查 2. 执行动作脚本,并返回值(要么为null,要么为Object[])

3. 遍历处理后的单据VO数组,判断动作是否为最后一个动作,执行动作驱动; 同时进行动

作执行后的工作流处理(依次启动审批流)。

参数说明:

4.1.3返回值

UI端PfUtilClient动作处理的返回值就是对应BS端动作处理的返回值。

BS端动作处理PfUtilBO.processAction(…)以及批处理PfUtilBO.processBatch(…)的返回值受动作脚本返回值(参见4.2.2节)的影响。

4.1.4动作驱动

在BS端PfUtilBO动作处理的过程中,在执行完动作脚本后,根据其返回值的不同可能会进行动作驱动——依次执行被驱动的单据动作脚本,同时如果被驱动动作编码为“SAVE”或“EDIT”结尾,还尝试启动审批流。比如动作驱动:

30_APPROVE->7D_PUSHSAVE 7D_APPROVE 4F_SAVE 5G_NIKE

在NC30中,执行完7D_PUSHSAVE之后,如果启动了审批流,则退出后继驱动。这是一个Bug。

NC31审批流程开发文档_v1.2

但NC31中,执行完7D_PUSHSAVE之后,如果启动了审批流,仍然遍历被驱动的动作,但不会执行同单据类型的动作。也就是说,仍然会执行4F_SAVE和5G_NIKE动作脚本,但不会执行7D_APPROVE。

不执行动作驱动的情形:

1. 动作脚本返回值为IWorkFlowRet。

2. 动作脚本返回值为Object[],且Object[0]类型为IWorkflowBatch,并指明了不进行动作驱动。 3. 当前动作非单据类型注册的结束动作。

4.2动作脚本

4.2.1执行脚本编写

动作脚本是单据动作的后台执行体。通过功能点:客户化-〉二次开发工具-〉单据管理-〉单据动作执行脚本 来进行编写。保存时会自动生成脚本class文件。在这里可以对从UI端传递过来的单据聚合VO进行业务处理,这其中就包含有对审批流的处理。该功能点为方便执行脚本的编写,提供了单据类型注册的应用组件、应用函数以及常用语法。

注意:该功能点必须在集团下使用,否则产生错误的脚本class文件。

在开发环境中,我们一般把通过功能点生成的诸如N_40_APPROVE.java动作脚本源文件导入到项目中进行开发。但如果直接对源文件进行修改,记得要修改相应的getCodeRemark()方法,否则通过功能节点打开时,将会看到不一致的脚本。

下面对单据动作脚本中与审批流相关的常用语法宏进行分析。当然,完全可以不使用下述的语法宏而直接使用Java标准语法来编写动作执行脚本。

动作脚本类图:

>>>

常用语法:

NC31审批流程开发文档_v1.2

语法宏与实际代码的对照表:

NC31审批流程开发文档_v1.2

注意:单据批动作处理必须与批量的动作脚本相对应!

4.2.2返回值

NC31审批流程开发文档_v1.2

4.3状态回写与查询

4.3.1单据审批状态

一旦单据送审到审批流中,单据便处于某个审批状态。在审批流内部,单据的内部审批状态有

5

自由态

即单据尚在编写中(已保存或尚未保存)并未提交到审批流的状态。

提交态

通过执行单据动作SAVE或EDIT,将单据送审后的状态。提交态是审批流内部的一个状态,它的回写并不通过审批流检查类进行。只能由业务组通过SAVE动作脚本自己对单据状态进行设置。所以有的业务组的单据并没有提交态的概念。

审批进行中

流程实例正处于运行中的状态。

审批完成

如果流程实例正常运行完成,该单据的审批过程即完成。审批流程结束后具有最终审批结果:通过或不通过,这也是单据的最终审批结果。

状态转换图如下所示:

NC31审批流程开发文档_v1.2

业务单据根据自己的业务需求也可定义自己的审批状态,但不可与上述5种状态相冲突。比如UI

在各个状态下对单据的业务处理(比如是否可删除、是否可编辑等)由业务组自己控制。参见节和节。

4.3.2状态回写

分为两种,一种是对单据聚合VO的回写,一种是对单据数据库表的回写。都是在动作执行脚本中完成。参见4.8.1节。

NC31审批流程开发文档_v1.2

4.3.3状态查询

后台API:

int nc.bs.pub.pf.PfUtilBO.queryWorkFlowStatus( String busiType, //业务类型PK String billType, //单据类型PK String billId) //单据Id

4.4送审

送审也称为提交,就是单据产生后进入到流程平台并启动审批流的步骤,通过调用单据动作处理来完成。审批流的触发支持两种单据动作,分别为“SAVE”和“EDIT”,即动作编码以两者结尾即可。送审后,流程平台会根据单据类型和制单人ID查找符合条件的流程定义并实例化然后启动它。如果找不到流程定义,则不启动审批流。

送审分为两种情形,一种是前台送审,即业务UI新增单据后保存并提交;另一种是后台送审,即某张单据在后台推式生成另一张单据时。

4.4.1动作处理

前台送审调用示例:

Object retObj = nc.ui.pub.pf.PfUtilClient.processAction(parentUI, “SAVE”, “D1”, “2005-05-30 12:23:44”, billVo, userObj, null, null )

如果单据数据billVo中没有保存制单人的信息,则可通过动作编码来传递。但要求原动作编码不能长于20个字符。

Object retObj = nc.ui.pub.pf.PfUtilClient.processAction(parentUI,

“SAVE”+billMakerUserId, “D1”, “2005-05-30 12:23:44”, billVo, userObj, null, null )

后台送审调用示例:

NC31审批流程开发文档_v1.2

Object retObj = new PfUtilBO().processAction(parentUI,

“SAVE”, “D1”, “2005-05-30 12:23:44”, null, billVo, userObj )

前台送审与后台送审的区别在于,前台送审会先向服务器获取流程定义中第一个审批人的可指派(参见《NC31审批流使用文档》4.1.6节)信息,以便于与客户端交互。而后台送审则默认为不可指派。

对于单张单据的送审,也可以按照批量(参见4.4.3)的方式来处理(这种应用在NC财务和供应链产品中比较常见),这时VO数组中传递的就是一张单据。

4.4.2动作脚本

送审的动作脚本没有特殊的要求,可以在脚本中进行单据VO的保存,也可以对单据VO进行更新。但如果单据UI的开发使用了UI工厂,为了维护单据数据的一致性,可在脚本中调用如下方法来保存单据并更新聚合VO。

retObj=runClass("nc.bs.trade.business.HYPubBO", "commitBill", "nc.vo.pub.AggregatedValueObject:01",vo,m_keyHas,m_methodReturnHas);

或者

SuperVO headVO = (SuperVO) billVo.getParentVO(); //主表必须为SuperVO SuperDMO dmo = new SuperDMO();

//从数据库获取到更新了ts的VO

billVo.setParentVO(dmo.queryByPrimaryKey(headVO.getClass(), headVO.getPrimaryKey()));

注意:NC30要求送审的动作脚本必须返回ArrayList或String类型的对象,在NC31中并没有这种限制了,但前提是单据聚合VO中包含有完整的单据号和单据ID信息。

4.4.3批量处理

批量送审是指多张(包括单张)单据产生后一起进行送审处理。多张单据的制单人可以相同,也可以不相同,但必须保证批处理的单据是同类型的。不同制单人的多张单据一起送审可能会启动不同的审批流程。所以对于前台的批量送审,并不会与用户交互来获取指派信息,而默认为不指派。但如果批量送审的单据VO数组中只包含一张单据,则还是会与用户交互来获取指派信息。 前台批送审调用示例:

Object retObj = nc.ui.pub.pf.PfUtilClient.processBatch(parentUI, “SAVE”, “D1”, “2005-05-30 12:23:44”, billVoAry, userObjAry, null)

后台批送审调用示例:

Object retObj = new PfUtilBO().processBatch(parentUI,

“SAVE”, “D1”, “2005-05-30 12:23:44”, billVoAry, userObjAry, null)

NC31审批流程开发文档_v1.2

4.4.4特殊应用

下面对如下几种特殊应用进行分析,

1. 对于保存/提交分离的应用,制单人保存后,由业务组控制非制单人可否提交单据;审批流会根

据单据VO中的制单人信息来获取审批流定义并启动审批流。 2. 多次提交问题:

a) 单据提交后会启动审批流,这时如果再次修改后提交,会删除旧的流程实例和工作项记录,

并重新启动审批流。

b) 如果业务组没有控制单据审批进行中的不可编辑,那么单据在审批过程中可被修改,然后

再次提交,这时执行完动作脚本后,EngineService.sendWorkFlowOnSave()会直接返回而不会再次启动审批流。

c) 单据审批完成后(即审批流程结束后),再次修改该单据并提交,这时会重新启动一个审

批流程,同时保留了原已结束流程所产生的工作项(参见《NC31审批流使用文档》4.1.13节)记录。

4.5审批

审批是登录到NC的操作员完成流程平台分配给他的工作项的过程,它是驱动流程流转的关键应用。每个工作项的审批有“通过”、“不通过”和“驳回到制单人”三种结果。关于工作项的审批结果与流程审批结果的异同,参见《NC31审批流使用文档lj》4.1.3节。

根据单据是否启动了审批流,审批分为:

有流程实例:单据送审后,根据制单人查询到流程定义,并启动了流程实例。如果对一个尚未提交的单据进行审批,会提示“单据尚未提交,无法审批。”的错误。

无流程实例:单据送审后,根据制单人查询不到流程定义,即没有启动流程实例。不管其是否提交,都不会启动审批流,任何人都可直接审批通过。这种审批由于没有流程实例和工作项,并不属于真正意义上的流程审批,更多的是进行业务处理。

根据业务需求,审批还分为两种情形,一种是前台审批,即业务UI查询到单据后进行审批或者通过待办事务来审批;另一种是后台审批,会将单据直接审批通过。后台审批只适用于无流程实例的情形,对于启动了流程实例的单据,不可进行后台审批。

4.5.1动作处理

前台审批调用示例:

Object retObj = nc.ui.pub.pf.PfUtilClient.processActionFlow(parentUI,

“APPROVE”, “D1”, “2005-05-30 12:23:44”, billVo, userObj, null)

如果单据数据billVo中没有保存当前审批人的信息,则可通过动作编码来传递。

Object retObj = nc.ui.pub.pf.PfUtilClient.processActionFlow(parentUI,

“APPROVE”+checkUserId, “D1”, “2005-05-30 12:23:44”, billVo, userObj, null,)

后台审批调用示例:

NC31审批流程开发文档_v1.2

Object retObj = new PfUtilBO().processAction(parentUI,

“APPROVE”, “D1”, “2005-05-30 12:23:44”, null, billVo, userObj )

对于单张单据的审批,也可以按照批量(参见4.5.3节)的方式来处理(这种应用在NC财务和供应链产品中比较常见),这时VO数组中传递的就是一张单据。

4.5.2动作脚本

审批的动作脚本具有特殊的要求。可对单据VO进行更新操作,也可在审批通过(分为两种,每个工作项的审批通过和整个流程的审批通过)后进行业务处理。 单张单据审批动作脚本示例:

Object m_sysflowObj = procActionFlow(vo); /** 流程仍处于审批进行中时直接返回IWorkFlowRet */ if (m_sysflowObj != null) { return m_sysflowObj; }

doBusi(getVo()); //审批流程结束(通过)后的业务处理

如果单据UI的开发使用了UI工厂,为了维护单据数据的一致性,需要在脚本中调用如下方法来更新聚合VO。

SuperVO headVO = (SuperVO) billVo.getParentVO(); //主表必须为SuperVO SuperDMO dmo = new SuperDMO();

//从数据库获取到更新了ts的VO

billVo.setParentVO(dmo.queryByPrimaryKey(headVO.getClass(), headVO.getPrimaryKey()));

4.5.3批量处理

批量审批是指当前操作员对查询到的多张(包括单张)单据一起进行审批处理。必须保证当前操作员对这些单据都具有审批权限(即都轮到他审批)。

批审批的动作脚本具有特殊的要求,可参考如下示例。

Hashtable m_sysHasNoPassAndGonging = procFlowBacth(vo) ; for (int i = 0; i < getVos().length; i++) {

Object obj = m_sysHasNoPassAndGonging.get(String.valueOf(i)); if (obj == null)

doBusi(getVos()[i]); //审批流程结束(通过)后的业务处理

}

//控制可否进行动作驱动

BatchWorkflowRet bwr = new BatchWorkflowRet(); bwr.setNoPassAndGoing(m_sysHasNoPassAndGonging); bwr.setUserObj(getVos());

return new Object[]{bwr}; //动作脚本返回值

本文来源:https://www.bwwdw.com/article/k3d4.html

Top