Tuesday, 28 December 2021

Validate Application Interface Framework (AIF) Value Mappings by Domain

Introduction

In a customer project we defined quite some AIF Value Mappings and noticed that Users can insert any Data into the Value Mapping Table. We wanted to limit the possible entries to the fixed Vales or Values in the Value Table of the Domain of the Data Element used in the Value Mapping Definition.

Example

Let´s say we have

“BUKRS” and Internal Field “XFELD”:

SAP ABAP Development, SAP ABAP Exam, SAP ABAP Exam Preparation, SAP ABAP Career, SAP ABAP Learn, SAP ABAP Tutorial and Material, SAP ABAP Skills, SAP ABAP Job
Value Mapping Definition

The Domains we use have a Value Table (BUKRS) and Fixed Values (XFELD):

SAP ABAP Development, SAP ABAP Exam, SAP ABAP Exam Preparation, SAP ABAP Career, SAP ABAP Learn, SAP ABAP Tutorial and Material, SAP ABAP Skills, SAP ABAP Job
Value table

SAP ABAP Development, SAP ABAP Exam, SAP ABAP Exam Preparation, SAP ABAP Career, SAP ABAP Learn, SAP ABAP Tutorial and Material, SAP ABAP Skills, SAP ABAP Job
Fixed Values

Our Objective: Validate all Entries based on Value Table (Key Field with same Domain as Key) and Fixed Values (Or Value Ranges)

Implementation Steps


Solution: Implement BaDI “/AIF/VMAP” in SE19

SAP ABAP Development, SAP ABAP Exam, SAP ABAP Exam Preparation, SAP ABAP Career, SAP ABAP Learn, SAP ABAP Tutorial and Material, SAP ABAP Skills, SAP ABAP Job
Create BaDI Implementation

In Implementation for /AIF/IF_VMAP_MAIN~BEFORE_SAVE we can validate the maintained Values.

The maintained Values are persisted in the Global Table “‘(/AIF/VALUE_MAPPING)LT_TABLE->*’ “. We assign it to a Field Symbol:

DATA: lt_dbfields             TYPE dfies_tab,
          lt_allowed_content      TYPE cim_t_string,
          lv_maintained_value_str TYPE string.

    FIELD-SYMBOLS: <lt_maintained_values> TYPE ANY TABLE,
                   <lt_columns>           TYPE ANY TABLE.

ASSIGN ('(/AIF/VALUE_MAPPING)LT_TABLE->*') TO <lt_maintained_values>.

The used Data Elements can be retrieved from the vmap manager instance:

DATA(lt_columns) = vmap_manager->get_column_types( ).

Then we loop thorugh the column, get their type, domain, Fixed Valued Indicator and Value Table and, if there is a Value Table, get the allowed Values from there

IF <lt_columns> IS ASSIGNED.
          LOOP AT <lt_columns> ASSIGNING FIELD-SYMBOL(<ls_column>).
            "Get Names of Column Types
            ASSIGN COMPONENT 'NAME'
              OF STRUCTURE <ls_column>
              TO FIELD-SYMBOL(<lv_column_name>).

            IF <lv_column_name> IS ASSIGNED.
              CASE <lv_column_name>. "Only these columns are relevant
                WHEN 'EXT_VALUE'
                  OR 'INT_VALUE'
                  OR 'EXT_VALUE1'
                  OR 'EXT_VALUE2'
                  OR 'EXT_VALUE3'
                  OR 'EXT_VALUE4'
                  OR 'EXT_VALUE5'.

                  ASSIGN COMPONENT 'TYPE'
                    OF STRUCTURE <ls_column>
                    TO FIELD-SYMBOL(<lv_column_type>).

                  IF <lv_column_type> IS ASSIGNED "These Data Elements are used if no Data Element is provided in /AIF/CUST
                    AND <lv_column_type> <> '/AIF/VMAP_EXTVAL'
                    AND <lv_column_type> <> '/AIF/VMAP_INTVAL'.

                    SELECT domname "Get Domain for Data Element
                      FROM dd04l INTO @DATA(lv_domain_name) UP TO 1 ROWS
                      WHERE rollname = @<lv_column_type>.
                    ENDSELECT.                       

                    IF lv_domain_name IS NOT INITIAL.
                      SELECT valexi, entitytab "Get Fixed Valued Indicator and Value Table
                        FROM dd01l INTO @DATA(ls_domain_data)  UP TO 1 ROWS
                        WHERE domname = @lv_domain_name.
                      ENDSELECT.
                      IF sy-subrc IS NOT INITIAL.
                        CLEAR ls_domain_data.
                      ENDIF.  
                    ENDIF.

                    IF ls_domain_data IS NOT INITIAL.
                      IF ls_domain_data-entitytab IS NOT INITIAL.
                        "Get DB Table Data
                        CALL FUNCTION 'DDIF_FIELDINFO_GET'
                          EXPORTING
                            tabname   = ls_domain_data-entitytab
                          TABLES
                            dfies_tab = lt_dbfields.

                        "Get the Field with the same Domain
                        LOOP AT lt_dbfields ASSIGNING FIELD-SYMBOL(<ls_dbfield>)
                          WHERE domname = lv_domain_name
                          AND keyflag = abap_true.
                          DATA(lv_fieldname) = <ls_dbfield>-fieldname.
                        ENDLOOP.
                        IF sy-subrc IS NOT INITIAL.
                          CLEAR lv_fieldname.
                        ENDIF.
                        "Select
                        IF lv_fieldname IS NOT INITIAL.
                          SELECT (lv_fieldname)        
                            FROM (ls_domain_data-entitytab)
                            INTO TABLE @lt_allowed_content.
                        ENDIF.
                      ENDIF

Then we loop through the maintained Values and check if the data corresponds to the allowed data in the value table. If the domain is defined as domain with fixed values (indicator “valexi”), we check this with a Function Module FM_DOMAINVALUE_CHECK

LOOP AT <lt_maintained_values> ASSIGNING FIELD-SYMBOL(<ls_maintained_values>).
                        ASSIGN COMPONENT <lv_column_name> OF STRUCTURE <ls_maintained_values> TO FIELD-SYMBOL(<lv_maintained_value>).
                        IF <lv_maintained_value> IS ASSIGNED.
                          lv_maintained_value_str = <lv_maintained_value>.
                        ENDIF.
                        IF lv_maintained_value_str <> '*' AND lv_maintained_value_str IS NOT INITIAL. "Values "*" and "" are always allowed.
                          IF ls_domain_data-valexi IS NOT INITIAL.
                            "Check against Fix Values / Intervals
                            CALL FUNCTION 'FM_DOMAINVALUE_CHECK'
                              EXPORTING
                                i_domname         = lv_domain_name
                                i_domvalue        = CONV val_single( lv_maintained_value_str )
                              EXCEPTIONS
                                input_error       = 1
                                value_not_allowed = 2
                                OTHERS            = 3.
                            IF sy-subrc <> 0.
                              MESSAGE e003(xxxxx) WITH <lv_maintained_value> lv_domain_name.
                            ENDIF.
                          ELSEIF ls_domain_data-entitytab IS NOT INITIAL.
                            "Check against DB Table we derived before
                            LOOP AT lt_allowed_content ASSIGNING FIELD-SYMBOL(<lv_data>)
                              WHERE table_line = <lv_maintained_value>.
                            ENDLOOP.

                            IF sy-subrc IS NOT INITIAL.
                              MESSAGE e002(xxxxx) WITH <lv_maintained_value> lv_fieldname lv_domain_name ls_domain_data-entitytab .
                            ENDIF.
                          ENDIF.
                        ENDIF.
                        CLEAR lv_maintained_value_str.
                      ENDLOOP.
                    ENDIF.
                  ENDIF.
              ENDCASE.
            ENDIF.
            CLEAR lv_domain_name.
            CLEAR lv_fieldname.
            CLEAR ls_domain_data.
          ENDLOOP.
        ENDIF.
      ENDIF.
    ENDIF.

The Message Class used has to be maintained of course.

Let´s Test in /AIF/VMAP:

With correct Values

SAP ABAP Development, SAP ABAP Exam, SAP ABAP Exam Preparation, SAP ABAP Career, SAP ABAP Learn, SAP ABAP Tutorial and Material, SAP ABAP Skills, SAP ABAP Job

With BUKRS = “XXXX” (not existent on T001):

SAP ABAP Development, SAP ABAP Exam, SAP ABAP Exam Preparation, SAP ABAP Career, SAP ABAP Learn, SAP ABAP Tutorial and Material, SAP ABAP Skills, SAP ABAP Job

With XFELD = “F” (Only “X” and “” are allowed)

SAP ABAP Development, SAP ABAP Exam, SAP ABAP Exam Preparation, SAP ABAP Career, SAP ABAP Learn, SAP ABAP Tutorial and Material, SAP ABAP Skills, SAP ABAP Job

No comments:

Post a Comment