Citeck Records Query Examples
Working with records from JavaScript
Adding a user or group to a group
let rec = Records.get('emodel/person@someuser'); // пользователь или группа, которого(ую) нужно добавить в группу
rec.att('att_add_authorityGroups', 'emodel/authority-group@accountant'); // группа, в которую нужно добавить
rec.save();
Removing a user or group from a group
let rec = Records.get('emodel/person@someuser'); // пользователь или группа, которого(ую) нужно удалить из группы
rec.att('att_rem_authorityGroups', 'emodel/authority-group@accountant'); // группа, из которой нужно удалить
rec.save();
Checking whether a user or group belongs to a group
Checking whether the current user belongs to a group:
await Citeck.Records.get('emodel/person@CURRENT').load('authorities._has.GROUP_ECOS_ADMINISTRATORS?bool!')
Checking whether a specific user belongs to a group:
await Citeck.Records.get('emodel/person@someuser').load('authorities._has.GROUP_testers?bool!')
Checking whether a group belongs to another group is not yet supported.
Role Computation Diagnostics
To check who is computed into a role, use the _roles.assigneesOf attribute:
// Проверить, кто вычислен в роль
await Records.get('emodel/your-type@doc-id').load('_roles.assigneesOf.myRole[]?raw')
If a role is computed based on an association, you can compare the association contents with the role computation result for diagnostics:
// Загрузить содержимое ассоциации и результат вычисления роли одновременно
await Records.get('emodel/your-type@doc-id').load([
'myAssocAttr[]?raw',
'_roles.assigneesOf.myRole[]?raw'
])
Loading identifiers from associations: .id and ?id
When working with associations in the system, it is important to understand the difference between the ways to retrieve an identifier:
Attribute .id — returns the part of the reference after @ (localId):
// emodel/person@ivan.petrov → "ivan.petrov"
// emodel/authority-group@accountant → "accountant"
document.load('myAssoc.id')
Scalar ?id — returns the full reference to the entity:
// → "emodel/person@ivan.petrov"
// → "emodel/authority-group@accountant"
document.load('myAssoc?id')
Important
To pass references to other associations, use full references via ?id.
Searching records and modifying them in a loop
var typeId = 'deal';
var typeRef = "emodel/type@" + typeId;
var sourceId = await Records.get(typeRef).load('sourceId');
var queryResult = await Records.query({
sourceId,
query: { t: 'eq', att: '_type', val: typeRef },
language: 'predicate',
page: { maxItems: 4000 }
});
var records = queryResult.records;
console.log("Found " + records.length);
var newStatus = 'old';
for (let i = 0; i < records.length; i++) {
let record = Records.get(records[i]);
let currentStatus = await record.load('_status?str', true);
if (currentStatus == 'new') {
console.log('change status for ' + record.id + " from " + currentStatus + " to " + newStatus);
record.att('_status', newStatus);
await record.save();
}
}
Here the script searches for objects (max = 4000) with data type deal and status new, and changes the status to old (these statuses must be defined for the deal type).
Getting a value from the config (ecos config)
Citeck.Records.get('eapps/meta@').load('$cfg.service-desk-groups')
// либо
Citeck.Records.get('eapps/cfg@service-desk-groups').load('value')
A scope is needed if the goal is to retrieve from one microservice a config that is defined in another microservice.
Getting different localized values for the Status attribute (_status)
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('_status._disp?json', true)
Response:
{
"ru": "Новый",
"en": "New"
}
Alternatively, you can get the value in a specific language:
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('_status._disp.en', true)
Checking whether a specific record exists
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('_notExists?bool!', true)
Checking that a record is a subtype of a specific type
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('_type.isSubTypeOf.case?bool!', true)
Checking access permissions for a record
// Проверка права на чтение
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('permissions._has.Read?bool!', true)
// Проверка права на запись
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('permissions._has.Write?bool!', true)
// Проверка кастомного права
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('permissions._has.bpmn-process-instance-read?bool!', true)
Checking communication between microservices: notifications -> eproc -> uiserv
await Citeck.Records.get('notifications/meta@').load('rec.eproc/meta@.rec.uiserv/meta@.time', true)
Getting attributes directly through an association
For a contract object, we get the counterparty and retrieve its TIN, creation date, and display name:
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('counterparty{?disp,inn,_created}', true)
Example response:
{
"?disp": "ООО Стальпром",
"inn": "111111111111",
"_created": "2023-08-03T09:28:49.071Z"
}
If the association is multiple, you can get the attributes of all objects:
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('payments[]{plannedPaymentDate,amount?num}', true)
Example response:
[
{
"plannedPaymentDate": "2025-02-10T00:00:00Z",
"amount": 1000
},
{
"plannedPaymentDate": "2025-02-20T00:00:00Z",
"amount": 10500
}
]
If the association is multiple and you need attributes of only the first object:
await Citeck.Records.get('emodel/ecos-contract@you-doc').load('payments{plannedPaymentDate,amount?num}', true)
Example response:
{
"plannedPaymentDate": "2025-02-10T00:00:00Z",
"amount": 1000
}
Getting multiple attributes together with nested attributes
Getting multiple attributes together with attributes from an association:
await Citeck.Records.get('emodel/ecos-contract@you-doc').load(['?disp', 'payments[]{plannedPaymentDate,amount?num}'], true)
Example response:
{
"?disp": "Договор №16808",
"payments[]{plannedPaymentDate,amount?num}": [
{
"plannedPaymentDate": "2025-02-10T00:00:00Z",
"amount": 1000
},
{
"plannedPaymentDate": "2025-02-20T00:00:00Z",
"amount": 10500
}
]
}
You can also assign custom names to the retrieved attributes:
await Citeck.Records.get('emodel/ecos-contract@you-doc').load({'contractName': '?disp', 'payments': 'payments[]{plannedPaymentDate,amount?num}'}, true)
Example response:
{
"contractName": "Договор №16808",
"payments": [
{
"plannedPaymentDate": "2025-02-10T00:00:00Z",
"amount": 1000
},
{
"plannedPaymentDate": "2025-02-20T00:00:00Z",
"amount": 10500
}
]
}
Nested attributes can be retrieved not only from associations but also from any attributes that represent objects, for example the _content attribute:
await Citeck.Records.get('emodel/ecos-contract@you-doc').load({'name': '?disp', 'content': '_content{size,mimeType}'}, true)
Example response:
{
"name": "Договор №16808",
"content": {
"size": "248446",
"mimeType": "application/pdf"
}
}
Working with Files
Working with files from the UI is possible either by loading content as a base64 string or by getting a download link.
The script retrieves the file content as a base64 string from the _content attribute:
await Records.get('emodel/ecos-contract@3a4e11cf-4227-44f4-98dd-1eeefba30e28').load('_content.bytes')
The script retrieves a download link for the file from the _content attribute:
await Records.get('emodel/ecos-contract@3a4e11cf-4227-44f4-98dd-1eeefba30e28').load('_content.url')
You can upload a file as formData at the following address:
/gateway/emodel/api/ecos/webapp/content
or via base64 (suitable only for small files).
Starting a business process for a document
let rec = Records.get('eproc/bpmn-proc@some-process-id'); // id процесса
rec.att('action', 'START');
rec.att('document', 'emodel/contract@0b54aed0-d288-4d29-aec3-c1ff37cfa089'); // Документ, для которого стартуем процесс
rec.save();