Saturday, April 20, 2013

AWE Workflow Application Class Criteria

I had a little trouble creating my first App Class criteria so I thought I would share some tips on how to write an App Class for use as AWE criteria. Here are the primary secrets:

  • Your App Class must extend EOAW_CRITERIA:DEFINITION:CriteriaBase (PTAF_CRITERIA:DEFINITION:CriteriaBase for 9.0 apps).
  • Your constructor must take a Record definition as a parameter.
  • Your constructor must set %Super by passing the criteria's ID. The following example uses the criteria ID value specified in the parameter record.
  • Your App Class must implement the Check(&bindRec_ As Record) Returns boolean method.

Here is a sample template:


class MyCriteria extends EOAW_CRITERIA:DEFINITION:CriteriaBase
   method MyCriteria(&REC_ As Record);
   method Check(&bindRec_ As Record) Returns boolean;

method MyCriteria
   /+ &REC_ as Record +/
   %Super = create EOAW_CRITERIA:DEFINITION:CriteriaBase(&REC_.EOAWCRTA_ID.Value);

method Check
   /+ &bindRec_ as Record +/
   /+ Returns Boolean +/
   /+ Extends/implements EOAW_CRITERIA:DEFINITION:CriteriaBase.Check +/
   REM ** TODO evaluate something here;
   Return True;


Pavan said...

Hi Jim,

I have tried using your code in my Program as Criteria , but its not working .


Jim Marion said...

@Pavan, can you elaborate? How do you know it isn't working? Are you getting an error message?

Chris said...

Jim - Thanks for your books and blog - solid stuff.

On a related note to this post, I have several step and path app package criteria working as expected. What I am struggling with is the 'definition criteria' for which i would expect a False return code to disable WF for the transaction assuming criteria is met. Now according to PBooks the definition criteria is 'used to determine which Definition ID is to be used to process the Approval'

So I am looking at either pointing to a definition that has no WF OR adding the criteria to every step...

Have you ever done something similar? Suggestion? Thanks in advance.

Chris said...

Jim - Following up on my own comment - Ii was able to continue researching and found oracle support ticket Is it Possible to Setup Approval Workflow to Work With Multiple Approval Definition IDs? [ID 1134294.1].

Essentially this boils down to the fact that you can have multiple definitions configured for each approval process - the logical path being active status, default definition and effective date. If you return a False code in the default it will continue to cycle through the the active definitions.

Thanks for letting me bounce the idea off of you, hopefully another reader finds this thread useful!

Jim Marion said...

@Chris, thank you for sharing both the problem and resolution.

A "Well" developed work flow will allow definition criteria to select the right definition. I have, however, seen work flows that hard code the definition ID. Obviously, in that case, it won't cycle through the list of definitions. And, like you said, it iterates over the collection of definitions until it finds one that returns true.It is my experience that if none return true, it will fall silently... basically the case where there is no work flow.

Chris said...

Jim -
My current expectation is that returning False in from the approval definition criteria would bypass approval for the transaction as you stated. But this is not the case for me - a false return code continues to process the default definition...unless another definition is configured. Currently i have configured another definition that will always self-approve (or i can setup the second definition to bogus criteria) but it seems odd to have to configure this separately. Once i can come up for air, i will trace to find out why. Thanks again.

Jim Marion said...

@Chris, what you are seeing is correct. If they all return false, then the default will be used. If there is no default, then there would be nothing to use.

Chris said...

Thanks again. What is your recommendation when in the following situation: IF the req has an origin of ONL then process WF else no workflow is required?

Jim Marion said...

@Chris, I'm sure there are a dozen ways to solve this. Here are a couple that came to mind:

* self approve by having the approver user list return the logged in user.

* Auto approve in the OnProcessLaunch event.

MattY said...

Hi Jim:

I have a question related to AWE notifications for a specific event. Here is what I am encountering:

For the "Final Approval" event, I have configured three separate notifications to be generated -- all with the Participant = User List (different User Lists for each).

However, I have noticed that only the FIRST of the three notifications is being generated upon Final Approval. Is this an issue with how the AWE notifications execute or is there something that can be done within configuration to ensure delivery of all notifications?


Jim Marion said...

@MattY, just to make sure I understand correctly... In the Transaction Configuration, do you have multiple rows with the same Event: "On Final Approval"? I can't say that I've tried that. I haven't looked into the code to see why it is behaving the way you described either. Perhaps there is an SQLExec in there to find rows by type rather than a loop? That would certainly behave the way you are describing. It would be nice if what you describe were supported. Perhaps an alternate method would be to create a query, app class, or SQL user list that combined all of three into a single user list? I'm sure you could make that work with an app class user list.

MattY said...

Thanks Jim. Yes - I have multiple rows in the Transaction Configuration for the same event.

The problem with combining the three different users into a single User List is that I have three different notifications that are being generated. Different content & different recipients for each.

We'll investigate to determine if we can incorporate a loop in the code so it will execute all the rows. Thx

Thor said...

Has anyone had success creating custom AWE Line Level Approval? I’m having trouble trying to get the OnLineApprove method to fire. I have header level working so I decided to dig deeper. I added the keys to the Xref table, Updated the Registry, Configured the Events, added the method to my event handler, and created a new Process Definition using line level (very simple “Always True”). I have seen OnProcessLaunch fire so my routing has begun. But when my approver hits the Approve button, it saves and nothing happens to the approval. Tracing it show that the method does not fire. How does the system know to fire the line level method vs the header level method? Any ideas are appreciated.


Jim Marion said...

@Thor, I have not worked on line level approvals. You may want to post your question on the PeopleSoft General OTN Forum.

Thor said...

Thanks Jim, I just posted the question.

Kunal Tyagi said...

Hi Jim ,
First of all, let me tell you that your posts have been immensely helpful to all the peoplesoft developers out there. They are precise, to the point and very accurate. Thank You.

Now coming to my query....

How do we get the reference to step number in the “Check” method of App Package class which is used for evaluating the Step Criteria in a AWE transaction.

I need to run this criteria for all steps in advance when the user initially clicks on submit button.So I need something which tells me what is the step “Check ” method is currently evaluating …

In UserList Class, I am able to find the reference to Step Number by using this
/*get the current step*/
&nStepnbr = %This.step.step_nbr

I need something similar in Step Criteria App Package, i have tried numerous things but no use, kindly help me out .

Jim Marion said...

@Kunal, a very good question. I do not know the answer off the top of my head. What I can't remember is the contents of the constructor &REC parameter and the check &bindRec parameter. You should print out the names of those records (log file or something). If the &bindRec has all of the header values, etc, then you could get a reference to the ApprovalManager which has an AppInst, stage and txn.

Please post back when you figure it out.

satish kumar said...


Can we pass values to the class, like POI_ID. If yes, Can you please eloborate.


satish kumar said...


Can we pass parametes to the definition criteria or Can we capture the non keys from cross reference record. I need PO_ID, Is there any way, please elaborate.

Jim Marion said...

@Satish, short answer to both questions is "yes." You do this through one of the two records passed into the constructor or the check method. Unfortunately, I like I told @Kunal, I can't remember what those record variables contain. I wish I had documented that piece. I recommend printing the record names. From there, you can determine the SQL needed to investigate the transaction records or xref values.

Srini.B.Reddy said...

Hi Jim,
I used the code from your book 'webservice enabling approvals' to update the approval status using sync service. When there are multiple approval steps (this is Requisition process), only first step gets approved whereas the subsequent steps are updated to skipped and the Requisition status is updated to approved.
When approved from the online page, it is routed to the next step/ approver just fine.
Any pointers for me on what to look for?

Jim Marion said...

@Srini, Congratulations on getting the web service working! I have only done header level approvals and have not looked into the line level approvals API.

Srini.B.Reddy said...

Hi Jim,
I am doing header level approval too. But when there are multiple approval steps, first step is approved and the second one's status turns to skipped.
Whereas if I approve from the online page, it gets routed to second step just fine. I am not understanding what am I doing differently when I call doapprove?

Saurav Suman said...

Hello Jim,

First of all many thanks for the blog. Secondly, I'm working on Line level AWE. I need some help.

Suppose I've 5 lines for approval. 3 of them for level 1 approval and other two will undergo level 1 approval followed by level 2 approval.

On the second level approval page, I want to show only the 2 lines that need approval and the approval status of these two in monitor. Not for all the 5.

Please help me how it can be achieved.


Jim Marion said...

@Saurav, I have no experience with line level approvals. I suggest you post your question on the PeopleSoft OTN Discussion Forum.

Pavan Chaitanya N said...


Auto-approve is not working in one of our client after upgrading the tools from 8.52 to 8.53.

My process has "Auto Approval" checkbox enabled and "self approval" for that particular step is enabled with "Always True" criteria.

It's a line level approval.

Can you please help me??

Jim Marion said...

@Pavan, I suggest you log a support case with Oracle support for something like this.

Pavan Chaitanya N said...

Thanks for the reply Jim.. Few days back i was facing problem in Self-approval.. the code you shared in this blog was very helpful...Thanks a lot for that..

Pavan Chaitanya N said...


Gone through Chapter 3 i.e Workflow configuration.. it is very informative :)

Jim Marion said...

@pavan, I am very glad that you find this information and the book content useful.

Saeem Ahamed said...

Hi Jim, I have a small problem with my AWE. I have two steps in my awe. When user creates a request the AWE got triggered to the Step1 userlist and the Monitor Showed clearly Step1: Pending and Step2:Not routed.

Then I went and logged in as the Step1 user and approved. But this time it dint trigger the Worklist to the second step userlist.

The thread status for this transaction is still in P Pending. The stepstatus for the first step is in Pending and for the second step it is N Notrouted.

Below is a snippet of my AWE component savepostchange code. Please help me , Am I missing anything.

import HMAF_AWE:ApprovalsFactory;
import HMAF_AWE:INTERFACES:ILaunchManager;
import HMAF_AWE:INTERFACES:IApprovalManager;
import HMAF_AWE:INTERFACES:IStatusMonitor;
import HMAF_AWE:*;

/*Declare local and component object variables*/

Local HMAF_AWE:ApprovalsFactory &AprvFactory;
Local HMAF_AWE:INTERFACES:IApprovalManager &AprvMgr;
Component HMAF_AWE:INTERFACES:IStatusMonitor &Monitor;
Local HMAF_AWE:INTERFACES:ILaunchManager &LaunchMgr;

/*Declare variables*/
Component Record &HDR_REC;

Component string &AprvProcId, &strAction;

/*GetHeader Rec*/

&prcs_name = "MYPROCESSID";

Local string &Transaction_Name = &prcs_name;
Local Record &EOTransRec = CreateRecord(Record.EO_TRANSACTIONS);
&EOTransRec.TRANSACTION_NAME.Value = &prcs_name;
&AprvProcId = &EOTransRec.PTAFPRCS_ID.Value;

/*Create Approvals Factory*/

&AprvFactory = create HMAF_AWE:ApprovalsFactory();

/*Create launch manager object*/

&LaunchMgr = &AprvFactory.getLaunchManager(&AprvProcId, &HDR_REC, %OperatorId);

rem &LaunchMgr.DoSubmit();
/* Submit approval process */

/* create approval manager object */
If &strAction = "P" Then

If &LaunchMgr.hasAppDef And
&LaunchMgr.submitEnabled Then

&AprvMgr = &AprvFactory.getApprovalManager(&AprvProcId, &HDR_REC, %OperatorId);

&AprvMgr = &AprvFactory.getApprovalManager(&AprvProcId, &HDR_REC, %OperatorId);

&ActionTaken = True;
Evaluate &strAction
When "A"
When "D"
When "B"
&AprvMgr.DoPushback(&HDR_REC); /***Push back***/
&ActionTaken = False;

I have both the steps correctly configured

Jim Marion said...

@Saeem, I don't see anything wrong with your code. You may want to post your question on the PeopleSoft General Discussion OTN Forum.

Saeem Ahamed said...

Hi Jim,

Thank You very much for the speedy reply. I made it work and now the worklist got triggered to the Second Level also.

I missed this piece of code
If &ActionTaken Then
&appInst = &AprvMgr.the_inst;
&Monitor = &AprvFactory.getStatusMonitor(&appInst, "D", Null);
&strAction = " ";

But Now a new problem has arised. When i try to access the link for the second level approver , nothing is happening the page is staying as it is. No action is happening, its not taking me to the approval page.

Buit for the first level approval this worklist link worked and took me to the Appr component.

Can you please help me where I should debug. Or am I missing something.

Thank You

Saeem Ahamed said...

Hi Jim,

Am I missing any configuration. I have the following foursteps configured in the transaction:

Onfinal Denial.
Onfinal Approval.
Route for Approval
and On Process Launch.

Should I include OnStepComplete.

Jim Marion said...

@Saeem, only implement the methods you are actually using. If you don't have logic in OnStepComplete, then you should not implement it.

Tom Mannanchery said...

Hi Jim,

I have a question regarding Escalation Notifications in AWE. Normally escalations are set at the Path Level in AWE (via 'Details' on the path). Is it possible to apply Escalations on a Step level?


Jim Marion said...

@Tom, great question. Unfortunately, I don't know the answer. I suggest you ask it on the PeopleSoft General OTN Forum. search of new said...

Hi Jim,

I have followed exact same steps for AWE as you suggested in Book. But i am stuck in error "Class extends another, but has no constructor." I am posting same code here:
import PTAF_CORE:DEFN:UserListBase;

class WebAsset_ApprUserList extends PTAF_CORE:Defn:UserListBase
method WebAsset_ApprUserList(&rec_ As Record);
method GetUsers(&aryPrevOpr_ As array of string, &thread_ As Record)
Returns array of string;

rem %Super = create PTAF_CORE:DEFN:UserListBase(&rec_);

rem WebAsset_ApprUserList super= new &WebAsset_ApprUserList;
rem super = create PTAF_CORE:DEFN:UserListBase(&rec_);

rem create PTAF_CORE:DEFN:UserListBase(&rec_);

method WebAsset_ApprUserList
/+ &rec_ as Record +/
rem %Super = create PTAF_CORE:DEFN:UserListBase(&rec_);

%Super = create PTAF_CORE:DEFN:UserListBase(&rec_);

method GetUsers
/+ &aryPrevOpr_ as Array of String, +/
/+ &thread_ as Record +/

/+ Returns Array of String +/
/+ Extends/implements PTAF_CORE:DEFN:UserListBase.GetUsers +/
Local array of string &oprid_arr = CreateArrayRept("", 0);
Local SQL &admin_sql = CreateSQL("SELECT ROLEUSER " | "FROM PSROLEUSER WHERE ROLENAME = 'Portal Administrator'");
Local string &oprid; Local number &counter = 1;
While &admin_sql.Fetch(&oprid)
If (Mod(&counter, 2) = 0) Then
&counter = &counter + 1;
Return &oprid_arr;

Jim Marion said...

Is this a 9.1 or later application? If so, try using the EOAW classes instead of PTAF classes. PTAF were only in 9.0 applications. Oracle renamed the AWE classes in 9.1 to EOAW. Likewise, change all of your other configurations, etc, to use the EOAW versions (including tables). search of new said...

hi Jim,

Its 9.0 application only for Campus solution but tools are on 8.53.

Does that make any effect on coding of AWE??

Also i searched for EOAW but there are no packages like this name.

Jim Marion said...

That is correct. There is no EOAW in Campus 9.0. I do not have experience with AWE in Campus 9.0. I have heard of customers using it in 9.0 Campus. You might try posting your question on the PeopleSoft OTN General discussion forum. Be sure to note your app and tools release when you post your question.

William Galusz said...

This looks Great...

I wish to create 1 user List App package ,
I have 7 User lists L1,L2,L3,L4 the SQL is the same except the Code type

I noticed in 8.54 there is a new thing called User List Attributes

So my thought is One app Package and Based on the Attribute in the user list perform I can adjust what I need to get done..

My Question .. How Do I get User List Attributes for that specific User list... Or even if i figure out the tables how do I get the Userlist ID that it is running..


Saeem said...

Hi Jim,

Can you please help me with this problem. I have my AWE configured and everything is working perfect except for the AWE monitor.

In my AWE monitor I am not able to expand the Comments section. Nothing happens when I click on the Comments expand button.

Please Help

Jim Marion said...

@Saeem, you may need to file a support case for that.

Jack Richard said...

Hi Jim,

We are configuring AWE for Absence management and we have bit different requirement,

We need to specify the job level depending on the Grade field to specify whether leave should be Auto Approved or workflow should be triggered.

IF Grade <300 then approval required
IF Grade >300 Then Auto approved
IF Grade C1,C2 then Approval required
IF Grade P1,P2 then Auto approved.

Can you please help me what is the best way we can achieve this?

I have tried using User entered criteria but it is not working for me.

Also can you help me how the peoplesoft system evaluates the User Enter criteria ?

Jim Marion said...

@Jack, I wish I could, but I'm not familiar enough with that specific workflow to speak intelligently about it. I suggest posting your question on the PeopleSoft General OTN Forum

Jack Richard said...

Hi Jim,

I have placed my query to General discussion forum. But no reply yet.

Anyways, If I want to try with custom app package then the suggestions you provided above, at which all other places I need to include/change peoplecode? I have never tried with app package so not sure how to do this.

It would be very helpful for me if you provide any example end to end.


Jim Marion said...

@Jack/Rashmin, First you create your App Class in Application Designer and then you assign it in the criteria section. You do not need to change any delivered code. If you are new to Application Classes, then you may find value in my chapter on creating Application Classes.

Jack Richard said...

Hi Jim,

First of all, Thanks a bunch for providing the such an informative book on peoplesoft..!!

Then Thanks to you for your quick help. I always find very helpful information on your blog.

Just one question came in my mind.

I have prepared a new app class and wrote a check method to apply my custome validations (As I mentioned in my earlier comment, Grade related validations from JOB).

Now, as you suggested, I will assign it in the criteria section and will perform necessary testing.

So is that all do I need to do OR anything else apart from this that I need to take care ?


Jim Marion said...

@Jack, yes, that is it.

Jack Richard said...

Hi Jim,

Thakns a bunch for your quick help..!! I always find your blog very useful and also refer it to some of my friends and juniors to learn the things. Again thanks a lot for making this blog and helping the people. :)

I have created the App class with my custom validations.
Now, for one of the validation, I need to fetch reg_region field from JOB and to do so I need EMPLID, EFFDT, EMPL_RCD, EFFDT etc.

So I need help to know which record will be there in parameter of check method and how can I get the above details in custom app class.


Jim Marion said...

@Jack, it has been so long since I reviewed this, I can't remember what&REC_ and &bindRec_ contain. If I were investigating this, I would print &REC_.Name and &bindRec.Name to a log file.

Jack Richard said...

Hi Jim,

Thanks for all you rsupport and this blog. I got all requirement and have created a app class and it is working fine.
Below are few points that I have researched and might be helpful to our other friends.

1. Parameter for the Check Procedure is nothing but a XREF record.
2. If you use the "User Entered" criteria type to provide criteria for your workflow, then below keep in mind the below points.
- you should have few common keys in between the header record & the record you are selecting in User entered criteria.
- Make sure your selected record fetches only top most row per employee. If not then you can create a new view to fetch top most row.


William Galusz said...

Really quick question

I created an appPackage for my criteria... I am using the criteria in Multiple Stages

How do i Figure out what Stage I am processing at any point of time

I am assuming it is GetStageNbr from Some where

Jack Richard said...

You must need to set the WORKFLOW trace for the same. You might need to change the code little bit, but you will get the step by step information on that.

William Galusz said...

Question About WorkFlow Monitor

I want to Reassign a user on a workflow I created...

On the requesition and Expense Sheet It works as expected...
Reassigns to new User , Sets work list to worked and creates a now Work List for the new user..

But on a New Workflow It Reassigns the New User, Sets the worklist to worked BUT it does not create the new work list entry... Am I missing some setting somewhere

William Galusz said...

Found the Issue, Needed to setup a Re-Assign event and all worked out great..

Ashwin jain said...


How to confirm on clicking on a transaction whether this is final step in my AWE.
As I have to make certain fields editable on final step.

I know we can write SQL. However I found the function GetPendingSteps() also but not sure how to use it for the same. Is there any function or code which can help me with this will be great.