API Before-Save Script¶
As of v7.5.
A formula script that is executed on POST and PUT API requests to an entity endpoint before a record is saved. It's executed only when a record is created or updated via API (this also includes actions made through the UI as EspoCRM is a single page application – the frontend communicates with the backend via API). It's not executed when a record is saved from within the system (e.g. in hooks, workflow actions, custom code). Can be used for custom validation, duplicate checking and access control. Available at Administration > Entity Manager > {Entity} > Formula.
Note
API Before-Save Script is not executed when doing mass update.
Note
Avoid accessing related records in API Before-Save Script using a dot (e.g. account.assignedUserId
). When the script is executed, the relation can be not yet established.
Special functions¶
Warning
These functions are available only in API Before-Save Script. Using them in other places will produce an error.
recordService\skipDuplicateCheck¶
Returns true if a skipDuplicateCheck HTTP header is passed (when a user is warned about a duplicate but opts to save the record anyway).
Example
if (!recordService\skipDuplicateCheck()) {
// process duplicate checking
}
recordService\throwDuplicateConflict¶
recordService\throwDuplicateConflict(RECORD_ID)
recordService\throwDuplicateConflict(RECORD_IDS)
– receives a list of IDs.
Throws a duplicate conflict exception. This will show a modal dialog warning the user that the saved record might be a duplicate.
Example
if (!recordService\skipDuplicateCheck()) {
$id = record\findOne('MyEntityType', null, null, 'name=', name);
if ($id) {
recordService\throwDuplicateConflict($id);
}
}
recordService\throwBadRequest¶
recordService\throwBadRequest(MESSAGE, [BODY])
Throws a Bad Request exception.
Example
recordService\throwBadRequest('Invalid value.')`
Example
$obj = object\create();
object\set($obj, 'key', 'value');
recordService\throwBadRequest('Invalid value.', $obj)`
recordService\throwForbidden¶
recordService\throwForbidden(MESSAGE, [BODY])
Throws a Forbidden exception.
recordService\throwConflict¶
recordService\throwConflict(MESSAGE, [BODY])
Throws a Conflict exception.
Examples¶
Duplicate checking¶
Example 1:
if (entity\isNew() && !recordService\skipDuplicateCheck()) {
$id = record\findOne('MyEntityType', null, null, 'name=', name);
if ($id) {
recordService\throwDuplicateConflict($id);
}
}
Example 2:
if (entity\isNew() && !recordService\skipDuplicateCheck()) {
$ids = list();
$id = record\findOne('MyEntityType', null, null, 'name=', name);
if ($id) {
$ids = array\push($ids, $id);
}
$id = record\findOne('MyEntityType', null, null, 'emailAddress=', emailAddress);
if ($id) {
$ids = array\push($ids, $id);
}
$ids = array\unique($ids);
if (array\length($ids)) {
recordService\throwDuplicateConflict($ids);
}
}
Validation¶
Example 1:
if (status == 'Completed' && !dateCompleted) {
recordService\throwBadRequest("Missing `dateCompleted` value.");
}
Access control¶
Example 1:
if (
entity\isAttributeChanged('status') &&
!array\includes(env\userAttribute('teamsIds'), '6133380f577a93492')
) {
recordService\throwForbidden("Not allowed to change status.");
}