S/4HANA Flexible Workflows: Workflow Scenario Development and Configuration – Part 2
This blog is part 2 of blog. In previous blog, we have created the workflow scenario and defined the 2 user decision steps, one condition and did other required activities. In this blog, we will look at the run time callback class, workflow configuration and testing of workflow.
Run Time callback class
We specified this class under ‘Control’ tab of workflow scenario. We defined the class ZCL_CUSTUSER_RUNTIME_DATA as subclass of base class proposed by system. We can redefine various base class methods in this class as per need, but for our development, we are primarily interested in 2 methods:
Method which is called after completion of each activity – ~ AFTER_COMPLETION_CALLBACK
This method can be used to derive any intermediate information based on workflow context or current activity, handle different approval results from previous step etc. For example, we can derive some customizing information after a step based on run time field value.
It is not necessary to implement this method to make our workflow work. Framework can handle POSITIVE/ NEGATIVE outcomes by itself. I wanted to show its implementation as this could be a very useful method for intermediate calculations.
METHOD if_swf_flex_ifs_run_appl_step~after_completion_callback. DATA(step_execution_results) = io_current_activity->get_execution_results( ). TRY. DATA(approval_result) = step_execution_results[ 1 ]-nature. CATCH cx_sy_itab_line_not_found. ENDTRY. IF approval_result EQ 'POSITIVE'. ev_action = if_swf_flex_component=>c_action_continue. ELSEIF approval_result EQ 'NEGATIVE'. "Means it's rejected ev_action = if_swf_flex_component=>c_action_cancel. ENDIF. ENDMETHOD.
Method which is called at workflow completion –~ RESULT_CALLBACK
This method is important to implement as this is where we do the final update which should happen at the completion of workflow. In our case, it is to update the custom table.
METHOD if_swf_flex_ifs_run_appl~result_callback. DATA: ls_user_data TYPE zcustusermast. DATA(ls_result) = io_result->get_result( ). IF ls_result-nature = 'POSITIVE'. DATA(lr_wf_container) = io_context->get_workflow_container( ). TRY. lr_wf_container->get( EXPORTING name = 'UserData' " Name of the Component Whose Value Is to Be Read IMPORTING value = ls_user_data ). " Copy of the Current Value of the Component CATCH cx_swf_cnt_elem_not_found. " Name Entered Is Unknown CATCH cx_swf_cnt_elem_type_conflict. " Value Not Type Compatible to Current Parameter CATCH cx_swf_cnt_unit_type_conflict. " Unit Not Type Compatible to the Current Parameter CATCH cx_swf_cnt_container. " Exception in the Container Service ENDTRY. IF ls_user_data IS NOT INITIAL. MODIFY zcustusermast FROM ls_user_data. ENDIF. ENDIF. ENDMETHOD.
Our Workflow Scenario development is complete now. Save and activate the scenario.
Once scenario is created, next activity is to define the workflow. This activity is primarily for business users, who can design the workflow without being concerned about the complexity that lies under. Ideally business users should be configuring the user-decision steps only while workflow scenario should handle rest of the process complexity.
Open fiori Application ‘Manage Workflows’ and choose your workflow scenario. In our case, it is ‘Custom User Master’:
Press ‘Add’ and enter ‘Name’ and properties like validity dates and description.
Under ‘PRECONDITIONS’, our Company ID precondition is shown:
As defined under ‘Conditions’ tab in Part 1 of blog series, precondition for company ID is available.
Add steps under ‘STEP SEQUENCE’:
Step 1: Type – Validate the Data
( For the Type, you get a drop-down from the activities you defined in Part 1)
Recipient – Workflow Initiator
Default recipients are shown from the ones already available under ‘Agents’ tab in Workflow Scenario. Since we haven’t created any agents there, we are offered the default ones here.
Same Company ID precondition is available here as well. Since, we have already configured it at header level, we won’t use it at step level.
We accept the default exception handling:
‘Name’ is the NEGATIVE outcome from the Activity we defined in Part 1.
Step 2: Type – Create the Table Records
Follow the similar steps as Step 1.
Both the workflow steps are created now:
Save and activate the workflow. If there are already existing workflows for your workflow scenario, make sure that order is such that your workflow is the first to trigger for given data.
We create the data through our entry program. I execute the program with below data:
Transaction SBWP and I see the work item in my inbox
( Same work item should be available in ‘My inbox’ Fiori app as well and processing should happen the same way as it happens through SBWP ).
I approve the work item and now, I receive the second approval work item as well:
I approve this work item as well. Now, my records should get created in custom table:
Entries are created in custom database table:
I tested by creating a table entry with a company ID other than ‘1010’. As expected, no workflow instance was created.
I tested by rejecting one of the approvals. As expected, workflow was terminated, and no workflow instance was created.
I hope this simple workflow development has given you enough idea to develop a small prototype yourself. There are lot more possibilities in workflow scenarios, which I will explore and keep on sharing my learning as well. Looking forward to many other blogs in this space!