SAP MM BAPI for PO Create and Change: BAPI_PO_CREATE1 and BAPI_PO_CHANGE
sap mm bapi for po create and change
Also searched as
- BAPI_PO_CREATE1 example
- BAPI_PO_CHANGE example
- BAPI_PO_CREATE1 POHEADERX POITEMX
Short answer
Use BAPI_PO_CREATE1 to create a purchase order and BAPI_PO_CHANGE to change one. Each takes a data structure and a matching X-structure that flags which fields to apply, returns messages in the RETURN table, and only persists after you call BAPI_TRANSACTION_COMMIT when no error message came back.
Applies to: SAP ECC 6.0 and S/4HANA on-premise; BAPI_PO_CREATE1 replaces the older BAPI_PO_CREATE
How to create and change a PO with BAPIs
- 1Fill POHEADER with company code, document type, vendor, purchasing organization and group, and set the matching flags in POHEADERX.
- 2Fill POITEM with item number (00010, 00020), material, plant, quantity and price, and set the same fields to 'X' in POITEMX, along with the item number.
- 3Fill POSCHEDULE (item, schedule line, delivery date, quantity) and POSCHEDULEX, since the PO needs a schedule line to be deliverable.
- 4Call BAPI_PO_CREATE1; check the RETURN table for messages of type E or A. If there are none, call BAPI_TRANSACTION_COMMIT, otherwise call BAPI_TRANSACTION_ROLLBACK.
- 5Read the new number from EXPPURCHASEORDER.
- 6To change, call BAPI_PO_CHANGE with PURCHASEORDER and only the structures you need, again flagging every changed field in the X-structure.
- 7Use TESTRUN = 'X' in create to simulate without saving.
Minimal create example
The pattern below is the common minimum for a material PO. Field names follow the BAPI structures (BAPIMEPOHEADER, BAPIMEPOITEM, BAPIMEPOSCHEDULE); confirm them in SE37 or SE11 for your release, because available fields differ between versions.
The X-structure is the part that causes the most bugs: any field you do not flag with 'X' is ignored, even if its value is set.
DATA: ls_header TYPE bapimepoheader,
ls_headerx TYPE bapimepoheaderx,
lt_item TYPE TABLE OF bapimepoitem,
lt_itemx TYPE TABLE OF bapimepoitemx,
lt_sched TYPE TABLE OF bapimeposchedule,
lt_schedx TYPE TABLE OF bapimeposchedulx,
lt_return TYPE TABLE OF bapiret2,
lv_po TYPE bapimepoheader-po_number.
ls_header-comp_code = '1000'. ls_headerx-comp_code = 'X'.
ls_header-doc_type = 'NB'. ls_headerx-doc_type = 'X'.
ls_header-vendor = '0000100001'. ls_headerx-vendor = 'X'.
ls_header-purch_org = '1000'. ls_headerx-purch_org = 'X'.
ls_header-pur_group = '001'. ls_headerx-pur_group = 'X'.
APPEND VALUE #( po_item = '00010' material = 'RM-1001' plant = '1000'
quantity = 100 net_price = '12.50' ) TO lt_item.
APPEND VALUE #( po_item = '00010' po_itemx = 'X' material = 'X'
plant = 'X' quantity = 'X' net_price = 'X' ) 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 = 'X'
sched_linex = 'X' delivery_date = 'X' quantity = 'X' ) TO lt_schedx.
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.
READ TABLE lt_return WITH KEY type = 'E' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.
ENDIF.
Changing a PO with BAPI_PO_CHANGE
BAPI_PO_CHANGE takes PURCHASEORDER plus POHEADER/POHEADERX, POITEM/POITEMX and POSCHEDULE/POSCHEDULEX. To change a price, pass the item number with the new NET_PRICE and flag NET_PRICE in POITEMX. To delete an item, set DELETE_IND = 'L' with the flag, rather than removing the row.
The BAPI locks the PO while it runs. If a user has it open in ME22N, you get a lock message in RETURN. Handle it by retrying after a delay, not by ignoring it.
Released orders may be reset by changes to value-relevant fields, depending on your release strategy, so test your change against an order that is already released.
Error handling and commit
A BAPI does not commit. Calling BAPI_TRANSACTION_COMMIT with WAIT = 'X' makes the update synchronous, so a following read or change sees the PO. See the related page on the commit step for the common mistakes.
Read all RETURN lines, not just the first. Type W messages are warnings, and some, such as missing account assignment defaults, point to a PO that will later fail in release or invoice.
Try it here, free
BAPI_PO_CREATE1 Call Skeleton Generator
Enter vendor, plant, material and quantity and get a complete BAPI_PO_CREATE1 call with the matching X structures, error handling and BAPI_TRANSACTION_COMMIT.
Common pitfalls
- !Setting values but not flagging them in the X-structure, so they are silently ignored.
- !Not committing, or committing after an error message, which saves a half-formed PO.
- !Missing schedule lines, which creates a PO that cannot be received against.
- !Using BAPI_PO_CREATE1 in a loop with a commit per order without checking locks and number ranges.
- !Assuming field names from an older release; check the BAPI structures in your system.
How an ERP-grounded AI assistant handles this
Developers often need to see what an existing PO actually looks like before coding against it. Netray's ERPray can run this kind of lookup in plain language against your own SAP system, read-only by default, showing the query it ran and respecting SAP authorizations, with the model served on your own hardware when the system is on-prem. It explains and finds the data; it does not replace configuration decisions or post documents without human approval.
Frequently asked questions
What is the difference between BAPI_PO_CREATE and BAPI_PO_CREATE1?
BAPI_PO_CREATE1 is the newer version and the one SAP recommends. It supports more of what ME21N can do, including enhancements and conditions. BAPI_PO_CREATE is obsolete, so use CREATE1 for new development.
Why are my PO fields not saved?
Most often the matching field in the X-structure was not set to 'X'. The BAPI only applies fields that are flagged, so check POHEADERX, POITEMX and POSCHEDULEX for every field you set.
Do I need BAPI_TRANSACTION_COMMIT?
Yes. The BAPI itself does not commit the database. Call BAPI_TRANSACTION_COMMIT after confirming no error messages were returned, with WAIT = 'X' if later code depends on the saved PO.
Can I add conditions through the BAPI?
Yes, using the POCOND and POCONDX tables to set condition types such as freight at item level. Make sure the condition type exists in the calculation schema, or it will not be applied.
Related
How to Use BAPI_TRANSACTION_COMMIT Correctly
SAP's BAPI programming model separates business logic from the database commit on purpose, so a caller must explicitly call BAPI_TRANSACTION_COMMIT after a successful BAPI - usually with WAIT = 'X' - or the created object never actually persists. Skipping this step, or forgetting WAIT, is the most common reason a BAPI 'runs fine' but nothing gets saved.
How-toSAP ME21N: why the release strategy is not determined on a purchase order
When a purchase order saves without a release strategy, no strategy in the release group matched the PO's characteristic values. Compare the PO header values (value, document type, purchasing group, plant) against the value ranges in the strategy classification (CL24N), and check that the release group and code are active for the PO document type.
How-toSAP open purchase orders report: ME2N, ME2M, ME2L and the underlying tables
Use ME2N for a flexible open PO list, ME2M by material and ME2L by vendor, with the selection parameter Still to be delivered. The open quantity is the scheduled quantity in EKET minus goods received in EKBE, excluding deleted and delivery-completed items. For custom reports, read EKKO, EKPO, EKET and EKBE.
Error fixSAP M7 021: Deficit of SL Stock Quantity
M7 021 fires during a goods issue, delivery, or confirmation when SAP checks the unrestricted-use (SL) stock for the exact plant, storage location and batch combination and finds less than what you are trying to post out. Fix the entry (batch, storage location, quantity) first; only enable negative stock or downgrade the message to a warning if the business genuinely needs to post ahead of a receipt.
Error fixSAP IDoc Status 51: Application Document Not Posted
Status 51 tells you the IDoc reached the application layer and failed to post, but the status text itself is not the error - the real cause sits in the status record's long text or the linked application log. Fix the underlying data or configuration, then reprocess the IDoc through BD87 rather than editing the status.
Error fixSAP Short Dump TIME_OUT: Maximum Runtime Exceeded
A TIME_OUT runtime error means a dialog (or RFC) work process ran longer than the maximum allowed runtime, controlled by profile parameter rdisp/max_wprun_time (600 seconds by default). The fix is almost always to move the long-running work to background processing or tune the underlying program, not to raise the timeout.
AI for ERPAI for SAP S/4HANA, Running On-Prem or in Your Private Cloud
Run AI on SAP S/4HANA without sending ERP data to a public API. On-prem and private-cloud architecture, CDS views, OData, and honest deployment trade-offs.
Stuck on SAP ECC / S/4HANA?
Talk to engineers who work inside SAP ECC / S/4HANA every week, and who build private AI that answers these questions from your own ERP data.
Keep exploring
Free tools
- BAPI_PO_CREATE1 Call Skeleton GeneratorEnter vendor, plant, material and quantity and get a complete BAPI_PO_CREATE1 call with the matching X structures, error handling and BAPI_TRANSACTION_COMMIT.
- SAP BAPI_PO_CREATE1 ABAP Skeleton GeneratorFill in vendor, plant and material to generate an ABAP skeleton for creating a purchase order with BAPI_PO_CREATE1.
- SAP BAPI Production Order Create and Release ABAP TemplateFill in material, plant, order type and dates and get an ABAP skeleton that creates and releases a production order with a commit.
ERP fixes and how-tos
- How to Use BAPI_TRANSACTION_COMMIT CorrectlyBAPIs never commit their own update. Here is when to call BAPI_TRANSACTION_COMMIT with WAIT, and why a BAPI can run fine and still save nothing.
- How to Create a Purchase Order in SAP MM (ME21N)Step-by-step purchase order creation in SAP MM with ME21N: manual PO, PO from requisition, account assignment, release and the order-to-invoice flow.
- SAP MM Return to Vendor Process: Return PO, MIGO 161 and Credit MemoReturn goods to a vendor in SAP MM: return PO, MIGO movement 161 or 122, credit memo in MIRO, and how to handle scrap, rework and replacement shipments.