Wednesday, November 14, 2012

AWE Mass Approval

The sample chapter for my PeopleTools Tips and Techniques book (Chapter 3) contains all of the steps required to add AWE to a PeopleSoft transaction. A colleague who recently used this chapter to AWE enable a transaction asked me how to mass approve transactions. Most of the code required to mass approve transactions is actually on the last page of Chapter 3. Here is an expanded template with placeholders. Just wrap this in a loop and wire it up to a button, App Engine, or some other execution environment.

Local Record &headerRec = CreateRecord(Record.NAME_OF_AWE_HEADER_RECORD);  
Local EOAW_CORE:ApprovalManager &apprManager;  
Local string &processId = /* hard coded value goes here */;  

REM ** Populate approval header record keys here;
&headerRec.GetField(Field.KEY1).Value = /* Key 1 from scroll */
&headerRec.GetField(Field.KEY2).Value = /* Key 2 from scroll */
...

&apprManager = create EOAW_CORE:ApprovalManager(&processId, &headerRec, %OperatorId);  

If (&apprManager.hasAppInst) Then  
  &apprManager.DoApprove(&headerRec);  
Else  
  REM ** throw error;  
End-If;

Each time through the loop, update the header record values, acquire a new instance of the ApprovalManager, and execute DoApprove.

30 comments:

peterparker - Servant of BHAGWAN PARASHURAMA said...

Hi Jim,

I have found that lot of people still struggle with AWE. I believe that massive configurations and application packages make people go confusing. Any way to fix this out?

Jim Marion said...

@peterparker, A lot of the existing AWE configurations use complex transactions and complex approval rules. That is true, and it makes AWE difficult to use. Like anything, it is best to start small and simple. From there, you can get more complex. EFFDT'd transactions further complicate AWE configurations.

For someone learning AWE, I recommend starting with a very simple transaction. Start with a simple level 0 custom transaction. Chapter 3 of my Tips and Techniques book takes this approach. A developer could even AWE enable the User Profile component or something simple like that component.

rohan tyagi said...

Jim, Sorry to put this question here. This is not related to the post however I could not find a place to ask a question separately.
Q: We have student admin application which communicates with the portal side to get a value for the field through synchronous message service. The default time out for the connector (PSFTTARGET) is 5 minutes. Is there a way to reset it to a lower number. Peoplebooks suggest a way to reset properties of HTTP listening connector but not for default PSFTTARGET connector.

Thanks in advance
_Rohan

Jim Marion said...

@Rohan, you might try that one on the PeopleSoft OTN forum. I don't recall trying to change the timeout.

rohan tyagi said...

I will put this question there. Thanks for a quick response.

Raj_Indiran said...

Hi Jim,

thanks for your code Mass approval...


I have tried it and working fine for mass approval header level.

Is there any code or delivered application package to approve line level like the same?

Regards
Rajendran

Jim Marion said...

@Raj, I am glad you were able to successfully implement header level approvals. Yes, line level is possible, but I haven't worked with it.

weilies said...

I try to create a mass approve absence during a fieldChange (button click)

here is my code
====================================

import EOAW_CORE:ApprovalManager;

Local Record &headerRec = CreateRecord(Record.GP_ABS_SS_DAT);
Local EOAW_CORE:ApprovalManager &apprManager;
Local string &processId = "HF_Absence_Mgmt";



REM ** Populate approval header record keys here;
&headerRec.GetField(Field.TRANSACTION_NBR).Value = "1021";
&headerRec.GetField(Field.EMPLID).Value = "SG00013";
&headerRec.GetField(Field.EMPL_RCD).Value = "0";
&headerRec.GetField(Field.BGN_DT).Value = Date3(2014, 1, 10);
&headerRec.GetField(Field.PIN_TAKE_NUM).Value = "250935";
&headerRec.GetField(Field.END_DT).Value = Date3(2014, 1, 10);

&headerRec.SelectByKey();
&apprManager = create EOAW_CORE:ApprovalManager(&processId, &headerRec, %OperatorId);

If (&apprManager.hasAppInst) Then
MessageBox(0, "x", 0, 0, "Success and approved");
&apprManager.DoApprove(&headerRec);
Else
REM ** throw error;
MessageBox(0, "x", 0, 0, "Error... missing App Instance");
End-If;


===================================

It's a delivered workflow header record so i didn't create any additional configurations.


System keep prompt me "Error... missing App Instance (0,0)"
But i have no idea what are the missing code line

Thanks for the pointers

Jim Marion said...

@weilies, instances are OPRID specific. Did the user executing this code have instances?

weilies said...

Hi Jim, i would like to create a scheduled AE to perform the mass approval process. so the %oprid could be the scheduled user i suppose?

Jim Marion said...

@Weilies, the OPRID you pass into the ApprovalManager does NOT need to be the logged in user. It does, however, have to be the OPRID of the current owner of the approval instance. If the schedule user is the one responsible for the current step, then yes, %OperatorID will work.

weilies said...

The error comes from
"If (&apprManager.hasAppInst) Then"

it couldn't find any app instance.
Here is the setup for AWE http://s22.postimg.org/cyeuochmn/awe.png

with the code mentioned above, i wonder what's still missing.

Thanks for the pointer.

Jim Marion said...

@Weilies, exactly. That is where it would fail. Are you using the OPRID that has an instance? You don't have to be logged in as the user. You just have to pass in the correct OPRID to find the instance. Otherwise, it won't find an instance.

weilies said...

Here is the monitor approval detail
http://s27.postimg.org/gm55qce7l/monitor_approval_detail.jpg

Abs requestor: SG00013
Next approval: KL0006
if i were to approve via monitor approval component then it will not have any issue.


But if i am going to use following code (hardcoded %operatorId to approval)
==================================
import EOAW_CORE:ApprovalManager;
Local Record &headerRec = CreateRecord(Record.GP_ABS_SS_DAT);
Local EOAW_CORE:ApprovalManager &apprManager;
Local string &processId = "HF_Absence_Mgmt";


REM ** Populate approval header record keys here;
&headerRec.GetField(Field.TRANSACTION_NBR).Value = "1021";
&headerRec.GetField(Field.EMPLID).Value = "SG00013";
&headerRec.GetField(Field.EMPL_RCD).Value = "0";
&headerRec.GetField(Field.BGN_DT).Value = Date3(2014, 1, 10);
&headerRec.GetField(Field.PIN_TAKE_NUM).Value = "250935";
&headerRec.GetField(Field.END_DT).Value = Date3(2014, 1, 10);

&headerRec.SelectByKey();
&apprManager = create EOAW_CORE:ApprovalManager(&processId, &headerRec, "KL0006");

If (&apprManager.hasAppInst) Then
MessageBox(0, "x", 0, 0, "Success and approved");
&apprManager.DoApprove(&headerRec);
Else
REM ** throw error;
MessageBox(0, "x", 0, 0, "Error... missing App Instance");
End-If;
==================================
And i execute it in FieldChange, it always prompt out
"Error... missing App Instance"

based on the search keys provided, i am not sure what's still missing and causing the API not able to instantiate.

Jim Marion said...

@Weilies, everything you typed there looks good. If the Process ID is spelled correctly, then it should work. The only thing I can think of is possibly some new security check within AWE to verify the OPRID? The OPRID parameter was actually there so you could pass alternate OPRID's, but who knows if something changed? Did you try running it as user KL0006? It should make no difference, but just curious.

weilies said...

@Jim, thanks for the prompt reply.

approach A:
1. changed the code to
&apprManager = create EOAW_CORE:ApprovalManager(&processId, &headerRec, %OperatorId);
2. Login as KL0006
3. Click a FieldChanged Event to trigger codes above

approach B:
1. changed the code to
&apprManager = create EOAW_CORE:ApprovalManager(&processId, &headerRec, "KL0006");
2. Login as KL0006
3. Click a FieldChanged Event to trigger codes above


both produced same result as below:
http://s28.postimg.org/t9jl49qt7/KL0006.jpg

Jim Marion said...

@weilies, I am at a loss. I assume there is a delivered page where you would normally perform the approval? I suggest you open that page/component and search for the PeopleCode that performs the approval. It might be easier to just turn on a PeopleCode trace, perform the approval, and then search the trace file, since you know you will be looking for ApprovalManager, etc. The approval on the component should use code that is very similar to what you are coding. Hopefully this will point out any discrepancies.

Unknown said...

Hi Jim
I have question on AF. Not sure if there is any other way I can send you the query.
In PeopleSoft FCSM 9.1,Is there any way where user can submit multiple Journals for approval in one go. Currently user has to go to individual journal & click on ‘Submit’ button to trigger approval.
Thanks in advance
Mahesh

Jim Marion said...

@Mahesh,

Yes, you can perform mass approvals. I am not sure if there is anything delivered, but you can write something using the EOAW App Classes.

BlackSheep said...

Hi Jim,

The code you had given seems to invoke single approval in a loop.

I came across some code which does not use "EOAW_CORE:ApprovalManager" but uses "EOAW_MASS_APPROVALS:CLIENT:MassApprovalsClient" to carry out mass approval.

Internally it gets invoked by the service operation "EOAW_APPROVALS" which is of operation type "Asynchronous - One Way".

Can you please comment on the same?

Local EOAW_MASS_APPROVALS:CLIENT:MassApprovalsClient &MassApprovalsClient;

&MassApprovalsClient = create EOAW_MASS_APPROVALS:CLIENT:MassApprovalsClient( True, True);

For &i = 1 To &levelTFX.ActiveRowCount
If &levelTFX.GetRow(&i).SUP_OB_APR_WRK.SELECT_PB.Value = "Y" Then
SQLExec("SELECT EOAWDEFN_ID, EOAWPRCS_ID, EOAWTHREAD_ID, EOAWPARENT_THREAD FROM PS_TFX_AW_ACTN_VW WHERE TFX_ID = :1 AND EOAWSTEP_STATUS IN ('P')", &TfxId, &temp_eoawdefn_id, &temp_awprcs_id, &temp_awthread_id, &temp_parent_thread);
&return_code = &MassApprovalsClient.AddApproval(&temp_eoawdefn_id, &temp_awprcs_id, &temp_awthread_id, &temp_parent_thread, %OperatorId, "A", &Comments);
End-If;
End-For;

&MassApprovalsClient.Submit();

Thanks,
BlackSheep

Jim Marion said...

@BlackSheep. That is great, thank you for sharing.

Ken Kaspersen said...

Just passing along similar code for approving reported time within HCM. I first attempted to use the "&ApprMgr.DoApprove(&HdrRec);" method to approve the entire batch of reported time. That ran without any error, but did not seem to accomplish anything. In other words, the time was still stuck in 'Needs Approval' status and the AWE rows were all in 'Pending'. Had no luck debugging that, so switched to the following method using the line level approval. Seems to work fine.

It seem like PeopleSoft might provide a PeopleBooks section (similar to the API guide) for their App Package methods and properties. Maybe I'm missing it, but I usually find taking advantage of the wealth of App Classes already out there involves too much trial and error. If they were documented a bit, they'd be much more useful.

At any rate, this blog was a big help along the way ... so thanks for everyone's notes. And of course, thanks to Jim!

Regards,
Ken

&AprvFactory = create HMAF_AWE:ApprovalsFactory();

REM Create and format header record;
&HdrRec = CreateRecord(Record.TL_APP_HDR);
&HdrRec.TRANSACTIONID.Value = TL_APP_AET.TRANSACTIONID.Value;
&HdrRec.EOAWDEFN_ID.Value = TL_APP_AET.EOAWDEFN_ID.Value;
&HdrRec.EMPLID.Value = TL_APP_AET.EMPLID.Value;
&HdrRec.EMPL_RCD.Value = TL_APP_AET.EMPL_RCD.Value;
&HdrRec.PUNCH_TYPE.Value = TL_APP_AET.PUNCH_TYPE.Value;

&kcApprMgr = &AprvFactory.getApprovalManager("TLReportedTime", &HdrRec, &sOprID);

/* Fill a Rowset with the Line data for this Transaction */
&rsLine = CreateRowset(Record.TL_APP_RPT_LINE);
&rsLine.Fill("where EMPLID =:1 and EMPL_RCD =:2 and PUNCH_TYPE =:3 and TRANSACTIONID =:4", &HdrRec.EMPLID.Value, &HdrRec.EMPL_RCD.Value, &HdrRec.PUNCH_TYPE.Value, &HdrRec.TRANSACTIONID.Value);

/* Execute the 'DoApproveRowset' Delivered Method */
/* This sets the Reported Time to Approved (along with all the related AWE tables */
&kcApprMgr.DoApproveRowSet(&rsLine);

Jim Marion said...

@Ken, thanks for sharing.

Rampi said...

Hi Jim

I would like to know whether we can do mass re-assignments? I am only a beginner in AWE having implemented few custom AWE frameworks and my question would be, is it possible to run a batch process to perform mass re-assignments?

Thanks
Praveen

Jim Marion said...

@Praveen, great question. I have not looked into that use case.

Ankit said...

I am trying to run the delivered Voucher Mass Approve VCHR_APRV_WF. The AE is wriiten in such a way that if there are no Vouchers in "Pending for Approval Status", the process will check if there are any vouchers to be submitted "Submit for Approval"(calls the DoSubmit()Section :- VCHRAFAP.Step01). In my case there are no Vouchers to be approved so the process goes to the section (VCHRAFAP.Step01) which calls DoSubmit().
I got the below error while running this process

"Message not found - 18081, 5703, URL not set (18081,5703) EOAW_UTILITIES.Portal.portalURL.OnExecute Name:getServletURL_ PCPC:5012 Statement:68 Called from:EOAW_UTILITIES.Portal.portalURL.OnExecute Name:GenerateComponentPortalURL Statement:40 Called from:EOAW_CORE.DEFN.AWTxn.OnExecute Name:GetNotifyURLOverride Statement:350 Called from:EOAW_CORE.NOTIFICATION.InlineStrategy.OnExecute Name:ProcessNotifications Statement:67 Called from:EOAW_CORE.NotificationEventHandler.OnExecute Name:ProcessNotif"

Jim Marion said...

@Ankit, AWE uses URL definitions to determine the portal URL. Make sure you set values for the appropriate URL definitions.

Sarah D said...

Hello, I am having an issue w Approval Monitor as well. I hope it is a pretty easy fix I am just over looking.

I set up my process id in Monitor Configuration.
If I go to User Monitor I can see the set up process id when i search w the magnifying glass.
However, if i go to MOnitor Approval I do not see it.
Yes, my user id is linked to the appropriate Role I set up in Monitor Configuration.

This set up is on the client side. I set it up the same way in a Demo environment from my company and it worked ok. So there is a setting somewhere that I am missing...

Any assistance is appreciated!!

Sarah D said...

Well, I randomly tried removing the Role configured in Monitor Configuration and then added back into my profile.
I was then successfully able to see my process id in Monitor Approval.

Sometimes these things are a bit crazy ;)!

GVK said...

Hey Jim,

I am trying to add new translate value to EOAWSTEP_STATUS for AP Voucher Mass Approve so while approving i want to pass new translate value using following code %This.UpdateStatus(&utils.STEP_STATUS_MASS_APPRV) in EOAW_CORE:UserStepInst in method Approve.Code is updating the EOAW_USERINST table EOAWSTEP_STAtUS to new translate value but not on the EOAW_STEPINST table.How to update the EOAW_STEPINST table?