Jobs: scheduling and lifecycle
Assign one job to a tenant user
/a/Job_setUserId
Change a job's tenant-user assignee and update its mobile-removal and assignment-notification state.
When to use this endpoint
Use for a normal tenant user or unassigned job. Use Job_setUserIdAndType for an explicit outsourcing type; these setters do not have identical permissions or notification behavior.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. Legacy edit-restriction bit 128 is enforced; client administrators retain the existing admin exception.
The primary job selection is tenant-scoped. There is no automatic schedule-conflict or assignee-ownership check. Cross-tenant follow-ups use persisted outsourcing context.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer string | Yes | Positive active job ID. |
value | Integer string | Yes | Active tenant user ID; 0 unassigned. Negative/missing values are rejected, and a positive ID must resolve to an active user in this tenant. |
Example request
$result = FM_api('Job_setUserId', ['id' => '1042', 'value' => '27']);
Example response
{"ok":1}
Already assigned to that ID with type 0 returns {"ok":1,"msg":"this user is already set"} before recalculation or mail.
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: value"} | Missing/negative user value. |
{"error":"no such job exists"} | Missing/deleted job. |
{"error":"No permission to edit"} | Legacy bit 128 is set. |
{"error":"Failed to update job assignment"} | Primary assignment write failed. An earlier Authorised-to-Incomplete change may already have happened. |
{"error":"Invalid job assignee"} | Positive user is missing/inactive or outside the tenant. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Always writes user_type=0 and records meta.previousUser as the old numeric user ID. If status was Authorised (4), attempts to reopen it to 0 before the assignment; the status-helper response is not checked.
- Mobile deletion-marker cleanup, history and assignment mail/cron run only when the numeric ID changes. A type-only change from an outsourcing ID to the same numeric tenant-user ID saves, but skips that block.
- Immediate Job_emailAbout is attempted only when the old type was tenant user, the new ID is nonzero, and disable-job-notification/form/Job Type overrides enable it. The hierarchy is tenant default, then form, then Job Type; values 1 disable and 2 enable at each object level.
- Does not cancel an old outsourced copy or create a new one. Use the typed setter to unwind outsourcing. No scheduling/overlap validation.
Side effects
- Updates user_id/user_type, previousUser, last_edited and edited_uuid. For a numeric change, withdraws the new user's mobile removal marker and records removal for the previous tenant user.
- Logs assignment history, queues global assigned/reassigned cron type 5/6 with typed old/new snapshots, optionally emails the new user, and runs Job_updateCosts.
See it in Fieldmotion
CRM1
Change assignment from a user's Jobs list, Asset Jobs or Asset Maintenance. Those inline pickers send value to Job_setUserId. The main Jobs picker instead uses the typed setter.
CRM2
Use Move Jobs in the user-move widget; widgetUserMoveJobs.js posts value to Job_setUserId. The main timeline uses Job_setUserIdAndType.
Related endpoints
Job_setUserIdAndTypehandles typed outsourcing handover.Job_setUserAndTimeapplies one checked scheduling row.Jobs_setUseruses the legacy bulk assignment workflow.