Building field catalog in Floorplan Manager

Tags: FPM

As you already know, Floorplan Manager was built on top of ABAP WebDynpro to standardize the look & feel and development of web based UIs built with ABAP. Some of the generic tasks is to create the field catalog and description. We'll go through proper field setup in case of FORM, LIST and TREE GUIBBs.

FPM form field catalog - method IF_FPM_GUIBB_FORM~GET_DEFINITION

    DATA:
      ls_carrier 	 TYPE scarr,
      ls_component       TYPE abap_componentdescr.

    FIELD-SYMBOLS:
      <ls_field_descr>  TYPE fpmgb_s_formfield_descr.

    eo_field_catalog ?= cl_abap_structdescr=>describe_by_data( ls_carrier ).

    LOOP AT eo_field_catalog->get_components( ) INTO ls_comp.
      CASE ls_component-name.
        WHEN 'CARRID'.
          APPEND VALUE #(
            name = ls_component-name
            default_display_type = if_fpm_guibb_constants=>gc_display_type-drop_down_list_box
          ) TO et_field_description.
 
        WHEN OTHERS.
          APPEND INITIAL LINE TO et_field_description ASSIGNING <ls_field_descr>.
          <ls_field_descr>-name = ls_component-name.
      ENDCASE.
    ENDLOOP. 

You could usecl_abap_structdescr=>describe_by_name( 'SCARR' )instead, without declaring ls_carrier, but this would hide this usage of structure SCARR, in the where-used-list, which is wrong. Common task is to find standard data in customer code, or find the usage of customer dictionary objects in the source code.

You can do your adjustments on field properties, maintaining the mandatory et_field_description, which has to contain exactly the same components as the eo_field_catalog, always. 

FPM list field catalog - method IF_FPM_GUIBB_LIST~GET_DEFINITION

    DATA:
      lt_payment_data      TYPE zdtt_payment,  "<-This is a table type
      lr_structdescr       TYPE REF TO cl_abap_structdescr,
      lr_structdescr_incl1 TYPE REF TO cl_abap_structdescr,
      lr_structdescr_incl2 TYPE REF TO cl_abap_structdescr,
      ls_component         TYPE abap_componentdescr,
      ls_component_incl1   TYPE abap_componentdescr,
      ls_component_incl2   TYPE abap_componentdescr.

    FIELD-SYMBOLS:
      <ls_field_descr>  TYPE fpmgb_s_listfield_descr.

    "Field catalog
    eo_field_catalog ?= cl_abap_tabledescr=>describe_by_data( lt_payment_data ).
    lr_structdescr ?= eo_field_catalog->get_table_line_type( ).

    "Field description
    "We analyze two level of includes, when more levels (will be) included, just code a recursive processing
    LOOP AT lr_structdescr->get_components( ) INTO ls_component.
      IF ls_component-as_include EQ abap_true.
        lr_structdescr_incl1 ?= ls_component-type.
        LOOP AT lr_structdescr_incl1->get_components( ) INTO ls_component_incl1.
          IF ls_component_incl1-as_include EQ abap_true.
            lr_structdescr_incl2 ?= ls_component_incl1-type.
            LOOP AT lr_structdescr_incl2->get_components( ) INTO ls_component_incl2.
              APPEND VALUE #( name = ls_component_incl2-name ) TO et_field_description.
            ENDLOOP.
          ELSE.
            APPEND VALUE #( name = ls_component_incl1-name ) TO et_field_description.
          ENDIF.
        ENDLOOP.
      ELSE.
        APPEND VALUE #( name = ls_component-name ) TO et_field_description.
      ENDIF.
    ENDLOOP.

    "Adjust field description
    LOOP AT et_field_description ASSIGNING <ls_field_descr>.
      CASE <ls_field_descr>-name.
        WHEN 'SKONT'.
          <ls_field_descr>-default_display_type = if_fpm_guibb_constants=>gc_display_type-input_field.
          <ls_field_descr>-ddic_shlp_name = 'ZSKONT'.
        WHEN 'ACTION_DEL_VISIBLE'.
          <ls_field_descr>-technical_field = abap_true.
      ENDCASE.
    ENDLOOP. 

FPM tree field catalog - method IF_FPM_GUIBB_TREE~GET_DEFINITION

Alternate name of the Tree is Hierarchical List. It is not enough to collect the same fields into field description table et_field_description, but you need to tell the system, which fields are the technical fields containing the required data to build the hierarchy. To do this, implement method set_tree_master_columns. You can include structure FPMGB_S_TREE_MASTER_COLUMN into your data structure (on which zdtt_payment_tree table type is based on in our example) containing all the required fields by the system, to build the tree. These inlcuded fields are marked in method set_tree_master_columns as the technical fields of the tree.

Building the tree 

You can attach a node/leaf under a node in the hierarchy setting the PARENT_KEY of the current row to a ROW_KEY of a different row. Building a tree is such easy.
Hint : you do not need to generate GUIDs/UUIDs as ROW_KEY, create your own meaningful row keys instead manually, helping analyzis and data processing, to save a separate technical field. F.e. for rows containing Purchase Order Documents PO:2014:0056789:0001, and for rows containing Goods Receipt Documents GR:2014:6000789:0003 from their (db) keys. Encapsulate the logic to generate and analyze the keys, and to be able to evaluate about a row which kind of business data is contained, when accessing the UI data in LOOPs, when converting to API/DB data structure format. When you find 'PO' as prefix on the first two places, you exactly know the type of the row. Always encapuslate the prefix used (like 'PO' and 'GR') in constants, and use the same length for all prefixes fully. (Exception: In case you do not use mixed data or entities with related antieties based on BOL within the same structure etc.)

    DATA:
      lt_payment_tree      TYPE zdtt_payment_tree, "<-This is a table type
      lr_structdescr       TYPE REF TO cl_abap_structdescr,
      lr_structdescr_incl1 TYPE REF TO cl_abap_structdescr,
      lr_structdescr_incl2 TYPE REF TO cl_abap_structdescr,
      ls_component         TYPE abap_componentdescr,
      ls_component_incl1   TYPE abap_componentdescr,
      ls_component_incl2   TYPE abap_componentdescr.

    "Field catalog
    eo_field_catalog ?= cl_abap_tabledescr=>describe_by_data( lt_payment_tree ).

    "Field properties
    lr_structdescr ?= eo_field_catalog->get_table_line_type( ).

    "We analyze two level of includes, when more levels (will be) included, just code a recursive processing
    LOOP AT lr_structdescr->get_components( ) INTO ls_component.
      IF ls_component-as_include EQ abap_true.
        lr_structdescr_incl1 ?= ls_component-type.
        LOOP AT lr_structdescr_incl1->get_components( ) INTO ls_component_incl1.
          IF ls_component_incl1-as_include EQ abap_true.
            lr_structdescr_incl2 ?= ls_component_incl1-type.
            LOOP AT lr_structdescr_incl2->get_components( ) INTO ls_component_incl2.
              APPEND VALUE #( name = ls_component_incl2-name ) TO et_field_description.
            ENDLOOP.
          ELSE.
            APPEND VALUE #( name = ls_component_incl1-name ) TO et_field_description.
          ENDIF.
        ENDLOOP.
      ELSE.
        APPEND VALUE #( name = ls_component-name ) TO et_field_description.
      ENDIF.
    ENDLOOP.

    set_tree_master_columns( CHANGING ct_field_description = et_field_description ).
  METHOD set_tree_master_columns.

    FIELD-SYMBOLS:
      <ls_field_descr> TYPE fpmgb_s_treefield_descr.

    READ TABLE ct_field_description ASSIGNING <ls_field_descr> WITH KEY name = 'PARENT_KEY'.
    <ls_field_descr>-column_type = if_fpm_guibb_constants=>gc_guibb_tree_columns-parent_key.
    READ TABLE ct_field_description ASSIGNING <ls_field_descr> WITH KEY name = 'ROW_KEY'.
    <ls_field_descr>-column_type = if_fpm_guibb_constants=>gc_guibb_tree_columns-row_key.

    READ TABLE ct_field_description ASSIGNING <ls_field_descr> WITH KEY name = 'TEXT'.
    <ls_field_descr>-column_type = if_fpm_guibb_constants=>gc_guibb_tree_columns-text.
    <ls_field_descr>-default_display_type = if_fpm_guibb_constants=>gc_display_type-caption.
    <ls_field_descr>-header_label = 'NoE/Internl Order'(001).

    READ TABLE ct_field_description ASSIGNING <ls_field_descr> WITH KEY name = 'EXPANDED'.
    <ls_field_descr>-column_type = if_fpm_guibb_constants=>gc_guibb_tree_columns-expanded.

    READ TABLE ct_field_description ASSIGNING <ls_field_descr> WITH KEY name = 'IS_LEAF'.
    <ls_field_descr>-column_type = if_fpm_guibb_constants=>gc_guibb_tree_columns-is_leaf.

    READ TABLE ct_field_description ASSIGNING <ls_field_descr> WITH KEY name = 'CHILDREN_LOADED'.
    <ls_field_descr>-column_type = if_fpm_guibb_constants=>gc_guibb_tree_columns-child_load.

    READ TABLE ct_field_description ASSIGNING <ls_field_descr> WITH KEY name = 'IMAGE_SRC'.
    <ls_field_descr>-column_type = if_fpm_guibb_constants=>gc_guibb_tree_columns-img_src.

  ENDMETHOD.