(DI-2011) Enhance IDoc Detail Table Records

Custom BAdI implementation of the enhancement spot /DVD/MON_IDOC_BADI_DETAIL can be used to fill in the placeholder fields (CUSVAL[1-6], CUSLVAL[1-2], CUSNUM[1-2]) of the Detail table records that were selected according to Input table rules.

Intended use case of this enhancement spot is to implement the logic around specific IDoc message types, select IDoc segment records (EDID4) for these IDocs and fill in the placeholder fields with the segment field values.

It is recommended to use only header type segments (that can occur only once in the IDoc), segments with a specific name (EDID4-SEGNAM) and number (EDID4-SEGNUM field) or a segment name and hierarchy level (EDID4-HLEVEL). An IDoc can have multiple segments with the same segment name, but different segment numbers or hierarchy levels.

Without proper checks and restrictions, the same placeholder field can be overwritten by repeated processing of the same segment. As a result, the placeholder field would hold a value of last processed segment. The following example implementation code also contains workarounds.


Example implementation code
METHOD /dvd/mon_idoc_if_badi_detail~fill_custom_fields.

  DATA:
*   Static structures for segment data
*   Each type corresponds to EDID4-SEGNAM value of a given segment
    ls_e1idku1      TYPE e1idku1,
    ls_e1idpu1      TYPE e1idpu1,
    ls_e1rsrh       TYPE e1rsrh,
    ls_e2edk01001   TYPE e2edk01001,
    ls_e1edk02      TYPE e1edk02.

  DATA:
    lt_docnum       TYPE STANDARD TABLE OF edidc-docnum,
    lt_edidd        TYPE SORTED TABLE OF edid4 WITH UNIQUE DEFAULT KEY.

  FIELD-SYMBOLS:
    <lv_field>      TYPE any,
    <ls_edidd>      LIKE LINE OF lt_edidd,
    <ls_detail>     LIKE LINE OF ct_detail.

* No detail table records available - exit
  IF ct_detail IS INITIAL.
    RETURN.
  ENDIF.

* 1. Collect only relevant records that we want to enhance
* Other useful condition fields are:
* - KPI
* - DIRECT
* - STATUS
* - RCV* and SND* field combinations
  LOOP AT ct_detail ASSIGNING <ls_detail>
      WHERE mestyp = 'ORDERS'
         OR mestyp = 'RSRQST'
         OR mestyp = 'BLAORD'.
    APPEND <ls_detail>-docnum TO lt_docnum.
  ENDLOOP.

* No records remaining - exit
  IF lt_docnum IS INITIAL.
    RETURN.
  ENDIF.

  SORT lt_docnum.

* 2. Select segment data for relevant records
  SELECT * FROM edid4
    INTO TABLE lt_edidd
    FOR ALL ENTRIES IN lt_docnum
      WHERE docnum = lt_docnum-table_line
* Further restriction by segment type is recommended to improve
* overal performance and data efficiency
        AND segnam IN ('E1IDKU1','E1IDPU1','E1RSRH','E2EDK01001','E1EDK02')
      ORDER BY PRIMARY KEY.

  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

* 3. Process detail table records
  LOOP AT ct_detail ASSIGNING <ls_detail>.

* 3.1. Check if current record is relevant
    READ TABLE lt_docnum TRANSPORTING NO FIELDS
      WITH KEY table_line = <ls_detail>-docnum
      BINARY SEARCH.

* Not relevant - skip it
    IF sy-subrc <> 0.
      CONTINUE.
    ENDIF.

* 3.2. Process IDoc segments per IDoc message type and segment type
* Extract specific segment field values into detail table
* record placeholder fields
    LOOP AT lt_edidd ASSIGNING <ls_edidd> WHERE docnum = <ls_detail>-docnum.

*   3.3. IDoc message type specific processing
      CASE <ls_detail>-mestyp.

*     IDoc message type ORDERS
        WHEN 'ORDERS'.

          CASE <ls_edidd>-segnam.
            WHEN 'E1IDKU1'.

*         Cast segment data to static structure
              ls_e1idku1 = <ls_edidd>-sdata.

*         Move value from static structure to placeholder field of choice
              <ls_detail>-cusval1 = ls_e1idku1-bgmref.

            WHEN 'E1IDPU1'.
              ls_e1idpu1 = <ls_edidd>-sdata.

*         Prevent overwriting of this placeholder field in case an ORDERS IDoc
*         contains multiple E1IDPU1 segments
              IF <ls_detail>-cusval2 IS INITIAL.
                <ls_detail>-cusval2 = ls_e1idpu1-docnummr.
              ENDIF.
          ENDCASE.

*     IDoc message type RSRQST
        WHEN 'RSRQST'.

          CASE <ls_edidd>-segnam.
            WHEN 'E1RSRH'.
              ls_e1rsrh  = <ls_edidd>-sdata.
              <ls_detail>-cusval1 = ls_e1rsrh-request.
              <ls_detail>-cusval2 = ls_e1rsrh-requser.
          ENDCASE.

*     IDoc message type BLAORD
        WHEN 'BLAORD'.

          CASE <ls_edidd>-segnam.
            WHEN 'E2EDK01001'.
              ls_e2edk01001  = <ls_edidd>-sdata.
              <ls_detail>-cusval1 = ls_e2edk01001-belnr.
              <ls_detail>-cusval2 = ls_e2edk01001-recipnt_no.
            WHEN 'E1EDK02'.
              ls_e1edk02     = <ls_edidd>-sdata.

*         Multiple E1EDK02 segments can exist, populate next empty placeholder field
*         with value from each additional segment of this type
              IF      <ls_detail>-cusval3 IS INITIAL.
                ASSIGN <ls_detail>-cusval3 TO <lv_field>.
              ELSEIF  <ls_detail>-cusval4 IS INITIAL.
                ASSIGN <ls_detail>-cusval4 TO <lv_field>.
              ELSEIF  <ls_detail>-cusval5 IS INITIAL.
                ASSIGN <ls_detail>-cusval5 TO <lv_field>.
              ELSEIF  <ls_detail>-cusval6 IS INITIAL.
                ASSIGN <ls_detail>-cusval6 TO <lv_field>.
              ELSE.
                CONTINUE.
              ENDIF.
              CONCATENATE ls_e1edk02-qualf '-' ls_e1edk02-belnr INTO <lv_field>.

          ENDCASE.
      ENDCASE.
    ENDLOOP.
  ENDLOOP.

ENDMETHOD.