Triggering Virtual Approver Routings

This section provides an overview of virtual approver routings.

After you create approval rule sets, the steps for developing a Virtual Approver approval process are basically the same as for any other business process. You define roles, events, and routings. When you set event triggers, however, instead of using the TriggerBusinessEvent PeopleCode function, you use a pair of functions that trigger routings based on the approval rule set that you specify. To access these functions, you must first add special work pages to the component where the event is triggered.

Every component that uses Virtual Approver PeopleCode must include the pages WF_FUNCTIONS_01 and APPR_WRK_01. These special work pages load several important Workflow PeopleCode functions into memory. For example, if you’re using route controls, WF_FUNCTIONS_01 enables the system to determine which route control types are relevant for the event that you’re triggering.

To add work pages to a component:

  1. In PeopleSoft Application Designer, open the component.

  2. Add WF_FUNCTIONS_01 and APPR_WRK_01 to the list of pages in the component.

  3. Save the component.

Note: Usually, after adding a page to a component, you use PeopleTools Security to grant users access to the page. However, because WF_FUNCTIONS_01 and APPR_WRK_01 are work pages, you do not want users to see them or be able to access them.

Note: The derived/work record APPR_FIELDS_WRK includes the field PREV_ROLEUSER, which is typically used to identify the previous approver if the process is recycled. If your approval process includes parallel paths, note that if the process recycles from the step above the parallel path, PREV_ROLEUSER is the user who approved at the highest path of the previous step. If this person recycles the process again, it will go through the lower path on the same step, then to the prior step. If the process recycles from a parallel step without an approval, then PREV_ROLEUSER is the user who approved the previous step, and the application must take care of the worklist on the other path of this step.

PeopleSoft designed Virtual Approver to simplify the PeopleCode that you must write for approval processes. Rather than writing complex PeopleCode programs, you define the approval rules using pages in the Workflow Administrator, then use two simple PeopleCode functions to check those rules.

After you add the Virtual Approver work pages to the component with the page where the triggering event occurs, you must add both SaveEdit PeopleCode and Workflow PeopleCode to the record definition that is associated with that page.

  • The SaveEdit PeopleCode uses the Virtual_Approver PeopleCode library function to check the approval rules that you defined in the Workflow Administrator and determine whether an item must be routed for approval.

  • The Workflow PeopleCode uses the Virtual_Router PeopleCode function to route items to the next step in the approval process.

Note: The Virtual_Router PeopleCode library function is located in the FieldFormula event of the APPR_VA0_WRK.FUNCLIB_02 record field. The Virtual_Approver function is located on the FieldFormula event of the APPR_VA0_WRK.FUNCLIB_01 record field.

You must add the SaveEdit and Workflow PeopleCode to the same record field.

SaveEdit PeopleCode

This is the general structure of the SaveEdit PeopleCode program:

  1. Declare the external workflow functions Get_RoleUser and Virtual_Approver.

  2. Set values in the APPR_FIELDS_WRK work record to give the Virtual_Approver function the data it needs to check the approval rules.

    Set these values:

    • The name of the role user attempting to approve the transaction.

    • The business process and approval rule set that you want Virtual_Approver to use.

    • The approval action that the current user gave to the current work item. The valid status values are A (Approve), D (Deny), or R (Recycle).

  3. Use the Virtual_Approver function.

  4. Set the approval status record field to the value that Virtual_Approver returns: A (Approved), D (Denied), and P (Pending).

    Enter the following code exactly as it’s shown, replacing the values in angle brackets with the values that are appropriate for your application.

    /* Declare the Virtual Approver workflow functions */
    
    declare function Get_RoleUser PeopleCode APPR_VA0_WRK.ROLEUSER FieldChange;
    declare function Virtual_Approver PeopleCode APPR_VA0_WRK.FUNCLIB_01 FieldFormula;
    
    /* Get the role user name for the current user */
    &USERID = %UserId;
    Get_RoleUser(&USERID, &EMAILID, &FORMID, &EMPLID, &ROLEUSER);
    /* Set values in the work record for Virtual_Approver */
    APPR_FIELDS_WRK.ROLEUSER = &ROLEUSER;
    APPR_FIELDS_WRK.BUSPROCNAME = BUSPROCESS.<BusProcessName>;
    APPR_FIELDS_WRK.APPR_RULE_SET = <approval_rule_set>;
    APPR_FIELDS_WRK.APPR_ACTION = <approval_action>;
    APPR_FIELDS_WRK.APP_ROW_NUMBER = <current_row_number>;
    /* Call the Virtual Approver */
    Virtual_Approver();
    /* Set the application record’s approval status field to the value  */
    /* Virtual_Approver returns */
    <status_record_field> = APPR_FIELDS_WRK.APPR_STATUS;

    The variables in this code are:

    Field or Control

    Definition

    BusProcessName (business process name)

    The name of the business process whose approval rules you want to use.

    Approval_rule_set

    The name of the approval rule set that you want Virtual_Approver to use to determine whether an item needs further approval.

    Approval_action

    The approval action to provide Virtual_Approver as input. Usually, approval_action is the name of the record field in which the user sets the approval status. It can also be one of the string constants: P, D, or R.

    Note: If the user specifies the approval action at level 0 on the page, that is, if the user specifies a single approval action for the entire page, it’s preferable to include the field APPR_FIELDS_WRK.APPR_ACTION on the page and let the user set it directly. However, this direct approach doesn’t work if the user must specify approval actions for each row in a scroll. You must have the user set the action in another field, then transfer the value to the APPR_ACTION field before the Virtual_Approver call.

    Current_row_number

    The current row number in the scroll. Setting this field is not necessary at level 0.

    APPR_ROW_NUMBER is only required when Virtual Approver is triggered on a non-level-0 scroll.

    Status_record_field

    The record field that holds the approval status of the transaction, such as Purchase Request Approval Status.

The user should store the APPR_INSTANCE in the application table and pass it to the Virtual Approver. For example, APPR_FIELDS_WRK.APPR_INSTANCE = <application table>.APPR_INSTANCE. Optionally, the user can also pass the VA_BEHAVIOR_TYPE: APPR_FIELDS_WRK.VA_BEHAVIOR_TYPE = "1". Only the value of 1 is supported. The user can check the field value of APPR_FIELDS_WRK.VA_BEHAVIOR_STATUS after calling Virtual_Approver():

  • If the approval process has been denied, the value is 1.

  • If the approval process has been completed, the value is 2.

  • If the operation is at a lower step that has already been approved, the value is 3.

    If the user is on a step that has been approved by another user, the status of the "Resubmit VA Worklist" flag determines whether this is allowed.

    See Setting Workflow System Defaults.

Virtual Approver PeopleCode

The Virtual Approver PeopleCode looks like this:

declare function Virtual_Router PeopleCode APPR_VA0_WRK.FUNCLIB_02 FieldFormula;
APPR_FIELDS_WRK.APPR_VR_ROW = <scroll_info>;
Virtual_Router();
if None(APPR_INSTANCE) then
   <application record name>.APPR_INSTANCE = APPR_FIELDS_WRK.APPR_INSTANCE;
endif;

The scroll_info is a number. If you’re calling the router from level 0, scroll_info is 0; if you’re calling it from a scroll, scroll_info is the row number of the current row in the scroll. If you’re calling from a level 1 scroll, use the CurrentRowNumber PeopleCode function.

The if statement assigns an instance ID to a transaction if it does not already have one.