Monday, 15 January 2024

“Unlocking EDI Flexibility: A Customizable ABAP Journey in SAP”

Enhancing EDI Processing with Customizable ABAP Code


In the realm of Electronic Data Interchange (EDI), flexibility and adaptability are paramount. In this post, we will explore a robust ABAP code for handling EDI files, specifically in the context of SAP systems. The code is designed to be customizable, allowing for seamless integration with various client-specific EDI scenarios.

Customizing the Main Table

To start, we create a main customizing table that serves as the backbone for EDI processing. This table incorporates essential elements for mapping and customization:

“Unlocking EDI Flexibility: A Customizable ABAP Journey in SAP”
IDOC se11 Ztable

  • EDI_IDOC_TYPE: Key identifier for different client-specific requests.
  • EDI_SEGDEF: EDI segment definition.
  • IDOC_LINE: Mapping for a 1025-character long text field.
  • FIELD_DESC: Area for IDOC field descriptions, such as ‘werks’ or ‘lgort.’
  • LENGTH: Mapping of the length of the field in the 1025-character text IDOC.
  • FIXED_VALUE: Indicates if the IDOC segment structure has a fixed value.
  • ABAP_FIELD: Specifies if the IDOC segment structure has an ABAP data element.
  • FIELD: Denotes the area of the IDOC coming from the EDI file.
  • FIELD_LENGTH: Controls EDI mapping based on specific length requirements.
  • DESCRIPTION: Provides a description of the area for better table management.

Here’s an example of the customizing table structure:

“Unlocking EDI Flexibility: A Customizable ABAP Journey in SAP”
Example of Customizing Table

SELECT-OPTIONS: so_file FOR text250 NO INTERVALS.
DATA: ls_data_tab TYPE zsd_edidir_tab.
DATA: lt_data_tab TYPE zsd_tt_edidir_tab.

START-OF-SELECTION.
  PERFORM read_files.

Main program will look like this:

FORM read_files .
  DATA: lv_filenam     TYPE char80,
        lv_idocfname   TYPE text250, 
        ls_pathname    LIKE edi_path-pthnam, 
        lt_ediidoccust TYPE zsd_tt_ediidoccust.

  " Read the header information from the EDI file
  READ TABLE lt_data_tab INTO DATA(ls_header) INDEX 1.
  DELETE lt_data_tab INDEX 1.

  " Fetch the function name based on custom conditions
  SELECT SINGLE func_name
    FROM zsd_edi_function 
    INTO @DATA(lv_func_name).

  " Retrieve customization data for IDOC processing
  SELECT *
    INTO TABLE @lt_ediidoccust
    FROM zsd_ediidoccust 
    ORDER BY ediidoctype, edisegdef, ssira.

  " Initialize the IDOC table
  DATA(lt_idoctab) TYPE zsd_tt_edi_field1025.

  " Call the custom function for processing EDI data
  CALL FUNCTION lv_func_name
    EXPORTING
      is_edifilepath = ls_edifilepath 
      it_data_tab    = lt_data_tab
      it_ediidoccust = lt_ediidoccust 
    IMPORTING
      et_idoc        = lt_idoctab.

  TYPES:
    BEGIN OF lty_edisegdef,
      edisegdef TYPE edisegdef,
    END OF lty_edisegdef.

  LOOP AT it_data_tab INTO ls_data_tab.
    LOOP AT lt_edisegdef INTO DATA(lv_edisegdef).
      CLEAR lt_idoctab.

      " Perform additional processing based on EDI segment definition
      " Populate lt_idoctab with relevant data based on customization

    ENDLOOP.

    " Additional logic based on your specific requirements and scenarios.
    " ...

    " Check if IDOCs are available for processing
    IF lt_idoctab[] IS NOT INITIAL.
      " Create a file for IDOCs
      CONCATENATE gv_al11 sy-datum '_' sy-uzeit ls_edifilepath-ediidoctype lv_txt_no '.txt' INTO lv_idocfname.

      " Open the file for output
      OPEN DATASET lv_idocfname FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
      CHECK sy-subrc EQ 0.

      " Transfer IDOCs to the file
      LOOP AT lt_idoctab INTO DATA(ls_idoctab).
        TRANSFER ls_idoctab TO lv_idocfname.
      ENDLOOP.

      " Close the file
      CLOSE DATASET lv_idocfname.

      " Determine the file path
      ls_pathname = lv_idocfname.

      " Check if IDOC processing is required
      IF lt_idoctab[] IS NOT INITIAL.

        " Call SAP function for incoming EDI data
        CALL FUNCTION 'EDI_DATA_INCOMING'
          EXPORTING
            pathname = ls_pathname
            port     = 'Z000000002'
          EXCEPTIONS
            OTHERS   = 1.

        COMMIT WORK AND WAIT.

        " Check for successful SAP function execution
        IF sy-subrc IS INITIAL.

          " Perform cleanup, e.g., delete logical path file
          " Change the method or use Zclass for the specific cleanup process
          go_ftp->delete_logical_path_file( iv_logical_path = CONV #( lv_idocfname ) ).

        ENDIF.

      ENDIF.

    ENDIF.

  ENDLOOP.

ENDFORM.
 
Here is the example of Ztable for custom scenerios.

“Unlocking EDI Flexibility: A Customizable ABAP Journey in SAP”

“Unlocking EDI Flexibility: A Customizable ABAP Journey in SAP”

And main function for general scenerios will be look like this;

FUNCTION zoa_sd_fm_edi_inc_sn01.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(IS_EDIFILEPATH) TYPE  ZSD_EDIFILEPATH
*"     VALUE(IT_DATA_TAB) TYPE  ZSD_TT_EDIDIR_TAB
*"     VALUE(IT_EDIIDOCCUST) TYPE  ZSD_TT_EDIIDOCCUST
*"  EXPORTING
*"     VALUE(ET_IDOC) TYPE  ZSD_TT_EDI_FIELD1025
*"----------------------------------------------------------------------

  " Fetch additional data for EDI processing

  " Define types for EDI segment definitions
  TYPES:
    BEGIN OF lty_edi_segdef,
      edi_segdef TYPE edi_segdef, " Type for EDI segment definition
    END OF lty_edi_segdef,
    BEGIN OF lty_idocs,
      value_0011 TYPE char50,  " Type for IDOC value 0011
      value_0015 TYPE char50,  " Type for IDOC value 0015
      value_0099 TYPE char50,  " Type for IDOC value 0099
      value_0100 TYPE char50,  " Type for IDOC value 0100
    END OF lty_idocs.

  DATA: lt_collect    TYPE TABLE OF lty_idocs,  " Collection of IDOCs
        ls_idoc       TYPE lty_idocs,           " Current IDOC
        lv_idoc       TYPE i,                   " IDOC counter
        lv_line(6),                             " Line counter
        ls_data_tab   TYPE zsd_edidir_tab,      " Data structure for EDI file
        lv_screl      TYPE numc2,               " Screen release
        lv_lines      TYPE i,                   " Line counter
        lt_edi_segdef  TYPE TABLE OF lty_edi_segdef,   " Table for EDI segment definitions
        lt_e2edp16002 TYPE TABLE OF lty_edi_segdef,   " Table for E2EDP16002 segment definitions
        lt_e2psjcl003 TYPE TABLE OF lty_edi_segdef,   " Table for E2PSJCL003 segment definitions
        BEGIN OF lt_idoctab OCCURS 0,
          field(1025),                           " IDOC field of length 1025 characters
        END OF lt_idoctab. 

  " Determine the number of IDOCs based on specific conditions
  LOOP AT it_data_tab ASSIGNING FIELD-SYMBOL(<lfs_data_tab>).

    ASSIGN COMPONENT 'VALUE_0069' OF STRUCTURE <lfs_data_tab> TO FIELD-SYMBOL(<lfs_val>).
    IF <lfs_val> IS ASSIGNED AND <lfs_val> IS NOT INITIAL.
      CASE <lfs_val>.
        WHEN '1' OR '5' OR '6'.
          <lfs_data_tab>-value_0099 = 'split_1'.
        WHEN '3' OR '4'.
          <lfs_data_tab>-value_0099 = 'split_2'.
        WHEN OTHERS.
      ENDCASE.
    ELSE.
      ASSIGN COMPONENT 'VALUE_0068' OF STRUCTURE <lfs_data_tab> TO <lfs_val>.
      IF <lfs_val> EQ '3' OR <lfs_val> EQ  '4' .
        <lfs_data_tab>-value_0099 = 'split_2'.
      ENDIF.
    ENDIF.

  ENDLOOP.

  IF sy-subrc IS INITIAL.
    CLEAR lt_collect.
    lv_idoc = 0.

    " Loop through the data and determine IDOC values
    LOOP AT it_data_tab ASSIGNING <lfs_data_tab>.
      CLEAR ls_idoc.
      ASSIGN COMPONENT 'VALUE_0099' OF STRUCTURE <lfs_data_tab> TO <lfs_val>.
      IF sy-subrc IS INITIAL.
        ls_idoc-value_0099 = <lfs_val>.
      ENDIF.
      ASSIGN COMPONENT 'VALUE_0011' OF STRUCTURE <lfs_data_tab> TO <lfs_val>.
      IF sy-subrc IS INITIAL.
        ls_idoc-value_0011 = <lfs_val>.
      ENDIF.
      ASSIGN COMPONENT 'VALUE_0015' OF STRUCTURE <lfs_data_tab> TO <lfs_val>.
      IF sy-subrc IS INITIAL.
        ls_idoc-value_0015 = <lfs_val>.
      ENDIF.

      " Continue if IDOC values are not available
      IF ls_idoc-value_0099 IS INITIAL AND
         ls_idoc-value_0011 IS INITIAL AND
         ls_idoc-value_0015 IS INITIAL.
        CONTINUE.
      ENDIF.

      " Determine IDOC value_0100 and add to collection
      ASSIGN COMPONENT 'VALUE_0100' OF STRUCTURE <lfs_data_tab> TO <lfs_val>.
      IF sy-subrc IS INITIAL.
        READ TABLE lt_collect INTO DATA(ls_collect) WITH KEY value_0099 = ls_idoc-value_0099
                                                             value_0011 = ls_idoc-value_0011
                                                             value_0015 = ls_idoc-value_0015.
        IF sy-subrc IS INITIAL.
          <lfs_val> = ls_collect-value_0100.
        ELSE.
          ADD 1 TO lv_idoc.
          <lfs_val> = |idoc_| && lv_idoc.
          ls_idoc-value_0100 = <lfs_val>.
          APPEND ls_idoc TO lt_collect.
        ENDIF.
      ENDIF.

      UNASSIGN <lfs_val>.
    ENDLOOP.
  ENDIF.

  " Create IDOCs
  LOOP AT lt_collect INTO DATA(ls_idocs).

    " Define EDI segment definitions
    lt_edi_segdef = VALUE #( ( edi_segdef = 'EDI_DC40' )
                            ( edi_segdef = 'E2EDK09003' )
                            ( edi_segdef = 'E2EDKA1003LF' )
                            ( edi_segdef = 'E2EDKA1003WK' )
                            ( edi_segdef = 'E2EDP10002' )
                            ( edi_segdef = 'E2EDP16002' )
                           ).

    lt_e2edp16002 = VALUE #( ( edi_segdef = 'E2EDP16002' )
                         ).

    DATA(lv_first) = abap_true.
    lv_line = '000001'.
    SORT it_data_tab BY (lv_descending_value) DESCENDING.

    LOOP AT it_data_tab INTO ls_data_tab WHERE value_0100 EQ ls_idocs-value_0100.

      LOOP AT lt_edi_segdef INTO DATA(lv_edi_segdef).

        CLEAR lt_idoctab.

        LOOP AT it_ediidoccust INTO DATA(ls_ediidoccust) WHERE edi_segdef EQ lv_edi_segdef.

          IF ls_ediidoccust-abap_field IS NOT INITIAL.
            lt_idoctab-field+ls_ediidoccust-idoc_line = sy-(ls_ediidoccust-abap_field).
          ELSEIF ls_ediidoccust-fixed_value IS NOT INITIAL.
            CASE ls_ediidoccust-fixed_value.
              WHEN 'P_LINE'.
                ADD 1 TO lv_line.
                UNPACK lv_line TO lv_line.
                lt_idoctab-field+ls_ediidoccust-idoc_line = lv_line.
              WHEN 'P_CUSTOM'.
                " Add your custom process.

              ELSE.
                " Handle other cases.

            ENDCASE.
          ELSE.

            " Assign values based on field and idoc_line
            ASSIGN COMPONENT ls_ediidoccust-field OF STRUCTURE ls_data_tab TO <lfs_val>.
            IF <lfs_val> IS ASSIGNED AND <lfs_val> IS NOT INITIAL.
              IF ls_ediidoccust-field_length IS INITIAL.
                lt_idoctab-field+ls_ediidoccust-idoc_line =  <lfs_val>.
              ELSE.
                lt_idoctab-field+ls_ediidoccust-idoc_line =  <lfs_val>(ls_ediidoccust-field_length).
              ENDIF.
            ENDIF.
          ENDIF.

          UNASSIGN: <lfs_val> , <lfs_date>.
        ENDLOOP.

        " Append the IDOC to the collection
        APPEND lt_idoctab.
      ENDLOOP.

      " Update lt_edi_segdef for subsequent iterations
      IF lv_first EQ abap_true.
        lv_first = abap_false.
        CLEAR lt_edi_segdef.
        lt_edi_segdef = lt_e2edp16002.
      ENDIF.
    ENDLOOP.

  ENDLOOP.

  " Assign the IDOCs to the output parameter
  et_idoc[] = lt_idoctab[].

ENDFUNCTION.
 
In conclusion, the presented ABAP code offers a robust and customizable solution for Electronic Data Interchange (EDI) processing within the SAP environment. The customizing table serves as a flexible backbone, allowing users to adapt the code to diverse client-specific EDI scenarios seamlessly. By providing key elements for mapping and customization, such as EDI segment definitions, field lengths, and descriptions, the code ensures adaptability to various EDI requirements.

The main program efficiently reads EDI files, calls a custom function for processing EDI data, and generates IDOCs based on client-specific conditions. The example Ztable and main function cater to both general and custom scenarios, showcasing the versatility of the code in handling diverse EDI use cases.

This customizable ABAP code not only streamlines EDI processing but also enhances flexibility and adaptability, key factors in the ever-evolving landscape of electronic data exchange. Its modular structure allows for easy extension and modification, ensuring that organizations using SAP systems can seamlessly integrate EDI functionalities tailored to their specific needs.

In the dynamic world of EDI, where different clients may have unique requirements, this code provides a solid foundation for efficient and adaptable EDI processing in SAP systems, contributing to improved data exchange capabilities and overall business efficiency.

No comments:

Post a Comment