Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
svasani
Employee
Employee

Introduction


We all know the world is evolving. So is SAP. 🙂

In the era of SAP ECC, there used to be Workflow builder (Transaction Code - SWDD) which ties together all the workflow component and the approval cycle very tightly with all the building blocks.

SAP HANA came up with yet better solution design for generalized approval mechanism using which business documents approval cycle can now be configured dynamically.

Today, most of the standard document's approval mechanism is built on Flexible Workflow. (e.g., RFQ, Supplier Quotation, Purchase Contract, Purchase Order and many more. Documents Supporting the Flexible Workflow | SAP Help Portal)

 

You might also encounter a need to build an approval mechanism by using Flexible Workflow for a business process specific to your client/organizational process.

As part of this blog series, I will be sharing development approach required to build Flexible Workflow.

Types of Approvals Mechanism


Based on the approver involved in Business Documents approval cycle, Flexible workflow supports following kind of approval cycles (by design) -

  • Automatic Approval mechanism

    • This is a scenario/activity which takes care of approval/rejection activity of business document placed without human intervention.

    • For example, in an organization we might have some predefined threshold in terms of Amount/Quantity/Other to decide on the requirement of approvals.

    • In case of scenario where the business document is not exceeding those thresholds or it's not falling in criteria which requires manual approval, but still some basic sanity checks are required in order for the document to be consider as legit.

    • In this scenario Automatic Approval mechanism will come into picture.
      This will be the key focus area of current blog.



  • Agent based Approval mechanism

    • This is a scenario/activity where one more series of manual approvals will be required in order for the business document to reach final approved state / to be consider as legit document.




Steps to Create Flexible Workflow with Automatic Approval Cycle


Step 1- Create a Global class by adding following interfaces as member of it - BI_OBJECT & IF_WORKFLOW. (This class will serve the purpose as type of Leading Object required for Flexible workflow)


Class with workflow relevant interfaces


Step 2- Implement all the methods of interface (with no logic for now) and also create one method called WORKITEM_EXECUTE as Public Instance Method with no parameters and no logic. (Which will serve the purpose of dummy execution method during actual workitem execution further).


Dummy method for Automatic Workitem execution


Step 3-Also add following 3 events in class along with the parameters-


Event SUBMITTED_FOR_APPROVAL



Event RELEASED



Event REJECTED


Step 4-Go to transaction code SWDD_SCENARIO and create new Flexible Workflow.


Create Flexible Workflow


Step 5-Create a Container Element in the scenario context referring class created earlier, which will serve as the required Leading Object in the flexible workflow.


Create Container Element


Step 6- Feed in the process data in first tab and map Workflow Start event with the class event SUBMITTED_FOR_APPROVAL.


Process Data


Step 7-Create 2 more Global class (from proper Superclass as shown in below screenshot), which will serve as Callback Classes for workflow. (Definition Data Class & Runtime Data class)


Callback Class - Definition Data



Callback Class - Runtime Data


 


Control Data


Step 8-Create an Activity and provide it some meaningful name. (Keep the Task ID as blank, system will generate standard Task ID which we can copy to create our own custom task)


Create an Activity


Activity list should start look something like following upon creation -


Activity List


Step 9-Map Object method created above at Task Level.


Task Setup


Step 10-Set the Outcome in the Outcome tab along with its nature POSITIVE/NEGATIVE.


Activity Outcome


Step 11-Set Task Level binding as follows-


Activity Binding


Step 12-Set Event binding as follows at Workflow Start Events Level and activate the event linkage. (In Process Data tab)


Setting EventLinkage and Parameters


Step 13-Upload Pre-delivered Content in the workflow Control tab in order to enable activate Automatic Approval(by default - before workflow step has been configured by relevant workflow template application).


XML format for this Pre-Delivered content will be as follows -
<?xml version="1.0" encoding="UTF-8"?>
<workflow formatVersion="3.0" id="">
<scenario>Scenario ID e.g., WSXXXXXXXX</scenario>
<scenarioVersion/>
<subject>Title</subject>
<validFrom/>
<validTo/>
<processFlow artifactId="">
<activity artifactId="">
<step id="$ScenarioVersion$ActivityId" e.g., "$0000$InspAutoapproval"/>
</activity>
</processFlow>
</workflow>

Upload Pre-delivered Content


Once it's done, please activate the workflow. It should generate the runtime components required in order for the workflow to execute.

 

Logic Implementation for System Approval/Rejection upon Workitem execution


Once above workflow is submitted/triggered via relevant business document creation/change activity, Workitem is created as a normal workflow approval process.

This workitem gets executed automatically as there is no human intervention involved.

Internally it triggers call to the callback class we created and assigned earlier.

To perform any system decision - approve/reject and update relevant business document, following method of class Runtime Data needs to be redefined - if_swf_flex_ifs_run_appl~result_callback.

You can implement required business logic to approve/reject business document based on criteria involved by implementing the required logic referring following sample implementation -
CLASS zcl_blg_insp_wfl_run_appl_base DEFINITION
PUBLIC
INHERITING FROM cl_swf_flex_ifs_run_appl_base
FINAL
CREATE PUBLIC .

PUBLIC SECTION.
METHODS if_swf_flex_ifs_run_appl~result_callback
REDEFINITION .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.



CLASS ZCL_BLG_INSP_WFL_RUN_APPL_BASE IMPLEMENTATION.


METHOD if_swf_flex_ifs_run_appl~result_callback.

DATA: lv_object_reference TYPE sibflpor,
lv_inspplanuuid TYPE sysuuid_x16.

lv_object_reference = CORRESPONDING #( io_context->get_leading_object_reference( ) ).

" get the Plan for the workflow call.
IF lv_object_reference IS NOT INITIAL.
lv_inspplanuuid = lv_object_reference.
"Read plan details based on UUID
SELECT SINGLE @abap_true
FROM zblg_t_insp_tsp
WHERE uuid = @lv_inspplanuuid
AND approvalstatus = 'W' "Waiting For approval
AND isdeleted = @abap_false
INTO @DATA(lv_exists).
" is the Plan is in awaiting approval status, and exist, we will process it.
IF sy-subrc EQ 0 AND lv_exists = abap_true.
DATA lv_decision TYPE swc_elem.

lv_decision = io_result->get_result( )-result.

"set status to approved if the decision indicated to do so
IF lv_decision = 'APPROVED'.
DATA(lv_status) = 'A'.

"set status to rejection - upon rejection
ELSEIF lv_decision = 'REJECTED'.
lv_status = 'R'.
ENDIF.
" Take relevant action - upon Approval/Rejection
UPDATE zblg_t_insp_tsp SET approvalstatus = lv_status
WHERE uuid = lv_inspplanuuid.
" validate the plan could be updated.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE cx_swf_flex_ifs_run_exception
EXPORTING
textid = cx_swf_flex_callback_exception=>system_error
m_id = CONV string( io_result->get_result( )-wi_id ).
ENDIF.
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.

 

Example Implementation & Integration with RAP based Application


I've created and example implementation of above workflow where a RAP Application will trigger workflow approval once an Inspection Plan is created.

Following are the building blocks required for this implementation -

Step 1-Define a Determination which will get triggered on Save during create operation.
  determination startWorkflow       on save { create; }

Step 2-Invoke the workflow trigger upon determination execution and set original object status to awaiting approval.
CLASS lhc_inspectionplan DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.

METHODS startworkflow FOR DETERMINE ON SAVE
IMPORTING keys FOR inspectionplan~startworkflow.

ENDCLASS.

CLASS lhc_inspectionplan IMPLEMENTATION.
METHOD startworkflow.
READ ENTITIES OF zi_blg_inspectionplantp IN LOCAL MODE
ENTITY inspectionplan
ALL FIELDS WITH CORRESPONDING #( keys )
RESULT DATA(lt_inspplans)
FAILED DATA(lt_failed).

LOOP AT lt_inspplans ASSIGNING FIELD-SYMBOL(<fs_inspplan>).
IF NEW lu_zi_blg_inspectionplantp( )->start_workflow( iv_inspplanuuid = <fs_inspplan>-inspectionplanuuid ) = abap_false.
MODIFY ENTITIES OF zi_blg_inspectionplantp IN LOCAL MODE
ENTITY inspectionplan
UPDATE FIELDS ( approvalstatus )
WITH VALUE #( ( %tky = <fs_inspplan>-%tky
approvalstatus = 'W' ) )
REPORTED DATA(lt_update_reported)
FAILED DATA(lt_modifyfailed).
ENDIF.
ENDLOOP.
ENDMETHOD.

ENDCLASS.

Step 3-Create a local class and a utility method to invoke the workflow when requested from above determination implementation-
CLASS lu_zi_blg_inspectionplantp DEFINITION.
PUBLIC SECTION.
METHODS start_workflow
IMPORTING
!iv_inspplanuuid TYPE sysuuid_x16
RETURNING
VALUE(rv_failed) TYPE abap_bool .
ENDCLASS.
CLASS lu_zi_blg_inspectionplantp IMPLEMENTATION.
METHOD start_workflow.

CONSTANTS: lc_objecttype TYPE sibftypeid VALUE 'ZBLG_INSP_WORKFLOW',
lc_event TYPE sibfevent VALUE 'SUBMITTED_FOR_APPROVAL'.
DATA: lv_objectkey TYPE sibfinstid.

IF iv_inspplanuuid IS INITIAL.
RETURN.
ENDIF.
" Get a container for the submitted function
DATA(lo_event_container) = cl_swf_evt_event=>get_event_container( im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = lc_objecttype
im_event = lc_event ).
TRY.
lo_event_container->set( name = 'IV_OBJECT_ID' value = iv_inspplanuuid ).

lv_objectkey = iv_inspplanuuid.
" Raise workflow event
cl_swf_evt_event=>raise( im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = lc_objecttype
im_event = lc_event
im_objkey = lv_objectkey
im_event_container = lo_event_container ).
CATCH cx_swf_evt_invalid_objtype
cx_swf_evt_invalid_event
cx_swf_cnt_container.
rv_failed = abap_true.
ENDTRY.
ENDMETHOD.

ENDCLASS.

 

Output


Step 1-Upon Inspection plan creation, status has been set to Awaiting Approval.


Sent for Automatic Approval


Step 2-You can check workflow log (Transaction code- SWI1) to ensure workflow execution is complete.


Workflow Log


Step 3-Upon successful execution, status will be changed to Approved.


After Workitem execution



Summary


In the current blog post, we have learned basics of Flexible Workflow, How to Implement Automatic Approval Scenario and how to integrate/invoke it via a RAP based Application.

For more understanding, please use the following references which have helped me in gaining knowledge on this feature and get motivated to write this blog post:

I'll write blogs on following topics soon. Stay tuned. -

  • How to implement Agent based Approval in Flexible Workflow

  • How to generate and configure Fiori Application required for flexible workflow configuration


Please provide your feedback and ask questions in the comments section.

Regards,

Shyam Vasani