Клонирование операций#
Клонирование операций используется, когда на основе одной операции нужно сформировать несколько вложенных операций. Исходная операция выступает как контейнер или шаблон, а конкретные операции создаются по строкам источника данных, указанного в cloneQuery.
Обычная операция выборки описывает одно действие. Если связанных действий несколько, их можно создать отдельными операциями: для каждой операции задать свое имя, заголовок, порядок, иконку и обработчик или параметры. Такой вариант подходит, когда список действий заранее известен и редко меняется.
Если состав действий зависит от данных, ручное создание отдельных операций становится неудобным: при появлении нового варианта нужно изменять код или метаданные, а количество операций остается заранее заданным. Клонируемая операция формирует вложенные операции по данным из cloneQuery: система выполняет SQL-запрос или обращается к выборке, указанной в cloneQuery, и по каждой полученной строке создает отдельную вложенную операцию. Поэтому количество вложенных операций, их названия, порядок, иконки и параметры выполнения определяются строками источника данных, а не фиксированным набором операций в коде.
Например, в выборке документов могут отображаться объекты одного класса, но разных типов: приходная накладная, расходная накладная, акт или другой прикладной тип документа. Для каждого типа документа может быть настроен свой набор печатных форм. Операция печати при этом остается одной, но состав вложенных операций зависит от данных объекта, который отображается в текущей выборке: для одного типа документа выводится один перечень печатных форм, для другого типа — другой.
Каждая доступная печатная форма отображается как отдельная вложенная операция. При выборе вложенной операции вызывается общий обработчик печати, а конкретная печатная форма определяется параметрами строки, по которой создан клон. Например, в строке может быть передан идентификатор печатной формы, который обработчик получает через getVar и использует при построении отчета.
В интерфейсе клонируемая операция выглядит как обычная операция с выпадающим меню. Сама операция-контейнер не выполняет действие при нажатии. Пользователь раскрывает ее и выбирает одну из вложенных операций.
Формирование клонированных операций#
За клонирование отвечает свойство cloneQuery класса Operation. Оно указывает источник данных, по строкам которого система формирует вложенные операции.
Возможные варианты значения cloneQuery:
Вариант |
Пример |
Описание |
|---|---|---|
Имя выборки |
|
Клоны формируются по данным отображения |
Имя выборки с отображением |
|
Клоны формируются по данным указанного отображения выборки |
SQL-запрос |
|
Клоны формируются по записям, полученным при выполнении запроса |
Каждая строка источника данных формирует отдельную операцию. Результирующая таблица, полученная из cloneQuery, должна содержать предустановленные системные колонки. При построении клонируемой операции сервер анализирует эти колонки и использует их значения для формирования вложенных операций.
Для управления свойствами создаваемых операций используются следующие системные колонки:
Название |
Обязательность |
Описание |
|---|---|---|
|
Обязательное |
Имя операции. Должно быть уникальным в пределах выборки |
|
Необязательное |
Заголовок операции. Если значение не указано, берется из клонирующей операции |
|
Необязательное |
Описание операции, которое используется как всплывающая подсказка |
|
Необязательное |
Номер картинки для операции. Если значение не указано, берется из клонирующей операции |
|
Необязательное |
Горячая клавиша, например |
|
Необязательное |
Имя родительской операции. Для корневых операций должно содержать |
|
Необязательное |
Имя стиля отображения наименования операции. Используется только для компонента |
|
Необязательное |
Номер операции для сортировки при отображении в меню, на панели управления и других элементах управления |
Кроме системных колонок, источник данных может содержать дополнительные колонки. Они используются как параметры выполнения. Перед выполнением операции выборка позиционируется на строку, по которой был создан выбранный клон, поэтому значения дополнительных колонок доступны в теле обработчика операции через getVar.
Связь с основной выборкой. Источник данных, указанный в cloneQuery, работает относительно выборки, где объявлена клонируемая операция. По отношению к этой выборке результат cloneQuery фактически является детальной выборкой: основная выборка задает текущий объект и его данные, а результат cloneQuery содержит строки, по которым формируются вложенные операции.
За счет этого набор клонов может зависеть от данных объекта, отображаемого в основной выборке. Например, если в выборке отображаются объекты разных типов, cloneQuery может вернуть разный набор строк для разных типов объекта.
Настройка cloneQuery#
Клонируемая операция создается как обычная операция, для которой задано свойство cloneQuery. В этом свойстве указывается источник данных: имя выборки, имя выборки с отображением или SQL-запрос. По строкам этого источника система формирует вложенные операции.
Источник данных должен возвращать обязательную колонку sName. Остальные системные колонки указываются при необходимости, если нужно задать название, порядок, иконку или другие свойства вложенной операции. Дополнительные колонки можно использовать как параметры выполнения.
Пример настройки операции с cloneQuery:
@Oper(cloneQuery =
"""select null as idBtkObjectType
,null idPlacementClass
,'Добавить на текущем уровне' as sCaption
,'insert_' as sName
,5 as nOrder
,0 as bChild
union
select t.id as idBtkObjectType
,tt.idPlacementClass
,'Добавить на текущем уровне ' || lower(t.sCaption) as sCaption
,'insertClone_' || t.sCode as sName
,10 as nOrder
,0 as bChild
from Btk_ObjectType t
join Bs_ObjTypePlacementExt tt on t.id = tt.idBtkObjectType
where t.idRefClass = :idObjTypeClass
""")
В этом примере запрос формирует вложенные операции для добавления объектов. Каждая строка результата становится отдельной операцией в выпадающем меню.
Стандартные системные колонки управляют отображением и идентификацией операции:
sName— системное имя вложенной операции;sCaption— название операции в интерфейсе;nOrder— порядок отображения операции.
Дополнительные колонки используются как параметры выполнения:
idBtkObjectType— тип объекта, который нужно использовать в логике операции;idPlacementClass— класс размещения;bChild— признак, который может использоваться обработчиком для выбора сценария выполнения.
Обработка выбранного клона#
Код клонируемой операции один для всех вложенных операций. При выборе клона вызывается общий обработчик исходной операции, а различия в поведении определяются данными строки, по которой был создан выбранный клон.
Перед выполнением операции выборка позиционируется на соответствующую строку результата cloneQuery. Поэтому в теле обработчика операции можно получить значения системных и дополнительных колонок через метод getVar.
Стандартные системные колонки позволяют сформировать вложенные операции и задать их отображение: имя, заголовок, порядок, иконку и другие свойства. Если для выполнения операции нужны прикладные данные, их нужно вернуть в результате cloneQuery отдельными колонками.
Например, если источник данных содержит колонку idPlacementClass, ее значение можно получить в теле обработчика операции и привести к нужному типу:
val idPlacementClass = getVar("idPlacementClass").asNLong
Для разных строк значение idPlacementClass может отличаться. За счет этого один обработчик выполняет разную логику в зависимости от выбранного клона.
Пример клонируемой операции#
Пример ниже показывает полный фрагмент клонируемой операции: объявление операции, cloneQuery и обработчик, который использует параметры выбранного клона.
В примере операция формирует вложенные операции для создания приказов разных типов. Запрос возвращает системные колонки для отображения операций и дополнительные колонки, которые используются в обработчике.
@Oper(
active = true,
headOperation = "order_root",
cloneQuery =
"""SELECT
t.id AS idOperObjectType,
concat('createOrder_', t.sCode) AS sName,
concat('Создать приказ ', '"', t.sCaption, '"') AS sCaption,
:super$super$id as "idPerson#"
FROM btk_objecttype t
JOIN btk_class bc ON t.idrefclass = bc.id
WHERE bc.sname = 'Bhr_OrderSimple'""")
def order_clone_oper(): Unit = {
val idObjectType = getSelfVar("idOperObjectType").asNLong
val idPerson = getSelfVar("idPerson#").asNLong
val idEmployee = getVar("super$id").asNLong
Btk_Lib().getDefCardByObjType(idObjectType)
.newForm()
.params(Map(
CardRep.EditingType -> EditingType.insert,
"idInsertOT#" -> idObjectType,
"idInsertPerson#" -> idPerson,
"idInsertEmployee#" -> idEmployee
))
.open()
}
В этом примере:
sName— системное имя вложенной операции;sCaption— название вложенной операции в интерфейсе;idOperObjectType— дополнительная колонка, которая определяет тип создаваемого приказа;idPerson#— дополнительная колонка, переданная из мастер-контекста в строку клона;getSelfVar(...)получает значения из строки выбранного клона;getVar("super$id")получает значение из контекста операции.
При выборе вложенной операции открывается карточка по типу объекта idObjectType. Остальные параметры передаются в карточку при открытии формы.
Обновление клонируемых операций#
Для обновления клонируемых операций используется метод updateMultiplicatingOperations(). Метод синхронизирует набор клонируемых операций текущей выборки с данными, по которым они формируются.
Обновление нужно, когда данные для формирования клонов изменились уже после открытия выборки. Например, если для типа объекта, отображаемого в выборке, настроили новую печатную форму, пользователь не увидит ее в выпадающем меню операции печати, пока выборка не будет переоткрыта или пока не будет выполнено обновление клонируемых операций.
Метод обновляет все клонируемые операции текущей выборки:
selection.updateMultiplicatingOperations()
Точечное обновление отдельных клонируемых операций по системным именам не поддерживается.