SRM7 – Include Custom logic inside standard FPM Action in PO
In this Blog I am going to talk to about, how to interrupt the standard FPM actions and induce our custom logic and then continue with the execution of standard code. Instead of just explaining the methodology, I would like to state an imaginary requirement and explain the methodology as we fulfill the requirement. Here is the most amazing requirement you have ever heard 🙂
When we click on EDIT button on PO screen, user should get a pop-up which will have some check boxes, each referring to a particular field of PO. Once the user selects some check box and clicks on OK button, corresponding field and label should be removed from the screen. Below is screen shot of how it should look
Now on a high level, we should know which code gets triggered when we click on EDIT button, enhance it and include the code to generate a pop-up screen. Also when we click on OK button execute whatever logic we want to execute and then let the standard code get execute.
How to figure out the code that gets executed when we click on EDIT button:
The header buttons in PO screen are not part of any particular webdynpro component. This makes it difficult to debug these actions. We have to go to the corresponding AppCC component ( refer to my blog to know more about AppCC ( Dynamically Modifying Purchase order FPM in SRM7 using custom AppCC) and debug the component controller method OVERRIDE_EVENT_OIF to figure out what code gets executed when we click on EDIT button. Below are the details
– control first goes to the statement wd_this->mo_oif_helper->override_event_oif( ). Here mo_oif_helper refers to class /SAPSRM/CL_FPM_OVRIDE_OIF_PO.
– once inside the method OVERRIDE_EVENT_OIF of class /SAPSRM/CL_FPM_OVRIDE_OIF_PO, control goes to the statement
EXPORTING io_event = mo_fpm_oif->mo_event ).
Here mo_ident_mapper refers to class /SAPSRM/CL_CH_WD_IDEN_MAP_PO. Inside the method handle_event is the code related to respective action.
How to generate a pop-up dialog box:
To do this, first we enhance the AppCC component and create a View ( POP_VIEW), a window (POP_WIN) and embed the view inside the window. Also, add two check box with descriptions as shown in the above screen shot ( I assume reader knows how create view, window and check boxes, so i am not going to explain that in detail here ).
Layout of the view
Create two context attributes and bind them to ‘Checked’ property of the check-box
Once we have everything ready, we go to the method HANDLE_EVENT method of class /SAPSRM/CL_CH_WD_IDEN_MAP_PO, create an implicit enhancement and insert the below code.
DATA lo_window_manager TYPE REF TO if_wd_window_manager.
DATA lo_api_component TYPE REF TO if_wd_component.
DATA lo_api_controller TYPE REF TO if_wd_controller.
DATA lo_window TYPE REF TO if_wd_window.
*check if the event is EDIT
IF io_event->mv_event_id = ‘FPM_EDIT’.
*check if pop up is required
IF zcl_popup=>popup_req EQ ‘X’.
lo_api_controller = mo_wd_component_controller->wd_get_api( ).
CALL METHOD lo_api_controller->get_component
component = lo_api_component.
*get access to window manager
lo_window_manager = lo_api_component->get_window_manager( ).
lo_window = lo_window_manager->create_window(
window_name = ‘POP_WIN’
title = ‘Please selct…’
message_display_mode = if_wd_window=>co_msg_display_mode_selected
close_button = abap_false
button_kind = if_wd_window=>co_buttons_ok
message_type = if_wd_window=>co_msg_type_none
default_button = if_wd_window=>co_button_ok
* Set the height and width here
lo_window->set_window_size( width = ‘20%’ height = ‘15%’ ).
To your surprise, most important piece of code in the above code is ‘EXIT’ statement. If we don’t exit from the method after raising the pop up, what happens is, we get the pop-up BUT system continues with the afterwards code and removes the pop-up from the screen. So, we will not be able to select any check box on the pop-up. In order for pop-up to stay on the screen, till we select something on the screen and click on OK button, we have to exit the method. But there is a catch here… If we exit the method, we are skipping the actual code related to EDIT action. So, we have to somehow re trigger the action EDIT, once we are done with check box selection on pop-up ( Just to keep the suspense alive, I will come back to this later 🙂 )
I have created a class with name ZCL_POPUP and added three static attributes as shown below
Here POPUP_REQ attribute is used to check, if pop-up needs to be created or not ( by default it is set to ‘X’). Attributes CHECK1 and CHECK2 are used to capture the selection made by the user on pop-up screen.
Let’s look at what happens in the view POP_VIEW…
In WDDOMODIFYVIEW method, we use the below code to assign an action to button OK on pop-up
DATA:l_api TYPE REF TO if_wd_view_controller,
l_window_ctlr TYPE REF TO if_wd_window_controller,
l_popup TYPE REF TO if_wd_window.
l_api = wd_this->wd_get_api( ).
l_window_ctlr = l_api->get_embedding_window_ctlr( ).
IF l_window_ctlr IS BOUND.
l_popup = l_window_ctlr->get_window( ).
button = if_wd_window=>co_button_ok
action_name = ‘OK’
action_view = l_api
is_default_button = abap_true ).
we also add an event with name OK, this creates an event handler with name ONACTIONOK in methods tab of the view POP_VIEW. In the action handler we write the below code
DATA: lo_fpm TYPE REF TO if_fpm.
DATA lo_el_context TYPE REF TO if_wd_context_element.
DATA ls_context TYPE wd_this->element_context.
DATA lv_check1 TYPE wd_this->element_context-check1.
DATA lv_check2 TYPE wd_this->element_context-check2.
*clear static attribute popup_req
* get element via lead selection
lo_el_context = wd_context->get_element( ).
* read context attributes check1 and check2
name = `CHECK1`
value = lv_check1 ).
name = `CHECK2`
value = lv_check2 ).
*set the static variables
zcl_popup=>check1 = lv_check1.
zcl_popup=>check2 = lv_check2.
*Get rererence to current FPM instance
lo_fpm = cl_fpm_factory=>get_instance( ).
*Trigger the EDIT action again
CALL METHOD lo_fpm->raise_event_by_id
iv_event_id = ‘FPM_EDIT’.
Here we are reading the context attributes CHECK1 and CHECK2 and store the values in static attributes of the class ZCL_POPUP. Then using raise_event_by_id method we are re triggering event FPM_EDIT ( suspense is over now.. 🙂 )
Now to Hide the PO number and PO name fields from the overview, we can use the BADI WD_BADI_DOMODIFYVIEW. Create an implementation with below filter
Inside the method IF_WD_BADI_DOMODIFYVIEW~WDDOMODIFYVIEW, write below code
DATA : lo_ref TYPE REF TO cl_wd_transparent_container.
lo_ref ?= view->get_element( ‘LEFT_CONTAINER’ ).
IF zcl_popup=>check1 EQ ‘X’.
IF lo_ref IS NOT INITIAL.
lo_ref->remove_child( id = ‘PO_NUMBER_LABEL’ ).
lo_ref->remove_child( id = ‘PO_NUMBER’ ).
IF zcl_popup=>check2 EQ’X’.
IF lo_ref IS NOT INITIAL.
lo_ref->remove_child( id = ‘PO_NAME_LABEL’ ).
lo_ref->remove_child( id = ‘PO_NAME’ ).
Here based on values of static attributes CHECK1 and CHECK2 of class ZCL_POPUP, we conditionally remove PO number / PO name fields from the PO screen
User clicks on EDIT button on PO screen, which triggers a pop-up that has two check boxes on it. User selects both the check boxes and clicks on OK button.
After OK button is clicked, PO number and PO name fields are removed from the overview screen.
I am sure that there might be a better solution for this and I sincerely welcome all the suggestions from readers.
Finally, I would like to thank Matteo Montalto for his invaluable contribution towards this blog.