cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamic parallel processing in SAP S/4HANA flexible workflow

SumitKundu
Active Participant
0 Kudos
446

Hi,

We have an existing custom classic workflow for purchase order where the approval is based on multiple cost centers of line items. It uses dynamic parallel processing (par-for-each) using multiline element and a sub workflow 

In SAP S/4HANA in-premise flexible workflow, is it possible to achieve dynamic parallel processing if we create a custom workflow scenario? Would appreciate if any content or blog post is available. 

Best regards,

Sumit 

 

View Entire Topic
SumitKundu
Active Participant
0 Kudos

Hi @SBach ,

I have used below code in IF_SWF_FLEX_IFS_RUN_APPL_STEP~ON_CREATION_CALLBACK.

 

data itab TYPE STANDARD TABLE OF gnetw.
    APPEND 30 to itab.
    APPEND 40 to itab.
    DATA(lo_container) = io_context->get_task_container( ).
    lo_container->set( EXPORTING name = 'Amount'
                         value = itab ).

 

 But the task container in the workflow log shows same value in both the runtime instances of the task.

 

p619793_1-1718108717925.png

p619793_3-1718108798982.png

Also I used the amount expression in the workitem text, however it did not update the workitem text as seen in the workflow log screenshot above.

Best regards,

Sumit

 

 

 

SBach
Product and Topic Expert
Product and Topic Expert
SBach
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Sumit, unfortunately I never did a POC on that and actual there is no time for. Also I guess there is a need to adapt the task ui. Regarding the callback. I found some example coding (but didn´t run it) in our FORMABSENC- Demo Flexworkflow Scenario for the on_creation_callback that may help.

 

 

 

 

 

DATA(lv_task_id) = io_current_activity->get_task_id( ). 
IF lv_task_id = 'TS77408433'. 
" The application object could be fetched 
" DATA(lv_appl_obj) = io_context->get_leading_object_reference( ). 
" The following code will set an approval comment depending on the value of a step property 

DATA(lt_step_properties) = io_current_activity->if_swf_flex_ifs_run_component~get_properties( ). 
IF line_exists( lt_step_properties[ id = cl_swf_flex_def_appl_lra=>cs_prop_milestone-id ] ). 
DATA(lo_formabsenc) = CAST cl_swf_formabsenc( cl_swf_formabsenc=>bi_persistent~find_by_lpor( CONV #( io_context->get_leading_object_reference( ) ) ) ). 
IF lo_formabsenc IS NOT BOUND. RAISE EXCEPTION TYPE cx_swf_flex_ifs_run_exception EXPORTING textid = cx_swf_flex_ifs_run_exception=>leading_object_key_error. 
ENDIF. 
DATA(ls_formabsenc) = lo_formabsenc->get_detail( ). 
CASE lt_step_properties[ id = cl_swf_flex_def_appl_lra=>cs_prop_milestone-id ]-value. "value field contains a key (if a fixed value list is used) or the value itself (if no value list is used) WHEN cl_swf_flex_def_appl_lra=>cs_prop_milestone-value_id_1. ls_formabsenc-approval_comment = 'Stage 1 reached' ##NO_TEXT. WHEN cl_swf_flex_def_appl_lra=>cs_prop_milestone-value_id_2. ls_formabsenc-approval_comment = 'Stage 2 reached' ##NO_TEXT. ENDCASE. 
" Update leading object here 
TRY.
lo_formabsenc->update_background( 
EXPORTING
 is_swxformabs = ls_formabsenc iv_do_commit = abap_false ). 
CATCH cx_bo_error INTO DATA(lx_bo_error). 
RAISE EXCEPTION TYPE cx_swf_flex_ifs_run_exception EXPORTING previous = lx_bo_error. ENDTRY. ENDIF. 
TRY. 
io_context->get_task_container( )->set( 
EXPORTING 
name = 'dummy' 
value = 'A' 
). 
CATCH cx_swf_cnt_cont_access_denied cx_swf_cnt_elem_access_denied cx_swf_cnt_elem_not_found cx_swf_cnt_elem_type_conflict cx_swf_cnt_unit_type_conflict cx_swf_cnt_elem_def_invalid cx_swf_cnt_container INTO DATA(lx_container_write). 
RAISE EXCEPTION TYPE cx_swf_flex_ifs_run_exception EXPORTING previous = lx_container_write. 
ENDTRY.

** --- Simulate MMPUR_WFL_CONTEXT_ENHANCE BAdI to set step priority ----
*    DATA(lt_execution_list) = io_current_activity->get_execution_results( ).
*    DATA(lt_work_items_id) = VALUE swwtwiid( FOR line IN lt_execution_list ( line-wi_id ) ).
*    APPEND io_context->get_wi_id( ) TO lt_work_items_id . "Main workitem priority also needs to be set
*    LOOP AT lt_work_items_id INTO DATA(ls_work_item_id).
*      CALL FUNCTION 'SWW_WI_PRIORITY_CHANGE'
*        EXPORTING
*          priority  = 2
*          wi_id     = ls_work_item_id
*          do_commit = ' '
**       AUTHORIZATION_CHECKED       = ' '
**       PRECONDITIONS_CHECKED       = ' '
**       PROPAGATE_TO_FLOW           = ' '
**       FUNCNAME                    = ' '
*        EXCEPTIONS
*          OTHERS    = 0.
*    ENDLOOP.

 

 

 

 

 

SBach
Product and Topic Expert
Product and Topic Expert
0 Kudos

What also sometimes helps in custom workflow dev is the Programming Exit on activity Level.

*How do the program exits work?
*To change alternatives of the user decision at runtime dynamically (for each *work item), you can define an ABAP class here that supports interface *IF_SWF_IFS_WORKITEM_EXIT.

*At runtime, method IF_SWF_IFS_WORKITEM_EXIT~EVENT_RAISED is called multiple *times. Here you can define source code that is run for different time points *of the work item processing.

*To delete or change the alternatives, your code must be run at the time *point SWFCO_EVENT_BEFORE_DECISION.

*Example: Class CL_SWH_T_DECISION_EXIT from workflow definition WS77400143 "WF_Verify141"

Method IF_SWF_IFS_WORKITEM_EXIT~EVENT_RAISED.
  data lt_decialts type IF_WAPI_WORKITEM_CONTEXT=>swrtdecialts.
  if im_event_name = IF_SWF_IFS_DECISION_EXIT~C_EVTTYP_BEFORE_DECISION.
    call method IM_WORKITEM_CONTEXT->get_decision_alts
       importing et_decialts = lt_decialts.
*   --- hide alternative 0001 and 0002 ---
    delete lt_decialts where altkey <> '0003'.
    call method IM_WORKITEM_CONTEXT->set_decision_alts
       exporting it_decialts = lt_decialts.
  endif.
endmethod.