E122: Create receipt against purchase order
POST /api/purchase-orders/:id/receipts
Records a delivery against an open purchase order. Triggered from the Purchase Order Detail receipts section when goods arrive from the vendor. The workflow writes the PO-side receipt rows, posts the matching entries to the materials or finished-goods inventory ledger, advances the PO's status, and, for materials POs, propagates the receipt's unit costs downstream through every work order that consumes the affected materials.
Authentication
Standard tenant route. Requires Authorization: Bearer <firebase-id-token> and X-Org-Id: <org-id>. Access: Member.
Request
{
"receiptDate": "2026-05-25",
"notes": "Partial delivery",
"items": [
{ "poItemId": "uuid", "quantity": 60, "unitCost": 12.34 }
]
}
| Field | Type | Required | Notes |
|---|---|---|---|
receiptDate | date | yes | |
notes | string | no | |
items | array | yes | At least one line; unitCost defaults to the PO line's unit cost when omitted. |
Posts ledger entries (MaterialsInventory.recordReceipt or FinishedGoodsInventory.recordReceipt depending on targetType), rolls up PO costs, advances PO status to Partial / Received, and (materials only) cascades costs to dependent work orders. Atomic across the cascade — see W122.
Response — 201 Created
{
"id": "uuid",
"poId": "uuid",
"receiptDate": "2026-05-25",
"notes": "...",
"items": [
{ "id": "uuid", "poItemId": "uuid", "quantity": 100, "unitCost": 12.34 }
]
}
Errors
| HTTP | code | Condition |
|---|---|---|
| 404 | not_found | PO not found, or poItemId does not belong to this PO. |
| 409 | invalid_transition | PO is terminal. |
| 422 | validation_failed | No items, or negative quantity / cost. |