The standard Workflow inbox delivered by SAP Master Data Governance is very generic, since it does not contain any business data (like Material attributes). Luckily we can change this.

Business requirement

Turn this:
inbox_old.PNG
… into this:
/wp-content/uploads/2015/05/inbox_new_699692.png

Technical background

The MDG Inbox uses the Suite Inbox (CA-EPT-IBO) or Lean Workflow Inbox as a basis. This is basically a WebDynpro application that uses a POWL List to display Workitems. While the application offers Workflow-specific features not found in the standard POWL application (e.g. substitution settings for Workflow), it is driven by a specialization of the POWL feeder.

Implementation

We implement a new Query by deriving a new ABAP Class from the SAP MDG Standard one. First the SAP Standard fetches the assigned Workitems and standard fields (like priority, CR status, …), then we add the business data (here: Material).

1. DDIC Structure & Table Type

In SE11, create new DDIC structure and table types describing your result structure. The structure must contain the base fields of the MDG inbox in structure USMD_S_CREQUEST_POWL. Use a named INCLUDE so that you have easier access to the Material fields in your ABAP coding later on. I include the Material structure /MDGMM/_S_MM_PP_MATERIAL generated by MDG-M, i.e. all fields of the Type1 entity MATERIAL will be available for the end user.

inbox_ddic.PNG

2. ABAP Class for Query

Create a new ABAP class derived from CL_USMD_CREQUEST_POWL, the standard Inbox feeder. Overwrite the following methods:

  • SET_MV_RESULTS: Set me->mv_results to the name of your result table type
  • SET_MV_RESULTSTRUCTURE: Set me->mv_resultstructure to the name of your result structure
  • CONSTRUCTOR: Copy the code from the super Constructor into this method
    (for ABAP internal reasons, the Constructor does not execute the code in your overwritten methods as you might expect. It’s in the documentation, so you cannot complain, and I for once am not half as good in explaining such things as Mr. ABAP himself)

3. Register the new POWL application

Using transaction POWL_COCKPIT, you create a new POWL application, query type (this references our ABAP class), query, and finally register your query to the application. See the POWL documentation for details.

4. Create WebDynpro configurations

Now we need WebDynpro application and component configurations that start the Suite Inbox application IBO_WDA_INBOX with our new POWL list:

  1. Copy the application configuration USMD_CREQUEST_POWL into customer namespace & edit it
  2. Copy & edit the component configuration of IBO_WDC_INBOX. Change the parameter applid to the name of your newly created POWL application
    inbox_comp_inbox.PNG
  3. (Optional) Copy & edit the component configuration of POWL_UI_COMP. This allows you to modify the look&feel of the POWL result table.
  4. Assign the newly created component configurations in the application configuration created aboveinbox_appl_config.PNG
  5. (Optional) From transaction POWL_QUERY, define a standard ALV layout for the result table, e.g. which columns are being displayed initially.

5. ABAP code for reading Material data

At last, some real coding (You didn’t think you could just customize this together, did you?! 😉 ). In this code, we first let the MDG standard fetch the Workitem information, then we add the Material data using theMaster Data Governance Application Programming Interface.

The code uses some tricks for enhancing the performance that are applicable to MDG programming as a whole:

  • Use concrete DDIC types whenever possible
  • Reduce the MDG API calls to the bare minimum, i.e. it is better to do more work in your own code than to call the API. For instance, in the code below, instead of invoking the MDG API from within the LOOP (n calls), I prepare a list of Material numbers and invoke the API only once.

First display is pretty slow (>1.5s), as the MDG API initialization (CL_USMD_GOV_API=>GET_INSTANCE())alone adds 0.5s to the start-up time. 😯


METHOD if_powl_feeder~get_objects.
     "Let Standard fetch & fill basic fields
     CALL METHOD super->if_powl_feeder~get_objects
       EXPORTING
         i_username              = i_username
         i_applid                = i_applid
         i_type                  = i_type
         i_selcrit_values        = i_selcrit_values
         i_langu                 = i_langu
         i_visible_fields        = i_visible_fields
       IMPORTING
         e_results               = e_results
         e_messages              = e_messages
         e_workflow_result_count = e_workflow_result_count.
     IF e_results IS INITIAL.
       RETURN.
     ENDIF.

     "Cast result into real type
     FIELD-SYMBOLS: <workitems> TYPE y0mm_mat_ui_t_ibo_creq_mat.
     ASSIGN e_results TO <workitems>.

     "Create mapping table workItem --> CR
     DATA(lt_wi_crequest) = cl_usmd_wf_crequest_mapper=>get_crequest_by_wi(
       it_wi = VALUE #( FOR <wi> IN <workitems> ( <wi>-wi_id ) )
     ).

     "Get MDG GOV API
     DATA: lo_mdg_api TYPE REF TO if_usmd_gov_api.
     TRY .
         lo_mdg_api = cl_usmd_gov_api=>get_instance(
                      iv_model_name   = cl_mdg_bs_mat_c=>gc_usmd_model
         ).
       CATCH cx_usmd_gov_api.
         RETURN.   "Some error, so we show only vanilla worklist
     ENDTRY.

     "Get list of (first) Material in each CR
     DATA: lt_material_keys TYPE SORTED TABLE OF /mdgmm/_s_mm_kf_material
             WITH UNIQUE KEY material.
     TYPES: BEGIN OF ty_wi2material,
       wi_id     TYPE y0mm_mat_ui_s_ibo_creq_mat-wi_id,
       material  TYPE /mdgmm/_s_mm_kf_material-material,
     END OF ty_wi2material.
     DATA: lt_wi2material TYPE HASHED TABLE OF ty_wi2material
             WITH UNIQUE KEY wi_id.
     LOOP AT <workitems> ASSIGNING FIELD-SYMBOL(<workitem>).
       "Get CR for that Workitem
       READ TABLE lt_wi_crequest
         ASSIGNING FIELD-SYMBOL(<wi2crequest>)
         WITH TABLE KEY wi_id = <workitem>-wi_id.
       IF sy-subrc <> 0.
         CONTINUE.
       ENDIF.
       TRY .
           "Get object list of that CR
           lo_mdg_api->get_object_list(
             EXPORTING
               iv_crequest_id             = <wi2crequest>-usmd_crequest
             IMPORTING
               et_object_list_db_style    = DATA(lt_object_list)    " Change Request, Entity, Table Type
           ).
           "Is Material entity in CR?
           READ TABLE lt_object_list
             ASSIGNING FIELD-SYMBOL(<ent_material>)
             WITH KEY usmd_crequest = <wi2crequest>-usmd_crequest
                      usmd_entity = cl_mdg_bs_mat_c=>gc_entity_name_mat.
           IF sy-subrc <> 0.
             CONTINUE.
           ENDIF.
           "Get Material key into key table (conversion!)
           INSERT
             VALUE #(
               material = <ent_material>-usmd_value
             )
             INTO TABLE lt_material_keys
             ASSIGNING FIELD-SYMBOL(<material>).
           "Store association workItem -> material
           INSERT
             VALUE #(
               wi_id     = <workitem>-wi_id
               material  = <material>-material
             )
             INTO TABLE lt_wi2material.
         CATCH cx_usmd_gov_api.
           "Ignore errors, just let add-on data fields empty in output
           CONTINUE.
       ENDTRY.
     ENDLOOP.
     IF lt_material_keys IS INITIAL.
       RETURN.   "No CRs in list, nothing to add
     ENDIF.

     "Read all Materials from MDG API (Only 1 call for performance reasons!)
     DATA: lt_materials TYPE HASHED TABLE OF /mdgmm/_s_mm_pp_material
             WITH UNIQUE KEY material.
     lo_mdg_api->retrieve_entity(
       EXPORTING
         iv_crequest_id = VALUE #( )         "Initial CR, means read all
         iv_entity_name = cl_mdg_bs_mat_c=>gc_entity_name_mat    "Material
         it_key         = lt_material_keys    "Material in current CR
       IMPORTING
         et_data        = lt_materials    " Entity Keys and Attributes
     ).
     IF lt_materials IS INITIAL.
       RETURN.   "No Materials, nothing to add
     ENDIF.

     "Add Material information to Change Requst Work Item List
     LOOP AT <workitems> ASSIGNING <workitem>.
       "Get material_id by workitem_id
       READ TABLE lt_wi2material
         WITH TABLE KEY wi_id = <workitem>-wi_id
         ASSIGNING FIELD-SYMBOL(<wi2material>).
       IF sy-subrc <> 0.
         CONTINUE.
       ENDIF.
       "Get Material data into WorkItem list
       READ TABLE lt_materials
         WITH TABLE KEY material = <wi2material>-material
         INTO <workitem>-yy_material.
     ENDLOOP.

   ENDMETHOD.

6. Test it

You can invoke your new MDG-M Inbox by starting the Suite Inbox with the newly created configuration. The URL should look something like this:
https://<your_host>:<your_port>/sap/bc/webdynpro/sap/IBO_WDA_INBOX?WDCONFIGURATIONID=<your_appl_config>


7. Inbox customizing

You might have realized that the Suite Inbox is showing all Workitems from all workflows and that the MDG specific buttons (e.g. “Process request”) are not working. This is due to missing customizing settings, that SAP delivers for the MDG Inbox. The customizing is specific to the POWL applicationID, which is of course different for our own Inbox.


You can copy over the settings made by SAP (in system tables) into customizing tables. There are some Customizing transactions for this in SPRO, but I entered it directly. SM30 for the customizing table, SE16 for the system tables, as well as Copy&Paste are your friends in this task.


Customizing
System
Description
IBO_C_WF_TA_P_SC IBO_C_WF_TA_P_TY Tasks to show in Inbox. Leave empty to see all tasks of all workflows in system.
IBO_C_WF_ACC IBO_C_WF_ACS Action types for the Inbox actions: Describes how a navigation event triggered by one of the Inbox buttons is evaluated by the Inbox, e.g. via OBN or a function module handler.
IBO_C_WF_TAC IBO_C_WF_TAS Overwrite the standard action to execute on a task.
IBO_C_WF_TTAC IBO_C_WF_TTAS Which Inbox actions (buttons) are available for a task in the inbox.


Acknowledgement

This work is heavily based on the blog MDG: “Empower the POWER List” by Florian Raab, which also contains some very nice screen cams (movies, not just pictures!) to guide you through the POWL setup process.

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

    1. Jürgen Lukasczyk Post author

      That’s completely up to you. I went for “show data of the first Material in the CR”. This also enables all the nice sort / filter / hierarchy features of the ALV used by POWL.

      For multiple BOs in a CR, I would perhaps create a result with text fields and fill them with the first 10 Material numbers. But this would not at all display nicely on screen in a tabular grid.

      (0) 

Leave a Reply