Schedule of Rates
Update mapped Schedule of Rates data
/a/ScheduleOfRate_updateData
Update one or more Schedule of Rates rows through CRM2’s mapped data helper.
When to use this endpoint
Use ScheduleOfRate_updateData for CRM2 edits, archive changes, and newer structured labour/metadata values. It accepts the same camel-case map as ScheduleOfRate_createData.
Authentication and permissions
The request must authenticate with signed API-key fields or a logged-in CRM session. The handler calls the normal login guard but performs no additional page or role-permission check.
All reads and writes use the authenticated tenant. The CRM screens apply client-side Schedule of Rates permissions, but those controls are not repeated by this endpoint.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer string or native array | Yes | Target ID or decoded list of IDs. Scalar mode returns row-specific warnings. Array mode processes sequentially, discards per-row results, and returns {"ok":1}. |
Mapped updates | Mixed | No | Any writable key from name, code, stockUsed, cost, lastEdited, description, meta, metaNominal, metaNominalID, metaNominalCode, metaTaxTypeID, assetTypes, labourUsed, priceBands, archived, and metaCustomerCosts. Values completely replace their column/nested key; native arrays or objects in text/JSON fields are JSON-encoded. |
taxType | Native object | No | Composite picker input with id and nominalID. Integrations can instead send metaTaxTypeID, metaNominalID, metaNominalCode, and metaNominal explicitly. |
metaCustomerCosts | Native object, string, or blank | No | Customer-ID-to-price map in meta.customerCosts. Exact blank input triggers a preliminary JSON-key removal; other supplied values go through the normal nested-map update. |
noRecord / noRecordCustom | Native arrays | No | Internal generic-history controls. They do not suppress the write or the Schedule of Rates event. |
Example request
$result = FM_api('ScheduleOfRate_updateData', [
'id' => '430001',
'name' => 'Annual service plus',
'cost' => 165,
'archived' => 0,
]);
Example response
{
"ok": 1
}
A scalar no-op returns {"warning":"No Change."}; a missing target returns {"warning":"No data."}; only unknown update keys return {"warning":"no updated fields."}. Supplying only id returns success.
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: id"} | The id key is absent. |
Database error | An invalid value is assigned to the JSON price_bands column. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Unknown keys are ignored. IDs are integer-converted; there is no explicit positive-ID validation.
- An actual mapped change advances
last_editedto current server time. SupplyinglastEditeddoes not override this: the helper emits a second current-time assignment after the requested value. No-op and missing-row paths do not update the row. - Blank
metaCustomerCostsremoves onlymeta.customerCosts, preserves other metadata, and then removes that key from the mapped request. - These endpoints store the base price in
cost; they do not calculate a customer’s final price. Job/quote consumers can applymeta.customerCosts, the tenant settingsor-child-gets-parent-price, and the customer’s price band later.
Side effects
- Changed fields advance the
schedule_of_ratescache marker and write generic field-level history. - After any nonzero integer-converted request ID, fires the tenant-configurable
SOR_editevent with the rate ID. Any configured listeners run synchronously and can add integration-specific side effects. This also happens after no-op or missing-row warnings; a nonempty bulk-ID array incorrectly emits ID1instead of its members.
See it in Fieldmotion
CRM1
CRM1 edits the legacy table through focused ScheduleOfRates_set* routes.
CRM2
Open Stock → Schedule of Rates and edit a row, its archive state, tax picker, stock, labour, or customer prices. The shared widget calls this route.
Related endpoints
ScheduleOfRate_updateFieldapplies one mapped field to one or more IDs but does not fire the Schedule of Rates event.ScheduleOfRate_getRequestedDetailsreads the result.