Бизнес-правила (хуки)#

Бизнес-правила используются для обеспечения формы необходимой бизнес-логикой, они позволяют изменять и контролировать поведение бизнес-объектов. Например, валидировать вводимые данные, находить значения вычисляемых полей, проверять возможность удалить или создать объект, изменять поведение интерфейса системы в зависимости от состояния данных бизнес-объекта.

Типы бизнес-правил по цели применения:

  • Изменяющие внешний вид и поведение формы (метаданные и UI элементы, которые редактируют данные). Возвращают json patch для метаданных формы;

  • Изменяющие данные экземпляра формы. Возвращают json patch для данных экземпляра формы;

  • Проверяющие возможность выполнить операцию, валидирующие команду. Возвращают true/false или success/error (с деталями ошибки — почему нельзя выполнить).

Бизнес-правила реализуются в виде функций-хуков. Хуки представляют собой чистые функции на языке JavaScript, которые получают на вход необходимую информацию и возвращают изменение состояния. Эти функции вызываются системой при наступлении определенных событий (действие пользователя, модификация данных и так далее) и позволяют изменить поведение системы для конкретного бизнес-объекта.

Виды бизнес-правил (хуков)#

Изменяющие внешний вид#

viewUpdate#

  • Где вызывается:

    • При первом отображении сущности;

    • При необходимости изменить сущность из-за пришедшего ивента (реактивность, изменение view на событие).

  • За что отвечает:

    • Перегрузка внешнего вида и поведения формы (компонентов UI) в зависимости от контекста (разрешений пользователя, текущего состояния экземпляров формы и тд) — влияет на отображение формы;

Изменяющие данные экземпляра формы#

onChange#

  • Где вызывается:

    • При первом отображении сущности;

    • При необходимости изменить сущность из-за пришедшего ивента (реактивность, изменение view на событие, НО не влечет за собой событие onChange, иначе уйдем в бесконечный цикл);

    • При заполнении полей во время создания сущности.

  • За что отвечает:

    • Обновление вычисляемых или автоматически обновляемых полей экземпляров формы — влияет на данные.

  • Пример:

    • В чек-листе надо высчитывать количество заполненных элементов, сколько из них выставлены в статус “Принято”, а сколько в статус “Отклонено”. При изменении чек-листа хук делает пересчет счетчиков;

onCreate#

  • Где вызывается:

    • При инициализации формы, если создаем новый экземпляр;

    • Инициализация первоначального состояния вновь создаваемого экземпляров формы: задать поля по-умолчанию;

  • Пример:

  • Если пользователь из организации А создал заявку, то в поле “Номер договора” заполняется значением “2019-06-25” (в данном случае возможно номер договора не выводить при создании, этот момент надо обсудить в следующих итерациях)

  • Если пользователь из организации N, создал заявку, то в поле “Вид работы” заполняется 3-ье значение из справочника?

onSave#

  • Где вызывается:

    • Вызывается перед сохранением данных инстанса чтобы очистить данные от всяких временных и UI-only полей и тд;

  • За что отвечает:

    • Получает текущее состояние и контекст, возвращает состояние, очищенное от временных полей;

  • Пример:

    • При попытке сохранения заявки пользователями, не относящимся к заявке, отображается ошибка

Проверяющие возможность выполнить операцию#

canChange#

  • Где вызывается:

    • При попытке изменить данные в модели.

  • За что отвечает:

    • Проверка возможности изменить состояние экземпляров формы запрошенным образом: проверить запрашиваемое состояние экземпляров формы и на основе этого разрешить или отклонить операцию изменения (для валидации данных, для проверки прав);

  • Пример:

    • Не давать пользователю изменить заявку если он установил в поле какое-то недопустимое значение (какое поле и какое значение нельзя выбирать - все описывается внутри хука)

  • Ошибка:

    • Вы не можете изменять заявку.

canCreate#

  • Где вызывается:

    • Перед попыткой создать сущность, проверяет возможность выполнить данное действие)

  • За что отвечает:

    • Проверка возможности создать экземпляр формы в данном контексте (данному пользователю и тд)

  • Пример:

    • Только подрядчик может создавать заявку (Только пользователи организации N могут создавать заявку)

    • Только пользователь А может создавать заявку/чек-лист

  • Состояние:

    • Пункт меню в дизейбл состоянии

    • При наведении на пункт появляется тултип с текстом “Вы не можете создавать заявки. Обратитесь к Администратору”

canDelete#

  • Где вызывается:

    • При попытке удалить сущность (несколько сущностей одного типа).

  • За что отвечает:

    • Проверка возможности удалить одну (несколько) сущностей одного типа;

  • Пример:

    • Только автор заявки может удалять заявку

    • Только автор чек-листа может удалять чек-лист

  • Если у пользователя нет доступа, то кнопка дизейблится

canSave#

  • Где вызывается:

    • Вызывается перед сохранением, чтобы убедиться, что данный инстанс можно сохранить (например, все поля, которые должны быть заполнены — заполнены); иначе показывает ошибку;

  • За что отвечает:

    • Проводит проверку того может ли пользователь создать сущность;

  • Пример:

    • При попытке сохранения заявки пользователями, не относящимся к заявке, отображается ошибка

  • Ошибка:

    • Вы не можете создать данную сущность;

Описание параметров для хуков#

FormInstance#

viewUpdate(props: { user: User, item: IFormInstanceDTO, form: Form, isCreation: boolean = false }): Form;
onChange(props: { user: User, base: IFormInstanceDTO, item: IFormInstanceDTO }): IFormInstanceDTO;
canChange(props: { user: User, base: IFormInstanceDTO, item: IFormInstanceDTO, changes: Partial<IFormInstanceDTO> }): { value: boolean, errorMessage?: string };
onCreate(props: { user: User, item: IFormInstanceDTO, initData: object | null }): IFormInstanceDTO;
canCreate(props: { user: User }): boolean;
canDelete(props: { user: User, item: IFormInstanceDTO }): { value: boolean, errorMessage?: string };
canSave(props: { user: User, item: IFormInstanceDTO }): { value: boolean, errorMessage?: string };
onSave(props: { user: User, item: IFormInstanceDTO }): IFormInstanceDTO;

Вывод текста ошибки из хука, если нельзя совершить какое-то действие. Например, если документ еще не загрузился, при клике на кнопку Сохранить, выводить ошибку с указанным текстом

if (isLoadedAttachments) {
      return {
          value: false,
          errorMessage: "Загрузка документа ещё не завершена",
      };
  }