Developer ToolsFree generatorPDF, Excel, Word exportSAP ECC 6.0All SAP ECC 6.0 tools

Custom Inbound IDoc Function Module in SAP ABAP: Skeleton Generator

This generator produces an inbound IDoc function module for SAP ECC 6.0 for a custom message type and segment, with the standard ALE interface, segment cast from SDATA, validation, status 51 and 53 records and workflow return variables. It also lists the WE31 to WE20 configuration steps that connect the function module to the partner profile.

Fill in

The segment must also contain MATNR and WERKS

Generated code
Download:

Function module (create in SE37, interface as in the header comment)

FUNCTION Z_IDOC_INPUT_ZMATSTAT.
*----------------------------------------------------------------------
* Local interface (define these in SE37, same as IDOC_INPUT_ORDERS):
*  IMPORTING
*     VALUE(INPUT_METHOD)          LIKE  BDWFAP_PAR-INPUTMETHD
*     VALUE(MASS_PROCESSING)       LIKE  BDWFAP_PAR-MASS_PROC
*  EXPORTING
*     VALUE(WORKFLOW_RESULT)       LIKE  BDWF_PARAM-RESULT
*     VALUE(APPLICATION_VARIABLE)  LIKE  BDWF_PARAM-APPL_VAR
*     VALUE(IN_UPDATE_TASK)        LIKE  BDWFAP_PAR-UPDATETASK
*     VALUE(CALL_TRANSACTION_DONE) LIKE  BDWFAP_PAR-CALLTRANS
*  TABLES
*      IDOC_CONTRL STRUCTURE  EDIDC
*      IDOC_DATA STRUCTURE  EDIDD
*      IDOC_STATUS STRUCTURE  BDIDOCSTAT
*      RETURN_VARIABLES STRUCTURE  BDWFRETVAR
*      SERIALIZATION_INFO STRUCTURE  BDI_SER
*  EXCEPTIONS
*      WRONG_FUNCTION_CALLED
*----------------------------------------------------------------------

  DATA: ls_ctrl  TYPE edidc,
        ls_data  TYPE edidd,
        ls_seg   TYPE Z1MATSTAT,
        ls_row   TYPE ZMAT_STATUS,
        lt_rows  TYPE STANDARD TABLE OF ZMAT_STATUS,
        ls_stat  TYPE bdidocstat,
        ls_ret   TYPE bdwfretvar,
        lv_error TYPE c,
        lv_any_error TYPE c.

  in_update_task        = space.
  call_transaction_done = space.
  application_variable  = space.

  LOOP AT idoc_contrl INTO ls_ctrl.

    IF ls_ctrl-mestyp <> 'ZMATSTAT'.
      RAISE wrong_function_called.
    ENDIF.

    CLEAR: lv_error, lt_rows.

    LOOP AT idoc_data INTO ls_data
         WHERE docnum = ls_ctrl-docnum
           AND segnam = 'Z1MATSTAT'.

      ls_seg = ls_data-sdata.
      CLEAR ls_row.

      CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
        EXPORTING
          input        = ls_seg-matnr
        IMPORTING
          output       = ls_row-matnr
        EXCEPTIONS
          length_error = 1
          OTHERS       = 2.
      ls_row-werks      = ls_seg-werks.
      ls_row-STATUS = ls_seg-STATUS.

*     Validation: material must exist in the plant
      SELECT SINGLE werks FROM marc INTO ls_row-werks
        WHERE matnr = ls_row-matnr
          AND werks = ls_row-werks.
      IF sy-subrc <> 0.
        lv_error = 'X'.
        CLEAR ls_stat.
        ls_stat-docnum = ls_ctrl-docnum.
        ls_stat-status = '51'.
        ls_stat-msgty  = 'E'.
        ls_stat-msgid  = '00'.
        ls_stat-msgno  = '398'.
        ls_stat-msgv1  = 'Material not in plant:'.
        ls_stat-msgv2  = ls_seg-matnr.
        ls_stat-msgv3  = ls_seg-werks.
        ls_stat-segnum = ls_data-segnum.
        APPEND ls_stat TO idoc_status.
        EXIT.
      ENDIF.

      APPEND ls_row TO lt_rows.
    ENDLOOP.

    CLEAR ls_ret.
    ls_ret-doc_number = ls_ctrl-docnum.

    IF lv_error IS INITIAL.
*     Application update. ALE commits after the function module returns.
      MODIFY ZMAT_STATUS FROM TABLE lt_rows.

*     BAPI alternative instead of the Z table:
*     CALL FUNCTION 'Z_YOUR_BAPI' ... TABLES return = lt_return.
*     Map BAPIRET2 lines of type E or A to status 51 lines.

      CLEAR ls_stat.
      ls_stat-docnum = ls_ctrl-docnum.
      ls_stat-status = '53'.
      ls_stat-msgty  = 'S'.
      ls_stat-msgid  = '00'.
      ls_stat-msgno  = '398'.
      ls_stat-msgv1  = 'Material status updated'.
      APPEND ls_stat TO idoc_status.
      ls_ret-wf_param = 'Processed_IDOCs'.
    ELSE.
      lv_any_error = 'X'.
      ls_ret-wf_param = 'Error_IDOCs'.
    ENDIF.
    APPEND ls_ret TO return_variables.

  ENDLOOP.

  IF lv_any_error IS INITIAL.
    workflow_result = '0'.
  ELSE.
    workflow_result = '99999'.
  ENDIF.

ENDFUNCTION.

Configuration steps

* WE31  Create segment type Z1MATSTAT with fields MATNR, WERKS, STATUS and release it
* WE30  Create basic type ZMATSTAT01 containing Z1MATSTAT and release it
* WE81  Create message type ZMATSTAT
* WE82  Link message type ZMATSTAT to basic type ZMATSTAT01
* SE11  Create table ZMAT_STATUS with MANDT, MATNR, WERKS (keys) and STATUS
* SE37  Create Z_IDOC_INPUT_ZMATSTAT with the interface above
* WE57  Assign Z_IDOC_INPUT_ZMATSTAT to ZMATSTAT / ZMATSTAT01, function type F, direction 2
* BD51  Register Z_IDOC_INPUT_ZMATSTAT with input type 0 (mass) or 1 (individual)
* WE42  Create inbound process code ZMST pointing to Z_IDOC_INPUT_ZMATSTAT
* WE20  Add ZMATSTAT with process code ZMST to the sending partner (inbound parameters)
* WE19  Test: copy or build an IDoc and start inbound processing with Z_IDOC_INPUT_ZMATSTAT
* BD87  Reprocess IDocs in status 51 after fixing data

The interface must match the standard inbound interface exactly, otherwise ALE raises a runtime error; compare with IDOC_INPUT_ORDERS in SE37. Message 00 398 is the generic four-placeholder message; replace it with your own message class for production. The segment structure must contain MATNR and WERKS with those names, or adapt the mapping lines. Do not COMMIT WORK inside the function module unless input type 1 is used and you know why.

Get your inbound interface reviewed

Send us the segment layout and target object and we return a reviewed function module and configuration checklist for your release.

Optional. The tool and every export work without this. No spam.

Was this tool useful?

How inbound IDoc processing reaches your code

When an IDoc arrives, ALE reads the partner profile (WE20) for the sender and message type, finds the process code (WE42) and calls the function module behind it. The function module receives the control records in IDOC_CONTRL and all segments in IDOC_DATA, one EDIDD line per segment. It must write at least one status line per IDoc into IDOC_STATUS: 53 for posted, 51 for application error. RETURN_VARIABLES tells workflow which IDocs succeeded (Processed_IDOCs) or failed (Error_IDOCs), and WORKFLOW_RESULT 99999 triggers error handling.

  • WE57 links the function module to message and basic type.
  • BD51 defines input type: 0 mass, 1 individual, 2 individual with IDoc lock in CALL TRANSACTION.
  • Status 51 IDocs are reprocessed with BD87 after the cause is fixed.

How to use it

Enter the function module, message type, basic type, segment, target table and process code. The code assumes the segment has MATNR, WERKS and one value field, and writes them into a custom table. Create the objects in the order of the configuration block, paste the body into SE37 after defining the interface, then test with WE19. For a BAPI target, replace the MODIFY statement with the BAPI call and convert BAPIRET2 errors into status 51 lines.

Worked example

Message type ZMATSTAT with segment Z1MATSTAT carries MATNR 100-200, WERKS 1000, STATUS QA. The function module converts the material number with CONVERSION_EXIT_MATN1_INPUT, checks MARC for material 100-200 in plant 1000 and, if found, writes the row to ZMAT_STATUS and sets status 53. If the material is not extended to the plant, the IDoc gets status 51 with the text Material not in plant: 100-200 1000, visible in WE02 and BD87.

Gotchas

Rows are collected per IDoc and written only when the whole IDoc is valid, so a failed IDoc never leaves half its data behind. Do not issue MESSAGE statements of type E inside the function module: they abort the whole packet in mass processing. Keep the interface identical to the standard one, including the WRONG_FUNCTION_CALLED exception. If the IDoc must update standard objects, call a BAPI rather than writing SAP tables, and if that BAPI needs a commit, check how input type and ALE commit handling interact.

Frequently Asked Questions

How do I create an inbound IDoc function module in SAP?

Copy the interface of a standard inbound function module such as IDOC_INPUT_ORDERS in SE37, then loop over IDOC_CONTRL and IDOC_DATA, cast SDATA to your segment structure, process the data and append status lines. Register it in WE57 and BD51, create a process code in WE42 and add it to the partner profile in WE20.

How do I set the IDoc status to 51 or 53 in the function module?

Append a line to IDOC_STATUS with DOCNUM, STATUS 51 or 53 and the message fields MSGTY, MSGID, MSGNO and MSGV1 to MSGV4. ALE writes these into EDIDS after the function module returns. Also fill RETURN_VARIABLES with Processed_IDOCs or Error_IDOCs for that DOCNUM.

How do I read a custom segment in an inbound IDoc?

Loop at IDOC_DATA where SEGNAM equals the segment type and move SDATA into a variable typed with the segment structure created in WE31. All segment fields are character-like, so the move maps the 1000-character SDATA onto the fields by position.

How do I test a custom inbound IDoc without a partner system?

Use WE19. Start from an existing IDoc or from the basic type, edit the segment values, then choose inbound function module and enter your function module, or standard inbound to go through the partner profile. The test IDoc gets its own number and status records.

If you want integration support staff to ask about failed inbound IDocs and their causes in plain English on your own servers, we can set that up over your ECC system.

ArchRay builder
Design the on-prem AI stack for SAP ECC 6.0: model, GPUs, RAG pipeline, guardrails
See memory, speed and cost as you swap parts, then export the diagram. Free, in your browser.
Open the builder

Keep exploring

Free tools

ERP fixes and how-tos

Runs with your ERP

AI on your ERP

Integrations