Spend Management Blogs by Members
Check out community member blog posts about spend management and SAP Ariba, SAP Fieldglass, and SAP Concur solutions. Post or comment about your experiences.
cancel
Showing results for 
Search instead for 
Did you mean: 
konstantin_anikeev
Active Contributor

First part of this post: Custom Workflow - Developer view - Part 1 - Idea and preparation

Process Schema Evaluation

First start the transaction /SAPSRM/WF_PROCESS

Create new expression for schema evaluation

Provide expression name ZSRM_EX_SC_START.

ZSRM - Group Name

EX - Expression

SC - Shopping cart

START - Shopping cart event

As Implementation class  you should select OCF001 - Function module. A new expression will be created.

Result type should be defined as C(30), it is a type of Workflow schema. Function module interface can be coped from function module BRF_CALL_FUNCTION_TEMPLATE.

Create new event for schema evaluation

Provide event name ZSRM_EV_SC_START.

ZSRM - Group Name

EV - Event

SC - Shopping cart

START - Shopping cart event

Save Event. Then select Event->Change.

In the change mode you can add a new rule.

Here you should add a created expression.

Save the changes.

Setting all together

Worfklow setting are defined in the transaction /SAPSRM/WF_PROCESS.

Go to transaction /SAPSRM/WF_PROCESS and select object BUS2121, then double click on process schema evaluation.

Set the created evaluation id.

Then go to Process Schema Definition and create a new entry.

Provide following customizing.

Step 1:

Approval with completion.

Decision if the step relevant or not determined via ZSRM_EV_BOB.

Approver determined with rule ZRR_REQUESTER.

Workflow Task 99907917 deliver task description.

Step 2:

Approval with decision.

Decision if the step relevant or not determined via ZSRM_EV_CUST_APPR.

Approver determined with rule ZRR_APPROVER_C.

Workflow Task 99907918 deliver task description.

Last step is automatic and obligatory.

Save settings.

Implementation

Implementing agent determination strategies

For agent determination we need to create a BADI implementation(s). In this case 2 implementations will be created.

To implement the BADI go to:

SPRO->SAP Supplier Relationship Management->SRM Server->Business Add-Ins->Business Workflow->Process-Controlled Workflow->Define Agents

and create a new BADI Implementation.

Step 1

In the created Implementation double click on filter values.

and create a new combination.

Select all entries.

Set the values as shown and acivate implementation.

The most 2 important methods for this implementation are /SAPSRM/IF_EX_WF_RESP_RESOLVER~GET_AREA_TO_ITEM_MAP and /SAPSRM/IF_EX_WF_RESP_RESOLVER~GET_APPROVERS_BY_AREA_GUID.

The method GET_AREA_TO_ITEM_MAP called before GET_APPROVERS_BY_AREA_GUID and here you must already know your approvers. For the first step it is always requester for all positions.

Here is an implementation example

METHOD /sapsrm/if_ex_wf_resp_resolver~get_area_to_item_map.
  DATA lv_guid      TYPE /sapsrm/wf_area_guid.
  DATA ls_map       TYPE /sapsrm/s_bd_wf_item_to_area.
  DATA ls_partner   TYPE bbp_pds_partner.
  DATA lt_partner   TYPE bbpt_pds_partner.
  DATA lo_sc        TYPE REF TO /sapsrm/if_pdo_bo_sc_adv.
* get requester guid.
  TRY .
      lo_sc = /sapsrm/cl_pdo_factory_sc_adv=>get_buffered_instance( is_document-document_guid ).
      IF lo_sc IS NOT BOUND.
        lo_sc = /sapsrm/cl_pdo_factory_sc_adv=>get_instance( iv_header_guid   =     is_document-document_guid
                                                             iv_mode          =     /sapsrm/if_pdo_constants_gen_c=>gc_mode_display ).
      ENDIF.
      lo_sc->/sapsrm/if_pdo_do_partner~get_partners_of_type(
        EXPORTING
          iv_partner_fct          =  '00000016'
        IMPORTING
          et_partner              =  lt_partner
      ).
      READ TABLE lt_partner INTO ls_partner INDEX 1.
      lv_guid = ls_partner-partner_no.
    CATCH /sapsrm/cx_pdo_wf_mode_ban.    " transaction mode not allowed with respect to workflow status
    CATCH /sapsrm/cx_pdo_wrong_bus_type.    " Inconsistent Object Types
    CATCH /sapsrm/cx_pdo_pd_read_error.    " No result during PD Layer read access
    CATCH /sapsrm/cx_pdo_lock_failed.    " The document could not be locked
    CATCH /sapsrm/cx_pdo_no_authorizatio.    " No authorization for this action
    CATCH /sapsrm/cx_pdo_parameter_error.    " Inconsistent Parameter
    CATCH /sapsrm/cx_pdo_status_error.    " No change mode allowed
    CATCH /sapsrm/cx_pdo_incons_user.    " The user attributes are not defined in the right way
    CATCH /sapsrm/cx_pdo_abort.    " Fatal error caught by PDO Layer
    CATCH /sapsrm/cx_pdo_error.    " PDO General Exception
  ENDTRY.
* get mapping table
  ls_map-area_guid = /sapsrm/cl_wf_area=>/sapsrm/if_wf_area~create_instance(
    iv_area_type          =    /sapsrm/if_wf_process_c=>gc_area_type_employee
    iv_leading_object_id  =    lv_guid )->get_guid( ).
  CLEAR ls_map-item_guid. " means for all positions
  APPEND ls_map TO rt_item_to_area_map.
ENDMETHOD.
METHOD /sapsrm/if_ex_wf_resp_resolver~get_approvers_by_area_guid.
  rt_approver = /sapsrm/cl_wf_area=>/sapsrm/if_wf_area~get_instance_by_guid(
      iv_area_type = /sapsrm/if_wf_process_c=>gc_area_type_employee
      iv_area_guid = is_area-area_guid
  )->get_responsible_approvers( ).
ENDMETHOD.

Activate Class and Implementation

Step 2

And here is Implementation.

METHOD /sapsrm/if_ex_wf_resp_resolver~get_area_to_item_map.
  DATA lv_guid      TYPE /sapsrm/wf_area_guid.
  DATA ls_map       TYPE /sapsrm/s_bd_wf_item_to_area.
  TRY .
      lv_guid = cl_bbp_es_enterprise=>get_person_by_username( 'MANAGER_01' )->get_primarykey( ).
    CATCH cx_bbp_es_not_a_person.    " Exception: Person Unknown
    CATCH cx_bbp_es_not_found.    " No data found
  ENDTRY.
* get mapping table
  ls_map-area_guid = /sapsrm/cl_wf_area=>/sapsrm/if_wf_area~create_instance(
    iv_area_type          =    /sapsrm/if_wf_process_c=>gc_area_type_employee
    iv_leading_object_id  =    lv_guid )->get_guid( ).
  CLEAR ls_map-item_guid. " means for all positions
  APPEND ls_map TO rt_item_to_area_map.
ENDMETHOD.

MANAGER_01 is a hard coded value of existing and integrated user.

Implementation for /SAPSRM/IF_EX_WF_RESP_RESOLVER~GET_APPROVERS_BY_AREA_GUID is the same.

Implementation of Expression function ZSRM_WF_EX_CUST_APPR_REL.

Here is a source code of the function module.

FUNCTION zsrm_wf_ex_cust_appr_rel.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IT_EXPRESSIONS) TYPE  SBRF260A_T
*"     REFERENCE(IO_EVENT) TYPE REF TO  IF_EVENT_BRF
*"     REFERENCE(IO_EXPRESSION) TYPE REF TO  IF_EXPRESSION_BRF
*"  EXPORTING
*"     REFERENCE(EV_VALUE) TYPE  BRF_RESULT_VALUE
*"     REFERENCE(EV_TYPE) TYPE  BRF_RESULT_TYPE
*"     REFERENCE(EV_LENGTH) TYPE  BRF_RESULT_LENGTH
*"     REFERENCE(EV_CURRENCY) TYPE  BRF_CURRENCY
*"     REFERENCE(EV_OUTPUT_LENGTH) TYPE  BRF_RESULT_OUTPUT_LENGTH
*"     REFERENCE(EV_DECIMALS) TYPE  BRF_RESULT_DECIMALS
*"     REFERENCE(EV_DATA_MISSING) TYPE  BRF_DATA_MISSING
*"----------------------------------------------------------------------
  DATA lv_msg                   TYPE string.
  DATA lv_document_guid         TYPE /sapsrm/wf_document_guid.
  DATA lv_document_type         TYPE /sapsrm/wf_document_type.
  DATA ls_header                TYPE bbp_pds_sc_header_d.
  DATA lo_wf_brf_event          TYPE REF TO /sapsrm/cl_wf_brf_event.
  DATA lo_context_provider      TYPE REF TO /sapsrm/if_wf_context_provider.
  DATA lo_sc                    TYPE REF TO /sapsrm/if_pdo_bo_sc_adv.
  ev_type          = /sapsrm/if_wf_rule_c=>type_bool.
  ev_length        = 1.
  CLEAR ev_currency.
  ev_output_length = 1.
  ev_decimals      = 0.
  ev_value         = /sapsrm/if_wf_rule_c=>brf_result_bool_ok. " no processing
  CLEAR ev_data_missing.
* get event object
  IF NOT io_event IS BOUND.
* BRF event Object not bound. No further execution possible.
    MESSAGE e089(/sapsrm/brf) INTO lv_msg.
    TRY.
        CALL METHOD /sapsrm/cl_wf_brf_ccms=>send_message( ).
      CATCH /sapsrm/cx_wf_abort.
        ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
        EXIT.
    ENDTRY.
    ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
    EXIT.
  ENDIF.
*----------------------------------------------------------------
* get document data by context provider
*----------------------------------------------------------------
  lo_wf_brf_event ?= io_event.
  lo_context_provider = lo_wf_brf_event->get_context_provider( ).
* get Content Container from BRF event
  IF NOT lo_context_provider IS BOUND.
* BRF Context Container Object not bound. No further execution possible.
    MESSAGE e090(/sapsrm/brf) INTO lv_msg.
    TRY.
        CALL METHOD /sapsrm/cl_wf_brf_ccms=>send_message( ).
      CATCH /sapsrm/cx_wf_abort.
        ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
        EXIT.
    ENDTRY.
    ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
    EXIT.
  ENDIF.
  CALL METHOD lo_context_provider->get_document
    IMPORTING
      ev_document_guid = lv_document_guid
      ev_document_type = lv_document_type.
  CASE lv_document_type .
    WHEN /sapsrm/if_pdo_obj_types_c=>gc_pdo_shop.
      TRY.
          lo_sc = /sapsrm/cl_pdo_factory_sc_adv=>get_buffered_instance( lv_document_guid ).
          IF lo_sc IS NOT BOUND.
            lo_sc = /sapsrm/cl_pdo_factory_sc_adv=>get_instance( iv_header_guid = lv_document_guid
                                                                 iv_mode        = /sapsrm/if_pdo_constants_gen_c=>gc_mode_display ).
          ENDIF.
          lo_sc->/sapsrm/if_pdo_bo_sc~get_header_detail( IMPORTING es_header  = ls_header ).
          IF ls_header-created_by <> 'MANAGER_01'.
            ev_value = /sapsrm/if_wf_rule_c=>brf_result_bool_noprocessing. " processing
          ENDIF.
        CATCH /sapsrm/cx_pdo_wf_mode_ban /sapsrm/cx_pdo_wrong_bus_type
              /sapsrm/cx_pdo_pd_read_error /sapsrm/cx_pdo_lock_failed
              /sapsrm/cx_pdo_no_authorizatio /sapsrm/cx_pdo_parameter_error
              /sapsrm/cx_pdo_status_error /sapsrm/cx_pdo_incons_user
              /sapsrm/cx_pdo_abort /sapsrm/cx_pdo_error .
          MESSAGE e101(/sapsrm/brf) INTO lv_msg.
          TRY.
              CALL METHOD /sapsrm/cl_wf_brf_ccms=>send_message( ).
            CATCH /sapsrm/cx_wf_abort.
              ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
              EXIT.
          ENDTRY.
          ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
          EXIT.
      ENDTRY.
  ENDCASE.
ENDFUNCTION.

Implementation of Expression function ZSRM_WF_SCHEMA_DET.

Here is an exmaple content of function module.

FUNCTION zsrm_wf_schema_det.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IT_EXPRESSIONS) TYPE  SBRF260A_T
*"     REFERENCE(IO_EVENT) TYPE REF TO  IF_EVENT_BRF
*"     REFERENCE(IO_EXPRESSION) TYPE REF TO  IF_EXPRESSION_BRF
*"  EXPORTING
*"     REFERENCE(EV_VALUE) TYPE  BRF_RESULT_VALUE
*"     REFERENCE(EV_TYPE) TYPE  BRF_RESULT_TYPE
*"     REFERENCE(EV_LENGTH) TYPE  BRF_RESULT_LENGTH
*"     REFERENCE(EV_CURRENCY) TYPE  BRF_CURRENCY
*"     REFERENCE(EV_OUTPUT_LENGTH) TYPE  BRF_RESULT_OUTPUT_LENGTH
*"     REFERENCE(EV_DECIMALS) TYPE  BRF_RESULT_DECIMALS
*"     REFERENCE(EV_DATA_MISSING) TYPE  BRF_DATA_MISSING
*"----------------------------------------------------------------------
  DATA lv_msg                   TYPE string.
  DATA lv_document_guid         TYPE /sapsrm/wf_document_guid.
  DATA lv_document_type         TYPE /sapsrm/wf_document_type.
  DATA lt_item                  TYPE bbpt_pd_sc_item_d.
  DATA lo_wf_brf_event          TYPE REF TO /sapsrm/cl_wf_brf_event.
  DATA lo_context_provider      TYPE REF TO /sapsrm/if_wf_context_provider.
  DATA lo_sc                    TYPE REF TO /sapsrm/if_pdo_bo_sc_adv.
  FIELD-SYMBOLS: <fs_item>      TYPE bbp_pds_sc_item_d.
  ev_value = ''.
  ev_type = 'C'.
  ev_length = 30.
  CLEAR ev_currency.
  ev_output_length = 30.
  ev_decimals = 0.
  CLEAR ev_data_missing.
* get event object
  IF NOT io_event IS BOUND.
* BRF event Object not bound. No further execution possible.
    MESSAGE e089(/sapsrm/brf) INTO lv_msg.
    TRY.
        CALL METHOD /sapsrm/cl_wf_brf_ccms=>send_message( ).
      CATCH /sapsrm/cx_wf_abort.
        ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
        EXIT.
    ENDTRY.
    ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
    EXIT.
  ENDIF.
*----------------------------------------------------------------
* get document data by context provider
*----------------------------------------------------------------
  lo_wf_brf_event ?= io_event.
  lo_context_provider = lo_wf_brf_event->get_context_provider( ).
* get Content Container from BRF event
  IF NOT lo_context_provider IS BOUND.
* BRF Context Container Object not bound. No further execution possible.
    MESSAGE e090(/sapsrm/brf) INTO lv_msg.
    TRY.
        CALL METHOD /sapsrm/cl_wf_brf_ccms=>send_message( ).
      CATCH /sapsrm/cx_wf_abort.
        ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
        EXIT.
    ENDTRY.
    ev_data_missing = /sapsrm/if_wf_rule_c=>brf_data_missing.
    EXIT.
  ENDIF.
  CALL METHOD lo_context_provider->get_document
    IMPORTING
      ev_document_guid = lv_document_guid
      ev_document_type = lv_document_type.
  CASE lv_document_type .
    WHEN /sapsrm/if_pdo_obj_types_c=>gc_pdo_shop.
      CALL FUNCTION 'BBP_PD_SC_GETDETAIL'
        EXPORTING
          i_guid = lv_document_guid
        TABLES
          e_item = lt_item.
      LOOP AT lt_item ASSIGNING <fs_item> WHERE del_ind IS INITIAL
                                            AND catalogid IS INITIAL
                                            AND product IS INITIAL
                                            AND itm_type <> 'LIMI'.
        ev_value = 'ZSRM_WF_SC_CUST'. " Custom Workflow
        EXIT.
      ENDLOOP.
  ENDCASE.
  IF ev_value IS INITIAL.
    ev_value = '9C_BUS2121_EX99'. " No Workflow
  ENDIF.
ENDFUNCTION.

Result

First part of this post: Custom Workflow - Developer view - Part 1 - Idea and preparation

P.S.:  English language is not my native language, and any person is not insured from mistakes and typing errors. If you have found an error in the text, please let me know - I'll correct the post.

P.P.S.: If you have some ideas, how to correct/improve this post - please don't hesitate to leave a comment.

9 Comments