Quantcast
Channel: SAP Business Workflow
Viewing all articles
Browse latest Browse all 31

Workflow and WebDynpro with asynchronous tasks

$
0
0

Normallyfor the SAP Business Workflow with the transaction SBWP classic Dynpros areused foruser interaction. Now I hadtherequirement to combine SAP Business Workflow with WebDynpro (WDA) to substitute the classical Dynpro.

The reasonwas theWebDynproadvantageover 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).Thisclassrequiresthe interface IF_WORKFLOW, butan implementationis not required.

This classstarts the WebDynpro application using theWF-task (Step 4.).

 

 

 

On the method OPEN_WD of class Z_WD_WF_CLASS the WebDynpro application is started. TheWI_IDis passed as aURL 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 classalsorequiresthe interfaceIF_WORKFLOWand has twoevents(APPROVE and REJECT), which can befiredon the WebDynpro application. Thelink to theWF-task is a GUID.

 

The staticmethod GET_EVENT_OBJECT createsan object of class Z_WD_WF_EVENT_CLASS with a GUID, which will be passedto the WF-task data binding (Step 4). The other methodsarenecessary to the useof the WFtaskwith 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

 

Createanyworkflow.For this example,I createdthe following workflow.

2015-04-03 15_34_57-Workflow Builder - Display 'z_wd_wf'.png

4. asynchronous task

 

 

 

 

The class Z_WD_WF_CLASS withthe OPEN_WD methodis used forobject methodof the WFtask. TheseWF-task must be asynchronousbecausethe WFtaskis terminatedby an event.

 

 

2015-04-03 15_36_06-Standard Task_ Display.png

A containermust be created fortheEvent class Z_WD_WF_EVENT_CLASS.

2015-04-03 15_42_05-Standard Task_ Display.png
This allows the twoeventsAPPROVE andREJECTare enteredin the tab "Terminating events".

2015-04-03 15_41_24-Standard Task_ Display.png

 

Data bindingpasses theObjectClassXXpassed with theGUID.


 

 

Furthermore, theWeb Dynpro applicationis required:

5. WebDynpro




 

WDDOINIT in the Componentencontroller:

 

InWDDOINITisthe IDof the workitemthat has beenpassed through theURL parametersqueried.


The workitemIDis passed totheFubaSAP_WAPI_READ_CONTAINER. Thus, thecontainercontents of Z_WD_WF_EVENT_CLASS of theworkitemcanbe determined.

The objectofthe containeris passed tothe 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       = <fs_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 selectsan action, the event objectis usedand firesthe appropriate event(inthis exampleAPPROVE).

 

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)


Result


By clickingon the button "APPROVE" the event "APPROVE" is fired, thereby terminating the WFtask.


 

 

Thereafter, theentry in theinstance linkagesisno longer included.

 

 

Other suggestions?


Viewing all articles
Browse latest Browse all 31

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>