Scenario 21 — Pricing Procedure (Custom Conditions: Discount, Freight, Tax)

TIER 7 · CUSTOMIZATION ★★★★★ ⏱️ ~3 hours M/06 (cond types) → M/08 (proc) → OMFO (schema determination)
← Previous
Scenario 20: Custom Document Type
Next →
Scenario 22: Output Determination
✅ Live-tested on S/4HANA 2023 (PSPK)
Executed end-to-end from scratch: condition table 909 (M/03) → access sequence ZCUS (M/07) → condition type ZCUS (M/06) → schema Z_PSPK (M/08) → determination (OMFO) → live PO with the duty computing correctly (275,000/TO effective vs 250,000 net — the difference IS the duty). Every error you might meet on the way (cross-client locks, pricing keys, subtotal codes…) has its plain cause and fix in the Troubleshooting Center.

📊 Business Case

A PO price is rarely just a single "gross price". It is a build-up: gross price, minus vendor discounts, plus freight, plus customs duty, plus tax. The pricing procedure is the ordered recipe of condition types that adds and subtracts these elements in the right sequence so the PO's net/effective price — and therefore your inventory valuation — is correct. Here PakSteel models that real build-up and adds a custom ZCUS customs-duty condition.

🕐 When to use it

Whenever the real landed cost of a purchase involves more than a flat price — discounts, freight, duty, surcharges, tax — and you need the PO to compute the correct net/effective price automatically.

❓ Why it matters

The pricing procedure determines the PO net price, which flows into inventory valuation and the GR/IR postings. A wrong procedure means mis-valued stock and wrong margins — get it right and costing is accurate by default.

👤 Who triggers it

An MM consultant builds the condition types (M/06) and procedure (M/08); buyers see the conditions auto-populate on the PO conditions tab in ME21N.

🔁 The key distinction

This is mostly config, but its output is a number that does post: the net price drives GR/IR. Delivery costs (freight/duty) can post to inventory or a clearing account depending on the condition type's account key.

💰 Financial Impact — The Easy-Money Example

The pricing procedure's job is to make the effective price correct. Get it wrong and every goods receipt mis-values inventory. PakSteel's real build-up per tonne: a 250,000 gross price becomes a 303,647 effective price once discount, freight, duty and tax are layered in.

Gross Price (PB00)+ 250,000
Vendor Discount 3% (RA00)− 7,500
Freight 2% (FRA1)+ 4,850
Customs Duty 5% (custom ZCUS)+ 12,367 (planned)
17% Sales Tax (MWST)+ 43,930
Effective Price/TO303,647
🏷️ Gross only (wrong)
Stock at 250,000
If only PB00 is captured, inventory is valued at 250,000/TO — understated by every cost the procedure was supposed to add.
→
⚙️ Full procedure
Net price 259,717
Discount, freight and duty net to 259,717 in the stock value (tax is normally deductible, not capitalized). The PO carries the correct cost.
→
📊 GR posting
Inventory ↑ at true cost
At goods receipt, inventory (BSX) is debited at the procedure's net price; freight/duty post via their account keys (FR1/FR3) — landed cost captured correctly.

Where the posting is involved: the pricing condition flows straight into the GR/IR postings. The net price debits inventory; planned delivery costs (FRA1, ZCUS) post to inventory or a freight/duty clearing account per their condition-type account key — so a mis-built procedure literally mis-states your balance sheet and COGS.

💡 Lesson: the pricing procedure is where "what we pay" becomes "what inventory is worth." Configure the condition sequence and account keys correctly once, and every PO computes the right landed cost — wrong config silently mis-values stock and distorts margins on every receipt.

🇵🇰 The Business Story

PakSteel's PO price is rarely just "Gross Price". Real example:

Gross Price (PB00)+ 250,000
Vendor Discount 3% (RA00)− 7,500
Freight 2% (FRA1)+ 4,850
Customs Duty 5% (custom ZCUS)+ 12,367 (planned)
17% Sales Tax (MWST)+ 43,930
Effective Price/TO303,647

Pricing Procedure orchestrates all these condition types.

🎯 What you'll learn

✅ Before you start — what this scenario assumes

🔧 Step-by-Step

🗺️ First — the FULL build chain, and why we skip the early steps

A pricing procedure is built in this true order — and the steps below (21.1 → 21.7) follow exactly this sequence. At each step the copy/reuse shortcut is stated first (it's the normal consultant path), followed by the full from-scratch build for when nothing suitable exists:

OrderPieceT-codeBuild new or reuse?Why that choiceWhy this step exists
21.1Condition table (the key a price is stored under)M/03♻️ Reuse standardSAP ships dozens (vendor+material = info record, vendor-only…). Build your own only when no standard key fitsevery stored price needs a lookup key
21.2Access sequence (search order of tables)M/07♻️ Reuse — comes along freeCopying FRA1 in 21.3 brings its access sequence and its tables with it. Build one only for a new tableSAP needs a search order to find the right rate
21.3Condition type (a line on the bill)M/06📋 Copy standard → ZFRA1 → ZCUS: the hard flags (delivery cost, %, accruals) come pre-set correctcustoms duty needs its own line on the bill
21.4Calculation schema (the bill format)M/08📋 Copy standard → ZRM0000 → Z_PSPK, then insert your row — never edit SAP's originala line only counts once it is in the bill format
21.5Schema determination (which bill pad for whom)OMFO🔨 Build (tiny)Your org + vendor labels are yours — a few New Entriesthe right bill pad must open by itself on each PO
21.7Condition records (the actual numbers)MEK1 / info record🔨 Create — it's master dataThe stored % / prices are always your own data (21.6 = test the PO in between)buyers should not type the % on every PO

🎓 The consultant golden rule this teaches: in SAP config, never build what you can copy. Standard content is battle-tested and upgrade-safe; you copy it into the Z-namespace and adjust. You'll meet the same pattern everywhere — document types, movement types, material types, output types, schemas. "We skip this step" never means it doesn't exist — it means SAP already did it, and here's what you inherited.

📐 Academy convention: wherever we recommend copying, we also give the full from-scratch steps (🛠️ boxes below each step) — so if your system has nothing suitable to copy, or you want to truly understand every field, you can build it yourself.

⚙️ Config Steps — in true build order (focus: add custom condition ZCUS for customs duty)

21.1 — Condition Table · M/03 — where the price's KEY is defined

⚡ This step will: create the lookup key (condition table 909) that the duty % will later be stored under — pure config, nothing shows on any PO yet. 📄 paper: — (config object only) · 📦 stock: no change · 💰 money: no posting

📋 Copy/reuse first (the normal path): SAP ships dozens of standard tables (vendor+material = the info record, vendor-only, purch org+material…) — the MEK1 key-combination popup lists them. If a standard key fits your need, reuse it and move to 21.2 — nothing to create here. Build your own only when no standard table has your key. (Cloud: via Fiori SSCUIs instead of M/03 — same concept.)

🛠️ From scratch — when you DO need your own key. Case: duty % varies by material group (steel 5%, chemicals 12%), stored per Purch. Org + Material Group — no standard table has that combination:

Field / ActionFillWhat it asks (plain words)Why we choose this — and the impact if wrong
Table numbera free number in 501–999 (try 902, 905…)What number will this new condition table have?501–999 = customer namespace. Impact: use a number below 501 and an SAP upgrade can overwrite your table; use one already taken (SD and MM share the range) and you get "table already exists".
Key field 1 — Purchasing Organization (EKORG)in the Field Catalog (right), double-click it → it jumps to Selected FieldsWhat is the FIRST column of the search key?The selected fields ARE the key ("a % stored per org + material group"). Org field first. Impact: leave it out and you cannot store a rate that differs by buying company.
Key field 2 — Material Group (MATKL)double-click it next (catalog is alphabetical — use the 🔍 binoculars to find it)What is the SECOND column of the key?Duty varies by material group (steel 5%, chemicals 12%). Impact: omit it and steel and chemicals cannot have different rates; add extra fields and you multiply the records you must maintain.
"with Validity Period" tick✅ keep ticked (default)Should each stored rate carry Valid-From / Valid-To dates?Yes — a rate change should be a NEW dated record, not an overwrite. Impact: untick it and changing the duty erases the old rate, so last year's POs can no longer be explained.
"with Release Status" tick✅ keep ticked (default)Should records carry a release / processing status?A harmless SAP default that lets a record be blocked or released. Impact: negligible for us — leave it as SAP proposes.
Generate + Packagemenu Condition Table → Generate → confirm → Package popup: click "Local Object" ($TMP)Build the real database table, and decide where it may travel.Generation creates database table A9xx, so SAP asks for a package (not a customizing request). $TMP = stays in this system, never transported — right for IDES. Impact: on a real project you would pick a Z-package + workbench request so the table reaches production.
💡 What did you just build? (in simple words)

"Key" = the columns SAP uses to FIND the right row — like searching a name in your phone to get the number. Name = key, number = value. Here: Purch Org + Material Group together = the key, the % = the value. The buyer types nothing extra — every PO already has both values (org from the PO header, material group from the material master). At PO time SAP joins them (PKLO + STEEL01), searches your table, and if a date-valid row exists the % fills in by itself. No row? It tries the next table, or stays empty/manual. The table is just rows like:

Cond. typePurch. OrgMaterial GrpValidRate
ZCUSPKLOSTEEL012026 →5%
ZCUSPKLOCHEM012026 →12%

How does SAP know WHICH values to search with? By matching field names. At PO time SAP fills a "basket" of labeled values from the PO (EKORG=PKLO, MATKL=STEEL01, LIFNR=MUGHAL21…). Your table says "my key fields are EKORG + MATKL" → SAP takes the values with the same labels from the basket and searches. Same label = automatic match — nobody types anything. (The basket's real name: communication structure KOMK/KOMP — good interview word. This is also why the field screen only offered catalog fields: the catalog lists only fields that exist in the basket.)

Technically A9xx stores the key + validity + a record number; the % itself sits in the condition-record tables (KONH/KONP) — A9xx is the index card, KONP the page with the number. You'll write these entries in 21.7 (MEK1).

⚠️ Error "Table 901 already exists" though your list doesn't show it? The 9xx condition-table numbers are shared across SD, MM and clients → plain cause & fix

21.2 — Access Sequence · M/07 — the search order of the tables

⚡ This step will: create the search path ZCUS — the ordered list that tells SAP which tables to check, in what order, when it hunts for the duty %. Still pure config. 📄 paper: — (config object only) · 📦 stock: no change · 💰 money: no posting

📋 Copy/reuse first (the normal path): when you copy a standard condition type in 21.3 (FRA1 → ZCUS), its access sequence and its tables come along automatically — skip straight to 21.3. Build your own only if you created a new table in 21.1.

🛠️ From scratch. The M/07 screen has 3 folders on the left — 3 levels, like a cupboard: the sequence (the cupboard's name) → Accesses (the shelves = which tables, in what order) → Fields (inside a shelf = how the table connects to the PO "basket"):

Folder · FieldFillWhat the field asks (plain words)Why we choose this — and the impact if wrong
Folder 1 · Access Sequences (the cupboard) — New Entries
Access SequenceZCUSWhat NAME identifies this search path?Your own Z-code (customer namespace). Impact: this exact code must be typed into the condition type in 21.3 — a mismatch and ZCUS searches nothing.
Description"Customs duty search"A human label so colleagues recognise the sequence.Free text. Impact: readability only — a vague label just makes it hard to find later.
Access category (the "Ty." column)— (leave blank)Is this search path for PRICING, or for a REBATE agreement?Blank = relevant for pricing (our case); 1 = rebate (a vendor year-end-bonus machine). Impact: put 1 and a normal pricing condition type can never use this sequence. After Enter, SAP auto-fills the second description "relevant for pricing".
Folder 2 · Accesses (the shelves — which tables, in what order) — select ZCUS → double-click Accesses → New Entries
AcNo (access number)10In what ORDER should SAP try the tables? (a priority queue)SAP searches lowest number first (10 → 20 → 30). Steps of 10 leave gaps to slot a 15 in later. Impact: give a general table a lower number than a specific one and the wrong (general) rate is found first.
Table909WHICH condition table does this shelf search?Your table from 21.1. Impact: point to the wrong table number and SAP searches the wrong place — it never finds your rate.
Requirement— (blank)An optional test (routine) that must be TRUE before SAP bothers to search this table.Blank = always search it. Impact: attach a requirement that is false at PO time and this shelf is silently skipped — the duty is never found.
Exclusive✅ tickIf this table finds a record, should SAP STOP and not try the lower shelves?Tick = stop at the first hit. Golden rule: most SPECIFIC table first + Exclusive. Impact: untick it and SAP keeps searching, so a lower general table can overwrite your specific deal.
Folder 3 · Fields (how the table plugs into the PO "basket") — select the 10-row → double-click Fields → Enter
EKORG (Purch. Organization)source KOMK (auto)Where does the PO's Purch-Org value come from at search time?Org data lives in the document HEADER basket (KOMK). Impact: a wrong source builds the search key wrong, so the table never matches.
MATKL (Material Group)source KOMP (auto)Where does the material-group value come from?Material/item data lives in the ITEM basket (KOMP). Impact: same — a wrong source and the lookup fails. SAP proposes both sources automatically; you only press Enter to confirm.

Moving between folders: to open Accesses/Fields, click the narrow grey box at the FAR LEFT of a row (like an Excel row header) to select it, then double-click the folder. Save → the customizing-request and "development class … is local" popups are normal on IDES (click ✓). Finally, in 21.3 set the condition type's Access sequence = ZCUS — without that link the tables are never searched.

⚠️ Error "Access sequence inconsistent; target field EKORG missing in access 010"? It means the Fields level was saved before it was finished → plain cause & fix (related: "field assignment not yet made").

Later, add a fallback shelf: AcNo 20 → a general table (e.g. material-group-only) — special rates found at 10, normal rate at 20.

⚠️ M/07 opens as "Display View" with "No maintenance authorization for cross-client tables"? Access sequences are cross-client — work the SCC4 → S_TABU_CLI → S_USER_GRP ladder, or take the M/06 copy path (client-specific, no lock) → plain cause & fix

21.3 — Create Condition Type ZCUS · M/06

⚡ This step will: create the new bill line ZCUS — the rule that says "customs duty = a % delivery cost" — ready to be placed into a schema in 21.4. 📄 paper: — (config object only) · 📦 stock: no change · 💰 money: no posting

📛 Naming note (live-tested): condition-type names are max 4 characters in SAP — so our type is ZCUS. Yes, the access sequence from 21.2 is also named ZCUS — that's allowed and common: they are different object types in different name spaces (like a folder and a file sharing one name). Don't let the same name confuse you: 21.2's ZCUS = the search path; 21.3's ZCUS = the bill line.

Do it either way — the fields are identical:

Copying is faster because FRA1 is already a percentage delivery cost — exactly what customs duty is — so the hard settings come pre-filled and you only review them. (Customizing request is fine on the test server.)

📦 Running example (used in the last column): an imported steel PO worth ₨1,000,000 at 5% customs duty = ₨50,000 duty.

Section · FieldFillWhat the field asks (plain words)Why we choose this — and the impact if wrong
Top of screen
Condition Type / DescriptionZCUS · "Customs Duty %"What is this pricing line's name?Z = your own object. Impact: a Z-name is never overwritten by an SAP upgrade; reusing an SAP name risks a support pack changing it under you
Access SequenceZCUSWhich search path finds the % automatically? (your table 909 → access 10)Connects the condition to the chain you built. Impact: with ZCUS the PO auto-fills the duty from your records; leave it blank and the buyer must type the % by hand on every single PO
Control Data 1
Condition ClassA (Discount/surcharge)What KIND of line is this? Restaurant bill: food price = B, discount = A, tax = DDuty changes the price → A. Impact: pick B by mistake and SAP treats ZCUS as the base price itself — it fights PB00 and the PO net value comes out wrong
Calculation TypeA (Percentage)HOW is the amount worked out? Fixed ₨200 = B, ₨50/km = C, 10% = ADuty is a % of value → A. Impact: choose B (fixed) and every PO adds the same flat ₨ — the ₨1,000,000 PO and a ₨1,000 PO would get identical duty
Condition CategoryB (Delivery costs)What does this money REPRESENT in real life? B = a cost of getting the goods to you, often paid to another companyThe key setting. Impact: with B, the ₨50,000 posts to a customs-clearing account at GR and the agent can invoice it separately in MIRO. Leave it blank and that ₨50,000 just silently inflates the material price — no separate tracking, no separate-vendor billing
Rounding Rule— (Commercial)How are the paisa rounded?Commercial = normal round half-up. Impact: negligible — shifts the result by paisa only
Structure Condition— (None)Is this a grouped / bill-of-material condition?Not for us. Impact: a wrong value could try to "explode" the duty across BOM components — keep None
Plus/minusA (positive)Which DIRECTION may the value go? A = add only · X = subtract onlyDuty always adds → A. Impact: A stops anyone keying a negative duty (which would reduce the price); blank would allow both
Group Condition
Group Condition— (off)Should SAP add up several PO lines and work the amount out on the TOTAL, instead of each line on its own?Duty is per line → off. Impact: tick it and a scale like "5% over 100 TO" would look at the combined tonnage of all lines instead of each line
RoundDiffAdj. (rounding-difference comparison)— (off)When a group value is split back onto the items, should SAP fix the 1-paisa rounding gaps?Only relevant if Group Condition is on. Impact: when on, the tiny leftover is added to the largest line so the header total exactly equals the sum of the lines
Group Cond. Routine— (blank)Which formula builds the combined basis (e.g. total weight of all lines)?Used only with Group Condition. Impact: none while Group Condition is off
Changes which can be made
Manual EntriesC (manual has priority)Who wins — the human or the stored record? (may the cashier override the till price?)C lets the buyer type/override the %. Impact: choose D (not possible) and buyers could never fix the duty when a real shipment's rate differs — every change would need a config record
Header Condition— (off)May it appear once for the whole PO?Off. Impact: if only Header were allowed you could not have different duty on the steel line vs the chemical line of one PO
Item Condition✅ tickMay it appear on each line?Duty is per item → required. Impact: forget this tick and ZCUS never appears on any PO line — the setup looks finished but does nothing
Delete✅ tickMay the buyer remove a proposed line?Impact: lets a buyer drop a wrongly-proposed duty on a domestic PO; untick and they are stuck with it
Amount/Percent✅ tickMay the buyer change the %?Impact: lets the buyer correct 5%→8% the day customs raises the rate, before your config catches up
Quantity Relation— (off)May the buyer change the unit-conversion factor on the PO?Not relevant to a % duty → off. Impact: none here
Value— (off)May the buyer overwrite the calculated ₨ value on the PO?Off. Impact: with it on, a buyer could type a final figure over the calculated duty — usually not wanted for a governed tax
Master Data
Proposed Valid FromtodayThe default START date offered when you later create a condition recordConvenience only. Impact: you can still change it in the record (MEK1); it does not restrict the condition type
Proposed Valid To31.12.9999The default END date offered for new records"9999" = no end. Impact: stops records from silently expiring; still editable per record
Pricing Procedure ⚠️— leave BLANK (trap!)Attach a condition-supplement mini-procedure? This is NOT the M/08 schemaLeave blank. Impact: type your Z_PSPK here by mistake (name confusion) and SAP tries to load a supplement procedure → errors. A classic beginner trap
Delete from DB— (set deletion flag only)What happens when a record is "deleted"?Default only flags it (reversible). Impact: the harsher option physically removes records — keep the safe default
Scales
Scale Base Type— (default)What do the scale steps measure — quantity, value, or weight?Flat duty → default. Impact: only matters if you set graduated rates ("5% up to 100 TO, 4% above")
Check Scale (check value)— (None)Must the steps only go up (ascending), only down, or either?None = no check. Impact: a check would block a typo like a higher rate for a bigger quantity when you meant a bulk discount
Scale Type— (blank)Is it a "from" scale, a "to" scale, or a graduated scale?"maintained in condition record" = decided when you type the rate. Impact: none for a flat duty
Scale Routine— (blank)A custom formula for an unusual scale basis?Advanced. Impact: none unless you code a routine
Scale Unit— (blank)The unit of measure the scale steps are counted inFor weight/volume scales. Impact: none for a flat %
Control Data 2
Accruals✅ tickShould the duty be posted through a clearing/provision account instead of straight onto the material price?Tick it — a cost you will pay later (when the customs agent invoices) should wait in a holding account, not inflate stock value straight away. Impact: at GR the ₨50,000 parks in that clearing account until the invoice arrives, so stock value stays correct until the real cost is known; leave it off and that provision logic is lost
Rel. for Acct Assigt ("Relevant for account assignment")✅ tickDoes this condition post to accounting (reach a G/L account)?Tick it — a real duty must land in the books through an account key, not just show on screen. Impact: leave it off and the ₨50,000 is calculated but never posts to any account, so your landed cost is understated
Exclusion— (off)When found, should this condition BLOCK other conditions?Off. Impact: tick it and ZCUS could suppress other valid conditions on the PO (see Study 09) — only for deliberate exclusion
Suppl. Goods Receipt— (greyed: "No entry possible")Supplementary conditions at goods receipt?SAP has locked it for this condition. Impact: nothing to do
Currency Conversion— (off)For a foreign-currency group condition, convert AFTER multiplying by quantity (not before)?Off. Impact: only affects multi-currency group conditions; nothing for a plain % duty
Promotion Condition— (off)Is this condition valid only inside a Retail promotion?SAP Retail only → off. Impact: none in purchasing
Used for Var.Config.— (off)Does the price depend on a configurable product's characteristics (variant config)?Off. Impact: none for standard materials like steel
Invoice List Cond.— (off)Is this relevant for invoice lists (a periodic SD billing summary)?Sales only → off. Impact: none in purchasing
Quantity Conversion— (default)When the condition's unit differs from the PO unit, how should the basis be converted?Mainly for calc type C (per-unit). Impact: for a % duty the default is correct; a wrong setting could mis-scale a "per-tonne" charge
Intercomp. Billing— (off)Is this an inter-company billing condition (one group company billing another)?Sales only → off. Impact: none in purchasing
Copy Shipment Costs— (off)Should the value be copied from a shipment-cost document (transport module)?LE-TRA only → off. Impact: none unless you run SAP Transportation
Zero Value Proc. (zero-value processing)— (default)How should the condition be handled when its amount works out to zero?Leave default. Impact: default simply skips a zero line; change only for special display needs
Sales Pricing (SAP Retail)
Relevant to Pricing— (off)Is this condition used when Retail calculates a SALES price out of the purchase price?Off. Impact: none — this is a Retail sales-price feature, not purchasing
Pricing On/Off— (off)Master switch to turn that Retail sales-price use on or offOff. Impact: none in our scenario
Text Determination
TextDetermProcedure— (blank)Which scheme of standard texts may this condition carry?Blank. Impact: set it only if you want notes/texts stored on the condition
Text ID— (blank)Which single text slot within that schemeBlank. Impact: none unless a text procedure is assigned above

💡 Want the customs agent (a different vendor) billed for the duty? That is set later on the PO, on the condition line's own Vendor field — not in M/06. Condition category B is what makes that field appear there.

Tip: keep FRA1 open in display (a second session) as a reference while you fill ZCUS.

21.4 — Add ZCUS to the Pricing Procedure · M/08

⚡ This step will: give PakSteel its own bill format Z_PSPK (copied from RM0000) with the ZCUS duty row inside — the maths recipe future POs will compute their net/effective price with. 📄 paper: — (config object only) · 📦 stock: no change · 💰 money: no posting

Do: M/08 → select RM0000 → Copy As… Z_PSPK (never edit the SAP standard directly) → select Z_PSPK → Control data → New Entries for the ZCUS row → Save.

ColumnFillWhat the column asks (plain words)Why we choose this — and the impact if wrong
Step35WHERE in the bill does this line sit? (the bill computes top-to-bottom, so position = maths order)35 = after gross + discount (10–30), before tax — like the line order on a restaurant bill. Impact: place it before the discount and duty is charged on the pre-discount amount — too high on every PO.
Counter10A sub-position, used only when two conditions share one step.Nothing else sits on step 35, so 10 is just tidy. Impact: leaving gaps lets you insert another line later without renumbering.
CTyp (condition type)ZCUSWHICH pricing rule is this line?Your custom duty type from 21.3. Impact: name the wrong type and the schema runs a different rule (or none).
From / Tothe step of the net-value subtotal (in RM0000 the discounted net, e.g. step 20)5% OF WHAT? — which earlier line is the base the % multiplies?From/To points at the base: "take the total of those steps". Impact: point at the gross instead of the net and duty is computed on the wrong amount → mis-valued stock on every PO.
Manualtick if the access sequence is blankMay the buyer type this line by hand on the PO?Needed when there are no condition records to auto-fill from. Impact: leave it off with no records and the buyer cannot enter the duty at all.
Statisticalleave blank for ZCUSIs this line for SHOW only — displayed but NOT posted?Statistical = shown but not posted (like the deductible-tax row). Duty is real and must capitalize into stock → blank. Impact: tick it and the duty shows on screen but never reaches stock value — landed cost understated.
AccKey / Accrualsa delivery-cost account key (in IDES often FR3/FR4 — press F4 to list the freight/duty keys)WHICH G/L accounts does this line post to?The key is looked up in OBYC at GR — delivery cost Dr inventory / Cr this clearing account, cleared at MIRO "Planned delivery costs". Impact: no key and the line computes but can never post.

Print / Requirement columns: leave blank for the first build — they control where the line prints and an optional condition (formula) that must be true for the line to apply. The Subtotal column is NOT optional everywhere: two codes matter — 9 on the gross-price row (PB00) and S on the final subtotal row ("publish this as the effective price"). If you copied RM0000 they came along; built from scratch, you must type them (see the skeleton below + the 06 207 gotcha).

⚠️ Error "Effective price is 0.000 … material price is 250,000 …" (message 06 207)? A schema row needs Subtotal code S to publish the effective price → plain cause & fix (background: the Subtotal S + 9 codes).

⚠️ Final PO total double-counts the goods (e.g. 2,625,000 instead of 1,375,000)? The grand-total row's From must start AT the net subtotal (step 20), not step 1 → plain cause & fix

⚠️ Error "Provision account key missing for condition type ZCUS in schema Z_PSPK"? Accrual conditions need keys in BOTH account columns (customs = FR3 in both; the same applies to standard FRA1 in a from-scratch schema, because account keys live on the schema row, not the condition type) → full cause & fix

🛠️ From scratch — building a schema on a blank page (no RM0000 to copy)

M/08 → New Entries → procedure Z_PSPK → Control data → build the rows yourself. A minimum working purchasing schema needs this skeleton (row by row, why each exists):

StepCTypFrom–ToWhy this row is needed
1PB00 gross price—The anchor. Every schema needs one base-price type (condition class B) or nothing can be priced at all. Subtotal column: 9 = "this line is the gross value"
10RA01 discount %1Discounts compute on the gross — From 1 points at PB00
20(no CTyp — subtotal row)1–19A named stopping point "net after discounts" — later rows reference it as their base
30FRA1 freight %20Delivery cost on the net; give it AccKey + Accruals so it posts via OBYC clearing
35ZCUS duty %20Same pattern as freight — your custom line
40NAVS/MWST tax20Mark statistical — shown, but deductible input tax is not capitalized into stock
90(subtotal row)20–89The effective price — what valuation and GR/IR actually use. Two rules, both live-tested: ① Subtotal column S — REQUIRED; S "publishes" this row's result as the PO's effective price (blank = effective price 0, message 06 207). ② From must be 20, NOT 1 — the step-20 subtotal already contains lines 1–19, so a 1–89 range counts the goods TWICE (PO showed 2,625,000 instead of 1,375,000). Grand total = the subtotal + only what comes after it

This is why we copy RM0000 instead: it ships ~40 rows of this wiring already correct (requirements, print flags, subtotal codes). Build from blank only to learn — or on a system with no usable standard. Column positions vary slightly per release; keep RM0000 open in display as your model.

21.5 — Procedure Determination · OMFO (Schema Determination) + supporting T-codes

⚡ This step will: wire the rule that makes import-vendor POs open your Z_PSPK bill pad automatically — after this, SAP picks the schema by itself from the org + vendor stickers. 📄 paper: — (config rows + one vendor master field) · 📦 stock: no change · 💰 money: no posting

Pricing procedure determination involves 4 related T-codes (all under SPRO → MM → Purchasing → Conditions → Define Price Determination Process → Define Schema Group / Schema Determination):

T-codeWhat it does
OMFNDefine Schema Group for Vendor
OMFMDefine Schema Group for Purchasing Organization
OMFPAssign Schema Group to Purchasing Organization
OMFOSchema Determination — combine Vendor Schema Group + Purch Org Schema Group → Pricing Procedure

Action — 4 small steps, each with its fields:

Step · T-codeFillWhat you are creating (plain words)Why we choose this — and the impact if wrong
1 · OMFN New EntriesSchema grp, vendor = Z1 · "Import vendors"What LABEL (sticker) will mark this KIND of vendor?A schema group is just a sticker — this step only invents its name. Impact: until the sticker exists you cannot write a rule that says "imports get the customs bill".
2 · OMFM New EntriesSchema grp, purch org = P1 · "PakSteel purchasing"What LABEL will mark this BUYING ORG?The org-side sticker. Two stickers (vendor + org) make a rule grid, not one global switch. Impact: with only the vendor sticker you could never vary the rule by org (e.g. a foreign subsidiary that skips duty).
3 · OMFPRow: Purch org PKLO → SchGrp P1Which org actually WEARS the P1 sticker?Sticks P1 onto PKLO. Impact: skip it and PKLO has no sticker, so any rule row mentioning P1 can never match a PKLO purchase.
4 · OMFO New EntriesRow: SchGrp POrg P1 + SchGrp vendor Z1 → Procedure Z_PSPKWhich sticker-PAIR opens WHICH bill pad (schema)?The rulebook row: "this org-sticker + this vendor-sticker = this schema". Impact: no matching row and SAP falls back to the blank+blank row = standard RM0000, so your ZCUS never loads.

5 · Stamp the vendor: BP (or XK02) → MUGHAL21 → Purchasing data → field Schema group, vendor = Z1 → Save. This is where the vendor gets its sticker — a master-data field, not config. Vendors with a blank schema group keep getting standard RM0000 — that's why only import vendors see ZCUS, and why stamping one vendor never disturbs the others.

How it runs at PO time (the whole point): PO header carries purch org PKLO → sticker P1. Vendor MUGHAL21 → sticker Z1. SAP looks up OMFO row (P1, Z1) → bill pad Z_PSPK → its condition types (incl. your ZCUS) load onto the PO. Change the vendor to an unstamped one → the same PO silently uses RM0000 instead. One field on the vendor decides which pricing world the PO lives in.

⚠️ Note: M/03 (condition tables) and M/07 (access sequences) are the pricing building blocks from steps 21.1–21.2 — they have nothing to do with procedure determination. OMFO is the verified T-code for schema determination.

🔄 Test

21.6 — Test: Create PO + see the new condition

⚡ This step will: create a real test PO on which the ZCUS row appears and recalculates the effective price — live proof the whole chain works. A PO is still only a promise to the vendor, not stock. 📄 paper: purchase order (test) · 📦 stock: no change · 💰 money: no posting

Do: ME21N → vendor MUGHAL21 (now schema group Z1) → one line RM-IRON-01, 10 TO @ 250,000 → select the line → Conditions tab. Everything you check below is on that Item detail → Conditions tab (the bottom zone of the ME21N screen, for the selected line) — the pricing X-ray of the PO.

Where on screen · What you should seeWhy
Item detail → Conditions tab · ZCUS row appears in the conditions listOMFO picked Z_PSPK (P1 + Z1), and Z_PSPK contains your step 35
Item detail → Conditions tab · Amount column — type 5 → press EnterManual entry allowed (M/06 "Manual entries C")
Item detail → Conditions tab · effective price recalculates upwardThe From-To base picked up the net subtotal and added 5% on top

ZCUS row missing? Check in order: ① vendor's schema group really saved (BP → Purchasing data) → ② OMFO row exists for P1+Z1 → ③ ZCUS is in Z_PSPK (not only RM0000) → ④ condition not set "manual only" while you expected auto. That order matches how determination actually runs.

🔍 Pressed the Analysis button on the Conditions tab and see a message list (208 / 207 / 102 / 109)? That is the pricing X-ray — if ZCUS shows there at all, determination already worked. Decode each number in plain cause & fix: message 109 means the chain is correct and you simply have not stored the % yet — create it in MEK1 (step 21.7 below) or type it manually on the Conditions tab.

One nuance not in the registry: a stored condition record's Material Group must match the PO item's actual material group, or the search misses and ZCUS stays on message 109.

21.7 — Optional: store the % as a condition record · MEK1 (so buyers don't type it)

⚡ This step will: store the duty % as a dated master-data record, so every matching PO fills the rate in by itself — buyers stop typing it. 📄 paper: condition record (master data) · 📦 stock: no change · 💰 money: no posting

Everything so far = manual entry on each PO. A condition record writes the number on a "notebook page" so SAP fills it automatically. Needs ZCUS to have an access sequence (assigned in 21.3, built/reused per 21.2) — if you left it blank, skip this.

MEK1 runs across three screens: ① the initial screen (type the condition type), ② the Key Combination popup (pick which table/key you are filing the rate under), ③ the fast-entry grid (one row per record — the key fields, then the Amount/rate and validity columns).

Where on screen · FieldFillWhat the field asks (plain words)Why we choose this — and the impact if wrong
Initial screen · Condition typeZCUSWhich bill line (condition type) are you storing a number for?The duty type you built in 21.3. Impact: pick another type and you'd be filling a different rule's rate.
Key Combination popup · combinationpick Purch.Org/Material Group (your table 909!)On WHICH notebook page (which table) do you write the rate?The popup lists exactly the tables inside ZCUS — choosing one picks the key the % is filed under. Impact: pick the wrong combination and the PO's search (which uses table 909) never finds your record.
Fast-entry grid · Purch OrgPKLOFor which buying org does this rate apply?Half of the key. Impact: a different org here and PKLO's POs won't match this record.
Fast-entry grid · Material Groupsteel group (then a 2nd record for the chemicals group)For which material group does this rate apply?The other half of the key. Impact: one record per group is exactly how steel gets 5% and chemicals 12% — miss a group and its POs find no duty.
Fast-entry grid · Amount5 % (steel) · 12 % (chemicals)What rate is stored for this key?The value the PO auto-fills. Impact: the number here lands on every matching PO — a typo mis-prices them all.
Fast-entry grid · Valid from / totoday → 31.12.9999From WHEN to WHEN is this rate true?Records are date-bound. Impact: next year's rate change is a NEW dated record (history kept, old POs still explainable); a wrong start date means the PO finds "no valid record".

Now create a fresh PO → ZCUS fills with 5% automatically. That's the whole condition technique working end-to-end: table (key) → access sequence (search) → type (line) → schema (maths) → determination (which bill pad).

✅ Verification

#T-codeCheck
1M/06ZCUS exists with condition class A, calc type A (%), plus/minus A
2M/08Procedure (RM0000 / Z_PSPK) lists ZCUS at the expected step with correct From-To
3OMFOPurch-org + vendor schema-group combination resolves to procedure Z_PSPK
4ME21NImport-vendor PO conditions tab shows ZCUS; entering % recalculates the effective price

🎓 Interview-Ready Answers

Q: Explain the components of MM pricing (condition technique).

Four building blocks: Condition types (PB00 gross, RA00 discount, FRA1 freight, MWST tax — each a pricing rule); Access sequence (the search strategy telling SAP where to find a condition record — info record, contract, manual); Pricing procedure / calculation schema (the ordered list of condition types with steps, From-To references and account keys); and schema determination (which procedure applies for a given purch-org + vendor schema group).

Q: How is the pricing procedure determined for a PO?

By schema determination in OMFO: SAP combines the schema group of the purchasing organization (assigned via OMFM/OMFP) with the schema group of the vendor (on the vendor/BP purchasing data, defined in OMFN) to select the calculation schema (e.g. Z_PSPK). That schema's condition types then populate the PO.

Q: How do you add a custom condition like customs duty, and does it affect inventory value?

Create the condition type in M/06 (copy FRA1 → ZCUS, class A, % calc type), then insert it into the pricing procedure in M/08 at the right step with the proper From-To. Whether it capitalizes into inventory depends on its account key / accrual key — delivery costs like freight and duty are typically planned delivery costs that post to inventory (or a clearing account) at GR, so yes, they raise the landed/material value.

Q: Why does getting the pricing procedure wrong matter financially?

The procedure produces the PO net/effective price, which is the basis for inventory valuation and the GR/IR postings. If a condition is missing, in the wrong sequence, or has the wrong account key, stock is mis-valued — understated or overstated — which distorts the balance sheet, COGS and margins on every receipt. It is config with direct financial consequences.

← Previous
Scenario 20: Custom Document Type
Next →
Scenario 22: Output Determination