Purchase orders
Remove a cancelled Purchase Order
/a/PurchaseOrder_delete
Soft-delete a cancelled header and remove its accounting-sync links.
When to use this endpoint
Cancel an order first, then use Delete to remove its active header. This is not a receipt reversal or a stock rollback.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. Session requests use dispatcher CSRF protection when configured. API keys use their owner’s permissions.
Requires explicit View on Purchase Order or Purchase Orders, plus Delete on either page. Non-administrators with legacy Purchase Orders visibility disabled (crm_access bit 256) are denied.
Explicit order IDs must identify active, visible records in the authenticated tenant. TeamAccess follows linked Contracts, Customers, Jobs, Quotes and Departments; legacy department filtering follows Customer, Quote-customer and ordinary customer-Job links. Scoped users cannot read unlinked or Warehouse orders through this check.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Positive integer or digit string | Yes | Local Purchase Order ID; not po_num. Missing, malformed or inaccessible IDs fail. |
Example request
$result = FM_api('PurchaseOrder_delete', ['id'=>'1042']);
Example response
{
"ok": 1
}
Errors and unusual responses
| Response | Condition |
|---|---|
{"error":"not logged in"} | No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs. |
{"error": "permission denied"} | Page/action rights or the legacy visibility setting deny access. |
{"error": "purchase order does not exist"} | An explicit parent/header ID is absent, deleted or outside the caller’s scope. |
{"error": "Purchase Order not of a valid status for deletion"} | The header is not Cancelled. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Requires received status 4 (Cancelled). Despite the older comment about unsent/unfulfilled orders, this handler does not separately check date_sent or receipt quantities once status is Cancelled.
- Marks the header deleted with a deletion timestamp. It does not delete its line rows, detach requisition links, remove order containers or reverse inventory.
- Repeated deletion is rejected by the dispatcher’s active-parent check. There is no bulk selector or pagination.
Side effects
- Updates deleted/ddate, touches the header/cache and records the deletion log. Removes matching global queued accounting-upload links and tenant accounting mappings for this Purchase Order.
- These operations do not share a route-owned transaction; a later failure can leave the deletion only partly reflected in sync metadata.
See it in Fieldmotion
CRM1
In CRM1 Purchase Orders, delete a cancelled order and inspect PurchaseOrder_delete.
CRM2
In CRM2 Purchase Orders, use the bulk Delete action on cancelled orders. The client calls PurchaseOrder_delete once per selected ID; it is a sequence of separate deletes, not one atomic batch.
Related endpoints
PurchaseOrder_get— Inspect received status before deletion.