Invoices
Link an ancillary job to an invoice
/a/Invoice_linkJobAncillary
Attach a job to an invoice as an ancillary link when that job is not already linked to any active invoice.
When to use this endpoint
Use this when one invoice should show an indirect job association without making the job a direct source of the invoice.
Authentication and permissions
The request must use a logged-in CRM session or valid signed API credentials and is scoped to that tenant.
Users whose legacy crm_access mask contains bit 64 receive {"error":"no permission to access api"}. No record-owner check is made.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Positive integer | Yes | Active invoice ID. |
job_id | Positive integer | Yes | Job ID to insert as a type-4 ancillary link. |
Example request
$result = FM_api('Invoice_linkJobAncillary', ['id' => 981, 'job_id' => 2204]);
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":"job already linked to an invoice"} | The job has a direct or ancillary link to any active invoice. |
{"error":"invoice does not exist"} | The target invoice is absent or deleted. |
{"error":"job does not exist"} | The job is absent or deleted. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Both the invoice and job must be active. The job cannot already have a direct or ancillary link to any active invoice.
- The misspelled metadata key
jobs_linked_ancilliaryis retained as part of the stored compatibility contract.
Side effects
- Inserts a
manymanytype-4 relation, refreshes the ancillary-link count in invoice metadata, advances invoice edit metadata, and firesInvoice_edit.
See it in Fieldmotion
CRM1
The main Invoices page exposes the ancillary link action after checking the selected job is contract-invoiceable.
CRM2
Open an invoice’s Linked jobs (Indirect) dialog and choose Link Job. CRM2 performs the same contract-invoiceable check first.
Related endpoints
Invoices_getDataTablesupplies paginated CRM2 invoice rows and IDs.Invoices_getDTis the CRM1 invoice-list counterpart.