Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member184741
Active Contributor

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 :smile:

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

mo_ident_mapper->handle_event(

            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


        RECEIVING


          component = lo_api_component.



*get access to window manager


      lo_window_manager = lo_api_component->get_window_manager( ).



*create window


      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%' ).


      lo_window->open( ).


      EXIT.


    ENDIF.


  ENDIF.


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 :smile: )

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( ).




    l_popup->subscribe_to_button_event(


       button = if_wd_window=>co_button_ok


       action_name = 'OK'


       action_view = l_api


       is_default_button = abap_true ).




  ENDIF.



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



  CLEAR zcl_popup=>popup_req.



* get element via lead selection


  lo_el_context = wd_context->get_element( ).




* read context attributes check1 and check2


  lo_el_context->get_attribute(


    EXPORTING


      name =  `CHECK1`


    IMPORTING


      value = lv_check1 ).




  lo_el_context->get_attribute(


     EXPORTING


       name =  `CHECK2`


     IMPORTING


       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


    EXPORTING


      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.. :smile:   )

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' ).


    ENDIF.



  ENDIF.




  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' ).


    ENDIF.



  ENDIF.



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

DEMO:

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.

Labels in this area