Purchase orders
Record a supplier invoice against an order
/a/PurchaseOrder_setInvoiceDetails
Mark a supplier invoice as received and store its date and number as order metadata.
When to use this endpoint
Use the invoice indicator on a Purchase Orders row after receiving the supplier’s invoice. This does not create a Fieldmotion sales Invoice or an accounting bill.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. Session requests use dispatcher CSRF protection when configured.
Requires explicit View on Purchase Order or Purchase Orders. Writes also require the matching Edit permission; clearing invoice details requires Delete. A non-administrator blocked by the legacy Purchase Orders visibility flag (crm_access bit 256) is denied. API keys use their owner’s permissions.
The primary order is checked against the current tenant and Purchase Order record scope. Configured TeamAccess follows permitted linked Contracts, Customers, Jobs, Quotes and Departments; the legacy department filter follows direct Customer/Quote/customer-Job links. An inaccessible or missing order returns purchase order does not exist.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer-compatible | Yes | Positive local Purchase Order ID/digit string; not the displayed po_num. Missing, malformed or inaccessible IDs fail. |
invoice_date | String | Yes | Required string. Blank means server-local today; valid ISO or the configured account date format is canonicalized to YYYY-MM-DD. |
invoice_num | String | Yes | Explicit string up to 4096 bytes, including blank when no number is available. Quotes and backslashes round-trip unchanged. |
Example request
$result = FM_api('PurchaseOrder_setInvoiceDetails', [
'id'=>'1042',
'invoice_date'=>'2026-11-03',
'invoice_num'=>'SUP-INV-318',
]);
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": "no purchase order ID provided"} | id is absent/null; zero is not rejected by this presence check. |
{"error": "no invoice date provided"} | invoice_date absent/null. |
{"error": "permission denied"} | The required page/action or legacy visibility setting denies access. |
{"error": "purchase order does not exist"} | The primary order is missing or outside the caller’s permitted scope. |
{"error": "missing or invalid parameter: invoice_num"} | Number absent, non-string, too long or containing a NUL. |
{"error": "missing or invalid parameter: invoice_date"} | Date does not parse as a real supported calendar date. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- invoice_date and invoice_num are explicit required strings. Blank date becomes server-local today; otherwise exact YYYY-MM-DD or the account date-format is parsed as a real calendar date and stored as YYYY-MM-DD.
- Replaces invoice_received with JSON containing invoice_recd=1, canonical invoice_date and exact invoice_num. Text is JSON-encoded once and parameter-bound, preserving quotes/backslashes.
- This metadata does not create a Fieldmotion sales Invoice, accounting bill or payment. It does not change received status, stock or approval.
Side effects
- Header writes lock the existing order and tenant owner, check persistence and record history in the same transaction. Errors roll back the header and audit; a true no-op returns {ok:1,warning:"no change needed"} without a new event/history entry. Cache invalidation and edit-event follow-ups run after the owning transaction commits; an event exception returns saved=1 and a no-replay warning.
- A changed header emits PurchaseOrder_edit after commit; configured account listeners may perform integration work. No order email/PDF is sent directly by this route.
See it in Fieldmotion
CRM1
In CRM1 Purchase Orders, click the invoice indicator, enter its number/date and save. Filter for PurchaseOrder_setInvoiceDetails.
CRM2
In CRM2 Purchase Orders, open the supplier-invoice dialog and save. The caller formats a nonblank date using the account display format; the server stores it without normalization.
Related endpoints
PurchaseOrder_deleteInvoiceDetails— Clear the supplier-invoice marker.PurchaseOrder_getRequestedDetails— Read mapped fields with explicit IDs.