Availability and leave
Patch availability through the CRM2 mapped workflow
/a/Availability_updateData
Patch availability through the CRM2 mapped workflow
When to use this endpoint
Edit one event, or approve/reject/cancel it through CRM2’s Availability page. This wrapper validates and reconstructs an allowlisted payload before invoking the generic update helper; it is not an unrestricted mapped-column write.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. Uses the authenticated tenant’s data. Requires pageAvailability_edit. Client administrators and full-access roles are allowed. Other roleless users are denied; signed API keys use the key owner’s role. These are page/action permissions, not an employee-ownership or HR-profile approver-list restriction.
Management calls reject accounts with features2.disableHREnhancements=1, returning HR enhancements are disabled. The helper reads the account’s current global feature value before falling back to session values. Browser permission checks are not server-side authorization.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer | Yes | One integer-converted event ID. Zero/missing fails; a nonzero ID must resolve to a non-deleted tenant row. Do not send native ID arrays: the wrapper calls intval before the generic helper and does not implement generic bulk updating. |
objType | String | No | One of company, department, role, user. Case-sensitive after trimming. Omission retains the stored target type. |
objID | Integer | No | Company forces zero. Other targets require an existing tenant target row; active/deleted state is not checked. Omission retains the current ID. |
eventType | String | No | Allowed names: absence, annual_leave, sick_leave, unpaid_leave, public_holiday, company_holiday, unavailable, available_override. Omitted retains the current type. |
availability | Integer flag | No | Zero means unavailable, any nonzero integer-converted value means available. Omitted retains the current flag. |
status | Integer | No | 0 pending, 1 approved, 2 rejected, 3 cancelled; other integer-converted values are rejected. Omitted retains the stored status. |
name | String | No | Trimmed event label; blank is accepted. Omitted retains the stored label. |
startE / endE | Unix seconds | No | Start must be positive and end later than start after optional all-day normalization. Omitted values retain the stored endpoints. |
allDay | Integer flag | No | Truthy integer enables account-local midnight normalization; otherwise use supplied epochs. Omitted retains the stored flag. |
paid | Integer flag | No | Truthy integer means paid; no automatic inference from event type. Omitted retains the stored flag. |
notes | String | No | Trimmed text. Omitted retains current notes. |
metaLeaveDays | Number | Ignored in normal updates | The updater always has start/end from the existing/updated event, so recomputes leave_days from the complete range. Direct metaLeaveDays input does not override the computed value. |
Other mapped keys | Mixed | Ignored | Raw meta, requestedBy, approvedBy/approvedAt, cDate, createdBy, deleted, dDate, lastEdited and noRecord controls are not copied to the reconstructed update payload. Entering approved status assigns server approver/timestamp values instead. |
Example request
$result = FM_api('Availability_updateData', [
'id' => '1042',
'status' => '1',
]);
Example response
{"ok":1}
Returns the generic result after removing oldData. A no-op may return {"warning":"No Change."}, without an ok field. Failed primary persistence returns an error; recalculation/notification failures after saving add saved=1 and a no-replay warning.
No full normalized event is returned. Re-read through Availability_list.
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"} | The authenticated actor lacks the required page/action permission. |
{"error":"HR enhancements are disabled"} | The account has disabled HR enhancements. |
{"error":"invalid obj_type"} | Target type is not company, department, role, or user. |
{"error":"missing or invalid obj_id"} | A non-company target has an integer-converted ID less than one. |
{"error":"target does not exist"} | No tenant row exists for the selected non-company target. This lookup does not impose an active/deleted target filter. |
{"error":"invalid event_type"} | The event type is outside the eight-name allowlist. |
{"error":"invalid status"} | The integer-converted status is outside 0–3. |
{"error":"invalid start/end time"} | After optional all-day normalization, start/end are nonpositive or end is not later than start. |
{"error":"missing or invalid parameter: id"} | The wrapper integer-converts the ID to zero. |
{"error":"availability event not found"} | No non-deleted tenant row resolves the ID. |
{"error":"Unable to update record"} | The generic primary write returned false. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Event ranges are half-open:
[start_e,end_e). Epoch values are Unix seconds, not milliseconds. With all-day enabled, the helper converts both epochs to account-local dates and replaces them with local midnights. If the normalized end is not later than the start, it becomes the next local midnight. A multi-day end date therefore remains exclusive; include the following midnight when the UI’s final date is inclusive. - The event type label does not force
availability,status, orpaid. For example, an annual-leave event may be stored as available; approved annual-leave usage still keys on event type and status, not those flags. No overlap or entitlement-limit validation is performed. - Omitted content keys retain current values. The event is revalidated as a whole. Entering approved status stamps the authenticated approver/current time; remaining approved or moving away from approval retains existing approver fields.
- Recomputes meta.leave_days for every update, using current timezone and week-days-off, including pending/rejected and non-annual-leave events. This property is informational and differs from approved-only annual-leave usage.
- The wrapper handles only one event. CRM2 bulk actions iterate scalar calls, so earlier UI calls can remain committed if a later target fails. A single event’s primary write, history, balances and notifications have no encompassing transaction.
- The primary write is checked before dependent work. After saving, failed recalculation or notification work retains the normal success fields and adds
saved=1andwarning. Do not repeat the write to repair a follow-up; re-read the event and investigate balances/notification history. The event, history, balances and external queues are not one atomic transaction.
Side effects
- Changed mapped writes advance server Unix last_edited, invalidate availability_events cache and write generic change history. Nested metadata changes preserve unrelated meta properties.
- When an old or new event is approved annual leave, the helper recalculates affected users’ stored annual-leave usage for touched years, using current company/department/role/user membership. Each account-local date touched counts as one whole day except dates in
week-days-off(0 Sunday through 6 Saturday). Partial dates count as full days, year boundaries are split, and calendar arithmetic preserves DST dates. Overlapping leave events contribute separately; balances may become negative. Supported recalculation years are the server’s current year minus five through plus ten. - Uses configured
availabilitynotification rules, not the legacy hard-coded transition notices. Create evaluatescreate2/time2; changed update evaluatesupdate2/time2. Rule enablement, platform, recipients, conditions and templates determine queued email/push/notices. Missing/negative service acknowledgements produce a saved follow-up warning; this is not confirmation of delivery.
See it in Fieldmotion
CRM1
No direct CRM1 caller for Availability_updateData was found in the source search. The implemented management screen is CRM2’s Availability page.
CRM2
Create or edit an Availability row, or use Approve/Reject/Cancel. The page’s decision() function actually calls the shared updateData helper, so filter for Availability_updateData, not Availability_decision. Browser-supplied approvedBy/approvedAt are ignored in favor of server attribution on transition.
Related endpoints
Availability_list: load the current event.Availability_createData: insert rather than patch.Availability_decision: legacy focused status endpoint with built-in transition notices.