Перейти к содержанию

Создание своего типа условия

Создание своего типа условия

Для удобства настройки системы в ней есть такой тип карточки, как тип условия. Данный тип карточки позволяет реализовать свой тип условия с заданным редактором условия (поле Тип карточки настроек), местами возможности его использования (поле Места использования), описанием условия и собственно самим скриптом условия.

В качестве типа карточек настроек можно выбрать любой тип карточки системы, который имеет флаги Скрытый и Административный и не имеет флага Единственный экземпляр в настройках типа карточки.

Tip

Если для условий данного типа не требуется редактора, то данное поле можно не заполнять или в качестве типа выбрать Без редактора.

Указанный в карточке типа условия тип карточки настроек будет использован в качестве редактора условия данного типа, а все настройки условия можно использовать в описании условия и в скрипте условия.

Important

После создание нового типа условия или изменения типа карточки настроек редактора для корректной настройки условий данного типа необходимо перезапустить приложение.

Описание условие - это текст, поддерживающий простые плейсхолдеры, вроде {date}, строки локализации и плейсхолдеры {f} и {t}. В качестве данных для плейсхолдеров можно использовать секции и поля из типа карточек, указанного в качестве типа карточек настроек.

Tip

Например строка вида “{$CardTypes_Controls_Partner}: <_row>{t:KrPartnerCondition.PartnerName separate by (, )}; </_row>” позволяет вывести в качестве описания условия текст вида “Контрагенты: <список имен контргагентов из секции KrPartnerCondition, записанный через запятую>.

Условие - это скрипт, который должен вернуть true, если условие выполнено успешно, иначе он должен вернуть false. Данный скрипт в качестве параметра принимает параметр context, который имеет тип IConditionContext. Данный скрипт - асинхронный метод и поддерживает использование в скрипте асинхронного API с использованием операнда await (например await context.GetCardAsync())

Данный параметр имеет следующие свойства и методы:

  • GetCardAsync - асинхронный метод для получения карточки, по которой идет проверка условия.

  • Settings - набор секций с настройками. Соответствует типу карточек, укказанному в поле “Тип карточки настроек”.

  • DbScope - объект для взаимодействия с базой данных.

  • Session - сессия пользователя.

  • Container - контейнер зависимостей Unity.

  • Info - место хранения дополнительной информации. Может быть использована для хранения данных, полученных через DbScope, и повторного использования в следующих выполнениях проверки условий данного типа.

Особенность проверки условий заключается в том, что в ходе одной проверки условий по карточке все они выполняются с использованием одного и того же объекта context. Это позволяет в свою очередь в условиях, в которых может производиться загрузка данных из базы данных с использованием DbScope, производить эту загрузку единожды и записать эту информацию в context.Info, а все последующие проверки условий данного типа уже могут обращаться к этой информации без повторного обращения к базе данных.

Пример условия По состоянию, которое использует данную особенность.

// Пытаемся получить необходимую информацию из context.Info, и если ее еще там нет, то производим загрузку состояния карточки из базы if (!(context.Info.TryGetValue("StateID", out var stateIDObj) && stateIDObj is int stateID)) { var db = context.DbScope.Db; var builder = context.DbScope.BuilderFactory;

stateID = await db.SetCommand( builder .Select().Top(1).C("StateID") .From("KrApprovalCommonInfo").NoLock() .Where().C("MainCardID").Equals().P("ID") .Limit(1).Build(), db.Parameter("ID", context.CardID)) .LogCommand() .ExecuteAsync<int?>(context.CancellationToken) ?? 0; // 0 - состояние Проект, которое считается состоянием по умолчанию

// Записываем загруженное состояние в context.Info для возможности ее повторного использования context.Info["StateID"] = stateID; }

// Возвращаем true, если в строках секции KrDocStateCondition есть хотя бы одна строка, в которой указано данное состояние. return context.Settings["KrDocStateCondition"].Rows.Any(row => { var settingsStateID = row.TryGet<int>("StateID"); return settingsStateID == stateID; });

Другой пример типа условия - По контрагенту. В нем уже не используется Info, т.к. данные грузятся из карточки. Сама же карточка загружается только один раз и только при условии, что она не была еще загружена ранее.

// Получаем карточку из контекста. Непосредственно загрузка карточки из базы произойдет только при условии, что она еще не была загружена. var card = await context.GetCardAsync();

// Получаем идентификатор контрагента из карточки var partnerID = card.Sections.GetOrAdd("DocumentCommonInfo").Fields.TryGet<Guid?>("PartnerID");

// Возвращаеи true, если в строках секции KrPartnerCondition есть хотя бы одна строка, в которой указан данный контрагент. return context.Settings["KrPartnerCondition"].Rows.Any(row => { return partnerID == row.TryGet<Guid>("PartnerID"); });

Back to top