Normally for the SAP Business Workflow with the transaction SBWP classic Dynpros are used for user interaction. Now I had the requirement to combine SAP Business Workflow with WebDynpro (WDA) to substitute the classical Dynpro.

The reason was the WebDynpro advantage over classical Dynpro.


For that i had first to create two classes:


1. WF-Class (Z_WD_WF_CLASS)


Create a class which is used in the wf task (In this case Z_WD_WF_CLASS).This class requires the interface IF_WORKFLOW, but an implementation is not required.

This class starts the WebDynpro application using the WFtask (Step 4.).

On the method OPEN_WD of class Z_WD_WF_CLASS the WebDynpro application is started. The WI_ID is passed as a URL parameter.




 class Z_WD_WF_CLASS definition   public   final   create public . public section.   interfaces BI_OBJECT .   interfaces BI_PERSISTENT .   interfaces IF_WORKFLOW .   class-methods OPEN_WD     importing       !_WORKITEM type SIBFLPOR     returning       value(_WI_OBJECT_ID) type ref to Z_WD_WF_CLASS . protected section. private section. ENDCLASS. CLASS Z_WD_WF_CLASS IMPLEMENTATION. METHOD open_wd.   DATA lt_parameters TYPE tihttpnvp.   DATA ls_parameters LIKE LINE OF lt_parameters.   ls_parameters-name = 'WI_ID'.   ls_parameters-value = _workitem-instid+20.    "Name muss so sein   APPEND ls_parameters TO lt_parameters.   CALL FUNCTION 'WDY_EXECUTE_IN_BROWSER'     EXPORTING *     PROTOCOL                =       application             = 'Z_WD_WF_FORM'       parameters              = lt_parameters *     TRY_TO_USE_SAPGUI_THEME = ''     EXCEPTIONS       invalid_application     = 1       browser_not_started     = 2       action_cancelled        = 3       OTHERS                  = 4.   IF sy-subrc <> 0. * Implement suitable error handling here   ENDIF. ENDMETHOD. ENDCLASS. 


2. WF-Event-Class (Z_WD_WF_EVENT_CLASS)


This class also requires the interface IF_WORKFLOW and has two events (APPROVE and REJECT), which can be fired on the WebDynpro application. The link to the WFtask is a GUID.

The static method GET_EVENT_OBJECT creates an object of class Z_WD_WF_EVENT_CLASS with a GUID, which will be passed to the WFtask data binding (Step 4). The other methods are necessary to the use of the WF task with the class.


 class Z_WD_WF_EVENT_CLASS definition   public   final   create public . public section.   interfaces BI_OBJECT .   interfaces BI_PERSISTENT .   interfaces IF_WORKFLOW .   events APPROVE .   events REJECT .   methods CONSTRUCTOR     importing       !I_GUID_16 type GUID_16 .   class-methods GET_EVENT_OBJECT     returning       value(RO_EVENT_OBJECT) type ref to Z_WD_WF_EVENT_CLASS . protected section. private section.   data M_GUID_16 type GUID_16 .   data M_SIBFLPOR type SIBFLPOR . ENDCLASS. CLASS Z_WD_WF_EVENT_CLASS IMPLEMENTATION. method BI_OBJECT~DEFAULT_ATTRIBUTE_VALUE. endmethod. method BI_OBJECT~EXECUTE_DEFAULT_METHOD. endmethod. method BI_OBJECT~RELEASE. endmethod. METHOD bi_persistent~find_by_lpor.   DATA lo_wd_wf_event TYPE REF TO z_wd_wf_event_class.   DATA l_guid_16 TYPE guid_16.   l_guid_16 = lpor-instid.   IF l_guid_16 IS INITIAL.     RETURN.   ENDIF.   CREATE OBJECT lo_wd_wf_event     EXPORTING       i_guid_16 = l_guid_16.   .   result = lo_wd_wf_event. ENDMETHOD. METHOD bi_persistent~lpor.   result = m_sibflpor. ENDMETHOD. method BI_PERSISTENT~REFRESH. endmethod. METHOD constructor.   m_sibflpor-catid = 'CL'.   m_sibflpor-typeid = 'Z_WD_WF_EVENT_CLASS'.   m_sibflpor-instid = i_guid_16.   m_guid_16 = i_guid_16. ENDMETHOD. METHOD get_event_object.   DATA lo_system_uuid TYPE REF TO if_system_uuid.   DATA l_guid_16 LIKE m_guid_16.   lo_system_uuid = cl_uuid_factory=>create_system_uuid( ).   l_guid_16 = lo_system_uuid->create_uuid_x16( ).   CREATE OBJECT ro_event_object     EXPORTING       i_guid_16 = l_guid_16. ENDMETHOD. ENDCLASS. 


Now I can use the classes in the workflow:

3. Workflow

Create any workflow. For this example, I created the following workflow.

4. asynchronous task

The class Z_WD_WF_CLASS with the OPEN_WD method is used for object method of the WF task. These WFtask must be asynchronous because the WF task is terminated by an event.

A container must be created for the Event class Z_WD_WF_EVENT_CLASS.

This allows the two events APPROVE and REJECT are entered in the tab “Terminating events”.

Data binding passes the Object Class XX passed with the GUID.


Workflow and WebDynpro with asynchronous tasks

Furthermore, the Web Dynpro application is required:

5. WebDynpro




Workflow and WebDynpro with asynchronous tasks

WDDOINIT in the Componentencontroller:

In WDDOINIT is the ID of the workitem that has been passed through the URL parameters queried.


The workitem ID is passed to the Fuba SAP_WAPI_READ_CONTAINER. Thus, the container contents of Z_WD_WF_EVENT_CLASS of the workitem can be determined.

The object of the container is passed to the WebDynpro.

 METHOD wddoinit .    DATA lo_nd_wf_info TYPE REF TO if_wd_context_node.    DATA lo_el_wf_info TYPE REF TO if_wd_context_element.    DATA ls_wf_info TYPE wd_this->element_wf_info.    ls_wf_info-wi_id = cl_wd_runtime_services=>get_url_parameter( name = 'WI_ID' ). *    lo_nd_wf_info = wd_context->get_child_node( name = wd_this->wdctx_wf_info ).    lo_el_wf_info = lo_nd_wf_info->get_element( ).    lo_el_wf_info->set_static_attributes(       static_attributes = ls_wf_info ). ********************************************************* *  GET EVENT *************************************************************    DATA l_workitem_id TYPE swr_struct-workitemid.    DATA l_return_code TYPE  sy-subrc.    DATA l_ifs_xml_container TYPE  xstring.    DATA l_ifs_xml_container_schema  TYPE  xstring.    DATA l_task_id TYPE swr_struct-task.    DATA lo_container          TYPE REF TO if_swf_cnt_container.    DATA lt_simple_container TYPE STANDARD TABLE OF swr_cont.    DATA lt_message_lines TYPE STANDARD TABLE OF swr_messag.    DATA lt_message_struct TYPE STANDARD TABLE OF swr_mstruc.    DATA lt_subcontainer_bor_objects TYPE STANDARD TABLE OF swr_cont.    DATA lt_subcontainer_all_objects TYPE STANDARD TABLE OF swr_cont. *  DATA lo_wf_event TYPE REF TO /kibf/nacl_wf_event.    DATA ls_sibflpor TYPE sibflpor.    DATA l_guid_16 TYPE guid_16.    l_workitem_id = ls_wf_info-wi_id.    CALL FUNCTION 'SAP_WAPI_READ_CONTAINER'      EXPORTING        workitem_id              = l_workitem_id        language                 = sy-langu        user                     = sy-uname        buffered_access          = 'X'      IMPORTING        return_code              = l_return_code        ifs_xml_container        = l_ifs_xml_container        ifs_xml_container_schema = l_ifs_xml_container_schema      TABLES        simple_container         = lt_simple_container        message_lines            = lt_message_lines        message_struct           = lt_message_struct        subcontainer_bor_objects = lt_subcontainer_bor_objects        subcontainer_all_objects = lt_subcontainer_all_objects.    cl_swf_cnt_factory=>create_task_container(   EXPORTING     im_task_id        = 'TSXXXXXXXXX' "ID of the WF task   IMPORTING     ex_task_container = lo_container     ).    TRY.      CALL METHOD cl_swf_ifs_conversion_base=>if_swf_ifs_conversion~import_from_ifs_xml      EXPORTING        ifs_xml_stream        = l_ifs_xml_container        target_container      = lo_container *    import_param          = 'X' *    export_param          = 'X' *    local_elements        = 'X' *    no_system_elements    = SPACE *  IMPORTING *    num_elements_imported = *    error_handle          =        .    ENDTRY.    TRY.        CALL METHOD lo_container->if_swf_ifs_parameter_container~get          EXPORTING            name       = 'Z_WD_WF_EVENT_CLASS'          IMPORTING            value      = ls_sibflpor *         unit       =             returncode = l_return_code.        l_guid_16 = ls_sibflpor-instid.        CREATE OBJECT wd_this->mo_wd_wf_event_class          EXPORTING            i_guid_16 = l_guid_16.      CATCH cx_swf_cnt_elem_not_found .      CATCH cx_swf_cnt_elem_type_conflict .      CATCH cx_swf_cnt_unit_type_conflict .      CATCH cx_swf_cnt_container .    ENDTRY. ENDMETHOD. 

V_MAIN->ONACTIONAPPROVE

When the user selects an action, the event object is used and fires the appropriate event (in this example APPROVE).

 METHOD onactionapprove .    DATA ls_sibflpor TYPE sibflpor.    ls_sibflpor = wd_comp_controller->mo_wd_wf_event_class->bi_persistent~lpor( ).    TRY.        cl_swf_evt_event=>raise(           EXPORTING             im_objcateg = ls_sibflpor-catid             im_objtype  = ls_sibflpor-typeid             im_event    = 'APPROVE'             im_objkey   = ls_sibflpor-instid *    im_event_container =        ).      CATCH cx_swf_evt_invalid_objtype .      CATCH cx_swf_evt_invalid_event .    ENDTRY.    COMMIT WORK. ENDMETHOD. 



In the instance linkages (transaction SWEINST) you can see the link between GUID (Object Key) and workitem ID (Receiver Key)


Workflow and WebDynpro with asynchronous tasks

Result


Workflow and WebDynpro with asynchronous tasks

By clicking on the button “APPROVE” the event “APPROVE” is fired, thereby terminating the WF task.


Workflow and WebDynpro with asynchronous tasks

Workflow and WebDynpro with asynchronous tasks

Thereafter, the entry in the instance linkages is no longer included.

Workflow and WebDynpro with asynchronous tasks

Other suggestions?

New NetWeaver Information at SAP.com

Very Helpfull

User Rating: Be the first one !