Схемы расчетов
В данном разделе представлен обзор структуры, принципов работы и процесса создания схем расчетов в системе. Управление схемами расчетов в системе осуществляется в разделе Экспертиза.
О схемах расчетов
Схема расчетов — это элемент экспертизы, определяющий формулы, по которым рассчитываются числовые показатели для объектов системы. Например, с помощью схем расчетов можно вычислить комплексный показатель соответствия стандарту на основе оценок требований, входящих в этот стандарт, или среднее время реагирования на инциденты.
Расчеты в схемах поддерживают наследование — возможность создавать расчеты, копирующие свойства наследуемых расчетов за исключением тех, которые явно переопределены.
Результатом расчета по схеме всегда является конечное число. |
Чтобы добавить схему расчетов в систему, необходимо выполнить следующие действия:
-
Создать схему расчетов в разделе Экспертиза.
-
Определить структуру схемы расчетов.
-
Настроить запуск расчетов по схеме и отображение их результатов в интерфейсе.
Структура схемы расчетов
Схема расчетов содержит обязательные и опциональные поля, определяющие логику расчетов.
Поле | Описание | Тип данных | Обязательное поле |
---|---|---|---|
|
Уникальный идентификатор схемы расчетов, позволяющий ссылаться на нее из других сущностей системы. Должен быть уникальным в пределах экспертизы. Можно использовать UUID в качестве значения. |
строка |
да |
|
Название схемы расчетов. Допустимы латинские буквы, цифры, подчеркивания. |
строка |
да |
|
Краткое описание назначения схемы расчетов. |
строка |
нет |
|
Тип элемента экспертизы. Всегда устанавливается значение |
перечисление |
да |
|
Теги для классификации и поиска схемы в системе. |
массив строк |
нет |
|
Версия схемы в формате Semantic Versioning. |
строка |
да |
|
Статус текущей версии схемы расчетов. Может принимать любые текстовые значения. Примеры значений:
|
строка |
нет |
|
Имя и контактные данные автора схемы. |
строка |
нет |
|
FQID схемы расчетов, в которой определяются расчеты-наследники для расчетов из текущей схемы. |
строка |
нет |
|
Массив расчетов. Каждый расчет включает FQID сущностей, к которым применяются расчеты, а также формулы или ссылки на скрипты, которые определяют логику расчетов. См. описание поля. |
массив объектов |
нет |
|
Массив обобщающих расчетов, в котором задаются и описываются расчеты над несколькими несвязанными друг с другом объектами. См. описание поля. |
массив объектов |
нет |
В схеме расчетов должен быть определен хотя бы один расчет в поле calculations или summary_calculations .
|
Расчеты: поле calculations
Поле calculations
содержит объекты расчетов, каждый из которых реализует вычисление числового показателя по заданной формуле. В формуле можно использовать скрипты.
Результатом расчета по схеме всегда является конечное число. |
Объект расчета имеет следующую структуру:
Поле | Описание | Тип данных | Обязательное поле | ||
---|---|---|---|---|---|
|
Уникальный идентификатор расчета, по которому можно сослаться на расчет. Должен быть уникальным в пределах схемы расчетов. Можно использовать UUID в качестве значения. |
строка |
да |
||
|
Имя расчета, отображаемое в интерфейсе. |
строка |
да |
||
|
Краткое описание назначения расчета. |
строка |
нет |
||
|
FQID сущности, к которой применяется расчет. |
строка |
да |
||
|
Математическая формула, по которой выполняется расчет. См. правила описания формулы. |
строка |
да |
||
|
Максимальная сложность расчета. Сложность рассчитывается следующим образом:
При превышении предела сложности расчета, указанной в поле
|
положительное целое число |
да |
||
|
Будет ли расчет автоматически запущен при обновлении свойств или связей объекта, связанного с ним. |
булево |
да |
||
|
массив объектов |
нет |
Правила описания формулы расчета
В поле expression
следует указать формулу для расчета согласно следующим правилам:
-
В формулах поддерживаются все операции, реализованные в библиотеке JavaScript math.js.
-
В формулах можно использовать следующие аргументы:
-
целые и дробные числовые константы;
-
все атрибуты сущности, указанной в поле
entity
расчета, имеющие типыInteger
,Float
; -
глобальные переменные типов
Integer
,Float
; -
расчеты для сущностей, связанных с текущей сущностью. Связь должна быть настроена в схеме домена в поле
linkages
описания текущей сущности.Расчеты для связанных сущностей нужно обязательно указать в поле
children
. В таком случае расчет для текущей сущности называется родительским, а расчеты для связанных сущностей — дочерними.
-
Пример формулы
- id: test_calc
name: Тестовый расчет
entity: test_domain/TestEntity
expression: "2 * {field:weight} / {variable:divisor}"
auto_recalculation: false
complexity_limit: 1
Здесь:
-
2
— числовая константа. -
{field:weight}
— значение поляweight
сущностиTestEntity
. -
{variable:divisor}
— значение глобальной переменнойdivisor
.
Ссылки на атрибуты, переменные и скрипты следует указывать в фигурных скобках, например, {variable:divisor} .
|
Применение скриптов в расчетах
В поле expression
можно указать идентификатор скрипта, который будет выполнен при запуске расчета. В расчете будет использоваться значение, возвращенное скриптом.
Результатом работы скрипта должно быть конечное число. Автоматическая валидация возвращаемого значения в системе не предусмотрена, поэтому разработчик скрипта должен реализовать его так, чтобы он возвращал только числа. |
Пример формулы, дополненный вызовом скрипта
- id: test_calc
name: Тестовый расчет
entity: test_domain/TestEntity
expression: |
mean(
2 * {field:weight} / {variable:divisor},
{script:test_calculation_script}
)
auto_recalculation: false
complexity_limit: 11
Здесь:
-
{script:test_calculation_script}
— вызов скриптаtest_calculation_script
.
Минимально допустимое значение |
Дочерние расчеты
Дочерние расчеты — это расчеты для связанных сущностей, участвующие в расчете для текущей сущности (родительском расчете). Ссылки на них следует указать в поле children
родительского расчета.
Ссылка на дочерний расчет содержит следующие поля:
-
linkage
— идентификатор связи между сущностью, для которой выполняется родительский расчет, и сущностью, для которой выполняется дочерний расчет. Связь должна быть настроена в схеме домена в полеlinkages
описания сущности, для которой выполняется родительский расчет. -
calculation
— идентификатор дочернего расчета.
Дочерний расчет выполняется для всех сущностей, связанных с текущей, поэтому его результат всегда интерпретируется системой как массив. Чтобы преобразовать результат дочернего расчета в одно число, используйте функции массивов, такие как min , max , mean , count или sum .
|
Пример настройки дочернего расчета
- id: test_calc_with_child
name: Тестовый расчет с дочерним
entity: test_domain/TestEntity
expression: |
mean(
2 * {field:weight},
sum({calculation:child_calc})
)
children:
- linkage: test_domain/TestEntity_ChildEntity
calculation: child_calc
auto_recalculation: true
complexity_limit: 200
- id: child_calc
name: Дочерний расчет
entity: test_domain/ChildEntity
expression: "{script:child_calculation_script}"
auto_recalculation: true
complexity_limit: 100
Здесь:
-
Результат дочернего расчета преобразован в одно число с помощью функции
sum
:sum({calculation:child_calc})
. -
test_domain/TestEntity_ChildEntity
— идентификатор связи между сущностямиTestEntity
иChildEntity
, заданной в схеме доменаtest_domain
в разделеlinkages
описания сущностиTestEntity
. -
child_calc
— идентификатор дочернего расчета.
Обобщающие расчеты: поле summary_calculations
Обобщающие расчеты — это расчеты, позволяющие вычислить метрики для сущностей, для которой нет обобщающей сущности: например, среднее время выполнения задач операторами.
Результатом расчета по схеме всегда является конечное число. |
В схеме расчетов обобщающие расчеты настраиваются в поле summary_calculations
.
В обобщающем расчете можно использовать только результаты других расчетов, созданных в этой же схеме. Чтобы использовать свойство сущности в обобщающем расчете, это свойство нужно указать в поле |
Обобщающий расчет имеет следующую структуру:
Поле | Описание | Тип данных | Обязательное поле |
---|---|---|---|
|
Уникальный идентификатор расчета, по которому можно сослаться на расчет. Должен быть уникальным в пределах схемы расчетов. Можно использовать UUID в качестве значения. |
строка |
да |
|
Имя расчета, отображаемое в интерфейсе. |
строка |
да |
|
Краткое описание назначения расчета. |
строка |
нет |
|
Математическая формула для обобщающего расчета. |
строка |
да |
Пример обобщающего расчета
calculations:
- id: task_processing_time
name: Время обработки задачи
entity: test_tasks/Task
expression: "{field:processing_time}"
auto_recalculation: true
complexity_limit: 1
summary_calculations:
- id: mean_task_processing_time
name: Среднее время обработки задачи
expression: "mean({calculation:task_processing_time})"
Здесь:
-
task_processing_time
— расчет, возвращающий время выполнения одной задачи. -
mean_task_processing_time
— обобщающий расчет, возвращающий среднее время выполнения всех задач в системе.
Пример схемы расчетов
В данном разделе приведен пример схемы расчетов.
id: evo.compliance.audit.calculations
name: audit_calculations
description: Расчеты для аудитов
type: calculation_schema
tags: [audit, calculations]
version: 1.0.0
status: stable
author: John Doe <johndoe@example.com>
calculations:
- id: audit_assessment_sum_compliance_index
name: Сумма индексов соответствия
entity: evo.compliance.audit/Audit
expression: |
round(
sum({calculation:audit_assessment_compliance_index}),
{variable:audit_assessment_compliance_index_round}
)
children:
- linkage: evo.compliance.audit/Audits_RequirementValues
calculation: audit_assessment_compliance_index
auto_recalculation: true
complexity_limit: 100
- id: audit_assessment_compliance_index
name: Индекс соответствия, вычисленный через скрипт
entity: evo.compliance.audit/RequirementValues
expression: "{script:calculate_comp_index}"
auto_recalculation: true
complexity_limit: 20
- id: progress_metric
name: Прогресс аудита в процентах
entity: evo.compliance.audit/Audit
expression: "{field:progress}"
auto_recalculation: true
complexity_limit: 1
summary_calculations:
- id: mean_audit_progress
name: Средний прогресс по аудиту
expression: "mean({calculation:progress_metric})"
Интерпретация примера
Метаданные схемы расчетов
-
id
: идентификатор схемы расчетов —evo.compliance.audit.calculations
. -
name
: наименование схемы расчетов —audit_calculations
. -
description
: описание схемы расчетов — "Расчеты для аудитов". -
type
: тип элемента экспертизы —calculation_schema
. -
tags
: теги схемы расчетов, используемые для классификации —audit, calculations
. -
version
: версия схемы расчетов —1.0.0
. -
status
: статус разработки схемы —stable
. -
author
: автор схемы расчетов —John Doe <johndoe@example.com>
.
Расчеты
Схема содержит три расчета:
-
audit_assessment_sum_compliance_index
— сумма индексов соответствия требований аудита, округленная до количества разрядов, определенного глобальной переменнойaudit_assessment_compliance_index_round
. Индексы соответствия отдельных требований вычисляются с помощью дочернего расчетаaudit_assessment_compliance_index
. -
audit_assessment_compliance_index
— индекс соответствия требования, вычисляемый скриптомcalculate_comp_index
. -
progress_metric
— расчет, возвращающий значение поля прогресса аудитаprogress
для обобщающего расчетаmean_audit_progress
.
Запуск и отображение расчетов по схеме
Расчеты можно запускать:
-
при нажатии кнопки, добавленной в интерфейс домена;
-
автоматически с помощью триггера;
-
при изменении объекта, с которым связан расчет.
Чтобы запустить расчеты по схеме и отобразить их результаты в интерфейсе системы, необходимо выполнить следующие действия:
-
Если расчеты будут запускаться при нажатии кнопки или по триггеру, следует создать плейбук для запуска расчетов.
Если схема расчетов выключена в разделе Экспертиза, при запуске связанного с ней плейбука любым способом расчеты по ней производиться не будут. -
Настроить метод запуска плейбука расчетов.
Создание плейбука для запуска расчетов
Пример плейбука для запуска расчета
id: calculation_sdk_test_exec
name: Вызов exec через SDK расчётов
version: 1.0.0
author: John Doe <johndoe@example.com>
tags: [audit, calculations]
type: playbook
body:
input:
properties: {}
modules:
- id: module_0
body:
type: rawscript
input: {}
source: !bun |
import * as sdk from '@playbooks/sdk';
export async function main() {
// Получение ID текущего объекта из контекста.
const objectId = await JSON.parse(get_context()).objectId;
// Формирование объекта с аргументами расчета.
const command = {
calculationSchemaId: "calculate_test",
calculationId: "test",
object: {
domainId: "evo.entity.category.standards",
entityId: "Requirement",
id: objectId
},
cacheFirst: false
}
// Выполнение расчета и получение его результатов.
const result = await sdk.calculation.exec(command);
console.log('result', result);
return result;
}
Настройка метода запуска расчетов
Запуск расчетов при нажатии кнопки
Чтобы запустить расчеты при нажатии кнопки, следует внести изменения в схему домена:
-
создать действие типа
playbook
, в котором указать идентификатор ранее созданного плейбука; -
создать кнопку (виджет типа
button
) и связать ее с действием; -
добавить кнопку в представление (например, таблицу или карточку) сущности, для которой производится расчет.
Пример описания кнопки для запуска расчетов
actions:
- id: actions.countComplianceIndex
name: Вычислить индекс соответствия
type: playbook
entity: Audit
playbook: count_compliance_index
views:
- id: auditView
type: entity
entity: Audit
widgets:
- id: countComplianceIndexButton
type: action
action: actions.countComplianceIndex
control:
type: regular_button
label: "Вычислить индекс соответствия"
groups:
- id: infoAuditBlock
description: Информация об аудите
type: block
layout:
direction: column
expandable: false
components:
- widget: countComplianceIndexButton
Интерпретация примера
-
Действие
actions.countComplianceIndex
связано с плейбукомcount_compliance_index
, который запускает схему расчета индекса соответствия для аудита. -
Кнопка
countComplianceIndexButton
запускает действиеactions.countComplianceIndex
. -
Представление карточки аудита
infoAuditBlock
содержит кнопкуcountComplianceIndexButton
.
Запуск расчетов с помощью триггера
Можно автоматизировать запуск плейбука расчетов, настроив триггер для него. Поддерживаются оба типа триггеров, доступных в системе — Расписание и Событие триггера.
Запуск расчетов при изменении связанного объекта
Если в конфигурации расчета установить для свойства auto_recalculation
значение true
, при изменении свойств или связей объекта, связанного с расчетом, расчет будет выполнен заново.
Для этого метода запуска создавать плейбук не требуется.
Необходимость перезапуска родительских и дочерних расчетов относительно текущего расчета определяется по следующей логике:
|
Отображение результатов расчетов в интерфейсе
Чтобы отобразить результат расчетов в интерфейсе системы, нужно связать расчет с атрибутом сущности с помощью поля calculation
, а затем добавить виджет для вывода атрибута в представление сущности.
Пример вывода результата расчета в карточку требования
entities:
- id: Requirement
attributes:
- id: assessmentIndexCalculation
name: Результат расчета индекса соответствия
dataType: Calculation
calculation:
schemaId: evo.compliance.audit.calculations
id: audit_assessment_compliance_index
...
views:
- id: requirementView
type: entity
entity: Requirement
widgets:
- id: editors.assessmentIndexCalculation
type: attribute
attribute: assessmentIndexCalculation
description: Результат расчета индекса соответствия
groups:
- id: blocks.info.requirement
description: Информация о требовании
type: block
layout:
direction: column
expandable: false
components:
- widget: editors.assessmentIndexCalculation