# S4hana Create Goods Receipt

> Create Goods Receipts (Material Documents) in SAP S/4HANA Cloud Public or on-prem private edition via OData V2 A_MaterialDocumentHeader deep-insert at API_MATERIAL_DOCUMENT_SRV. Use whenever the user wants to create, post, add, generate, seed, receive, or confirm receipt of goods on S/4HANA — phrases like "post a goods receipt", "receive goods for PO X", "create GR for these POs", "seed GR demo d…

- **Type:** Skill
- **Install:** `agentstack add skill-ilia-inovaflow-s4hana-create-record-skills-s4hana-create-goods-receipt`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ilia-inovaflow](https://agentstack.voostack.com/s/ilia-inovaflow)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ilia-inovaflow](https://github.com/ilia-inovaflow)
- **Source:** https://github.com/ilia-inovaflow/s4hana-create-record-skills/tree/main/skills/s4hana-create-goods-receipt

## Install

```sh
agentstack add skill-ilia-inovaflow-s4hana-create-record-skills-s4hana-create-goods-receipt
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# s4hana-create-goods-receipt

Create Goods Receipts (Material Documents) on SAP S/4HANA Cloud Public. **Verified production-ready against SAP S/4HANA Cloud Public Edition 2026-05-12 — Material Documents 5000000001 + 5000000002 posted via API.**

## When to trigger
Verbs: create / post / add / generate / seed / receive / confirm
Objects: GR(s), Goods Receipt(s), Material Document(s), receipt of goods
Counts: 1 to ~100 records.

## Hard rules (never violate)
1. Always do a 1-record live POST as a probe before bulk (≥3 records).
2. Never invent material/PO IDs — Material must match the referenced PO line exactly (`M7/360` if mismatched).
3. If a required field has no sensible default and the user didn't specify → **ask once**, then auto-pick.
4. Scripts go in `/.s4hana-tmp/create-grs-/`. Never commit, never modify `.env`.
5. POSTs are sequential with 200ms delay; halt on 3 consecutive failures.
6. **Do NOT include `PurchaseOrder`/`PurchaseOrderItem` fields WITHOUT also including `GoodsMovementRefDocType="B"`** — the API rejects the fields as "not supported for type 101" without that hint.

## Endpoint
- Service path: `/sap/opu/odata/sap/API_MATERIAL_DOCUMENT_SRV`
- Entity sets: `A_MaterialDocumentHeader`, `A_MaterialDocumentItem`
- Method: POST (deep-insert with `to_MaterialDocumentItem`)
- Communication scenario: **`SAP_COM_0108`** — "Material Document Integration"

## Phase 0 — Setup check (MANDATORY, no exceptions)

**Before any API call, before any tool use, do this check. Even if you already know credentials from earlier in the conversation — IGNORE that knowledge and re-check from scratch each invocation.**

1. **Announce**: tell the user "Checking for SAP credentials in ``..."
2. **Check ONLY these two sources:**
   - A `.env` file at `./.env` (in the current working directory — NOT parent dirs, NOT `~/.env`, NOT any memory file)
   - Shell-exported env vars: `SAP_HOST` AND `SAP_AUTH_MODE` both present
3. **If neither**: auto-create `./.env` from the bundled template (curl from `https://raw.githubusercontent.com/ilia-inovaflow/s4hana-create-record-skills/main/.env.example`), append `.env` to `.gitignore` if not already there, tell the user clearly what to fill in (auth mode + host + creds), and **wait** for them to say "ready" before making any API call. Never overwrite an existing `.env`.
4. **If credentials are present**: report back to the user: "✓ Loaded credentials for `` in `` mode. Proceeding with [task]."

**Never use credentials from conversation memory, from another project's `.env`, or from any tenant the user previously worked with in a different session.** Each project gets its own `.env`. See [`shared/setup-check.md`](../../shared/setup-check.md) for the full rationale and edge cases.

## Phases

### Phase 1 — Parse & gather input

Per GR, required:

| Field | Notes |
|---|---|
| `PurchaseOrder` + `PurchaseOrderItem` | The PO line being received against |
| `Material` | Must EXACTLY match the PO line's material (`M7/360` otherwise) |
| `Plant` | Match PO line |
| `StorageLocation` | Default `101A` for plant 1010 on a Cloud Public tenant. Varies by tenant. |
| `QuantityInEntryUnit` + `EntryUnit` | Partial receipts allowed (typical: 25–100% of order qty) |
| `PostingDate` | **Must be in open MM posting period** — same gate as SES (typically 2025/07 or 2025/08 on this tenant) |
| `GoodsMovementType` | `"101"` = Receipt for PO to warehouse (most common) |
| `GoodsMovementRefDocType` | **`"B"`** for PO reference (without this, PURCHASEORDER fields are rejected) |

If user said "auto" or "random", pull eligible PO lines:
```
GET /sap/opu/odata/sap/API_PURCHASEORDER_PROCESS_SRV/A_PurchaseOrderItem?$filter=ProductType eq '1' and PurchaseOrderItemCategory eq '0' and IsCompletelyDelivered eq false&$select=PurchaseOrder,PurchaseOrderItem,Material,Plant,OrderQuantity,PurchaseOrderQuantityUnit
```

Skip PO lines whose Material is `M7/175: Maintain serial numbers` (serialized materials need extra fields).

### Phase 2 — Tenant defaults
Cache via tenant memory. For ``:

| Setting | Value |
|---|---|
| Plant | `1010` |
| StorageLocation default | `101A` |
| GoodsMovementCode (header) | `"01"` |
| GoodsMovementType (item) | `"101"` |
| GoodsMovementRefDocType (item) | `"B"` |
| Open MM posting period | `2025/07`, `2025/08` (verify with M7/053 if uncertain) |

### Phase 3 — Build payload

**Verified working envelope:**

```json
{
 "DocumentDate": "/Date()/",
 "PostingDate": "/Date()/",
 "MaterialDocumentHeaderText": "API GR batch ABC",
 "GoodsMovementCode": "01",
 "to_MaterialDocumentItem": [
 {
 "Material": "FG041",
 "Plant": "1010",
 "StorageLocation": "101A",
 "GoodsMovementType": "101",
 "GoodsMovementRefDocType": "B",
 "PurchaseOrder": "4500000000",
 "PurchaseOrderItem": "10",
 "QuantityInEntryUnit": "250",
 "EntryUnit": "PC"
 }
 ]
}
```

**Critical field — `GoodsMovementRefDocType="B"`**: SAP V2 OData treats type 101 with `PurchaseOrder` fields as ambiguous unless you also pass `GoodsMovementRefDocType="B"` (B = Purchase Order). Without it: `MM_IM_ODATA_API_MDOC/011: Property PURCHASEORDER is not supported for GoodsMovementType 101`. Easy fix, but unintuitive — easy to miss.

### Phase 4 — CSRF + POST
Standard OData V2 CSRF flow — see `../s4hana-create-po/references/csrf-flow.md`. MaterialDocument ID is auto-assigned in `500000000x` range, paired with `MaterialDocumentYear`.

### Phase 5 — Verify
```
GET /A_MaterialDocumentHeader(MaterialDocument='',MaterialDocumentYear='')?$expand=to_MaterialDocumentItem
```

After GR posting, the referenced PO line's `IsCompletelyDelivered`, `GoodsReceiptQuantity`, and related stock fields update automatically.

## Known error catalog

| Code | Cause | Fix |
|---|---|---|
| `MM_IM_ODATA_API_MDOC/011` | "Property PURCHASEORDER not supported for GoodsMovementType 101" | Add `GoodsMovementRefDocType="B"` on the item |
| `MM_IM_ODATA_API_MDOC/014` | "Material Document processing failed" | Generic — read other error rows in the response for specifics |
| `M7/360` | "Material document data and PO data do not match (Material)" | Material on GR item must match PO line material exactly |
| `M7/001` | "Check table EKPO: entry ... does not exist" | The PurchaseOrderItem doesn't exist on the PO. Verify with a GET first |
| `M7/175` | "Maintain serial numbers for total quantity" | Material requires serial-number tracking — needs `to_SerialNumber` deep-insert (out of scope for typical demo) |
| `M7/053` | "Posting only possible in periods YYYY/MM" | `PostingDate` outside open MM period — backdate or open current period |
| `ME/006` | "User X already processing Purchasing doc item Y" | Lock — another session is editing the PO. Wait 5–30s and retry, or pick a different PO |
| `403 You do not have start authorization for R3TR IWSV API_MATERIAL_DOCUMENT_SRV` | Comm arrangement `SAP_COM_0108` not added | Add the arrangement in Fiori → Communication Arrangements → New → `SAP_COM_0108` |

## Output structure
```
/.s4hana-tmp/create-grs-/
├── eligible-po-lines.json
├── create-log.jsonl
├── results.json
└── verify-sample.json
```

## Reference files
- `references/envelope-template.md` — full schema with optional fields
- `references/movement-types.md` — common movement-type codes and their semantics
- `scripts/bulk-gr-poster.mjs` — reference implementation

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ilia-inovaflow](https://github.com/ilia-inovaflow)
- **Source:** [ilia-inovaflow/s4hana-create-record-skills](https://github.com/ilia-inovaflow/s4hana-create-record-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-ilia-inovaflow-s4hana-create-record-skills-s4hana-create-goods-receipt
- Seller: https://agentstack.voostack.com/s/ilia-inovaflow
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
