E147: Update sales order
PATCH /api/sales-orders/:id
Edits an SO's header fields and walks it through its lifecycle: Received → Entered → Shipped → Invoiced → Paid → Completed, plus terminal branches Rejected and In-Dispute. Triggered from Sales Order Detail. Status changes drive the FG ledger sync: DEMAND from Received onwards, ALLOCATE from Entered onwards, CONSUME from Shipped onwards. The sync is append-only and idempotent.
Authentication
Standard tenant route. Requires Authorization: Bearer <firebase-id-token> and X-Org-Id: <org-id>. Access: Member.
Request
{ "expectedShipDate": "2026-05-23", "status": "Confirmed", "fulfillmentStatus": "Allocated", "notes": "..." }
Header-level edits only; item edits go through E149–E152. Cancellation (status → Cancelled) triggers reverse FG ledger entries per W147.
Response — 200 OK
{
"id": "uuid",
"soNumber": "SO-2026-0123",
"customerId": "uuid",
"orderChannelId": "uuid",
"brokerId": null,
"shipToLocationId": "uuid",
"orderDate": "2026-05-18",
"expectedShipDate": "2026-05-22",
"status": "Confirmed",
"fulfillmentStatus": "Allocated",
"totalCost": 1234.56,
"totalRevenue": 2400.00,
"notes": "..."
}
Errors
| HTTP | code | Condition |
|---|---|---|
| 404 | not_found | No such SO. |
| 409 | invalid_transition | Status change not allowed from current state. |
| 422 | validation_failed | Shape invalid. |
Workflow
Calls W147 Update sales order.