转 Program Exits in Work Item for Workflow

Program Exits in Work Item for Workflow

By Anirban Bhattacharjee, KPIT Cummins and Infosystems from Link

Purpose: The purpose of this document is to demonstrate how to use Program Exits in a Work Item for Workflow.

Business Scenario: Many times we have scenarios where we want to do some additional custom processing when a work item is created or executed. 

SAP has given us a way by which we can design Program Exits in a work item. The events on which we can program this are mentioned below

  • Before Work Item Creation

  • After Work Item Creation

  • Before Work Item Execution

  •  After Work Item Execution

  • After the execution of a Synchronous Object Method in the work item

  • Before Physical Deletion of the Work Item

  • On the Status Change of a Work Item

  • On a Rule execution in the Work Item

  • After an action execution in the Work Item

  • Before and action execution in the Work Item

We will see that the class we will model later on in this tutorial will contain the methods that can be implemented for handling the above events.

Here we will send e-mail via this Program Exit once when a work item is created and once when it is executed.

There will be no e-mail steps modeled in the workflow. They will happen solely from the program exit.

Process to design the Program Exit in a Work Item

Let us look at the tab in a work item where this exit is designed

转 Program Exits in Work Item for Workflow

Note that the SAP Documentation states that the class that will be modeled here must support the IF_SWF_IFS_WORKITEM_EXIT interface. Please ensure that inside this class we will not be using any ABAP Instruction that can release the current LUW like COMMIT WORK, ROLLBACK WORK or using RFC Function Calls.

Now we will design a class via the transaction SE24. We will call this class ZZCL_WORK_ITEM_EXIT.

The Properties tab of the class will look as shown. We will add the type group SWRCO

转 Program Exits in Work Item for Workflow

We will now declare the interface IF_SWF_IFS_WORKITEM_EXIT in the interface tab

转 Program Exits in Work Item for Workflow

Once we declare the interface, the attributes related to this interface will appear in the Attributes Tab.

转 Program Exits in Work Item for Workflow

Notice the events that can happen with a work item in the Description column. This is what was mentioned at the start of the tutorial.

We will now add a couple of custom attributes as mentioned below:

WI_CONTEXT as a type reference to IF_WAPI_WORKITEM_CONTEXT; this interface returns the various attributes of a work item.

Displaying this interface via SE24 and showing you the methods

转 Program Exits in Work Item for Workflow

To see how to implement these methods in a class, please refer CL_SWF_RUN_WORKITEM_CONTEXT.

This class is very helpful to understand how to do various operations on a work item.

The other custom attribute will be named PROCESS_STATUS. This will contain a default value ‘sap.bc.bmt.wfm.process.status’.

The attributes tab now looks like as shown below

转 Program Exits in Work Item for Workflow

Both the attributes are Instance Attribute and Private visibility.

Now let us navigate to the Methods Tab of this class.

转 Program Exits in Work Item for Workflow

The only method created by default is EVENT_RAISED. This will be called whenever the Work Item Events (mentioned at the start of the tutorial) are triggered.

The parameters that appear in this method are

转 Program Exits in Work Item for Workflow

(Note that there is a parameter IM_WORKITEM_CONTEXT which refers interface IF_WAPI_WORKITEM_CONTEXT)

Now we will create two more methods called AFTER_WI_CREATION and AFTER_WI_EXECUTION as shown.

转 Program Exits in Work Item for Workflow

Both the methods are Instance Method with Private Visibility.

Write the following code in the AFTER_WI_CREATION method

(This code will send an e-mail to a dummy e-mail ID with the Work Item ID stating that it was Created. Will trigger after work item is created)

METHOD after_wi_creation.

  DATA: lcl_v_wi_id        TYPE sww_wiid,  "Work Item ID
        lv_wid_text        TYPE char12,
        send_request       TYPE REF TO cl_bcs,
        text               TYPE bcsy_text,
        body_text          TYPE so_text255,
        document           TYPE REF TO cl_document_bcs,
        sender             TYPE REF TO cl_sapuser_bcs,
        recipient          TYPE REF TO if_recipient_bcs,
        bcs_exception      TYPE REF TO cx_bcs,
        sent_to_all        TYPE os_boolean.

* For simplicity of the demo, we are only fetching the work item ID
* You can get the complete work item and workflow details as well
* Please refer class CL_SWF_RUN_WORKITEM_CONTEXT and interface IF_WAPI_WORKITEM_CONTEXT
* Get the Work Item ID
  CALL METHOD wi_context->get_workitem_id
    RECEIVING
      re_workitem = lcl_v_wi_id.

* Pass WID to text field
  CLEAR: lv_wid_text.
  lv_wid_text = lcl_v_wi_id.

*----------------------------------------------------------------------------------------*
* Send an e-mail to a dummy e-mail ID stating that the above Work Item has been created
*----------------------------------------------------------------------------------------*
  TRY.
*     -------- create persistent send request ------------------------
      send_request = cl_bcs=>create_persistent( ).

*     -------- create and set document -------------------------------
*     Build the e-mail Body
      CLEAR: body_text.
      CONCATENATE 'Work Item Created. WID:'
                  lv_wid_text INTO body_text SEPARATED BY space.

      APPEND body_text TO text.
      document = cl_document_bcs=>create_document(
                      i_type    = 'RAW'
                      i_text    = text
                      i_length  = '12'
                      i_subject = 'E-Mail sent AFTER Work Item Creation' ).

*     Add document to send request
      CALL METHOD send_request->set_document( document ).

*     --------- set sender -------------------------------------------
*     note: this is necessary only if you want to set the sender
*           different from actual user (SY-UNAME). Otherwise sender is
*           set automatically with actual user.

      sender = cl_sapuser_bcs=>create( sy-uname ).
      CALL METHOD send_request->set_sender
        EXPORTING
          i_sender = sender.

*     --------- Add recipient (e-mail address) -----------------------
*     Create recipient - passing a dummy e-mail ID here
      recipient = cl_cam_address_bcs=>create_internet_address('[email protected]' ).

*     Add recipient with its respective attributes to send request
      CALL METHOD send_request->add_recipient
        EXPORTING
          i_recipient = recipient
          i_express   = 'X'.

*     ---------- Send document ---------------------------------------
      CALL METHOD send_request->send(
        EXPORTING
          i_with_error_screen = 'X'
        RECEIVING
          result              = sent_to_all ).

      COMMIT WORK.

* -----------------------------------------------------------
* *                     exception handling
* -----------------------------------------------------------
    CATCH cx_bcs INTO bcs_exception.
*  Write own code to catch exception
  ENDTRY.

ENDMETHOD.

Write the following code in the AFTER_WI_EXECUTION method

(This code will send an e-mail to a dummy e-mail ID with the Work Item ID stating that it was Executed. Will trigger after work item is executed)

METHOD after_wi_creation.

  DATA: lcl_v_wi_id        TYPE sww_wiid,  "Work Item ID
        lv_wid_text        TYPE char12,
        send_request       TYPE REF TO cl_bcs,
        text               TYPE bcsy_text,
        body_text          TYPE so_text255,
        document           TYPE REF TO cl_document_bcs,
        sender             TYPE REF TO cl_sapuser_bcs,
        recipient          TYPE REF TO if_recipient_bcs,
        bcs_exception      TYPE REF TO cx_bcs,
        sent_to_all        TYPE os_boolean.

* For simplicity of the demo, we are only fetching the work item ID
* You can get the complete work item and workflow details as well
* Please refer class CL_SWF_RUN_WORKITEM_CONTEXT and interface IF_WAPI_WORKITEM_CONTEXT
* Get the Work Item ID
  CALL METHOD wi_context->get_workitem_id
    RECEIVING
      re_workitem = lcl_v_wi_id.

* Pass WID to text field
  CLEAR: lv_wid_text.
  lv_wid_text = lcl_v_wi_id.

*----------------------------------------------------------------------------------------*
* Send an e-mail to a dummy e-mail ID stating that the above Work Item has been created
*----------------------------------------------------------------------------------------*
  TRY.
*     -------- create persistent send request ------------------------
      send_request = cl_bcs=>create_persistent( ).

*     -------- create and set document -------------------------------
*     Build the e-mail Body
      CLEAR: body_text.
      CONCATENATE 'Work Item EXECUTED. WID:'
                  lv_wid_text INTO body_text SEPARATED BY space.

      APPEND body_text TO text.
      document = cl_document_bcs=>create_document(
                      i_type    = 'RAW'
                      i_text    = text
                      i_length  = '12'
                      i_subject = 'E-Mail sent AFTER Work Item EXECUTION' ).

*     Add document to send request
      CALL METHOD send_request->set_document( document ).

*     --------- set sender -------------------------------------------
*     note: this is necessary only if you want to set the sender
*           different from actual user (SY-UNAME). Otherwise sender is
*           set automatically with actual user.

      sender = cl_sapuser_bcs=>create( sy-uname ).
      CALL METHOD send_request->set_sender
        EXPORTING
          i_sender = sender.

*     --------- Add recipient (e-mail address) -----------------------
*     Create recipient - passing a dummy e-mail ID here
      recipient = cl_cam_address_bcs=>create_internet_address('[email protected]' ).

*     Add recipient with its respective attributes to send request
      CALL METHOD send_request->add_recipient
        EXPORTING
          i_recipient = recipient
          i_express   = 'X'.

*     ---------- Send document ---------------------------------------
      CALL METHOD send_request->send(
        EXPORTING
          i_with_error_screen = 'X'
        RECEIVING
          result              = sent_to_all ).

      COMMIT WORK.

* -----------------------------------------------------------
* *                     exception handling
* -----------------------------------------------------------
    CATCH cx_bcs INTO bcs_exception.
*  Write own code to catch exception
  ENDTRY.

ENDMETHOD.

Write the following code in the method EVENT_RAISED. In this method based on the Work Item event triggered, our corresponding custom method will be called.

METHOD if_swf_ifs_workitem_exit~event_raised.

* Get the Work Item Context
  me->wi_context = im_workitem_context.

* Check if the Event after WI Creation is triggered
  IF im_event_name = swrco_event_after_creation.

* Call our method AFTER_WI_CREATION
    me->after_wi_creation( ).

* Check if the Event after WI Execution is triggered
  ELSEIF im_event_name = swrco_event_after_execution.

* Call our method AFTER_WI_EXECUTION
    me->after_wi_execution( ).

  ENDIF.

ENDMETHOD.

转 Program Exits in Work Item for Workflow

Now save and activate the complete class ZZCL_WORK_ITEM_EXIT along with all its components.

转 Program Exits in Work Item for Workflow

Now we will call this class in our user decision step in the workflow at the tab Program Exits as shown below  

转 Program Exits in Work Item for Workflow

Now we save and activate the complete workflow definition as well.

Notice that there are no e-mail steps after the user decision anywhere in the workflow definition.

转 Program Exits in Work Item for Workflow

Now we will test the workflow via SWUS transaction. When the user decision step is created, the first e-mail should go.

转 Program Exits in Work Item for Workflow

The work item ID is 412083 as seen below

转 Program Exits in Work Item for Workflow

Checking in SOST transaction if the Work Item Creation E-Mail has triggered 

转 Program Exits in Work Item for Workflow

转 Program Exits in Work Item for Workflow

So we have successfully sent the first e-mail to the dummy e-mail ID, which went After Work Item Creation via the program exit.

Notice the work item ID is 412083. This is correct as per workflow logs.

Now we will execute the work item. After execution, we will see the workflow log

BEFORE EXECUTION

转 Program Exits in Work Item for Workflow

AFTER EXECUTION

转 Program Exits in Work Item for Workflow

Checking SOST if the e-mail after WI execution has triggered

转 Program Exits in Work Item for Workflow

转 Program Exits in Work Item for Workflow

So we have successfully sent the second e-mail to the dummy e-mail ID, which went After Work Item Execution via the program exit.

Conclusion: Hence we have successfully modeled the Program Exit that can be used in a work item. With the help of this exit, we can do numerous custom operations at various events, which occur during the complete life span of a work item.