BAPI_PO_CREATE1¶
Create purchase orders programmatically — the standard BAPI for MM purchasing document creation.
Purpose¶
BAPI_PO_CREATE1 creates standard purchase orders (document type NB) and other purchasing document types. Like all write BAPIs, it requires BAPI_TRANSACTION_COMMIT after success and uses the checkbox structure pattern (POHEADERX, POITEMX) to indicate which fields to populate.
Signature (key parameters)¶
| Parameter | Direction | Type | Description |
|---|---|---|---|
POHEADER |
Importing | BAPIMEPOHEADER |
PO header data |
POHEADERX |
Importing | BAPIMEPOHEADERX |
Checkbox — flag fields to populate |
POITEM |
Tables | BAPIMEPOITEM |
Line items |
POITEMX |
Tables | BAPIMEPOITEMX |
Checkbox table for items |
EXPHEADER |
Exporting | BAPIMEPOHEADER |
Created PO number |
RETURN |
Tables | BAPIRET2 |
Messages |
Checkbox structure pattern¶
Every field in POHEADER that you populate must also be set to 'X' in the corresponding field of POHEADERX. This tells the BAPI which fields to process — unset fields are ignored.
Example — create a standard PO¶
DATA: ls_header TYPE bapimepoheader,
ls_headerx TYPE bapimepoheaderx,
lt_items TYPE STANDARD TABLE OF bapimepoitem,
lt_itemsx TYPE STANDARD TABLE OF bapimepoitemx,
lv_po_number TYPE ekko-ebeln,
lt_return TYPE STANDARD TABLE OF bapiret2.
" Start from plant — find one with a valuation area and a material with description
" then derive company code and purchasing org from there to guarantee consistency
SELECT SINGLE m~matnr, m~werks, k~bukrs FROM marc AS m
INNER JOIN mara AS a ON a~matnr = m~matnr
AND a~mtart IN ('ROH', 'HALB', 'FERT', 'HAWA', 'VERP')
AND a~pstat LIKE '%E%'
INNER JOIN mbew AS b ON b~matnr = m~matnr AND b~bwkey = m~werks
INNER JOIN makt AS t ON t~matnr = m~matnr AND t~spras = @sy-langu
INNER JOIN t001k AS k ON k~bwkey = m~werks
INTO @DATA(ls_mat).
IF sy-subrc <> 0.
WRITE: / 'No suitable material/plant combination found — check MARC / MBEW / MAKT / T001K'.
RETURN.
ENDIF.
DATA(lv_plant) = ls_mat-werks.
DATA(lv_material) = ls_mat-matnr.
" Purchasing org assigned to the plant's company code
SELECT SINGLE ekorg FROM t024e
WHERE bukrs = @ls_mat-bukrs
INTO @DATA(lv_ekorg).
IF sy-subrc <> 0.
WRITE: / 'No purchasing org for company code', ls_mat-bukrs, '— check T024E'.
RETURN.
ENDIF.
SELECT SINGLE ekgrp FROM t024 INTO @DATA(lv_purgroup).
IF sy-subrc <> 0.
WRITE: / 'No purchasing group found — check T024'.
RETURN.
ENDIF.
" Vendor assigned to this purchasing org
SELECT SINGLE lifnr FROM lfm1
WHERE ekorg = @lv_ekorg
INTO @DATA(lv_vendor).
IF sy-subrc <> 0.
WRITE: / 'No vendor found for purch org', lv_ekorg, '— check LFM1'.
RETURN.
ENDIF.
" Header data
ls_header-comp_code = ls_mat-bukrs.
ls_header-doc_type = 'NB'.
ls_header-vendor = lv_vendor.
ls_header-purch_org = lv_ekorg.
ls_header-pur_group = lv_purgroup.
ls_header-doc_date = sy-datum.
" Checkbox header — X = process this field
ls_headerx-comp_code = 'X'.
ls_headerx-doc_type = 'X'.
ls_headerx-vendor = 'X'.
ls_headerx-purch_org = 'X'.
ls_headerx-pur_group = 'X'.
ls_headerx-doc_date = 'X'.
" Item data
APPEND VALUE #(
po_item = '00010'
material = lv_material
plant = lv_plant
quantity = '10'
po_unit = 'PC'
net_price = '25.00'
price_unit = '1'
) TO lt_items.
" Checkbox item
APPEND VALUE #(
po_item = '00010'
material = 'X'
plant = 'X'
quantity = 'X'
po_unit = 'X'
net_price = 'X'
price_unit = 'X'
) TO lt_itemsx.
CALL FUNCTION 'BAPI_PO_CREATE1'
EXPORTING
poheader = ls_header
poheaderx = ls_headerx
IMPORTING
exppurchaseorder = lv_po_number
TABLES
poitem = lt_items
poitemx = lt_itemsx
return = lt_return.
" Check errors
LOOP AT lt_return INTO DATA(ls_msg) WHERE type CA 'EA'.
WRITE: / ls_msg-type, ls_msg-message.
ENDLOOP.
IF sy-subrc <> 0. " no errors in loop above = no E/A messages
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = abap_true.
WRITE: / 'PO created:', lv_po_number.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ENDIF.
Common pitfalls¶
Checkbox pattern is mandatory
If you set a field in POHEADER but not in POHEADERX, the field is silently ignored. Every field you want to transfer must have 'X' in both structures.
Always check RETURN before committing
Messages with TYPE = 'E' or 'A' indicate failure. A non-zero sy-subrc after the BAPI call is not reliable — always read the RETURN table.
- Vendor number: Must be in internal format (10 digits with leading zeros). Selecting directly from
LFM1orLFA1already gives internal format. UseCONVERSION_EXIT_ALPHA_INPUTif the user enters a short number. - Material number: Same — internal format with leading zeros. Selecting from
MARC/MARAgives internal format directly. - Net price: Passed as a string-numeric value per
PRICE_UNITquantity. - Org-level consistency: The vendor must be assigned to the purchasing org (LFM1), and the plant must be assigned to the company code. Mismatched org values are the most common cause of header errors.
See also¶
BAPI_SALESORDER_CREATEFROMDAT2— sales order creation- Transaction ME21N — create PO manually (for comparison)
- Transaction ME22N — change PO