Skip to Content

Hello folks,

In my previous blog, I’d explain how a Generic FM to call the BOL/Genil Search Object. Here, I shall explain how to draft a generic FM to read the attributes and the children of the BOL objects.

Scope: In projects that involve developing/enhancing the CRM UI experience with external technologies like Adobe flex/AIR, there is always a need to develop RFCs to fetch the CRM objects like Accounts, One order objects or other master data. In such scenario, this generic FM will come in handy.

Functionality

A single multip purpose FM, to accept a BOL entity, a relationship name (multiple) and return all the entity attributes in a table.

Eg: You have a BuilHeader entity and a relationship name, BuilAddressRel/BuilAddressPhoneRel and want all the phone numbers in a internal table.

Prerequisites

1) Need to know the BOL application name. For eg: the application name for Business Transactions is ‘BT’.

(these values are stored in Table CRMC_GIL_APPCOMP. This is also
accessible from SPRO, through the node CRM->CRM Cross App
Comps->GENIL->Basic Settings)

2) The BOL entity’s instance is required. (a referrence variable pointing to an object of kind CL_CRM_BOL_ENTITY). This can be obtained by doing the generic search (Generic FM to call the BOL/Genil Search Object).

3) Relationship name. Once you have the application name, you can refer to the relationships under it through the BOL Model Browser (Tx: GENIL_MODEL_BROWSER). Identify the relationship name that you are interested to read.

To make the code completely generic, we will accept multiple heirarchy relationship names. Eg BuilAddressRel/BuilAddressPhoneRel. In this case, we will split the relationship names and call the same FM recursively for all the relationships.

Steps

Once we have the entity and the relationship name, we know the BOL method to read the entities is get_related_entities(), but now we are going to try and make this generic enough to work for all the relationships.

(Complete code is at the end of the post)

1. Get the object model from the application name

lv_obj_model = cl_crm_genil_model_service=>get_runtime_model
( iv_application = iv_application ).

2. Get the Object name from the relationship name 

      CALL METHOD lv_obj_model->get_related_object
        EXPORTING
          iv_relation_name = lv_relation_name
        RECEIVING
          rv_object_name   = lv_obj_name.

3. Get the structure name from the object name

lv_struc_name = lv_obj_model->get_attr_struct_name( lv_obj_name ).

We need to get the structure name because our code is generic and we need to use field symbols which will be instanciated on the run time.

  CREATE DATA lt_data TYPE TABLE OF (lv_struc_name).
  CHECK lt_data IS BOUND.
  CREATE DATA ls_data TYPE (lv_struc_name).
  CHECK ls_data IS BOUND.

4. Since there is a possibility of multiple relationship names being passed, we need to split it and get the first relationship and read its entities

SPLIT iv_relation_name AT '/' INTO lv_relation_name lv_relation_name2.+ +

  lr_collection = ir_entity->get_related_entities(

                              iv_relation_name = lv_relation_name

                              iv_mode          = 'b' ).

5. We then need to check if we have any more relationships left after split and branch accordingly

   a. If there are no more relationships, we get the properties and append to the export table

   b. If there are more relationships, we then need to call the same FM recursively

 

I’ll follow up with a generic FM to update the values of an entity. If you guys have any clarifications or comments, please leave them below.

*Complete Code *

FUNCTION generic_bol_mul_col_fetch.

*”—-


“Local Interface:

*”  IMPORTING

*”     REFERENCE(IR_ENTITY) TYPE REF TO  CL_CRM_BOL_ENTITY

*”     REFERENCE(IV_APPLICATION) TYPE  CRMT_GENIL_APPL

*”     REFERENCE(IV_RELATION_NAME) TYPE  YDE_REL_NAME_LONG

*”  EXPORTING

*”     REFERENCE(ET_DATA) TYPE REF TO  DATA

*”     REFERENCE(ET_RETURN) TYPE  BAPIRET2_T

*”—-


 

  DATA: lv_obj_model            TYPE REF TO if_genil_obj_model,           ” Reference for Object Model

    CATCH cx_crm_unsupported_relation .                 “#EC NO_HANDLER<br />

  ENDTRY.<br />

  lv_struc_name = lv_obj_model->get_attr_struct_name( lv_obj_name ).<br />

  CREATE DATA lt_data TYPE TABLE OF (lv_struc_name).<br />

  CHECK lt_data IS BOUND.<br />

  CREATE DATA ls_data TYPE (lv_struc_name).<br />

  CHECK ls_data IS BOUND.<br />

  ASSIGN: lt_data->* TO <ft_result_attr>,<br />

          ls_data->* TO <fs_result_attr>.<br />

  SPLIT iv_relation_name AT ‘/’ INTO lv_relation_name lv_relation_name2.++<br />

  lr_collection = ir_entity->get_related_entities(<br />

                              iv_relation_name = lv_relation_name<br />

                              iv_mode          = ‘b’ ).++<br />

  IF lr_collection IS BOUND.<br />

    TRY.<br />

        lr_entity ?= lr_collection->get_first( ).<br />

        WHILE lr_entity IS BOUND.<br />

          IF lv_relation_name2 IS INITIAL.<br />

            TRY.<br />

                CALL METHOD lr_entity->if_bol_bo_property_access~get_properties<br />

                  IMPORTING<br />

                    es_attributes = <fs_result_attr>.<br />

                INSERT <fs_result_attr> INTO TABLE <ft_result_attr>.<br />

              CATCH cx_crm_genil_model_error INTO lr_ex.<br />

            ENDTRY.<br />

          ELSE.<br />

            IF lr_entity IS BOUND.<br />

              CALL FUNCTION ‘GENERIC_BOL_MUL_COL_FETCH'<br />

                EXPORTING<br />

                  ir_entity        = lr_entity<br />

                  iv_application   = iv_application<br />

                  iv_relation_name = lv_relation_name2<br />

                IMPORTING<br />

                  et_data          = lt_data2.<br />

              ASSIGN lt_data2->* TO <ft_data>.<br />

              IF <ft_data> IS ASSIGNED.<br />

                LOOP AT <ft_data> ASSIGNING <fs_data>.<br />

                  INSERT <fs_data> INTO TABLE <ft_result_attr>.<br />

                ENDLOOP.<br />

                UNASSIGN <ft_data>.<br />

              ENDIF.<br />

            ENDIF.<br />

          ENDIF.<br />

          lr_entity ?= lr_collection->get_next( ).<br />

        ENDWHILE.<br />

      CATCH  cx_crm_genil_model_error INTO lr_ex.<br />

    ENDTRY.<br />

  ENDIF.<br />

  et_data = lt_data.<br />

ENDFUNCTION.</pre>

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply