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
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
We will now declare the interface IF_SWF_IFS_WORKITEM_EXIT in the interface tab
Once we declare the interface, the attributes related to this interface will appear in the Attributes Tab.
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
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
Both the attributes are Instance Attribute and Private visibility.
Now let us navigate to the Methods Tab of this class.
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
(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.
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.
Now save and activate the complete class ZZCL_WORK_ITEM_EXIT along with all its components.
Now we will call this class in our user decision step in the workflow at the tab Program Exits as shown below
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.
Now we will test the workflow via SWUS transaction. When the user decision step is created, the first e-mail should go.
The work item ID is 412083 as seen below
Checking in SOST transaction if the Work Item Creation E-Mail has triggered
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
AFTER EXECUTION
Checking SOST if the e-mail after WI execution has triggered
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.