Enhancing Activity Guides

This section discusses how to enhance the usage and implementation of activity guides including:

  • Using PeopleCode to enhance activity guides.

  • Creating a custom activity guide data type.

  • Defining activity guide system options.

The activity guide framework provides multiple methodologies for using PeopleCode to implement and customize activity guide usage in your system including:

  • Initializing activity guide instances.

    Whether an activity guide is created dynamically or manually, each instance created from a template can be initialized through a PeopleCode method that you define specifically for this purpose.

  • Performing pre-processing for action items.

    You can define a PeopleCode application class and method to perform pre-processing on an action item before the target transaction is displayed to the user. In addition to performing this pre-processing, the method must also redirect to the target transaction. In addition, Oracle recommends that you develop this application class and method by implementing and extending the PT_RCF:ServiceAGInterface interface class.

    Alternatively, pre-processing can be performed in an iScript that must also specify and transfer the user to the target transaction.

  • Performing post-processing for action items.

    You can define another PeopleCode method to perform post-processing on an action item after the user has completed the task. Post-processing can occur on the local system or the remote system if that’s where the transaction is hosted.

  • Developing custom navigation buttons.

    The navigation frame provides default navigation buttons to allow a user to move to the next or previous action item. You can create additional navigation buttons—for example, to allow a user to manually mark an action item as complete or to cancel the activity guide instance altogether.

  • Dynamically returning an image URL as context data.

    You can define a method to use defined context data to dynamically return an image URL as additional context data.

  • Performing pre-processing for the activity guide pagelet.

    You can define a PeopleCode method to perform pre-processing that will be executed every time the activity guide pagelet is loaded or reloaded in the WorkCenter pagelet area.

  • Creating an activity guide instance dynamically.

    While the browser interface provides pages that allow you to manually create activity guide instances, more typically, you will create activity guide instance dynamically from activity guide templates as the result of user actions.

Whether an activity guide is created dynamically or manually, each instance created from a template can be initialized through a PeopleCode method that you define specifically for this purpose. This method is identified on the Advanced Options page for the activity guide template.

In the following example, the InstanceIDCreation class implements and extends the delivered PTAI_ACTION_ITEMS:AGInterface class. This InstanceCreation method implements the delivered abstract method.

import PTAI_ACTION_ITEMS:*;
import PTAI_ACTION_ITEMS:AGInterface;
import PTAI_COLLECTION:Collection:*;
import PTAI_ACTION_ITEMS:Member:*;


class InstanceIDCreation implements PTAI_ACTION_ITEMS:AGInterface
   method InstanceCreation(&list As PTAI_ACTION_ITEMS:List);
end-class;


/**
* Sets the Instance items status to Assigned and Assigned to Operator ID to %User id.
**/
method InstanceCreation
   /+ &list as PTAI_ACTION_ITEMS:List +/
   /+ Extends/implements PTAI_ACTION_ITEMS:AGInterface.InstanceCreation +/
   
   Local array of string &childItemIds;
   Local integer &i;
   Local boolean &return;
   Local string &ptai_mbr_name, &ptai_mbr_type, &ptai_privset_ID, &ListID, &templateID, &templatelabel;
   
   Local PTAI_ACTION_ITEMS:ActionItem &item;
   Local PTAI_COLLECTION:Collection &members, &buttons, &contextfields;
   Local PTAI_ACTION_ITEMS:Member &member;
   Local PTAI_ACTION_ITEMS:Privilege &privileges;
   Local PTAI_ACTION_ITEMS:PgltButtons &button;
   
   &list.Status = "IP";
   SQLExec("Select PTAI_PARENT_TMPL From PS_PTAI_LIST Where PTAI_LIST_ID = :1 ", &list.ListId, &templateID);
   
   rem get the template label;
   SQLExec("Select PTAI_LABEL From PS_PTAI_LIST Where PTAI_LIST_ID = :1 ", &templateID, &templatelabel);
   
   &list.Label = &templatelabel;
   &return = &list.save();
   
   <*
   rem the button label and method;
   &buttons = create PTAI_COLLECTION:Collection();
   
   &button = create PTAI_ACTION_ITEMS:PgltButtons("Cancel", "CancelAG");
   &buttons.InsertItem(&button);
   
   &button = create PTAI_ACTION_ITEMS:PgltButtons("Continue Later", "ExitAG");
   &buttons.InsertItem(&button);
   
   rem leave the code here if the Ben Admin decides to use the mark task complete pushbutton;
   rem the label can be changed from Mark Task Complete' to another label based on the Ben Admin needs;
   rem the parameter MarkComplete must NOT be removed. This is the app method that executes code for the button;
   
   rem &button = create PTAI_ACTION_ITEMS:PgltButtons("Mark Task Completed", "MarkComplete");
   rem &buttons.InsertItem(&button);
   
   &list.SavePgltBtn(&buttons);
   
   
   *>
   
   Rem change the status of the action items;
   &childItemIds = &list.getActionItems();
   
   For &i = 1 To &childItemIds.Len
      &item = create PTAI_ACTION_ITEMS:ActionItem();
      &item.open(&childItemIds [&i]);
      &item.Status = "1";
      /*
         &item.PackageRoot = "W3EB_LIFE_EVENT";
         &item.QualifyPath = ":";
         &item.AppClassID = "ItemStatus";
      */
      &item.AssignedToOprid = %OperatorId;
      &item.AssignType = "USER";
      &return = &item.save();
      
   End-For;
   
   Rem Save the logged in UserID for security and privileges;
   
   &members = create PTAI_COLLECTION:Collection();
   
   &members = &list.getMembers();
   &ptai_mbr_name = %UserId;
   &ptai_mbr_type = "USER";
   
   SQLExec("Select PTAI_PRIVSET_ID From PS_PTAI_PRIVSET Where DESCR = 'Contributor' and PTAI_FEATURE = 'AI' AND ACTIVE_FLAG = 'A' AND PTAI_SYSTEM_ITEM = 'Y' ", &ptai_privset_ID);
   
   
   &member = create PTAI_ACTION_ITEMS:Member(&ptai_mbr_name, &ptai_mbr_type);
   &member.PrivilegeSetID = &ptai_privset_ID;
   &members.InsertItem(&member);
   &list.saveMembers(&members);
   
end-method;

You can define a PeopleCode application class and method to perform pre-processing on an action item before the target transaction is displayed to the user. In addition to performing this pre-processing, the application class and method must redirect to the target transaction. Alternatively, you can implement this functionality in an iScript instead of in an application class.

To implement pre-processing for an action item in an application class and method:

  1. Define an application class that extends the PT_RCF:ServiceAGInterface.

  2. Define the execute method, which implements and extends the execute method in the base class.

  3. Set the %This.StrRedirectUrl property to redirect to the target transaction.

  4. Append the %This.StrAGQueryParameter property to the end of the generated component URL.

  5. Create a related content service definition for this application class.

  6. In the Action Item Details grid, select App Class URL as the link type and select the related content service definition.

The following example shows the PTAI_AGPKG_UNINAV:TestPreProcessing, which implements and extends the PT_RCF:ServiceAGInterface base class:

import PT_RCF:ServiceAGInterface;
import PTAI_ACTION_ITEMS:*;

class TestPreProcessing extends PT_RCF:ServiceAGInterface
   method execute();
end-class;

method execute
   /+ Extends/implements PT_RCF:ServiceInterface.execute +/
   
   Local PTAI_ACTION_ITEMS:ActionItem &ObjAItem;
   Local boolean &boolSaved;
   Local string &market;
   
   &ObjAItem = create PTAI_ACTION_ITEMS:ActionItem();
   &ObjAItem.open(%This.StrActionItemId);
   If &ObjAItem.Status <> "4" Then
      &ObjAItem.Status = "2";
   End-If;
   &boolSaved = &ObjAItem.save();
   
   &market = %Market;
   If None(&market) Then
      &market = "GBL";
   End-If;
   
   %This.StrRedirectUrl = GenerateComponentContentURL(%Portal, %Node, MenuName.PTUN_MENU, &market, Component.PTUN_REMOTENODECFG, Page.PTUN_REMOTENODECFG, "") | %This.StrAGQueryParameter;
end-method;

You can define a PeopleCode application class and method to perform post-processing on an action item after the user has completed the transaction—for example, to update the status of the action item to complete. For post-processing, the method name must be called ItemPostProcess. Post-processing can occur on the local system or the remote system if that’s where the transaction is hosted.

Important! Post-processing can occur on the local system or the remote system if that’s where the transaction is hosted. Post-processing is executed through component save processing only. If you have implemented a custom save button on the page to save the component, the button’s page field properties must be configured to invoke the toolbar save action or the PeopleCode executed by these buttons must include either the DoSave or DoSaveNow built-in functions to trigger the component save events; otherwise, the post-processing specified here will not be executed.

Example 1

In the first example, the class has been developed by implementing and extending the PTAI_ACTION_ITEMS:AGInterface interface class, which is optional and not required. The ItemPostProcess method defines the post-processing that will occur for this action item.

import PTAI_ACTION_ITEMS:AGInterface;
import PTAI_ACTION_ITEMS:ActionItem;
import PTAI_ACTION_ITEMS:Constants;

class IB_GATEWAY implements PTAI_ACTION_ITEMS:AGInterface
   method IB_GATEWAY();
   rem method InstanceCreation(&list As PTAI_ACTION_ITEMS:List);
   rem method PageletPreProcess(&list As PTAI_ACTION_ITEMS:List);
   rem method ItemPreProcess(&item As PTAI_ACTION_ITEMS:ActionItem);
   method ItemPostProcess(&list_id As string, &item_id As string, &Nodename As string);
end-class;

/* constructor */
method IB_GATEWAY
end-method;

method ItemPostProcess
   /+ &list_id as String, +/
   /+ &item_id as String, +/
   /+ &Nodename as String +/
   /+ Extends/implements PTAI_ACTION_ITEMS:AGInterface.ItemPostProcess +/
   Local PTAI_ACTION_ITEMS:Constants &PTAI_CONSTANTS = create PTAI_ACTION_ITEMS:Constants();
   Local PTAI_ACTION_ITEMS:ActionItem &item = create PTAI_ACTION_ITEMS:ActionItem();
   Local boolean &ret;
   Local string &connurl;
   Local string &defaulturl = "http://machinename:port/PSIGW/PeopleSoftListeningConnector";
   Local number &count;
   
   /*** Debug Test ***/
   rem MessageBox(0, "", 0, 0, "I'm being triggered");
   
   &item.open(&item_id);
   /*** Add logic to check for step completion ***/
   SQLExec("select connurl from psgateway where local_flag='Y'", &connurl);
   SQLExec("select count(*) from psconn", &count);
   
   If All(&connurl) And
         (&connurl <> &defaulturl) And
         &count > 0 Then
      &item.Status = &PTAI_CONSTANTS.STATUS_COMPLETED;
   Else
      &item.Status = &PTAI_CONSTANTS.STATUS_IN_PROGRESS;
   End-If;
   
   /*** Save the Action Item State ***/
   &ret = &item.save();
end-method;

Example 2

In this second example, the ItemPostProcess method includes conditional logic that handles execution differently depending on whether the transaction is on the local node or a remote node. If the ItemPostProcess method is executing on the remote node for the remote transaction, then it uses the PTAI_UPDATEITEM service operation to update status on the local node.

import PTAI_ACTION_ITEMS:*;

Declare Function SecuritySyncMessage PeopleCode PTUN_NODECFGDVW.PTUN_BTN FieldFormula;
Declare Function IsLocalNode PeopleCode PSPTCSSRVDEFN.PTCS_SERVICEURLTYP FieldFormula;

method ItemPostProcess
   /+ &list_id as String, +/
   /+ &item_id as String, +/
   /+ &Nodename as String +/
   Local boolean &boolSaved;
   Local PTAI_ACTION_ITEMS:ActionItem &ObjAItem;
   Local PTAI_ACTION_ITEMS:Constants &AIConstants;
   Local string &Status, &Priority;
   Local string &Required;
   Local number &PercCompl, &Seqno;
   
   &AIConstants = create PTAI_ACTION_ITEMS:Constants();
   /* Test values */
   &Status = &AIConstants.STATUS_COMPLETED;
   &Priority = "1";
   &Required = "Y";
   &PercCompl = 100;
   rem &Seqno = 35;
   If Not IsLocalNode(&Nodename) Then
      Local Message &Req_Msg, &Response;
      Local XmlDoc &requestDoc;
      Local number &i1;
      Local XmlNode &currentParamsNode;
      Local array of XmlNode &SuccessNode, &errorNode;
      Local string &ResponseXml;
      Local SOAPDoc &TransformedDoc;
      
      &Req_Msg = CreateMessage(@("Operation." | "PTAI_UPDATEITEM"), %IntBroker_Request);
      &requestDoc = CreateXmlDoc(GetHTMLText(HTML.PTAI_UPDATEITEM_REQ, %UserId, GetHTMLText(HTML.PTAI_UPDATEITEM_REQ_PARAMS, &item_id, &list_id, &Nodename, &Priority, &Status, &Required, &PercCompl, &Seqno)));
      &Req_Msg.SetXmlDoc(&requestDoc);
      
      &Response = SecuritySyncMessage(&Req_Msg, &Nodename, "PTAI_UPDATEITEM");
      If &Response <> Null Then
         &ResponseXml = &Response.GenXMLString();
         &TransformedDoc = CreateSOAPDoc(&ResponseXml);
         &SuccessNode = &TransformedDoc.DocumentElement.GetElementsByTagName("SAVESUCCESS");
         &errorNode = &TransformedDoc.DocumentElement.GetElementsByTagName("ERRORMSG");
         
         If &SuccessNode <> Null And
               &SuccessNode.Len = 1 Then
            rem do nothing;
         End-If;
         If &errorNode <> Null And
               &errorNode.Len = 1 Then
            Error "Error from Application hosting Activity Guide : " | &errorNode [1].NodeValue;
         End-If;
      Else
         Error "No Response from IB";
      End-If;
   Else
      &ObjAItem = create PTAI_ACTION_ITEMS:ActionItem();
      &ObjAItem.open(&item_id);
      &ObjAItem.Status = &Status;
      &ObjAItem.Priority = &Priority;
      If &Required = "Y" Then
         &ObjAItem.Required = True;
      Else
         &ObjAItem.Required = False;
      End-If;
      &ObjAItem.PercCompl = &PercCompl;
      If All(&Seqno) Then
         &ObjAItem.Sequence = &Seqno;
      End-If;
      &boolSaved = &ObjAItem.save();
   End-If;
end-method;

The fluid banner (in guided mode) or the navigation frame of the classic WorkCenter provide default navigation buttons to allow a user to move to the next or previous action item. You can create additional navigation buttons—for example, to allow a user to manually mark an action item as complete or to cancel the activity guide instance altogether. Custom navigation buttons are defined on the Pagelet Options page for a template or instance and can be overridden per action item on the Configure Related Data page.

In classic activity guides, these buttons are displayed in the navigation frame of the classic WorkCenter. For fluid activity guides, some of these items are rendered as buttons and some are rendered as links in the Actions list depending on the feature implemented, the activity guide mode (guided or non-guided), and the width of the device or browser used to access the activity guide.

Note: For classic activity guides, Oracle recommends that you add no more than two additional custom navigation buttons.

Important! In custom navigation buttons, do not attempt component buffer access or use think-time functions such as MessageBox, WinMessage, or others.

Reserved Method Names

Certain reserved method names are recognized for use with guided activity guides. For some reserved method names (for example, MarkComplete and SubmitAGProcess), you must implement custom PeopleCode to perform the designated operation. In other cases (for example, PTAI_NAV_SAVE and PTAI_NAV_AUTO_SAVE), specifying the reserved method name will invoke delivered functions subject to the implementation requirements.

Method Name

Function

How to Implement

ExitAGProcess

Use this method to render a custom Exit button to run PeopleCode (for example, to display a warning message) prior to exiting the activity guide.

Implement the ExitAGProcess method as custom PeopleCode. See PTAI_UTILITIES:Utilities for an example.

MarkComplete

Use this method to render a custom Mark Complete button to allow a user to manually mark an action item as complete.

Implement the MarkComplete method as custom PeopleCode. See PTAI_UTILITIES:Utilities for an example.

ReturnToQuestionnaire

Use this method to render a custom Return to Questionnaire button to delete the current activity guide instance and return the user to the questionnaire page.

Implement the ReturnToQuestionnaire method as custom PeopleCode. See PTAI_UTILITIES:Utilities for an example.

SubmitAGProcess

Use this method to render a custom Submit button that must be placed on the final step of SUOW and single component activity guides. When a user clicks this Submit button, two operations occur in this order:

  1. Data added and modified by the user is submitted and then committed to the database.

  2. Your custom SubmitAGProcess program is executed. This method must set the activity guide instance status to complete and then save the instance.

Implement the SubmitAGProcess method as custom PeopleCode. See PTAI_UTILITIES:Utilities for an example.

PTAI_NAV_AUTO_SAVE

Use this method to introduce auto-save functionality for the built-in Next and Previous buttons for non-sequential, guided fluid activity guides.

Note: Auto-save is enabled for sequential and single unit of work activity guides automatically.

No additional implementation is required.

PTAI_NAV_SAVE

Use this method to render a custom Save button to invoke the transaction page’s Save button to save the current action item.

  1. At the template level, define PTAI_NAV_SAVE as a configurable field on the Template Properties: Advanced Options page.

  2. For each action item that requires this save functionality, you must map the HTML field ID of the Save button on the page to the configurable field.

    Use your browser’s built-in web developer tools to determine the HTML field ID. For pages that display the standard PeopleTools Save button, the HTML field ID is #ICSave.

    Then, specify this field ID as the value of the PTAI_NAV_SAVE configurable field on the action item’s Configure Related Data page.

PTAI_NAV_SAVE_NEXT

Use this method to combine the save action into the Next button, which invokes the transaction page’s Save button to save the current action item and then display the next action item.

Note: Use this method in classic activity guides only.

  1. At the template level, define PTAI_NAV_SAVE_NEXT as a configurable field on the Template Properties: Advanced Options page.

  2. For each action item that requires this save functionality, you must map the HTML field ID of the Save button on the page to the configurable field.

    Use your browser’s built-in web developer tools to determine the HTML field ID. For pages that display the standard PeopleTools Save button, the HTML field ID is #ICSave.

    Then, specify this field ID as the value of the PTAI_NAV_SAVE_NEXT configurable field on the action item’s Configure Related Data page.

PTAI_NAV_SAVE_PREV

Use this method to combine the save action into the Previous button, which invokes the transaction page’s Save button to save the current action item and then display the previous action item.

Note: Use this method in classic activity guides only.

  1. At the template level, define PTAI_NAV_SAVE_PREV as a configurable field on the Template Properties: Advanced Options page.

  2. For each action item that requires this save functionality, you must map the HTML field ID of the Save button on the page to the configurable field.

    Use your browser’s built-in web developer tools to determine the HTML field ID. For pages that display the standard PeopleTools Save button, the HTML field ID is #ICSave.

    Then, specify this field ID as the value of the PTAI_NAV_SAVE_PREV configurable field on the action item’s Configure Related Data page.

Custom Exit Button

In the following example for a classic activity guide, the Exit button that invokes this custom method exits the activity guide and the WorkCenter and returns the user to his or her default homepage.

Note: Exit is not a reserved method name and is different from ExitAGProcess, which is a reserved name.

Declare Function getHomepageURLForPortal PeopleCode FUNCLIB_PTBR.FUNCLIB FieldFormula;

method Exit
   /+ &list_id as String +/
   /+ Returns String +/
   
   Return getHomepageURLForPortal(%Portal);
   
end-method;

You can define a method to use defined context data to dynamically return an image URL as additional context data.

In the following example, the EMPLID is defined as context data, which is used to dynamically generate the image URL to the employee’s photo:

import PTAI_ACTION_ITEMS:*;
import PTAI_ACTION_ITEMS:AGInterface;
import PTAI_COLLECTION:Collection:*;
...

class AG implements PTAI_ACTION_ITEMS:AGInterface
   method getEmployePhoto(&oCtxt As PTAI_COLLECTION:Collection) Returns string;
   ...

end-class;


method getEmployePhoto
   /+ &oCtxt as PTAI_COLLECTION:Collection +/
   /+ Returns String +/
   Local integer &i = 1;
   While &i <= &oCtxt.Count
      If ((&oCtxt.Item(&i) As PTAI_ACTION_ITEMS:ContextData).fieldname = "EMPLID") Then
         Local Rowset &rs = CreateRowset(Record.EMPL_PHOTO);
         Local string &strEmplID = (&oCtxt.Item(&i) As PTAI_ACTION_ITEMS:ContextData).keyValue;
         &rs.Fill("where EMPLID =:1", &strEmplID);
         Return %Response.GetImageURL(&rs.GetRow(1).GetRecord(Record.EMPL_PHOTO));
      End-If;
      &i = &i + 1;
   End-While;
end-method;

You can define a pagelet pre-processing method that will be executed every time an activity pagelet is loaded or reloaded in the WorkCenter pagelet area. This method must be named PageletPreProcess. The application class containing this method is identified on the Pagelet Options page.

In the following example for the Unified Navigation pagelet, each time the pagelet is reloaded, the PageletPreProcess method creates a link for Manage Related Content for each remote system configured under unified navigation.

import PTAI_ACTION_ITEMS:ActionItem;
import PTAI_ACTION_ITEMS:List;
import PTAI_ACTION_ITEMS:AGInterface;
import PTAI_ACTION_ITEMS:Constants;

class UninavPageletPreprocessor implements PTAI_ACTION_ITEMS:AGInterface
   method PageletPreProcess(&oList As PTAI_ACTION_ITEMS:List);
end-class;


<*  
 method PageletPreprocess() - This method will be called everytime UniNav pagelet is rendered. This function creates a new action item in the UniNav pagelet 
for all the remote RC services. If an earlier created remote service is deleted then the corresponding action item also will be deleted.
*>
method PageletPreProcess
   /+ &oList as PTAI_ACTION_ITEMS:List +/
   /+ Extends/implements PTAI_ACTION_ITEMS:AGInterface.PageletPreProcess +/
   
   Local SQL &sqlGetRemoteSvc;
   Local string &svcId, &svcName, &svcDescr, &svcParamname;
   Local boolean &boolStatus;
   Local integer &seq, &i;
   Local array of string &arrChildItems;;
   Local PTAI_ACTION_ITEMS:ActionItem &oItem = CreateObject("PTAI_ACTION_ITEMS:ActionItem");
   Local PTAI_ACTION_ITEMS:ActionItem &oNewItem = CreateObject("PTAI_ACTION_ITEMS:ActionItem");
   Local PTAI_ACTION_ITEMS:Constants &PTAI_CONSTANTS = CreateObject("PTAI_ACTION_ITEMS:Constants");
   
   <* Every time the pagelet is opened child items under the node 'Related Content Setup' will be deleted and recreated. Nodes are deleted and added again
      everytime because, if some remote services are deleted then it will get reflected in the tree immediately and to prevent the addition of duplicate nodes *>
   try
      &oItem.open("PAPP_UNITM8_PAPP_UNINA1003");
      &arrChildItems = &oItem.getChildActions();
      If All(&arrChildItems) Then
         For &i = 1 To &arrChildItems.Len
            &oItem.open(&arrChildItems [&i]);
            If Not &oItem.ItemId = "PAPP_UNITM9_PAPP_UNINA1003" Then
               try
                  &boolStatus = &oItem.delete();
               catch Exception &e1
               end-try;
            End-If;
         End-For;
      End-If;
      
      SQLExec("Select MAX(PTAI_SEQ) from PS_PTAI_ITEM where PTAI_LIST_ID = :1", &oList.ListId, &seq);
      &sqlGetRemoteSvc = GetSQL(SQL.EPPAI_GET_REMOTE_SVC);
      While &sqlGetRemoteSvc.Fetch(&svcId, &svcName, &svcDescr)
         &oNewItem.new(&svcId, &svcName, &oList.ListId);
         &oNewItem.DescrLong = &svcDescr;
         &oNewItem.ServiceId = &svcId;
         &oNewItem.ParentId = "PAPP_UNITM8_PAPP_UNINA1003";
         &oNewItem.Status = "1";
         &oNewItem.CreatedDateTime = %Datetime;
         &oNewItem.CreatedByOprid = %UserId;
         &oNewItem.LastUpdatedDateTime = %Datetime;
         &oNewItem.LastUpdatedByOprid = %UserId;
         &oNewItem.Target = "T";
         &oNewItem.Type = "C";
         &oNewItem.AssignType = &PTAI_CONSTANTS.MEMBER_TYPE_ROLE;
         &oNewItem.AssignedToOprid = "Portal Administrator";
         &seq = &seq + 10;
         &oNewItem.Sequence = &seq;
         &boolStatus = &oNewItem.save();
      End-While;
      &sqlGetRemoteSvc.Close();
   catch Exception &e
   end-try;
end-method;

While the browser interface provides pages that allow you to manually create activity guide instances, more typically, your PeopleSoft system will create activity guide instance dynamically from activity guide templates as the result of user actions. There are multiple methodologies for deploying fluid and classic activity guides so that an instance is retrieved or a new instance is generated from supplied context data. See Deploying Activity Guides for more information on these methodologies.

However, in some circumstances, you may need to write a PeopleCode program to generate an activity guide instance. The following example presents excerpts of the InstanceCreation method from PeopleSoft HCM.

method InstanceCreation
   /+ &list as PTAI_ACTION_ITEMS:List +/
   /+ Extends/implements PTAI_ACTION_ITEMS:AGInterface.InstanceCreation +/
   
   Local array of string &childItemIds;
   Local integer &i;
   Local boolean &return;
   Local string &ptai_mbr_name, &ptai_mbr_type, &ptai_privset_ID, &ListID, &templateID, &templatelabel, &cnlbtn, &contbtn, &lang;
   
   &RequiredItems = CreateArrayRept(0, 0);
   
   rem Set the template instance status equal to in-progress;
      
   
   &list.Status = "IP";
   
   
   &return = &list.save();
   
   rem get the template ID based on the instance template ID;
   
   SQLExec("Select PTAI_PARENT_TMPL From PS_PTAI_LIST Where PTAI_LIST_ID = :1 ", &list.ListId, &templateID);
      
      
   rem get the template label;
   
   If %Language <> %Language_Base Then
      &lang = %Language;
      SQLExec("select PTAI_LABEL From PS_PTAI_LIST_LNG Where PTAI_LIST_ID = :1 and language_cd = :2", &templateID, &lang, &templatelabel);
   Else
      SQLExec("Select PTAI_LABEL From PS_PTAI_LIST Where PTAI_LIST_ID = :1 ", &templateID, &templatelabel);
   End-If;
   
   &list.Label = &templatelabel;
   &return = &list.save();
   
      
   Rem change the status of the action items;
   &childItemIds = &list.getActionItems();
   
   For &i = 1 To &childItemIds.Len
      &item = create PTAI_ACTION_ITEMS:ActionItem();
      &item.open(&childItemIds [&i]);
      
      If &item.Label = "Welcome" Then
         rem Item status is complete;
         &item.Status = "4";
         &item.PercCompl = 100;
         &item.Type = "C";
         REM &item.Summary = True;
         REM  &item.Type = " ";
         REM &item.ServiceId = " ";
      Else
         rem Item status is assigned;
         &item.Status = "1";
         &item.PackageRoot = "W3EB_LIFE_EVENT";
         &item.QualifyPath = ":";
         &item.AppClassID = "ItemStatus";
      End-If;
      
      &item.AssignedToOprid = %UserId;
      &item.AssignType = "USER";
      
      
      &return = &item.save();
            
   End-For;
   
   
   Rem Save the logged in UserID for security and privileges;
   
   &members = create PTAI_COLLECTION:Collection();
   
   &members = &list.getMembers();
   
   
   &ptai_mbr_name = %UserId;
   &ptai_mbr_type = "USER";
   
      
   &member = create PTAI_ACTION_ITEMS:Member(&ptai_mbr_name, &ptai_mbr_type);
   
   
   If &PTAI_CONSTANTS = Null Then
      &PTAI_CONSTANTS = create PTAI_ACTION_ITEMS:Constants();
   End-If;
   
   
   &ptai_privset_ID = &PTAI_CONSTANTS.PRIVSET_CONTRIBUTOR;
      
   
   &member.PrivilegeSetID = &ptai_privset_ID;
   
   
   &members.InsertItem(&member);
   
   &list.saveMembers(&members);
   
   SaveLEStateRec();
   
end-method;

Use the Define Activity Guide Data Type page to define custom activity guide data types.

Image: Define Activity Guide Data Type page

This example illustrates the fields and controls on the Define Activity Guide Data Type page. You can find definitions for the fields and controls later on this page.

Define Activity Guide Data Type page

Field or Control

Definition

Data Type

Displays the identifier entered for the custom data type on the Add a New Value page.

Label

Enter the descriptive name for the custom data type.

Long Description

Enter a description for the custom data type.

Object Owner ID

Select the object owner ID.

Package

Enter the name of the application package that .

Path

Enter the names of each subpackage in the application class hierarchy that define the location of the application class. Separate subpackage names by a colon. If the class is defined in the top-level application package, enter or select the colon.

Class ID

Enter the name of the application class that .

To implement a custom activity guide data type, create a PeopleCode application class definition:

  1. Extend the PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource class. For example:

    import PTPP_PORTAL:UTILITY:Collection;
    import PTPP_COLLECTIONS:*;
    
    import PTGP_GUIDED_PROCESS:DataSources:*;
    import PTGP_GUIDED_PROCESS:GuidedProcesses:*;
    import PTGP_GUIDED_PROCESS:Elements:*;
    import PTGP_GUIDED_PROCESS:Buttons:*;
    import PTGP_GUIDED_PROCESS:Steps:*;
    
    class MyCustAGDataType extends PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource
  2. In the constructor method for your custom application class, set default values for only the properties necessary to differentiate it from the BaseDataSource class. For example:

    method MyCustAGDataType
       /+ &pId as String +/
       
       %Super = create PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource(&pId);
       %This.setDataSourceType("MyCustAGDataType");
       %This.RenderType = %This.RENDER_TYPE_NONGUIDED_OPTIMIZED;
       
       /* Do not need to defer loading */
       %This.DeferMainGroupletsLoading = False;
       
    end-method;
    
  3. Do not implement and thereby override the populateDataSourceObject method of PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource.

    The populateDataSourceObject method loads critical activity guide template metadata.

  4. Implement the initializeContainerComponent method manipulate the look of the container component using style sheets, JavaScript, or data source properties. For example:

    method initializeContainerComponent
       /+ Extends/implements PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource.initializeContainerComponent +/
       
       Local string &renderType, &scname;
       
       /* Call the super */
       %Super.initializeContainerComponent();
       
       /* Get the collection name */
       &scname = %Request.GetParameter(&cstQUERYPARAMETER_SCNAME);
       If (All(&scname)) Then
          %This.CollName = &scname;
       End-If;
       
       /* Override render type */
       &PTGP_NAVCOLL_RENDER_TYPE = "";
       &renderType = %Request.GetParameter(&cstQUERYPARAMETER_RENDERTYPE);
       If (All(&renderType)) Then
          try
             %This.RenderType = &renderType;
             &PTGP_NAVCOLL_RENDER_TYPE = &renderType;
          catch Exception &e
          end-try;
       End-If;
       
       /* Override panel type */
       %This.ShowSide1PanelCollapsible = True;
       %This.ShowSide1PanelOpenWhenCollapsible = ( Not %This.IsSmallFormFactorMode);
       
    end-method;
    
  5. Implement the initializeGroupletComponent method manipulate the look of the grouplet component using style sheets, JavaScript, or data source properties. While it must call the populateGuidedProcessObject to load the process tree, it must not load data source metadata. For example:

    method initializeGroupletComponent
       /+ Extends/implements PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource.initializeGroupletComponent +/
       
       Local string &scname;
       
       /* Override render type */
       If (All(&PTGP_NAVCOLL_RENDER_TYPE)) Then
          %This.RenderType = &PTGP_NAVCOLL_RENDER_TYPE;
       End-If;
       
       /* Get the collection name */
       &scname = %Request.GetParameter(&cstQUERYPARAMETER_SCNAME);
       If (All(&scname)) Then
          %This.CollName = &scname;
       End-If;
       
       %Super.initializeGroupletComponent();
       
    end-method;
  6. Implement the populateGuidedProcessObject method to load the process tree from your custom data source. For example:

    method populateGuidedProcessObject
       /+ Returns PTGP_GUIDED_PROCESS:GuidedProcesses:BaseGuidedProcess +/
       /+ Extends/implements PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource.populateGuidedProcessObject +/
       
       Local string &text, &iconUrl, &msgNode;
       Local string &defaultFolderIconUrl, &defaultContentIconUrl;
       Local boolean &succeeded;
       
       Local Record &rec;
       
       Local PTGP_GUIDED_PROCESS:GuidedProcesses:BaseGuidedProcess &thisProcess;
       
       Local PTGP_GUIDED_PROCESS:Elements:StepElement &thisStep;
       Local PTGP_GUIDED_PROCESS:Elements:StepGroupElement &thisStepGroup, &theRootStep;
       Local PTGP_GUIDED_PROCESS:Elements:ContextTextElement &headerText;
       Local PTGP_GUIDED_PROCESS:Elements:ButtonElement &thisButton;
       
       Local PTPP_COLLECTIONS:NavigationCollection &thisNavColl;
       Local PTPP_COLLECTIONS:Folder &thisFolder;
       Local PTPP_COLLECTIONS:Shortcut &thisShortcut;
       
       
       &thisProcess = create PTGP_GUIDED_PROCESS:GuidedProcesses:BaseGuidedProcess("PTGPTester");
       &theRootStep = &thisProcess.RootStep;
       
       
       Evaluate %This.RenderType
       When %This.RENDER_TYPE_HORIZONTAL
       When %This.RENDER_TYPE_VERTICAL_OPTIMIZED_SEQUENTIAL
       When %This.RENDER_TYPE_VERTICAL_NONOPTIMIZED_SEQUENTIAL
          &thisProcess.IsSequential = False;
          Break;
          
       When %This.RENDER_TYPE_VERTICAL_OPTIMIZED
       When %This.RENDER_TYPE_VERTICAL_NONOPTIMIZED
       When %This.RENDER_TYPE_NONGUIDED_OPTIMIZED
       When %This.RENDER_TYPE_NONGUIDED_NONOPTIMIZED
          Break;
          
       End-Evaluate;
       
       
       /* Default icons */
       &defaultFolderIconUrl = %Response.GetImageURL(Image.PTPP_FN_LARGE_FOLDER_ICN);
       &defaultContentIconUrl = %Response.GetImageURL(Image.PTPP_FN_LARGE_CONTENT_ICN);
       
       &rec = CreateRecord(Record.PTPP_SITE_OPT);
       &rec.PORTAL_NAME.Value = %Portal;
       If (&rec.SelectByKey()) Then
          /* Site default */
          &defaultFolderIconUrl = %Response.GetImageURL(&rec.PTPP_SCLGFLDICN.Value);
          &defaultContentIconUrl = %Response.GetImageURL(&rec.PTPP_SCLGCNTICN.Value);
       Else
          SQLExec("SELECT MSGNODENAME FROM PS_PTPP_OPTIONS", &msgNode);
          &rec = CreateRecord(Record.PTPP_OPTIONS);
          &rec.MSGNODENAME.Value = &msgNode;
          If (&rec.SelectByKey()) Then
             /* System default */
             &defaultFolderIconUrl = %Response.GetImageURL(&rec.PTPP_SCLGFLDICN.Value);
             &defaultContentIconUrl = %Response.GetImageURL(&rec.PTPP_SCLGCNTICN.Value);
          End-If;
       End-If;
       
       
       /* Get the Collection */
       try
          &thisNavColl = create PTPP_COLLECTIONS:NavigationCollection(%This.PortalName, %This.CollName);
       catch Exception &ex1
          /* Ignore any error */
       end-try;
       
       
       /* Generate the list */
       If ((&thisNavColl <> Null) And
             &thisNavColl.Authorized And
             &thisNavColl.IsValid) Then
          
          /* Root steps */
          If (&thisNavColl.Shortcuts <> Null) Then
             
             &thisShortcut = &thisNavColl.Shortcuts.First();
             While (&thisShortcut <> Null)
                
                /* Create the step */
                &thisStep = create PTGP_GUIDED_PROCESS:Elements:StepElement(&thisShortcut.Name);
                &thisStep.Label = UnEscapeHTML(&thisShortcut.Label);
                &thisStep.URL = &thisShortcut.AbsoluteContentURL;
                &thisStep.SequenceNumber = &thisShortcut.SequenceNumber;
                &thisStep.IsFluid = &thisShortcut.IsFluid;
                
                If (&thisShortcut.IsNewWindow) Then
                   &thisStep.OnClick = "LaunchURL(null, '" | EscapeJavascriptString(&thisShortcut.AbsolutePortalURLnewWin) | "', 1);";
                End-If;
                
                If (&thisShortcut.IsTopWindow) Then
                   &thisStep.OnClick = "LaunchURL(null, '" | EscapeJavascriptString(&thisShortcut.AbsolutePortalURL) | "', 4);";
                End-If;
                
                &iconUrl = &thisShortcut.ImageURL;
                If (All(&iconUrl)) Then
                   &thisStep.IconUrl = &iconUrl;
                Else
                   &thisStep.IconUrl = &defaultContentIconUrl;
                End-If;
                
                &theRootStep.addChildStep(&thisStep);
                
                /* Next shortcut */
                &thisShortcut = &thisNavColl.Shortcuts.Next();
                
             End-While;
             
          End-If;
          
          
          /* Root folders */
          If (&thisNavColl.Folders <> Null) Then
             
             &thisFolder = &thisNavColl.Folders.First();
             While (&thisFolder <> Null)
                
                /* Create the step group */
                &thisStepGroup = create PTGP_GUIDED_PROCESS:Elements:StepGroupElement(&thisFolder.Name);
                &thisStepGroup.Label = UnEscapeHTML(&thisFolder.Label);
                &thisStepGroup.SequenceNumber = &thisFolder.SequenceNumber;
                
                &iconUrl = &thisFolder.ImageURL;
                If (All(&iconUrl)) Then
                   &thisStepGroup.IconUrl = &iconUrl;
                Else
                   &thisStepGroup.IconUrl = &defaultFolderIconUrl;
                End-If;
                
                /* First level child steps */
                If (&thisFolder.Shortcuts <> Null) Then
                   
                   &thisShortcut = &thisFolder.Shortcuts.First();
                   While (&thisShortcut <> Null)
                      
                      /* Create the step */
                      &thisStep = create PTGP_GUIDED_PROCESS:Elements:StepElement(&thisShortcut.Name);
                      &thisStep.Label = UnEscapeHTML(&thisShortcut.Label);
                      &thisStep.URL = &thisShortcut.AbsoluteContentURL;
                      &thisStep.SequenceNumber = &thisShortcut.SequenceNumber;
                      &thisStep.IsFluid = &thisShortcut.IsFluid;
                      &thisStepGroup.addChildStep(&thisStep);
                      
                      If (&thisShortcut.IsNewWindow) Then
                         &thisStep.OnClick = "LaunchURL(null, '" | EscapeJavascriptString(&thisShortcut.AbsolutePortalURLnewWin) | "', 1);";
                      End-If;
                      
                      If (&thisShortcut.IsTopWindow) Then
                         &thisStep.OnClick = "LaunchURL(null, '" | EscapeJavascriptString(&thisShortcut.AbsolutePortalURL) | "', 4);";
                      End-If;
                      
                      /* Next shortcut */
                      &thisShortcut = &thisFolder.Shortcuts.Next();
                      
                   End-While;
                   
                End-If;
                
                /* Sort and add the step group when it's not empty */
                If (&thisStepGroup.ChildSteps.Count > 0) Then
                   &succeeded = &thisStepGroup.ChildSteps.sort(&cstSEQ_NUMBER, True);
                   &theRootStep.addChildStep(&thisStepGroup);
                End-If;
                
                /* Next folder */
                &thisFolder = &thisNavColl.Folders.Next();
                
             End-While;
             
          End-If;
          
          
          /* Sort the root list */
          &succeeded = &theRootStep.ChildSteps.sort(&cstSEQ_NUMBER, True);
          
          
          /* Set the current step id to the first item */
          &thisStep = &theRootStep.ChildSteps.get(1);
          If (All(&thisStep)) Then
             &thisStepGroup = (&thisStep As PTGP_GUIDED_PROCESS:Elements:StepGroupElement);
             If (All(&thisStepGroup)) Then
                &thisProcess.CurrentStepId = &thisStepGroup.ChildSteps.get(1).ID;
             Else
                &thisProcess.CurrentStepId = &thisStep.ID;
             End-If;
          End-If;
          
          
          /* Header texts */
          &headerText = create PTGP_GUIDED_PROCESS:Elements:ContextTextElement("label");
          &headerText.StyleClass = "ps_ag-header-context-title";
          &headerText.Text = &thisNavColl.Label;
          &thisProcess.addHeaderText(&headerText);
          
          &text = &thisNavColl.Description;
          If (All(&text)) Then
             &headerText = create PTGP_GUIDED_PROCESS:Elements:ContextTextElement("description");
             &headerText.StyleClass = "ps_ag-header-context-text";
             &headerText.Text = &text;
             &thisProcess.addHeaderText(&headerText);
          End-If;
          
          
          /* Header buttons */
          &thisButton = create PTGP_GUIDED_PROCESS:Buttons:ExitButton(&thisProcess.ID | "-ExitButton");
          &thisProcess.addHeaderButton(&thisButton);
          
          &thisButton = create PTGP_GUIDED_PROCESS:Buttons:PreviousButton(&thisProcess.ID | "-PreviousButton");
          &thisProcess.addHeaderButton(&thisButton);
          
          &thisButton = create PTGP_GUIDED_PROCESS:Buttons:NextButton(&thisProcess.ID | "-NextButton");
          &thisProcess.addHeaderButton(&thisButton);
          
       End-If;
       
       
       Return &thisProcess;
       
    end-method;

Use the Activity Guide System Options page to define integration with Approval Workflow Engine (AWE).

Image: Activity Guide System Options page

This example illustrates the fields and controls on the Activity Guide System Options page. You can find definitions for the fields and controls later on this page.

Activity Guide System Options page

Classic Approval Chain

Field or Control

Definition

Menu Name

Enter the menu name that contains the classic AWE component—for example, EOAW_APPROVAL_WORKFLOW.

Component Name

Enter the name of the classic AWE component—for example, EOAW_APPCHAIN_VIEW.

Fluid Approval Chain

Field or Control

Definition

Fluid Name

Enter the menu name that contains the fluid AWE component.

Fluid Name

Enter the name of the fluid AWE component.