Skip to Content
Technical Articles
Author's profile photo Tobias Berger

TKS #12 – Enhancing Buttons in the Transportation Cockpit ( The Future of Modification in TM Planning Functionality – Part II )

Some while ago there was already a blog on the rising use of factories and factory injection in the area of TM planning and as time passed, I want to continue the path of extensibility enablement in the transportation cockpit.

Decoupling of Behavior and Action Handling

With 2021 we introduced a concept which decouples common code from certain specific handling which need to be done for certain object or action.

The concept work as following:

  • There is a factory class which creates classes which should deliver certain action handling code structured via an interface.
  • There is one method in the interface which is used to define what action this class is handling.
  • When the factory is instantiated, it checks all classes implementing the action handling interface and builds up a catalog of action to the handling class.
  • When a consumer needs the action handler the catalog is checked, and the correct class is instantiated.

With that in place new actions only need to implement the interface and plug into the existing code w/o the need to touch that one.

How to use this concept

With the refactoring of major technical parts of the transportation cockpit we introduced above concept for the transportation cockpit actions via the interface /SCMTMS/IF_UI_TCACT. To have further a structured handling as well as convenience functions the abstract class /SCMTMS/CL_UI_TCACT_BASE implements this one.

New button in the transportation cockpit

Now if you want to create a new button in the cockpit, you need to do the following:

1) Create a new class implementing the interface (best also inherit from our base super class) and redefine the methods needed.

In a small example I implemented the action handler for a new button in the application toolbar:

    • the necessary get_action_id method populating that my new action handler should be called for the “ZTB_NEW_TC_ACTION” action
    • the execute method for raising a message telling my code is executed
    • the check_selection method as the superclass was expecting at least any selection and I didn’t want one to be necessary
CLASS ztb_cl_ui_tcact_enhancement DEFINITION
  PUBLIC
  INHERITING FROM /scmtms/cl_ui_tcact_base
  CREATE PUBLIC .
  PUBLIC SECTION.
    METHODS:
      /scmtms/if_ui_tcact~get_action_ids  REDEFINITION .
  PROTECTED SECTION.
    METHODS:
       execute         REDEFINITION ,
       check_selection REDEFINITION.
    CONSTANTS sc_my_action_id TYPE fpm_event_id VALUE 'ZTB_NEW_TC_ACTION'.
    CONSTANTS:
      BEGIN OF sc_messages,
        class         TYPE string VALUE 'ZTB_ACTION_MESSAGE',
        num_my_action TYPE i      VALUE 0,
      END OF sc_messages.
  PRIVATE SECTION.
ENDCLASS.

CLASS ZTB_CL_UI_TCACT_ENHANCEMENT IMPLEMENTATION.
  METHOD /scmtms/if_ui_tcact~get_action_ids.
    rt_action_ids = VALUE #( (  sc_my_action_id ) ).
  ENDMETHOD.
 
  METHOD check_selection.
    "do nothing in check selection as the new global button does not need a selection
  ENDMETHOD.

  METHOD execute.
    " just raise some message showing that this code was called
    et_messages = VALUE #( ( severity = 'W' msgid = sc_messages-class msgno = sc_messages-num_my_action ) ).
  ENDMETHOD.
ENDCLASS.

 

2) Adding the new button to the page layouts. Therefore, you need to add the button in the IMG activity “Define Settings for Page Layouts”. For the button you will need to define the same event name as you used as the action ID in your handler class. After defining the button, you need to add the button to the corresponding list toolbar.

In my example I added the new button to the application toolbar for the transportation cockpit.

New Button in TC customizing

 

3) After adding the button in the customizing it will appear in new created page layouts. Be aware that existing page layouts will only display the button after you updated them using the application “Synchronize Page Layouts with Customizing”.

New%20Button%20Appears%20In%20Page%20Layout

New Button Appears In Page Layout

 

After adding it to your page layout you can go into the transportation cockpit click on the button and consume the code you have written.

The new Button can Directly be Used

Overwrite or enhance a button in the transportation cockpit

After having explained how the concept enables you to add own buttons, I also want to tell you that for cockpit actions we went one level further.

As we know lot of customers want to enhance or change the behavior of standard buttons. Therefore, we introduced an additional priority concept in which you can give your classes a higher priority to the priority used from SAP standard.

The basic idea works on the same premise. You also create a class for action handling but this time you populate action IDs which are already covered from standard classes.

Additionally you now need to redefine the method /scmtms/if_factory_priority~get_priority to make your class more important than the standard one (keep in mind that lower priority value is more important and will get respected first).

In the following example I exchanged the “Assign selected items” button with just raising a method. For sure I could also called the super code if I would just want to add my message to the standard execution.

CLASS ztb_cl_ui_tcact_enh_overwrite DEFINITION
  PUBLIC
  INHERITING FROM /scmtms/cl_ui_tcact_base
  CREATE PUBLIC .
  PUBLIC SECTION.
    METHODS:
      /scmtms/if_factory_priority~get_priority REDEFINITION,
      /scmtms/if_ui_tcact~get_action_ids       REDEFINITION .
  PROTECTED SECTION.
    METHODS:
      execute         REDEFINITION ,
      check_selection REDEFINITION.
    CONSTANTS sc_my_action_id TYPE fpm_event_id VALUE 'ZTB_NEW_TC_ACTION'.
    CONSTANTS:
      BEGIN OF sc_messages,
        class         TYPE string VALUE 'ZTB_ACTION_MESSAGE',
        num_my_action TYPE i      VALUE 0,
      END OF sc_messages.
  PRIVATE SECTION.
ENDCLASS.

CLASS ZTB_CL_UI_TCACT_ENH_OVERWRITE IMPLEMENTATION.

  METHOD /scmtms/if_factory_priority~get_priority.
    rv_priority = 1.
  ENDMETHOD.

  METHOD /scmtms/if_ui_tcact~get_action_ids.
    rt_action_ids = VALUE #( (  /scmtms/if_ui_pln_c=>sc_action-ovp-plan_selected ) ).
  ENDMETHOD.

  METHOD check_selection.
    "do nothing in check selection as the new global button does not need a selection
  ENDMETHOD.

  METHOD execute.
    " just raise some message showing that this code was called
    et_messages = VALUE #( ( severity = 'W' msgid = sc_messages-class msgno = sc_messages-num_my_action ) ).
  ENDMETHOD.
ENDCLASS.

Conclusion and Outlook

I hope I could show you how easy enhancing the transportation cockpit got already. You can now add a new button with own logic or exchange a standard functionality w/o the need of any explicit enhancements. I hope you can use our improvements in your projects

I guess the decoupling of the TM code in similar ways just begun and we will further process it in future. The priority concept will be more rarely used at places we expect customers also to consume it.

Feel free to comment if you have ideas where this concept should enable you to plug in own developments easily.

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Emanuel Grabler
      Emanuel Grabler

      Good Stuff!

      Author's profile photo Adrian Ruano Gonzalez
      Adrian Ruano Gonzalez

      Hello Tobias,

      Very nice post! This a great way to centralize all actions in one class only.

      I start implementing this class to move some actions I have in FU and TU areas of the TC. The actions I already have implemented are in the viewexit class of each area, and consist of selecting multiple stages when clicking on the custom buttons.

      However, in the new class you have brought, the method GET_SELECTION always retrieves an empty selection although I have done it manually. Am I missing anything? Is it possible to perform UI actions, such as selecting stages automatically or this class is intended to perform BO actions?

      Thank you very much.

      Adrián Ruano

      Author's profile photo Tobias Berger
      Tobias Berger
      Blog Post Author

      Hi Adrián,

      First of all I would like to say that I definitely recommend to not use one class for all actions but also to use multiple Z-classes (sure a bunch of similar actions can and should be grouped in one).

      Now to your question. We totally focused on the execution of BO actions (as most of the standard actions are those) but I guess that it should work to implement pure UI actions.

      Regrading "GET_SELECTION" I guess the following is the issue: The action class which processed the current event will get the selection from the TC selection manager. While getting it it also clears the selection as from the TC perspective it's now handled. In TCACT_BASE we store the selection in member ms_selection.

      I guess the standard calls and fills the member and when you call it one more time it's cleared.

      If this is not the issue please use breakpoints in /SCMTMS/CL_UI_CONTROLLER_TCSEL methods ADD_SELECTION & GET_SELECTION.

      You should be able to see how the list is raising it's own selection using ADD and how some code uses GET - for all places which are calling GET also check IV_CLEAR_SELECTION.

      Hope this helps you out.

      BR
      Tobi