Supply Chain Management Blogs by SAP
Expand your SAP SCM knowledge and stay informed about supply chain management technology and solutions with blog posts by SAP. Follow and stay connected.
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_foerster
Associate
Associate
1,665

Motivation


For any reason you may want to identify the current application context of the current UI in your own custom code. One reason might be: The type-ahead proposed values for an input field may not contain the desired values (which would end users help saving time by avoiding the use of the good old F4 help popups) - independent of whether TM is run on a HANA DB or not. Hence you may want to do a project based enhancement to narrow down the type ahead search results - depending on the current TM application UI context.

 

Preamble / Background


When you start entering a value in an input field, the system checks whether a so called type-ahead-search is enabled and is available to propose up to 10 values in a drop down. Actually the relevant DDIC search help is executed and returns the first 10 hits. If you continue typing, then the system restarts the search help again and again and hence you narrow down the search result by the standard search criteria. Based on the current context of your transaction, you may want to set other selection criteria (taken from the current UI) to automatically narrow down the hit list. For cases, where in TM Standard this was not done or foreseen via the UI structure and having additional fields as input fields for the DDIC search help, I explain below how you recognize programmatically the context in a search help exit in order to add search criteria.
If there is a collective search help and there are multiple elementary search helps, which are enabled for type ahead, then the system seems to pick the last elementary search help, which the user has used in the regular F4 help popup, but there is no clear default search help. You may want to set one particular elemenatry search help as the single type ahead search help. I explain below how this could be done.

 

Business Context of the example


The Freight Forwarder's Customer Service representative is creating a Forwarding Order (FWO) and is now about to enter a pick up location. (For sake of completeness: If this is a door-to-door shipment and the Shipper/Consignee have got only one single location, then the locations are defaulted. I assume here that there are multiple pick-up / delivery locations.) In TM standard the type ahead search for the location field uses the location ID as the only search criteria. Hence all the existing locations (could easily be millions) are relevant. You may want the system to add the already entered Business Partner "Shipper" or "Consignee" as an additional selection criteria (depending on the location-field) or you may want the system to add the location type "Customer" as an additional selection criteria - depending on the current context of the end users transaction.

 

Remark: Customer pickup locations usually have got a numeric ID, which the end users not tend to memorize. In HANA DB based TM systems the system automatically does a multi column fuzzy search and hence would also find numeric locations while typing the customer name. But hit list could still be 10+. In a non-HANA DB based TM system using belows concept you could also switch the search criteria from location ID to customer name or city name, but usually it is already sufficient to add the Shipper/Consignee as an additional serach criteria.




Code snippet to determine the context of the UI


I actually only intended to publish the rather complex way to determine the current context of a TM UI and how to retrieve data from the current instance although you are on the UI layer. Hence find here the relevant code snippet kind of hidden inbetween the lengthy story. As it was not fully self-explanatory I took the time to grew this post to come with an end to end story. Find the full example, which brings the the code snippet into action, in a separate section below.
...
* assuming this piece of code is only executed from UI and not in batch mode...
DATA lo_fpm TYPE REF TO if_fpm.
lo_fpm = cl_fpm_factory=>get_instance( ).

DATA lo_fbi TYPE REF TO /bofu/if_fbi_controller_new.
lo_fbi ?= /bofu/cl_fbi_controller_new=>get_instance( ).

DATA ls_fpm_runtime_info TYPE fpm_s_runtime_info.
ls_fpm_runtime_info = lo_fpm->get_runtime_info( ).

* ... depending from which UI the location search is triggered:
IF ls_fpm_runtime_info-config_id = '/SCMTMS/FWD_ORDER_OCEAN'.
* get the current instance
lt_root_key = lo_fbi->mo_connector->mo_source_entity->get_self_keys( ).
READ TABLE lt_root_key INTO ls_root_key INDEX 1.
CHECK sy-subrc = 0.
* read data of current instance directly from buffer or via retrieve via BOBF transaction manager
READ TABLE lo_fbi->mt_node_buffer ASSIGNING FIELD-SYMBOL(<ls_node_buffer>)
WITH KEY bo_key = /scmtms/if_trq_c=>sc_bo_key
node_key = /scmtms/if_trq_c=>sc_node-root.
IF sy-subrc EQ 0.
ASSIGN <ls_node_buffer>-t_data->* TO <lt_any_node_data>.
* here we know - it's a TRQ instance (as we know from which UI it is called)
lt_trq_data = <lt_any_node_data>.
READ TABLE lt_trq_data ASSIGNING <ls_trq_root_data> WITH KEY key = ls_root_key-key.
IF sy-subrc EQ 0.
...

 

Full Example


As indicated in the above section about the business context of the example, in TM standard it is not foreseen to use a BP or loc type as additional search criteria for a location search by default.
There might be shorter or simpler ways - I prototyped it modification-free. Find below the steps (assuming you know the technical backround).
1. Copy the standard SH /SAPAPO/TM_LOCADR and add the field PARTNER_GUID (data element BU_PARTNER_GUID)
2. Copy the SH exit of this SH (function /SAPAPO/F4IF_SHLP_EXIT_TMLOCNO) - the code is added in step 7
3. Copy the search method (DDIC view /SAPAPO/T_LOCADR) of the SH and add the field PARTNER_GUID (data element BU_PARTNER_GUID) here too
4. Enhance the standard collective search help /SCMTMS/LOC with an append
5. In the new append-collective-SH add your copied elementary SH and define the assignment (mapping) of SH fields
Relevant Screenshots for above steps:









6. Enhance the standard SH exit /SCMTMS/EXIT_SH_LOC of the Collective SH /SCMTMS/LOC

In the standard function switch into Enhance mode and create an implicit post exit and just delete all other SHs except yours in order to force the system to take this SH for the type ahead search.





7. Put the required code into your SH exit (from step 2)

For sake of testing you may want to delete all the in step 2 copied code first, which is for display authorization check purposes only. Once you use it in production it has to be added back in.
This SH exit brings the actual code snippet of concern into action. The system first identifies the WD UI configuration, hence you know in which business context the user is AND then the system determines the current document key, with which you can do all the nice things (for the known BO nodes), which you are used to do in TM backend...
In this example I retrieve the Shipper or the Consignee (from the current TRQ instance's root) depending on the field, for which the user just is typing in a value, and add the ID as an additional selection criteria to the selopt table. I also picked a simple use case - at the end I just added a particular location type as a selection criteria.
Following the same path you could add other SH fields too or modify the standard select option - here e.g. the select option for the location ID field LOCNO could be modified to use the user value for the location's description field (DESCR40) instead.


DATA:
ls_root_key TYPE /bobf/s_frw_key,
lt_root_key TYPE /bobf/t_frw_key,
lt_trq_data type /scmtms/t_trq_root_k.

FIELD-SYMBOLS:
<ls_trq_root_data> TYPE /scmtms/s_trq_root_k,
<lt_any_node_data> TYPE INDEX TABLE,
<ls_selopt> TYPE ddshselopt,
<ls_interface> TYPE ddshiface.

IF callcontrol-step = 'PRESEL'.

* add selection criteria only for type ahead search, not for regular F4 help popup
CHECK cl_web_dynpro=>valuehelpinfo-valuesuggest = abap_true.

READ TABLE shlp-interface ASSIGNING <ls_interface>
WITH KEY shlpfield = 'LOCNO'.
CHECK sy-subrc = 0.
* ABAP WD field, for which the type ahed search runs: <ls_interface>-VALFIELD
IF <ls_interface>-valfield IS INITIAL.
* ABAP WD bug; I put the valfield into memory in the collective search help exit.
IMPORT <ls_interface>-valfield from memory ID 'ZSTFLOCF4-FIELD'.
ENDIF.

* assuming this piece of code is only executed from UI and not in batch mode...
DATA lo_fpm TYPE REF TO if_fpm.
lo_fpm = cl_fpm_factory=>get_instance( ).

DATA lo_fbi TYPE REF TO /bofu/if_fbi_controller_new.
lo_fbi ?= /bofu/cl_fbi_controller_new=>get_instance( ).

DATA ls_fpm_runtime_info TYPE fpm_s_runtime_info.
ls_fpm_runtime_info = lo_fpm->get_runtime_info( ).

* ... depending from which UI the location search is triggered:
IF ls_fpm_runtime_info-config_id = '/SCMTMS/FWD_ORDER_OCEAN'.
* get the current instance
lt_root_key = lo_fbi->mo_connector->mo_source_entity->get_self_keys( ).
READ TABLE lt_root_key INTO ls_root_key INDEX 1.
CHECK sy-subrc = 0.
* read data of current instance directly from buffer or via retrieve via BOBF transaction manager
READ TABLE lo_fbi->mt_node_buffer ASSIGNING FIELD-SYMBOL(<ls_node_buffer>)
WITH KEY bo_key = /scmtms/if_trq_c=>sc_bo_key
node_key = /scmtms/if_trq_c=>sc_node-root.
IF sy-subrc EQ 0.
ASSIGN <ls_node_buffer>-t_data->* TO <lt_any_node_data>.
* here we know - it's a TRQ instance (as we know from which UI it is called)
lt_trq_data = <lt_any_node_data>.
READ TABLE lt_trq_data ASSIGNING <ls_trq_root_data> WITH KEY key = ls_root_key-key.
IF sy-subrc EQ 0.
* pre-fill the BP selection criteria for the location search
* ... depending on whether it's the pick-up or the delivery location
IF <ls_interface>-valfield = 'SRC_LOC_ID'.
IF NOT <ls_trq_root_data>-shipper_key IS INITIAL.
INSERT INITIAL LINE INTO TABLE shlp-selopt ASSIGNING <ls_selopt>.
<ls_selopt>-shlpname = 'ZSTF_TM_LOCADR'.
<ls_selopt>-shlpfield = 'PARTNER_GUID'.
<ls_selopt>-sign = 'I'.
<ls_selopt>-option = 'EQ'.
<ls_selopt>-low = <ls_trq_root_data>-shipper_key.
ENDIF.
ELSEIF <ls_interface>-valfield = 'DES_LOC_ID'.
IF NOT <ls_trq_root_data>-consignee_key IS INITIAL.
INSERT INITIAL LINE INTO TABLE shlp-selopt ASSIGNING <ls_selopt>.
<ls_selopt>-shlpname = 'ZSTF_TM_LOCADR'.
<ls_selopt>-shlpfield = 'PARTNER_GUID'.
<ls_selopt>-sign = 'I'.
<ls_selopt>-option = 'EQ'.
<ls_selopt>-low = <ls_trq_root_data>-consignee_key.
ENDIF.
ENDIF.
ENDIF.
ENDIF.

* set the allowed LOCTYPEs
INSERT INITIAL LINE INTO TABLE shlp-selopt ASSIGNING FIELD-SYMBOL(<ls_selopt_loctype>).
<ls_selopt_loctype>-shlpname = 'ZSTF_TM_LOCADR'.
<ls_selopt_loctype>-shlpfield = 'LOCTYPE'.
<ls_selopt_loctype>-sign = 'I'.
<ls_selopt_loctype>-option = 'EQ'.
<ls_selopt_loctype>-low = '1010'.

ENDIF.
ENDIF.

 

Result: significant user efficiency improvement


System behaviour without the enhancement:
The end user has to use the F4 help popup (using the mouse) and has to navigate to the right elementary search help via the drop down on the popup and type additional selection criteria in order to find the right pick up or delivery location.


System behaviour with the above enhancement in place:
The end user just types a '*' and the system auto-proposes the 2 delivery locations of the consignee (mouse-free certainly). The end user uses the arrow down key to select the right location and continues with the tab key to the next input field. It's a matter of a second now.
1 Comment