Jobs: forms and resources
Append asset-table data to a job
/a/Job_setSourcedTableData
Copy asset-table row values into a saved job table, preserving its existing rows.
When to use this endpoint
Use for the job table’s asset-data source action, after identifying the asset’s source table and the destination job table.
This takes a snapshot of values in source query order; it is not an ongoing link or a schema/field-name mapping.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. The handler performs no additional page or role-permission check.
Job and form IDs refer to the authenticated account. Cross-account writes occur only through the stored outsourcing relationship on the routes that explicitly mirror changes.
The dispatcher also applies account/user and IP restrictions. A CRM session carrying a CSRF token must supply it through X-FMCSRF or _csrf; missing/incorrect tokens can be rejected before this handler runs.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id | Integer string | Yes | Positive physical job ID. |
table_id | Integer string | Yes | Positive destination table-form ID; no attachment/schema check. |
source_id | Integer string | Yes | Positive source asset-table ID. |
source_object | Integer string | No | Asset ID used in the source query; defaults to 0. Not validated as positive or checked against the job’s customer/asset. |
source_type | String | Yes | Required truthy string; the only implemented value is asset-table. |
Example request
$result = FM_api('Job_setSourcedTableData', [
'job_id'=>'1042', 'table_id'=>'302',
'source_id'=>'401', 'source_object'=>'105', 'source_type'=>'asset-table',
]);
Example response
{"ok":1,"subform_values":{"302":[["Inspection","Passed"]]}}
subform_values is the in-memory merged collection, not the stored JSON string returned by job reads. Its top-level JSON object/array shape follows PHP array keys. It is returned before any subsequent helper-enriched cells are read back.
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":"missing or invalid parameter: job_id"} | Nonpositive job ID. |
{"error":"missing or invalid parameter: table_id"} | Nonpositive destination table ID. |
{"error":"missing or invalid parameter: source_id"} | Nonpositive source table ID. |
{"error":"missing or invalid parameter: source_type"} | Missing/PHP-falsy source type. |
{"error":"no such job exists"} | No job row is read. |
{"error":"invalid source type: example"} | Truthy source_type is not asset-table; the supplied type is interpolated. |
{"error":"Unable to save job"} | The primary database save failed. Successful-save history and subsequent follow-ups are not run. |
{"ok":1,"subform_values":{"302":[["Inspection","Passed"]]},"warning":"Job saved; follow-up incomplete. Inspect saved state before retrying.","warnings":["Job_updateCosts: Unable to save job"],"saved":1} | The primary save succeeded, but a recalculation, asset rebuild, notification or outsourced mirror failed. warnings identifies the failed follow-up; any normal response fields remain present. A benign no-change result from a follow-up is not a failure. Read saved state before retrying. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Job lookup and UPDATE require an active job. Source asset_tables rows have no active/deleted check, ownership validation or ORDER BY.
- Decodes each source row’s data and appends its values in iteration order, dropping original field keys. It does not map names or verify destination width/types.
- Existing destination rows are retained. No matching source rows adds nothing but still saves and triggers follow-ups. Replays append duplicates; no source-row IDs, paging or limit are accepted.
Side effects
- Unchecked write of subform_values, last_edited and edited_uuid; meetings-cache invalidation and generic job history.
- Calls Job_updateAssetJobs and Job_updateCosts; failures produce saved-state warnings. No source rows are changed; no inventory reconciliation or outsourced table mirror occurs.
See it in Fieldmotion
CRM1
On a job’s Tables page, use the configured asset-table data source action. pageJobTables.js supplies asset ID/source table ID and sends Job_setSourcedTableData, then uses the returned table collection.
CRM2
On an asset job’s Form, use the configured table’s source-data button. pageJobForm.js requires an asset customer in its UI and sends source_type=asset-table; the server does not enforce that UI condition.
Related endpoints
Job_addTableRowimports mapped positional rows with optional replacement of one table.Job_setTablesreplaces the full saved table collection and refreshes dependencies.Job_updateCostsrefreshes cost/resource snapshots and invokes the price follow-up.