When to use this endpoint

Use after saved main/table answers change which assets a job touches. Form-resource setters and job create/save already invoke it where appropriate; this is not an asset-field editor or a completion action.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. The handler requires login and adds no page/role-permission guard.

The primary job selection is tenant-scoped. Cross-tenant follow-ups, where described, use persisted outsourcing context.

Parameters

ParameterTypeRequiredDescription
idInteger stringYesPositive active job ID. Reads persisted target, form/table values, hours and dates; there is no request-supplied asset list.

Example request

$result = FM_api('Job_updateAssetJobs', ['id' => '1042']);

Example response

{"ok":1}

Errors and unusual responses

ResponseCondition
{"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: id"}Missing/nonpositive ID.
{"error":"job does not exist"}Missing/deleted job.
{"error":"Unable to save job delivery changes"}A checked read/write failed; this rebuild rolls back.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Collects the asset target, assets-type main answers by question name and assets-type table columns by position. Main meta.asset_not_tracked excludes a question; missing metadata means tracked. Table columns retain their legacy tracking behavior.
  • Locks the active job and checks all derived writes in a transaction/savepoint. When called inside another tenant transaction, it does not commit the caller's transaction.
  • Resolves only non-deleted assets by physical ID or legacy appId, preferring an exact physical ID and then lowest ID. Deduplicates resolved physical IDs.
  • Always rebuilds the derived asset/job association list, including when no movement rows exist, so stale/duplicate association-only records do not accumulate.
  • Replaces only identifiable tracking placeholders: no user/owner/location/rental data and blank/empty/tracking-source metadata. Richer movement history is retained unchanged; an existing rich row for the same asset/job prevents adding a duplicate placeholder.
  • Placeholder start uses the tenant-local start epoch; end uses stored date_completed, otherwise ceil(hours) elapsed hours. No working-calendar recalculation or affected-asset list is returned.
  • Historic address lookup ignores location-less placeholders. This is an association maintenance operation, not a physical asset relocation or completion workflow.
  • Malformed saved form/answer/table structures fail before rebuilding rather than being treated as empty answers. Blank or null legacy JSON still means no entries.

Side effects

  • Rebuilds derived associations and eligible placeholder movements together, records job tracking history, and preserves richer location/owner movements.
  • Does not update asset business fields, job edit timestamps, stock or completion status.

See it in Fieldmotion

CRM1

No direct browser call was found. Save main/table asset answers on a job; Job_setField/Job_setFields/Job_setTables and related setters invoke tracking server-side.

CRM2

No direct route caller was found. The shared PHP form-resource workflow invokes tracking after persisted answer changes; filter the save request rather than expecting a second browser request.

Related endpoints