Go back to the main page

SAP MRP Automated Data Generator

S/4HANA IDES — Material Requirements Planning via JCo RFC
MRP / Demand Planning

Overview

MRP (Material Requirements Planning) automated data generator that creates end-to-end demand-to-production-order documents via JCo RFC: planned independent requirements (PIR), MRP run, stock/requirements review, and planned-order-to-production-order conversion. Generates realistic SAP MRP transaction data on S/4HANA IDES using the bike finished goods family (MZ-FG-*).

Same SAP system as OTC, PP, and P2P. All programs connect to the same S/4HANA IDES instance. MRP creates demand via PIR and lets the MRP run generate planned orders, which are then converted to production orders. The bike family materials (MZ-FG-*, MZ-RM-*) are shared with the PP generator.

SAP System

System
S/4HANA IDES (SID: S4H)
Release
758 (HANA DB)
Client
100
System Number
03 (port 3303)
Company Code
1710
Plant
1710
Currency
USD

MRP Configuration

MRP Type
PD (deterministic)
Lot Size
EX (lot-for-lot)
Procurement
BESKZ=E (in-house production)
Finished Goods
9 bike models (MZ-FG-*)
BOM Components
7–10 per FG (MZ-RM-*)
Java Class
SAPMRPWorkflow.java
Connection
JCo RFC from local Mac

Local Connectivity

Everything runs from the local Mac — no need to SSH into sapidess4 or sapidesecc8. Client 100 is used for all operations.

Two connection methods are available: JCo RFC for BAPIs and function modules (used by the generator), and HANA SQL for direct database queries (useful for verification and debugging).

SAP RFC via JCo (BAPIs)

The generator connects directly to SAP over the network using the JCo 3 library. No SSH tunnel needed.

ParameterValue
Hostsapidess4.fivetran-internal-sales.com
System Number03 (port 3303)
Client100
UserIDES
Password(see vault)
LanguageEN

Required local files

../SAPjco/sapjco3.jarJava JCo library
../SAPjco/libsapjco3.dylibmacOS ARM64 native library
# Run the generator locally
java -Xmx512m -cp .:../SAPjco/sapjco3.jar \
  -Djava.library.path=../SAPjco SAPMRPWorkflow full 1

HANA Database (direct SQL)

Connect to HANA via SSH tunnel for direct SQL queries. Only the tunnel uses SSH — you never log into the server.

ParameterValue
Tunnellocalhost:30015sapidess4:30015
DatabaseFIV (S/4HANA tenant)
UserSAPHANADB
Password(see vault)
Python libpip3 install hdbcli
# Step 1: Start SSH tunnel (runs in background, one-time)
ssh -f -N -L 30015:127.0.0.1:30015 root@sapidess4

# Step 2: Query HANA via Python
python3 -c "
from hdbcli import dbapi
conn = dbapi.connect(address='localhost', port=30015,
    user='SAPHANADB', password='(see vault)', databaseName='FIV')
cur = conn.cursor()
cur.execute(\"SELECT PLNUM, MATNR, GSMNG FROM PLAF WHERE MATNR LIKE 'MZ%'\")
for row in cur.fetchall(): print(row)
"

Useful HANA queries for MRP

-- PIR demand
SELECT * FROM PBIM WHERE MATNR LIKE 'MZ-FG%' AND WERKS = '1710';

-- Planned orders
SELECT PLNUM, MATNR, GSMNG, PSTTR, PEDTR
FROM PLAF WHERE MATNR LIKE 'MZ%' AND PLWRK = '1710';

-- Production orders from conversion
SELECT AUFNR, OBJNR FROM AUFK
WHERE AUFNR IN ('000001002166', '000001002167');

Finished Goods (Bike Family)

All 9 finished goods are FERT materials with BOM + Routing in plant 1710, MRP type PD (deterministic planning), lot size EX (lot-for-lot), BESKZ='E' (in-house production).

MaterialDescriptionMRP TypeLot SizeComponents
MZ-FG-C900C900 BIKEPDEX7 ROH
MZ-FG-C950C950 BIKEPDEX7 ROH
MZ-FG-C990C990 BikePDEX7 ROH
MZ-FG-M500M500 BIKEPDEX7 ROH
MZ-FG-M525M525 BIKEPDEX7 ROH
MZ-FG-M550M550 BIKEPDEX7 ROH
MZ-FG-R100R100 BIKEPDEX7 ROH
MZ-FG-R200R200 BikePDEX7 ROH
MZ-FG-R300R300 BikePDEX7 ROH

Raw Material Components (MZ-RM-*)

Each bike has 7–10 ROH components following the naming pattern MZ-RM-{model}-01 through MZ-RM-{model}-07. These are the same components used by the PP generator and appear as dependent requirements when MRP explodes the BOM.

#PartExample (R100)UoM
01FrameMZ-RM-R100-01ST
02Handle BarsMZ-RM-R100-02ST
03SeatMZ-RM-R100-03ST
04WheelsMZ-RM-R100-04ST
05ForksMZ-RM-R100-05ST
06BrakesMZ-RM-R100-06ST
07Drive TrainMZ-RM-R100-07ST

End-to-End Flow

Step 0 Create PIR
MD61
PBIM / PBHI
Step 1 Run MRP
MD01/MD02
PLAF / MDKP
Step 2 Review
MD04
Stock/Req List
Step 3 Convert
Planned → Prod Order
AUFK / AFKO
PIR Demand → MRP creates Planned Orders → Converted to Production Orders
Document Flow: PIR (PBIM/PBHI) → MRP Run (MDKP/MDTB) → Planned Orders (PLAF) → Production Orders (AUFK/AFKO). After conversion, MRP re-run cleans up the consumed planned order (PLAF deletion).
Why PIR + MRP instead of BAPI_PLANNEDORDER_CREATE? BAPI_PLANNEDORDER_CREATE does NOT persist via RFC because the V2 collective update never completes in the RFC session. The workaround is to create demand via PIR, then let the MRP run generate planned orders in PLAF naturally.

Step 0 — Create PIR (Planned Independent Requirements)

Create Forecast Demand (MD61)

Creates Planned Independent Requirements (PIR) for bike finished goods. PIR represents forecast demand that MRP will convert into planned orders. Uses requirement type VSF (standard forecast) with auto-incrementing version 0009.

Transaction Codes

TcodePurpose
MD61Create Planned Independent Requirements
MD62Change Planned Independent Requirements
MD63Display Planned Independent Requirements

BAPI

Function ModulePurpose
BAPI_REQUIREMENTS_CREATECreate PIR with material, plant, version, qty, date
BAPI_TRANSACTION_COMMITPersist changes (WAIT='X')

Key Parameters

FieldValueNotes
REQU_TYPEVSFStandard forecast requirement
VERSION0009Auto-increments if version already exists
MATERIALe.g. MZ-FG-M500Random bike from pool of 9
PLANT1710
REQ_QTYQuantity (e.g. 2000)Configurable via --qty
REQ_DATEToday + lead daysConfigurable via --lead-days
Note: The BAPI returns an empty REQMTSPLANNUMBER via RFC, but the demand IS created in SAP. This is normal SAP behavior — the PIR number is assigned internally and can be verified in PBIM/PBHI.

Tables Populated

TableDescriptionKey Fields Written
PBIMPIR Header (Independent Requirements)BESSION (version), BEDID (req type), MATNR, WERKS
PBHIPIR Schedule Lines (Period Quantities)BESSION, PDATU (req date), PLNMG (planned qty)

Verification Query

-- Check PIR for bike materials
SELECT h.MATNR, h.WERKS, h.BESSION, i.PDATU, i.PLNMG
FROM PBIM h
JOIN PBHI i ON h.BESSION = i.BESSION AND h.BEDID = i.BEDID
WHERE h.MATNR LIKE 'MZ-FG%' AND h.WERKS = '1710'
ORDER BY h.MATNR, i.PDATU;

Step 1 — Run MRP

Material Requirements Planning (MD01/MD02)

Executes single-item MRP for a material. MRP reads PIR demand, checks available stock, explodes the BOM, and creates planned orders in PLAF to cover the net requirement. Uses net change planning (PROC_TYPE='1') with BOM re-explosion (PLANNING_MODE='3').

Transaction Codes

TcodePurpose
MD01MRP Run (Total Planning)
MD02MRP Run (Single-Item, Single-Level)
MD04Stock/Requirements List
MD05MRP List (Individual)

BAPI

Function ModulePurpose
BAPI_MATERIAL_PLANNINGRun single-item MRP
BAPI_TRANSACTION_COMMITPersist changes (WAIT='X')

Key Parameters

FieldValueNotes
MATERIALe.g. MZ-FG-R100Single material or loop all 9
PLANT1710
PROC_TYPE1Net change planning
PLANNING_MODE3Re-explode BOM and routing
MRP Logic: Planned Order Qty = Demand (PIR) − Available Stock. With lot size EX (lot-for-lot), MRP creates exactly one planned order per net requirement. If stock already covers the demand, MRP creates 0 planned orders — this is not an error.

Tables Populated

TableDescriptionKey Fields Written
PLAFPlanned OrdersPLNUM (planned order #), MATNR, GSMNG (order qty), PEDTR (end date)
MDKPMRP Document HeaderDTNUM (document #), MATNR, WERKS, DTART
MDTBMRP Document ItemsDTNUM, DTPOS, MRP element details
EBANPurchase RequisitionsBANFN, MATNR (for externally procured components)
RESBReservations (dependent requirements)Planned order component reservations

MRP Element Types (MD04 View)

CodeDescriptionSource
PAPlanned OrderMRP-generated (PLAF)
PPPlanned Independent Requirement (PIR)Step 0 (PBIM/PBHI)
FEProduction OrderConverted from planned order
VJSales OrderFrom OTC generator
BEPurchase RequisitionFor externally procured items

Verification Query

-- Planned orders from MRP run
SELECT PLNUM, MATNR, GSMNG, PEDTR, PSTTR, PLSCN
FROM PLAF
WHERE MATNR LIKE 'MZ-FG%' AND WERKS = '1710'
ORDER BY PLNUM DESC;

Step 2 — Review Stock/Requirements

Stock/Requirements List (MD04)

Read-only step that displays the current stock situation and all MRP elements for a material. Shows planned orders, PIR demand, production orders, sales orders, and current stock levels. Useful for verifying MRP results before conversion.

BAPI

Function ModulePurpose
BAPI_MATERIAL_STOCK_REQ_LISTRead stock/requirements list (equivalent to MD04)

Key Parameters

FieldValueNotes
MATERIALe.g. MZ-FG-R100Material to review
PLANT1710

Output Elements

ElementDescriptionMeaning
PAPlanned OrderMRP-generated supply (to be converted)
PPPIRForecast demand from Step 0
FEProduction OrderFirm supply (converted from PA)
VJSales OrderCustomer demand (from OTC)
StockCurrent available stockUnrestricted use inventory
No commit needed. This step is purely read-only — no BAPI_TRANSACTION_COMMIT is called.

Step 3 — Convert Planned Order to Production Order

Planned Order Conversion

Reads a planned order from PLAF, creates a production order using the planned order details, then re-runs MRP to clean up the consumed planned order. The profile PLDORD_PROFILE='LA' is required for in-house production materials (BESKZ=E), as defined in T460C.

Transaction Codes

TcodePurpose
CO40Convert Planned Order to Production Order
CO41Convert Planned Orders (Collective)
MD04Verify conversion (PA → FE)

BAPIs (Two-Step Process)

Function ModulePurposeStep
BAPI_PLANNEDORDER_GET_DETAILRead planned order details from PLAFRead
BAPI_PRODORD_CREATECreate production order from planned order dataCreate
BAPI_TRANSACTION_COMMITPersist production order (WAIT='X')Commit
BAPI_MATERIAL_PLANNINGRe-run MRP to clean up consumed planned orderCleanup
BAPI_TRANSACTION_COMMITPersist MRP cleanup (WAIT='X')Commit

Key Parameters (BAPI_PRODORD_CREATE)

FieldValueNotes
MATERIALFrom planned orderMaterial from PLAF
PLANT1710
ORDER_TYPEFrom planned order or defaultProduction order type
QUANTITYFrom planned order (GSMNG)
BASIC_START_DATEFrom planned order
BASIC_END_DATEFrom planned order
MRP cleanup is essential. After converting a planned order to a production order, MRP must be re-run to delete the now-consumed planned order from PLAF. Without the cleanup run, the planned order remains as a phantom supply element.
PLDORD_PROFILE='LA' is required for in-house production materials (BESKZ=E). This profile is defined in configuration table T460C and controls how planned orders are converted.

Tables Populated

TableDescriptionImpact
AUFKProduction Order HeaderNew order created with AUFNR
AFKOProduction Order MasterPLNBEZ (material), GAMNG (qty)
PLAFPlanned OrdersDeleted by MRP cleanup run

Verification Query

-- Production order created from planned order
SELECT a.AUFNR, k.PLNBEZ, k.GAMNG, k.GMEIN
FROM AUFK a
JOIN AFKO k ON a.AUFNR = k.AUFNR
WHERE k.PLNBEZ LIKE 'MZ-FG%'
ORDER BY a.AUFNR DESC;

-- Verify planned order was deleted
SELECT PLNUM, MATNR, GSMNG FROM PLAF
WHERE PLNUM = '0004000XXXXX';

SAP Tables Reference

MRP Core Tables

TableDescriptionCategoryPopulated By
PBIMPIR Header (Independent Requirements)DemandStep 0
PBHIPIR Schedule Lines (Period Quantities)DemandStep 0
PLAFPlanned OrdersSupplyStep 1 (created), Step 3 (deleted)
MDKPMRP Document HeaderMRP RunStep 1
MDTBMRP Document ItemsMRP RunStep 1
EBANPurchase RequisitionsProcurementStep 1
RESBReservations (Dependent Requirements)ComponentsStep 1

Production Order Tables (from Conversion)

TableDescriptionCategoryPopulated By
AUFKOrder Master (Header)Order HeaderStep 3
AFKOOrder Header Data (PP specific)Order MasterStep 3

Material Master Tables

TableDescriptionCategory
MARAMaterial General DataGeneral
MARCMaterial Plant Data (MRP, Production)Plant
MARDStorage Location StockStock
MAKTMaterial DescriptionsTexts
MBEWMaterial ValuationValuation

Configuration Tables

TableDescriptionPurpose
T001Company CodesCompany code 1710
T001WPlantsPlant definitions
T460CPlanned Order ProfilesPLDORD_PROFILE='LA' for BESKZ=E
T438MMRP Type CustomizingPD = deterministic planning

CDS Views Reference

Planned Independent Requirements (PIR) CDS Views

CDS ViewDescriptionBase Tables
I_PlannedIndepRqmtPIR headerPBIM
I_PlannedIndepRqmtItemPIR schedule linesPBHI
I_PlndIndepRqmtAPI01PIR header (API)PBIM
I_PlndIndepRqmtItemAPI01PIR schedule line (API)PBHI

Planned Order CDS Views

CDS ViewDescriptionBase Tables
I_PlannedOrderPlanned order headerPLAF
I_PlannedOrderAPI01Planned order header (API)PLAF
I_PlannedOrderComponentPlanned order componentsRESB
C_PlannedOrderConsumption: Manage Planned OrdersPLAF

MRP CDS Views

CDS ViewDescriptionBase Tables
I_MRPDocumentMRP document headerMDKP
I_MRPElementMRP element (stock/requirements list)MDTB
I_MRPMaterialMaterial MRP dataMARC
C_MRPStockRequirementListConsumption: Stock/Requirements List (MD04)MDTB
C_MRPMaterialConsumption: MRP material overviewMARC

Purchase Requisition CDS Views (from MRP)

CDS ViewDescriptionBase Tables
I_PurchaseRequisitionPR header compositeEBAN
I_PurchaseRequisitionItemPR item with all fieldsEBAN
I_PurReqnItemPurOrdRefPR item to PO referenceEBAN
C_PurchaseReqnHeaderConsumption: Manage PRsEBAN

Production Order CDS Views (from Conversion)

CDS ViewDescriptionBase Tables
I_ProductionOrderProduction order headerAUFK, AFKO
I_ProductionOrderAPI01Production order (API)AUFK, AFKO
I_ProductionOrderItemProduction order itemAFPO
I_ProductionOrderComponentOrder BOM componentsRESB
I_ProductionOrderOperationOrder routing operationsAFVV
C_ProdOrdConfirmationConsumption: Order confirmationsAFRU

Master Data CDS Views

CDS ViewDescriptionBase Tables
I_ProductProduct/material generalMARA
I_ProductPlantBasicProduct plant data (MRP params)MARC
I_ProductPlantMRPAreaMRP area dataMARC
I_ProductPlantProcurementProduct procurement dataMARC
I_ProductValuationProduct valuationMBEW
I_MaterialStockMaterial stock overviewMARD
I_BillOfMaterialBOM headerSTKO
I_BillOfMaterialItemBOM componentsSTPO
I_ProductionRoutingHeaderRouting headerPLKO
I_ProductionRoutingOperationRouting operationsPLPO

BAPI Reference

StepBAPIPurposeCommit?
0BAPI_REQUIREMENTS_CREATECreate PIR demandYes
1BAPI_MATERIAL_PLANNINGRun single-item MRPYes
2BAPI_MATERIAL_STOCK_REQ_LISTRead stock/requirements listNo
3BAPI_PLANNEDORDER_GET_DETAILRead planned order detailsNo
3BAPI_PRODORD_CREATECreate production orderYes
3BAPI_MATERIAL_PLANNINGMRP cleanup (delete consumed PA)Yes
*BAPI_TRANSACTION_COMMITCommit changes (WAIT='X')

Scripts & Usage

Quick Start (mrpgen.sh)

Generate N MRP cycles with configurable pipeline depth:

# PIR + MRP only (create demand and planned orders)
./mrpgen.sh 10 mrp

# Full pipeline: PIR + MRP + Convert (100 cycles)
./mrpgen.sh 100 convert

Individual Steps (mrpwf.sh)

./mrpwf.sh step0-pir 5              # Create 5 PIR demands
./mrpwf.sh step1-mrp MZ-FG-R100     # Run MRP for one material
./mrpwf.sh step1-mrp                 # Run MRP for all 9 finished goods
./mrpwf.sh step2-review MZ-FG-R100  # Review stock/requirements (MD04)
./mrpwf.sh step3-convert 4000001463  # Convert planned order to prod order
./mrpwf.sh full 3                    # 3 full cycles (PIR+MRP+Convert)
./mrpwf.sh list                      # List planned orders from PLAF
./mrpwf.sh status 4000001463         # Show planned order details

Stages (mrpgen.sh)

StagePipelineSAP Tables Created
mrpPIR → MRP RunPBIM, PBHI, PLAF, MDKP
convertPIR → MRP → Convert → Cleanup+ AUFK, AFKO (PLAF deleted)

Options

FlagDescription
--verbosePrint BAPI details and all return messages
--dry-runValidate only (no BAPI_TRANSACTION_COMMIT)
--qty NFixed PIR quantity (default: random)
--pause NSeconds between steps (default: 3)
--lead-days NDays ahead for PIR requirement date
--stop-at STAGEStop after stage: pir, mrp, review, convert

Project Structure

.
├── SAPMRPWorkflow.java              # Main automation program
├── mrpwf.sh                         # Workflow wrapper (individual steps)
├── mrpgen.sh                        # Bulk data generator (batch mode)
├── compile.sh                       # Compilation helper
├── docs/
│   └── SAP_MRP_Workflow_Documentation.html  # This document
└── skill/
    └── mrp-planning.md              # Claude Code skill file

Integration with Other Generators

The MRP generator sits at the center of the SAP data ecosystem, connecting demand from sales to supply via production and procurement. All generators share the same S/4HANA IDES instance.

OTC (Order-to-Cash)

Sales Orders → MRP Demand
OTC creates sales orders (VA01) which appear as VJ elements in MD04. MRP sees these as customer demand and generates planned orders to fulfill them.

MRP (This Generator)

PIR → Planned Orders → Prod Orders
Creates forecast demand via PIR, runs MRP to generate planned orders, converts to production orders. The central planning hub.

PP (Plan-to-Produce)

Production Order Execution
PP picks up where MRP Step 3 leaves off: release, GI, confirmation, GR. MRP creates the production order; PP executes it through the shop floor.

OTC: Sales Order MRP: Plan & Convert PP: Execute & Confirm P2P: Procure RM
P2P (Procure-to-Pay) handles the procurement of raw materials (MZ-RM-*) that MRP identifies as shortages during BOM explosion. When MRP finds insufficient component stock, it creates purchase requisitions (EBAN) which P2P converts into purchase orders and goods receipts.

Troubleshooting

Common Errors

ErrorCauseFix
Empty REQMTSPLANNUMBER BAPI_REQUIREMENTS_CREATE returns blank PIR number via RFC Normal SAP behavior. Demand IS created. Verify in PBIM/PBHI.
"Requirement already exists" PIR version 00 already used for material/plant/period Auto-increments version 00 → 09. If all 10 used, pick different date or material.
MRP creates 0 planned orders Existing stock covers PIR demand (net requirement = 0) Not an error. Increase PIR qty or consume stock first.
BAPI_PLANNEDORDER_CREATE fails V2 collective update does not complete in RFC session Do NOT use this BAPI. Use PIR + MRP run instead (the approach this generator uses).
"Cannot be changed manually" MRP-generated planned orders are system-managed Use MRP re-run to delete/modify planned orders, not manual changes.
Conversion fails (no profile) PLDORD_PROFILE not set for in-house production materials Set PLDORD_PROFILE='LA' (from T460C) for BESKZ=E materials.
Planned order not found PLAF record already deleted by previous MRP cleanup Run list to see current planned orders. Each can only be converted once.

MRP Configuration Prerequisites

SettingTableRequired ValuePurpose
MRP TypeMARC.DISMMPDDeterministic planning (reacts to PIR)
Lot SizeMARC.DISLSEXLot-for-lot (exact quantity)
Procurement TypeMARC.BESKZEIn-house production
MRP ControllerMARC.DISPOSetRequired for MRP to process the material
BOMMAST/STKO/STPOExistsRequired for BOM explosion in MRP

BAPI Parameter Gotchas

BAPIGotchaCorrect Approach
BAPI_REQUIREMENTS_CREATE REQMTSPLANNUMBER always empty via RFC Ignore the empty return; verify demand in PBIM
BAPI_MATERIAL_PLANNING Returns statistics (plaf_ins, plaf_del) but no order numbers Query PLAF after commit to get planned order numbers
BAPI_PRODORD_CREATE RETURN is export structure, not table getExportParameterList().getStructure("RETURN")
BAPI_PRODORD_CREATE Date fields are BASIC_START_DATE / BASIC_END_DATE Not BASIC_START / BASIC_END
BAPI_PLANNEDORDER_GET_DETAIL Planned order number must be 10-digit zero-padded Pad with leading zeros before calling

Test Results

Step 0 — PIR Creation

TestResultDetails
Create PIR for MZ-FG-M500 PASS 2,000 units, version 00 → demand created in PBIM/PBHI

Step 1 — MRP Run

TestResultDetails
MRP for MZ-FG-M500 PASS plaf_ins=1, planned order 4000001463 (1,129 units = 2,000 demand − 871 stock)

Step 3 — Conversion

TestResultDetails
Convert planned 4000001463 PASS Production order 000001002167 created
MRP cleanup run PASS plaf_del=1 — consumed planned order removed

Full Pipeline

StepResultDetails
PIR (Step 0)PASSDemand created
MRP (Step 1)PASSPlanned order generated
Review (Step 2)PASSPA + PP elements visible
Convert (Step 3)PASSProd order created, PLAF cleaned
All tests performed on SAP S/4HANA IDES, client 100, plant 1710. MRP uses BAPI_MATERIAL_PLANNING with PROC_TYPE='1' and PLANNING_MODE='3'.