Skip to Content
Technical Articles

MDG-C: Initial page for customer creation

Business Scenario

When you implement field values derivations based on some key fields (e.g. BP Grouping or BP Roles) it is not good when user change the key values after some derivations have already been run, especially if you still allow user to overwrite the derived values.

Assume that based on key field value K1=”Y” values of two other fields have been derived like: F1=”A”, F2=”B”. Then user decides to change template value of F2 into “C”.
So far, so good, but what if user wants now to change key field value K1 into “Z” and based on template the new values of F1, F2 are “D”, “E”.
Should the current values “A” and “C” be replaced with the new ones? Both, or just value of F1?

One of the solutions for that problem is to prevent the user from changing the key field value after it has already been set. This could be achieved with field properties BAdI (field editable if empty, otherwise read-only), however that would be not “natural” behavior of the UI. The better solution seems to be initial page on which user selects the key values and after confirmation the values are moved into corresponding read-only fields of the following data maintenance page.

Something like that:

Implementation

In standard approach you create new Customer from Search application like below:

In the list UIBB configuration you can see that in this case CREATE_ORG event is triggered with logical action CREATE:

 

Now let’s check what is happening in the feeder class of the search result list:

In case when we create new Organization a new parameter CATEGORY=2 is added to URL and navigation to new page of Customer Creation is triggered. This is the right place to set our initial page.

The “initial page” can be called as standalone application or as dialog box. Below I describe solution for the second option.

First, we need to create the dialog box page. Do it either with customizing or CBA adaptation of BS_OVP_CU configuration of application BS_OVP_BP.

Beforehand you need to create some UIBB to be embedded in this dialog box – I will not go into details how to do that, as there are many tutorials available in the Internet.

In my solution I’ve added an identifier “DEFERRED” to the event parameter CREATE_ORG mentioned already above:

This will allow to determine, that the handler of the CREATE_ORG event (i.e. previously mentioned method ON_CREATE) should open our “initial page dialog box” instead of navigating to the standard “customer creation page”.

After user selects/types data in the dialog and confirms with OK button then again the same event CREATE_ORG is called however without “DEFERRED” identifier but with the data typed by user passed in event parameters.

Below is an example how the overwrite exit of ON_CREATE method can look like. Note that the event ‘CREATE_ORG’ is handled in two ways: with “DEFERRED” identifier it opens dialog box and without the identifier (called already from the dialog) it collects data from the event parameters and pass them as URL parameters to the standard “customer creation page”.

METHOD iow_zmdgc_qr_enh~on_create.
  DATA:
    lt_url_parameters TYPE tihttpnvp,
    ls_url_parameter  LIKE LINE OF lt_url_parameters.

  core_object->mv_action = 'CREATE'.
  ls_url_parameter-name = 'CATEGORY'.
  CASE io_event->mv_event_id.
    WHEN 'CREATE_PER'.
      ls_url_parameter-value = '1'.
    WHEN 'CREATE_ORG'.
      ls_url_parameter-value = '2'.
    WHEN 'CREATE_GRP'.
      ls_url_parameter-value = '3'.
  ENDCASE.
  APPEND ls_url_parameter TO lt_url_parameters.

* Up to now - everything copied from standard 
  IF io_event->mv_event_id EQ 'CREATE_ORG'.
    DATA: lr_params TYPE REF TO data.
    FIELD-SYMBOLS: <lt_params> TYPE wdr_event_parameter_list,
                   <lv_any>    TYPE any. 
     DO 1 TIMES.
      io_event->mo_event_data->get_value( EXPORTING iv_key   = 'CONF_EVENT_PARAMS'
                                          IMPORTING er_value = lr_params ).
      IF lr_params IS BOUND.
        ASSIGN lr_params->* TO <lt_params>.
        READ TABLE <lt_params> ASSIGNING FIELD-SYMBOL(<ls_identifier>) WITH TABLE KEY name = 'IDENTIFIER'.
        CHECK sy-subrc EQ 0.
        ASSIGN <ls_identifier>-value->* TO FIELD-SYMBOL(<lv_identif>).
        CHECK sy-subrc EQ 0 AND <lv_identif> EQ 'DEFERRED'.
* Initialize dialog
        TRY.
            DATA lr_event_parameters TYPE REF TO if_fpm_parameter.
            CREATE OBJECT lr_event_parameters TYPE cl_fpm_parameter.
            lr_event_parameters->set_value( iv_key = if_fpm_constants=>gc_dialog_box-id
                                            iv_value = 'Z_INITIAL_DATA' ).
            DATA(lr_event) = cl_fpm_event=>create_by_id( iv_event_id    = 'FPM_OPEN_DIALOG'
                                                         io_event_data  = lr_event_parameters
                                                         iv_action_type = if_fpm_constants=>gc_action_type-standard ).
            cl_fpm_factory=>get_instance( )->raise_event( lr_event ).
            RETURN.
          CATCH cx_root.
        ENDTRY.
      ELSE.
* Add new parameters collected from dialog - just for clarity only BU_GROUP is added here, 
* the other values should be passed in similar way
        io_event->mo_event_data->get_value( EXPORTING iv_key   = 'DIALOG_BOX_ID'
                                            IMPORTING er_value = lr_params  ).
        CHECK lr_params IS BOUND.
        ASSIGN lr_params->* TO <lv_any>.
        CHECK <lv_any> EQ 'Z_INITIAL_DATA'.
        CLEAR lr_params.
        io_event->mo_event_data->get_value( EXPORTING iv_key   = 'BU_GROUP'
                                            IMPORTING er_value = lr_params  ).

        IF lr_params IS BOUND.
          ASSIGN lr_params->* TO <lv_any>.

          ls_url_parameter-name = 'BU_GROUP'.
          ls_url_parameter-value = <lv_any>.
          APPEND ls_url_parameter TO lt_url_parameters.
        ENDIF.
      ENDIF.
    ENDDO.

  ENDIF.

  core_object->navigate_to_ovp( lt_url_parameters ).
ENDMETHOD.

The PROCESS_EVENT method of the dialog box UIBB feeder can look like below:

METHOD if_fpm_guibb_form~process_event.
  DATA: lv_str TYPE string.

  CHECK io_event->mv_event_id EQ 'FPM_CLOSE_DIALOG'.
  io_event->mo_event_data->get_value( EXPORTING iv_key   = 'IN_DIALOG_MODE'
                                      IMPORTING ev_value = lv_str ).
  CHECK lv_str EQ abap_true.

  io_event->mo_event_data->get_value( EXPORTING iv_key   = 'DIALOG_BOX_ID'
                                      IMPORTING ev_value = lv_str ).
  CHECK lv_str EQ 'Z_INITIAL_DATA'.

  io_event->mo_event_data->get_value( EXPORTING iv_key   = 'DIALOG_BUTTON_ACTION'
                                      IMPORTING ev_value = lv_str ).
  CHECK lv_str EQ 'OK'.

  IF abap_true EQ validate_data( CHANGING ct_messages = et_messages ).
    TRY.
        DATA lr_event_parameters TYPE REF TO if_fpm_parameter.
        CREATE OBJECT lr_event_parameters TYPE cl_fpm_parameter.
        lr_event_parameters->set_value( iv_key   = if_fpm_constants=>gc_dialog_box-id
                                        iv_value = 'Z_INITIAL_DATA' ).
        lr_event_parameters->set_value( iv_key   = 'BU_GROUP'
                                        iv_value = gs_form_data-bu_group ).
        DATA(lr_event) = cl_fpm_event=>create_by_id( iv_event_id    = 'CREATE_ORG'
                                                     io_event_data  = lr_event_parameters
                                                     iv_action_type = if_fpm_constants=>gc_action_type-standard ).
        cl_fpm_factory=>get_instance( )->raise_event( lr_event ).
      CATCH cx_root.
    ENDTRY.
  ELSE.
    ev_result = if_fpm_constants=>gc_event_result-failed.
  ENDIF.
ENDMETHOD.

The last thing you need to do is just use the values passed as URL parameters in e.g. derivation BAdI. To access the values use the code snippet below:

DATA: lt_params TYPE tihttpnvp,
      ls_param  LIKE LINE OF lt_params.

DATA(lo_app_param) = cl_fpm=>get_instance( )->mo_app_parameter.

LOOP AT lo_app_param->get_keys( ) INTO ls_param-name.
  lo_app_param->get_value( EXPORTING iv_key   = ls_param-name 
			   			   IMPORTING ev_value = ls_param-value ).
  IF ls_param-value IS NOT INITIAL.
	INSERT ls_param INTO TABLE lt_params.
  ENDIF.
ENDLOOP.
1 Comment
You must be Logged on to comment or reply to a post.