Purchase orders
Email a Purchase Order
/a/PurchaseOrder_orderEmail
Submit the supplier email through the mail service and stamp the order’s sent time.
When to use this endpoint
Use the office Send action with the selected recipient, sender, template and composed message. This performs an external mail action; do not use it merely to mark an order sent.
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 Edit 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. |
email | Text | Yes | One email address or a comma-separated list. Each trimmed address must pass FILTER_VALIDATE_EMAIL. Blank cells and semicolon-separated lists fail. |
text | Text | Yes | Message body sent as body to the mail service. Presence required; empty string is accepted. |
subject | Text | Yes | Message subject. Presence required; empty string is accepted. |
template_id | Template value | Yes | Passed through to the mail service. Presence is required; this handler does not validate template ownership or nonemptiness. |
sender | Sender value | Yes | Passed through to the mail service. Presence is required; no sender-address validation is performed here. |
Example request
$result = FM_api('PurchaseOrder_orderEmail', [
'id'=>'1042',
'email'=>'supplier@example.test',
'subject'=>'Purchase order 1042',
'text'=>'Please find our purchase order attached.',
'template_id'=>'5',
'sender'=>'purchasing@example.test',
]);
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": "missing or invalid parameter: email"} | Email is omitted or blank; text, subject, template_id and sender have analogous missing-parameter errors. |
{"error": "invalid email address: bad-address"} | Any comma-separated recipient is invalid. |
{"error":"Approve the purchase order before sending it"} | The order has no current approval. |
{"error":"Only Open Purchase Orders can be sent"} | The received status is not Open. |
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 Purchase Order View/Edit, an approved Open order and permission to send. Non-administrators with userdata.permissions bit 64 are denied. Approval is not a separate received-status value.
- Submits mail type 5 with the order, sender/subject/body/template, JSON recipients, tenant/user and creation trace. This handler validates each comma-separated recipient; sender/template are passed to the mail service.
- Only a decoded mail-service acknowledgement with ok=1 permits date_sent, last_edited and checked send history to be written. Explicit mail failures or an uncertain acknowledgement do not stamp the sent marker. Acceptance is not final provider delivery.
- If mail was accepted but the local sent-marker transaction cannot be confirmed, returns ok=1,mail_accepted=1 and a no-resend warning. The external message cannot be undone by rolling back the local order.
- Repeated successful calls can resend an approved Open order and overwrite the sent timestamp. There is no client idempotency token; check mail history before replaying an uncertain request.
Side effects
- Holds the order/owner lock while checking the approved financial state and submitting email. After acceptance, commits the sent timestamp and checked history together. A failed local commit cannot recall an accepted external message.
See it in Fieldmotion
CRM1
In CRM1 Purchase Order details, Purchase Orders list or Customer Orders, choose Send email and inspect PurchaseOrder_orderEmail.
CRM2
In CRM2 Customer Orders, choose Email Purchase Order to Supplier and click Send Order; filter for PurchaseOrder_orderEmail. The dialog requires a subject and one address in its client validation, although the endpoint accepts a comma-separated recipient list. The mobile app goes through m/www’s separate PurchaseOrder_save/OrdersM workflow; its validation and ownership rules do not establish this office endpoint’s contract.
Related endpoints
PurchaseOrder_getPdf— Preview the order document.PurchaseOrder_approve— Approve the financial order separately.