SAPFree generatorPDF, Excel, Word exportSAP ECC / S/4HANA

BAPI_PO_CREATE1 Call Skeleton Generator

BAPI_PO_CREATE1 is the standard function module for creating purchase orders from ABAP, and the fiddly part is always the pairs of data and X structures. This generator builds a complete call you can adapt: header, item, schedule line, the flag structures, error check and commit.

Fill in

On releases with long material numbers, use MATERIAL_LONG.

Generated code
Download:

1. Declarations

DATA: ls_header  TYPE bapimepoheader,
      ls_headerx TYPE bapimepoheaderx,
      lt_item    TYPE STANDARD TABLE OF bapimepoitem,
      lt_itemx   TYPE STANDARD TABLE OF bapimepoitemx,
      lt_sched   TYPE STANDARD TABLE OF bapimeposchedule,
      lt_schedx  TYPE STANDARD TABLE OF bapimeposchedulx,
      lt_return  TYPE STANDARD TABLE OF bapiret2,
      lv_po      TYPE bapimepoheader-po_number.

2. Header, item and schedule line data

ls_header-comp_code  = '1000'.
ls_header-doc_type   = 'NB'.
ls_header-vendor     = '0000100010'.
ls_header-purch_org  = '1000'.
ls_header-pur_group  = '001'.
ls_header-currency   = 'USD'.

ls_headerx-comp_code = abap_true.
ls_headerx-doc_type  = abap_true.
ls_headerx-vendor    = abap_true.
ls_headerx-purch_org = abap_true.
ls_headerx-pur_group = abap_true.
ls_headerx-currency  = abap_true.

APPEND VALUE #( po_item   = '00010'
                material  = 'RM-1001'
                plant     = '1000'
                quantity  = 100
                po_unit   = 'EA'
                net_price = '12.50' ) TO lt_item.

APPEND VALUE #( po_item   = '00010'
                po_itemx  = abap_true
                material  = abap_true
                plant     = abap_true
                quantity  = abap_true
                po_unit   = abap_true
                net_price = abap_true ) TO lt_itemx.

APPEND VALUE #( po_item       = '00010'
                sched_line    = '0001'
                delivery_date = sy-datum + 14
                quantity      = 100 ) TO lt_sched.

APPEND VALUE #( po_item       = '00010'
                sched_line    = '0001'
                po_itemx      = abap_true
                sched_linex   = abap_true
                delivery_date = abap_true
                quantity      = abap_true ) TO lt_schedx.

3. Call, error check and commit

CALL FUNCTION 'BAPI_PO_CREATE1'
  EXPORTING
    poheader         = ls_header
    poheaderx        = ls_headerx
  IMPORTING
    exppurchaseorder = lv_po
  TABLES
    return           = lt_return
    poitem           = lt_item
    poitemx          = lt_itemx
    poschedule       = lt_sched
    poschedulex      = lt_schedx.

IF line_exists( lt_return[ type = 'E' ] ) OR line_exists( lt_return[ type = 'A' ] ).
  CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
* report the messages in lt_return to the user or the log
ELSE.
  CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
    EXPORTING
      wait = abap_true.
* lv_po now holds the new purchase order number
ENDIF.

Pass TESTRUN = 'X' first to validate without saving. Every field you fill in the data structure needs its flag in the matching X structure, otherwise the BAPI ignores the value. Check the exact parameter and field names in SE37 and SE11 for your release, because they vary slightly between ECC and S/4HANA. Test with your own customizing for document types, tax codes and number ranges.

Automate purchase order intake

Want PO data prepared from emails or spreadsheets with human approval before posting? Describe your flow.

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

How to use the skeleton

Fill in company code, document type, vendor, purchasing organization and group, then the material, plant, quantity, unit, price and delivery lead time. The output declares the structures, fills data and flag tables together, calls the BAPI and decides between commit and rollback based on the RETURN table. Paste it into a method, replace the constants with your inputs, and add more items by looping over your source data with an incrementing item number such as 00010, 00020.

Why every field needs an X flag

The BAPI works on a change-flag principle. For each field you supply in POHEADER, POITEM or POSCHEDULE, you set the same field to 'X' in POHEADERX, POITEMX or POSCHEDULEX, and you must also set the item key fields in the X tables. If the flag is missing, the value is silently ignored and the default or customizing value is used. This is the most common reason that a created PO does not contain the data you sent.

  • POITEMX carries PO_ITEM and PO_ITEMX plus one flag per filled field
  • POSCHEDULEX needs PO_ITEM, SCHED_LINE, PO_ITEMX and SCHED_LINEX
  • Test first with the TESTRUN parameter set to X

Reading RETURN and committing

The RETURN table is a list of BAPIRET2 messages. Types E and A mean the PO was not created, so roll back and report the text. Types S, I and W are information. BAPI_TRANSACTION_COMMIT with WAIT set makes the commit synchronous, so a following read finds the document. Do not call COMMIT WORK directly after a BAPI unless you know the update task logic, and never commit inside a loop of unrelated documents without handling failures.

Common mistakes

Typical defects are missing X flags, vendor numbers without leading zeros, material numbers in the wrong format or length, no unit conversion between order unit and base unit, and ignoring warning messages that point to missing price conditions. Another is forgetting that the BAPI uses the caller's authorizations, so a batch user needs the right purchasing authorizations. Newer releases also offer BAPI_PO_CREATE1 alongside the OData and API-based purchase order services, so check the recommended interface for your S/4HANA release.

Frequently Asked Questions

What is the difference between BAPI_PO_CREATE and BAPI_PO_CREATE1?

BAPI_PO_CREATE1 is the newer interface that uses the BAPIMEPOHEADER style structures with separate X structures, and it supports more functions such as account assignment and conditions. BAPI_PO_CREATE is the older one and is not recommended for new development.

Why is my price or plant not saved on the purchase order?

Most often the matching X flag is missing. Each value in the item or header must have the same field set to X in the X structure. Also check that the item key PO_ITEM and PO_ITEMX are set in the X table.

Do I need BAPI_TRANSACTION_COMMIT?

Yes. The BAPI does not commit on its own, so you must call BAPI_TRANSACTION_COMMIT after a successful call. Use WAIT = 'X' if later steps read the new document. On errors call BAPI_TRANSACTION_ROLLBACK.

How do I test without creating a PO?

Set the TESTRUN export parameter to 'X'. The BAPI runs the checks and returns messages in RETURN, but nothing is saved. This is the best way to find missing flags and customizing issues before going live.

If you build PO creation interfaces repeatedly, we can discuss a reviewed approach where an agent prepares the data and a person approves before anything is written to the ERP.