PeopleSoft AWE 审批状态机原理与实战配置指南
发布时间:2026/9/18 20:30:36来源:尧图网络
简介本资源是一份面向PeopleSoft开发工程师与HCM系统实施人员的AWEApproval Workflow Engine工作流配置实战指南聚焦费用报销审批流程的端到端落地解决审批规则动态路由、角色权限映射、跨层级多级审批如500元分界线触发VP介入等典型业务场景。文档以PT8.50FSCM9.1Oracle技术栈为基础完整覆盖许可权列表与用户概要配置、基础数据表X_EXP_RPT_HDR/LINE等与页面组件开发、交叉引用表设计、以及核心ApprovalEventHandler类的继承与方法重载实现附录含全部PeopleCode与SQL脚本。资源为单文件PDF大小1.59MB内容精炼、步骤清晰、图示标注到位适合作为AWE二次开发的速查手册与教学范例。目前已有155人学习下载特别适合刚接触PeopleSoft审批引擎、需快速掌握AWE标准配置路径与常见避坑要点的中初级开发者。1. PeopleSoft AWE 工作流不是“配个按钮就跑”而是用 EOAW_CORE 构建可追溯、可分支、可中断的审批状态机很多人第一次接触 PeopleSoft Approval Workflow EngineAWE时以为只是在 PIA 界面点几下“添加步骤”“选角色”填个金额阈值就完事。但实际踩过坑就会发现审批流程卡在“已提交”不动、经理点了批准却没触发副总裁环节、Status Monitor 显示空白或 KeyName12345 而非“报销单#789”——这些都不是界面操作失误而是底层状态机未对齐、事件处理器未覆盖关键路径、或审批上下文未正确绑定导致的。这份《PeopleSoft工作流配置[整理].pdf》之所以被反复传阅正因为它用一个真实可运行的费用报告场景金额分阶审批把 AWE 的核心约束讲透了它不是线性流程图而是一个基于EOAW_CORE:ENGINE:AppInst实例驱动的状态引擎每个审批动作Approve/Deny/Hold/Pushback都必须由ApprovalEventHandler的对应方法显式响应所有业务状态更新如EXP_HDR_STATUS RAP必须发生在OnHeaderApprove或OnStepComplete中而非页面按钮的 FieldChange 里。适合刚接手 HCM 9.1 或 FSCM 9.1 审批模块的开发人员也适合需要将旧版 PT8.49 工作流迁移到 AWE 的运维工程师——尤其当你发现EOAW_XREF_SBR子记录必须置于交叉引用表首位、且业务主键不能设为物理主键时这份文档给出的实操边界比官方白皮书更早暴露问题。2. 从零构建 AWE 基础结构Record/Page/Component/Menu 的命名规范与权限绑定逻辑AWE 的稳定性始于基础对象的严格命名与权限隔离。本节不只罗列创建步骤而是解释为什么X_EXP_RPT_HDR必须带_HDR后缀、为什么X_APPGD_WK要声明为 Derived Work Record、以及为何三个测试用户必须从 VP1 拷贝而非新建——这些细节直接决定后续SetAppKeys()调用能否成功获取业务主键。2.1 Record 设计头表、行表、审批表与工作表的职责分离PeopleSoft AWE 要求业务数据与审批元数据解耦。文档中创建的四张 Record 并非随意命名而是遵循EOAW_CORE的契约X_EXP_RPT_HDR头表存储费用报告主信息必须包含REPORT_DEFN_ID字段作为唯一业务主键该字段将在OnProcessLaunch中被SetAppKeys()提取并注入审批实例。X_EXP_RPT_LINE行表明细数据用于OnAllLinesProcessed事件批量处理其REPORT_DEFN_ID作为外键关联头表。X_EXP_APPROVAL审批表记录每次审批操作Approver、Status、Timestamp字段APPROVAL_STATUS的值域必须与OnHeaderApprove中硬编码的RAP、OnHeaderDeny中的DNA严格一致否则状态机无法识别。X_APPGD_WK工作表Derived 类型仅用于审批页面显示控制如按钮显隐不可写入数据库其字段APPROVAL_PB、DENY_PB等需在 PeopleCode 中通过DisplayOnly/Visible属性动态控制。注意X_APPGD_WK的 Derived 属性是强制要求。若误设为 SQL TableGetRecord(Record.X_APPGD_WK)在FieldChange中会因无物理存储而抛出Invalid record reference异常且 Status Monitor 初始化失败。2.2 Page 与 Component 的发布策略权限列表绑定的双重校验机制两个 PageX_EXP_RPT_R员工填报页、X_EXP_RPT_A经理审批页必须封装进同名 Component但发布权限有本质区别Component发布目标权限列表实际访问控制逻辑关键原因X_EXP_RPT_RX_1010员工 X_1020经理 手动添加X_1030VP员工可填报经理/VP 可查看但禁止修改防止审批人篡改原始申请数据所有状态变更必须经ApprovalEventHandler触发X_EXP_RPT_A仅发布到X_1020和X_1030经理和 VP 可审批员工访问时页面报错或空白AWE 要求审批页面的 Component 必须与审批用户角色严格匹配否则ApprovalManager初始化时GetParticipant(%UserId)返回空字符串验证权限是否生效的命令在 PIA 中执行-- 查询用户 XTEST2经理是否拥有 X_1020 权限列表 SELECT * FROM PSROLEUSER WHERE ROLEUSER XTEST2 AND ROLENAME IN ( SELECT ROLENAME FROM PSROLEDEFN WHERE ROLENAME IN (X_1020) );若返回空则X_EXP_RPT_A页面对 XTEST2 不可见PostBuild中的createStatusMonitor将因approvalMgr.the_inst为 Null 而崩溃。2.3 Menu 创建与导航路径避免因菜单项缺失导致 Launch Manager 失效X_MENU不仅是导航入口更是 AWE 启动的上下文载体。必须确保Menu ItemX_EXP_RPT_R指向 ComponentX_EXP_RPT_R且Component Name 与 Menu Item Name 完全一致大小写敏感Menu ItemX_EXP_RPT_A指向 ComponentX_EXP_RPT_A且该 Menu Item 必须分配给X_1020和X_1030权限列表若使用 Portal 导航需在PORTAL_URL中显式传递PAGEX_EXP_RPT_R参数否则SavePostChange中的%Component值可能为空导致 Launch Manager 不触发。常见错误在 PIA 中测试时点击X_EXP_RPT_R成功但SavePostChange无反应。此时检查Component Properties → Security → Permission List是否勾选X_1010并确认X_MENU的X_EXP_RPT_R项在Permission List标签页中已分配X_1010。3. AWE 核心配置交叉引用表、事件处理器与事务处理注册的三重校验AWE 的审批逻辑不依赖数据库触发器而由EOAW_CORE运行时引擎驱动。这要求交叉引用表结构、事件处理器方法签名、事务处理注册参数三者必须精确对齐任一偏差都会导致流程静默失败。3.1 交叉引用表X_EXP_RTP_XREFEOAW_XREF_SBR子记录的强制前置规则X_EXP_RTP_XREF是 AWE 的“路由地图”其结构违反常规数据库设计原则-- 正确的 DDL 结构Oracle CREATE TABLE X_EXP_RTP_XREF ( -- EOAW_XREF_SBR 子记录字段必须前置不可省略 PROCESS_INSTANCE NUMBER(10) NOT NULL, STEP_INSTANCE NUMBER(10) NOT NULL, USER_INSTANCE NUMBER(10) NOT NULL, -- 业务主键字段必须跟在子记录后且不可设为主键 REPORT_DEFN_ID VARCHAR2(10) NOT NULL, -- 其他业务字段... EFFDT DATE ); -- 注意REPORT_DEFN_ID 不能设为 PRIMARY KEY -- 物理主键只能是 PROCESS_INSTANCE STEP_INSTANCE USER_INSTANCE ALTER TABLE X_EXP_RTP_XREF ADD CONSTRAINT PK_X_EXP_RTP_XREF PRIMARY KEY (PROCESS_INSTANCE, STEP_INSTANCE, USER_INSTANCE);提示若将REPORT_DEFN_ID设为 Primary KeySetAppKeys(threadRecord)在OnProcessLaunch中会因无法匹配EOAW_XREF_SBR的复合主键而返回空记录导致hdrRecord.SelectByKey()失败后续Update()抛出No rows found异常。3.2ExpEventHandler类覆盖关键生命周期方法的最小必要集文档中的ExpEventHandler继承自EOAW_CORE:ApprovalEventHandler但并非所有方法都需要重载。根据费用报告需求必须实现以下 5 个方法其余可留空方法名触发时机业务逻辑要求文档中关键代码片段OnProcessLaunch流程启动后将头表状态设为PNDPending并调用SQLExec(SQL.X_UPD_APPR_STATUS, I, ...)记录启动日志hdrRecord.EXP_HDR_STATUS.Value PND; hdrRecord.Update();OnHeaderApprove所有审批人完成后将头表状态设为RAPApproved必须在此处更新业务状态hdrRecord.EXP_HDR_STATUS.Value RAP; hdrRecord.Update();OnHeaderDeny任一审批人拒绝后将头表状态设为DNADenied终止流程hdrRecord.EXP_HDR_STATUS.Value DNA; hdrRecord.Update();OnStepPushback审批人退回上一步时必须存在空实现即使无业务逻辑否则引擎抛出Method not implemented错误end-method;空方法体OnTerminate流程被管理员强制终止时将头表状态设为DENTerminatedhdrRecord.EXP_HDR_STATUS.Value DEN; hdrRecord.Update();未实现OnStepPushback的典型错误日志Error: Method OnStepPushback not implemented in class ExpEventHandler.此时即使页面显示“退回成功”审批实例仍停留在ACTIVE状态GetPendingSteps()持续返回非空数组。3.3 事务处理注册X_HDR_VW视图与交叉引用表的字段映射验证事务处理注册界面PIA → PeopleTools → Workflow → Transaction Registry中X_EXPApproval事务必须绑定Approval Header Record:X_HDR_VW非X_EXP_RPT_HDRCross Reference Record:X_EXP_RTP_XREFBusiness Key Field:REPORT_DEFN_ID必须与X_HDR_VW中的字段名完全一致X_HDR_VW视图定义示例OracleCREATE OR REPLACE VIEW X_HDR_VW AS SELECT a.REPORT_DEFN_ID, a.EXP_HDR_STATUS, a.OPRID_APPROVED_BY, a.APPROVAL_DTTM FROM X_EXP_RPT_HDR a; -- 关键VIEW 必须包含 REPORT_DEFN_ID且不能有 GROUP BY 或聚合函数若X_HDR_VW缺失REPORT_DEFN_IDSetAppKeys(threadRecord)将无法提取主键OnProcessLaunch中的hdrRecord.SelectByKey()返回空状态更新失效。4. 审批流程编排多级条件路由与 Status Monitor 的动态渲染逻辑AWE 的核心价值在于支持复杂条件分支。费用报告案例中“金额500仅经理审批≥500需VP追加审批”的逻辑不是靠 IF 语句硬编码而是通过事务处理配置中的“标准Criteria”和“路径Path”实现这要求开发者理解 AWE 的路由决策树。4.1 审批步骤配置Step 1 与 Step 2 的条件表达式语法在 PIA → PeopleTools → Workflow → Approval Process → Define Steps 中Step 1部门经理审批的“标准”配置为X_EXP_RPT_HDR.AMOUNT 500Step 2副总裁审批的“路径”配置为X_EXP_RPT_HDR.AMOUNT 500注意AWE 的条件表达式不支持 SQL 函数如TO_NUMBER()且字段名必须与头表X_EXP_RPT_HDR中的物理字段名完全一致区分大小写。若字段名为AMT则条件必须写X_EXP_RPT_HDR.AMT 500写成AMOUNT将静默忽略该路径。验证条件是否生效的方法在OnProcessLaunch中添加调试日志method OnProcessLaunch / appInst as EOAW_CORE:ENGINE:AppInst / Local Record threadRecord, hdrRecord; threadRecord CreateRecord(Record.X_HDR_VW); appInst.thread.SetAppKeys(threadRecord); hdrRecord CreateRecord(Record.X_EXP_RPT_HDR); hdrRecord.REPORT_DEFN_ID.Value threadRecord.REPORT_DEFN_ID.Value; hdrRecord.SelectByKey(); /* 调试输出金额和当前步骤数 */ MessageBox(0, , 0, 0, Amount | hdrRecord.AMOUNT.Value | , Steps | appInst.GetStepCount()); ... end-method;若MessageBox显示Amount600, Steps1说明 Step 2 未触发需检查X_EXP_RPT_HDR.AMOUNT字段类型是否为NUMBER非CHAR。4.2 Status Monitor 渲染从 KeyName12345 到报销单#789 的定制化改造默认 Status Monitor 显示REPORT_DEFN_ID789用户体验差。文档第 11 步提供改造方案核心是重写threadDescr类import EOAW_CORE:*; import EOAW_MONITOR:MONITOR:*; class threadDescr extends EOAW_MONITOR:MONITOR:threadDescr method threadDescr(); method GetThreadDescription(appInst As EOAW_CORE:ENGINE:AppInst) Returns string; end-class; method threadDescr %Super create EOAW_MONITOR:MONITOR:threadDescr(); end-method; method GetThreadDescription / appInst as EOAW_CORE:ENGINE:AppInst / Returns string Local Record hdrRecord; Local string desc; hdrRecord CreateRecord(Record.X_EXP_RPT_HDR); hdrRecord.REPORT_DEFN_ID.Value appInst.GetAppKey(REPORT_DEFN_ID); hdrRecord.SelectByKey(); desc 报销单# | hdrRecord.REPORT_DEFN_ID.Value | - | hdrRecord.DESCRLONG.Value; Return desc; end-method;然后在createStatusMonitor调用中指定该类Local object threadDescr create X_EXP_APPROVALS:threadDescr(); createStatusMonitor(theAppInst, D, savebtnLogic, False, threadDescr);提示GetThreadDescription方法中appInst.GetAppKey(REPORT_DEFN_ID)是安全的因为OnProcessLaunch已确保REPORT_DEFN_ID被注入AppInst。若此处SelectByKey()失败desc将为报销单# - 需检查X_EXP_RPT_HDR表中是否存在该REPORT_DEFN_ID。5. Launch Manager 与 Approval Manager 的协同机制SavePostChange 中的时序陷阱与防御性编程AWE 的启动Launch与审批Approval由两个独立 Manager 驱动但它们共享同一个审批实例AppInst。SavePostChange中的代码顺序稍有不慎就会导致状态不一致——例如员工提交后状态变为PND但经理审批时OnHeaderApprove却未执行。5.1 Launch Manager 的启动条件与防重提交逻辑X_EXP_RPT_R.SavePostChange中的启动逻辑必须满足三个前提状态检查仅当X_EXP_RPT_HDR.EXP_HDR_STATUS.Value OPNOpen时才启动实例清理调用launchMgr.TerminateRunningProcess()清除可能存在的僵尸流程提交策略按restartEnabled/resubmitEnabled/submitEnabled顺序判断避免重复提交同一笔申请。完整防御性代码If X_EXP_RPT_HDR.EXP_HDR_STATUS.Value OPN Then Local Record EXPrecord; Local object savebtnlogic; EXPrecord CreateRecord(Record.X_HDR_VW); GetLevel0()(1).GetRecord(Record.X_EXP_RPT_HDR).CopyFieldsTo(EXPrecord); launchMgr create EOAW_CORE:LaunchManager(X_EXPApproval, EXPrecord, %UserId); launchMgr.definition SHARE; /* 使用共享定义非私有 */ /* 关键先终止再提交防止并发重复 */ launchMgr.TerminateRunningProcess(); launchMgr.PrepareToSubmit(); If launchMgr.restartEnabled Then launchMgr.DoRestart(); Else If launchMgr.resubmitEnabled Then launchMgr.DoResubmit(); Else If launchMgr.submitEnabled Then launchMgr.DoSubmit(); /* 提交成功后强制刷新状态 */ X_EXP_RPT_HDR.EXP_HDR_STATUS.Value PND; DoSave(); End-If; End-If; End-If; End-If;5.2 Approval Manager 的审批动作与按钮控制联动X_EXP_RPT_A.SavePostChange中的审批逻辑必须与页面按钮状态同步/* 获取当前审批实例 */ approvalMgr create EOAW_CORE:ApprovalManager(X_EXPApproval, EXPrecord, %UserId); usteps approvalMgr.GetPendingSteps(); Evaluate GetRecord(Record.X_EXP_APPROVAL).APPROVAL_STATUS.Value When A approvalMgr.DoApprove(EXPrecord); /* 关键DoApprove 触发 OnHeaderApprove */ Break; When D approvalMgr.DoDeny(EXPrecord); /* 触发 OnHeaderDeny */ Break; When H approvalMgr.DoHold(EXPrecord); /* 触发 OnStepHold */ Break; When E approvalMgr.DoPushback(EXPrecord); /* 触发 OnStepPushback */ Break; End-Evaluate; /* 按钮控制仅当有未处理步骤时显示审批按钮 */ If approvalMgr.hasPending Then DiplayBtn(); /* 显示 APPROVAL_PB 等 */ Else HideBtn(); /* 隐藏所有按钮 */ End-If;关键参数说明approvalMgr.DoApprove(EXPrecord)的EXPrecord必须是X_HDR_VW类型且已通过CopyFieldsTo从头表同步数据。若传入X_EXP_RPT_HDROnHeaderApprove中的appinst.thread.SetAppKeys(threadRecord)将因字段名不匹配而失败。6. 排查 AWE 流程卡顿的四大日志断点与 SQL 验证脚本当审批流程停滞在“已提交”或“等待审批”时不要盲目重启服务。AWE 的状态流转全部记录在PSAEAPPRCST和PSAEAPPRCSTDET表中结合 PeopleCode 日志可精准定位卡点。6.1 四大必查日志断点位置断点位置检查内容失败表现应对措施OnProcessLaunch开头MessageBox输出Amount和Steps无输出 → Launch Manager 未触发检查X_EXP_RPT_R.SavePostChange中EXP_HDR_STATUS是否为OPN及DoSubmit()是否执行OnStepActivate中stepinst.GetStepName()输出步骤名无输出 → 步骤未激活检查事务处理中 Step 1 的“标准”是否匹配及X_EXP_RPT_HDR.AMOUNT值是否符合预期OnHeaderApprove开头hdrRecord.EXP_HDR_STATUS.Value输出当前状态输出OPN→ 状态未更新检查hdrRecord.Update()是否成功及X_EXP_RPT_HDR表是否有UPDATE权限createStatusMonitor后浏览器控制台console.log输出theAppInst对象undefined→ AppInst 为空检查ApprovalManager初始化时EXPrecord是否包含REPORT_DEFN_ID6.2 验证审批实例状态的 SQL 脚本Oracle直接查询数据库确认流程状态-- 1. 查看所有活跃审批实例 SELECT PROCESS_INSTANCE, BUSINESS_PROCESS, ACTIVITY_NAME, STATUS, LASTUPDDTTM FROM PSAEAPPRCST WHERE BUSINESS_PROCESS X_EXPApproval ORDER BY LASTUPDDTTM DESC; -- 2. 查看某实例的详细步骤替换 123456 为 PROCESS_INSTANCE SELECT STEP_INSTANCE, STEP_NAME, STEP_STATUS, APPROVER_ID, LASTUPDDTTM FROM PSAEAPPRCSTDET WHERE PROCESS_INSTANCE 123456 ORDER BY STEP_INSTANCE; -- 3. 检查交叉引用表是否正确关联 SELECT a.PROCESS_INSTANCE, a.REPORT_DEFN_ID, b.EXP_HDR_STATUS FROM X_EXP_RTP_XREF a JOIN X_EXP_RPT_HDR b ON a.REPORT_DEFN_ID b.REPORT_DEFN_ID WHERE a.PROCESS_INSTANCE 123456;若PSAEAPPRCST.STATUS AActive但PSAEAPPRCSTDET.STEP_STATUS CCompleted且无下一步说明条件路由配置错误需检查 Step 2 的X_EXP_RPT_HDR.AMOUNT 500是否成立。6.3 快速验证审批用户列表的 SQL 查询确保X_1020经理和X_1030VP用户列表已正确加载-- 查询经理列表假设使用角色 X_1020 SELECT DISTINCT b.ROLEUSER AS USERID, c.NAME1 AS NAME FROM PSROLEDEFN a JOIN PSROLEUSER b ON a.ROLENAME b.ROLENAME JOIN PSOPRDEFN c ON b.ROLEUSER c.OPRID WHERE a.ROLENAME X_1020; -- 查询副总裁列表 SELECT DISTINCT b.ROLEUSER AS USERID, c.NAME1 AS NAME FROM PSROLEDEFN a JOIN PSROLEUSER b ON a.ROLENAME b.ROLENAME JOIN PSOPRDEFN c ON b.ROLEUSER c.OPRID WHERE a.ROLENAME X_1030;若返回空则OnStepActivate中的stepinst.GetApprovers()将返回空数组审批任务无法生成。本文还有配套的精品资源点击获取
网站建设高端定制企业官网