Wednesday, May 2, 2012

Display specific actions as buttons in the CRM Webclient

Within SAP CRM actions are a very flexible way to customize the system to the customer’s requirements. Since these actions are often started by end users, we have looked for a way to optimize the execution of an action.

By default the CRM Webclient UI contains logic to display a button called “Actions”.

Once you click on this button, the Webclient UI will show a pop-up with all available actions that could be executed. Depending on the setting it takes some effort to execute an action:

- Click button “More”
- Click button “Actions”
- Choose an action

Since there might be actions that should be executed frequently, it would be useful to be able to start these actions directly via a separate button. There is a way to do so!

Step 1 : Set number of visible buttons

Since we want to start an action directly, we don’t want the new button to end up under button “More”. Go to the UI Component Workbench and display the correct Component’s View.  Check the implementation of Toolbar related Method “IF_BSP_WD_TOOLBAR_CALLBACK~GET_NUMBER_OF_VISIBLE_BUTTONS”.

If necessary, redefine this method to display the number of buttons that you need.

Step 2 : Add button

In step 1 we made sure that once we add a new button to the menu, it will be displayed correctly. Now we can continue with adding the button itself. Redefine the Toolbar related Method “IF_BSP_WD_TOOLBAR_CALLBACK~GET_BUTTONS” and make sure to call the super class first.

CALL METHOD super->if_bsp_wd_toolbar_callback~get_buttons
    rt_buttons = rt_buttons.
Next step is to determine if the action that we would like to output as a button is available. We need to get the current available actions and search for the one we need.

The following sample code shows how to determine the available actions. In this example we only read the first action and add it as a button to the menu. If you need to determine a specific action you need to loop over the available actions and process the action required.

    lr_entity TYPE REF TO cl_crm_bol_entity,
    lr_action_set TYPE REF TO cl_crm_bol_entity,
    lr_actions TYPE REF TO if_bol_entity_col,
    lr_action TYPE REF TO cl_crm_bol_entity,

    ls_button TYPE crmt_thtmlb_button_ext,
    ls_action_attr TYPE crmt_action_attr_aciil.

* Get current AdminH-Entity
  lr_entity ?= me->typed_context->btadminh->collection_wrapper->get_current( ).

* Get Action Set
  lr_action_set = lr_entity->get_related_entity( iv_relation_name = 'BTHeaderAction' ).

  IF lr_action_set IS BOUND.
        lr_action_set->execute( iv_method_name = 'ACIDetermine' ).
      CATCH cx_crm_genil_model_error

* Get Actions
    lr_actions = lr_action_set->get_related_entities( iv_relation_name = 'ACIInactiveActionRel' ).

* Get first action
    IF lr_actions IS BOUND.
      lr_action = lr_actions->get_first( ).

      IF lr_action IS BOUND.
* Get action properties
        lr_action->if_bol_bo_property_access~get_properties( IMPORTING es_attributes = ls_action_attr ).

* Add button
        CLEAR ls_button.         
        ls_button-on_click = 'EVENT_NAME'.
        ls_button-enabled  = abap_true.
        ls_button-text     = ls_action_attr-ttypedescr. "Action 1
        ls_button-page_id  = me->component_id.
        APPEND ls_button TO rt_buttons.
 As a result button “Action 1” is now available in the menu.

Step 3 : Create event handler

In step 2 we added one button to the menu. Now we can create the event handler using the name we specified in step 2 (EVENT_NAME).

Within the implementation of the event handler we need to get the action again. This coding was already listed in step 2, so below just an overview of the required steps:

- Get Context Node
- Get Current Entity
- Get Action Set
- Get Actions
- Get Action
- Get Action Properties

Once we found the correct action, we can call it using the code below. 

  lr_adminh TYPE REF TO cl_crm_bol_entity,
  lr_action TYPE REF TO cl_crm_bol_entity,

  ls_method_param TYPE LINE OF crmt_name_value_pair_tab,
  lt_method_param TYPE crmt_name_value_pair_tab.

* Execute action
    "Set parameters
    ls_method_param-name = 'OBJECT_NAME'.       
    ls_method_param-value = lr_adminh->get_name( ).
    INSERT ls_method_param INTO TABLE lt_method_param.

    ls_method_param-name = 'OBJECT_ID'.          
    ls_method_param-value = lr_adminh->get_key( ).
    INSERT ls_method_param INTO TABLE lt_method_param.

    lr_action->execute( iv_method_name = 'ACIActivate'
                        it_param       = lt_method_param ).

  CATCH: cx_crm_genil_model_error cx_crm_bol_meth_exec_failed.
The Action log will show the final result.




Depending on your solution you can now create buttons to start actions directly from the toolbar. This will definitely save a lot of time for end users of the system.