Иерархии задач¶
ℹ️ Иерархия задач — это интерфейс для просмотра дерева подчиненных задач. В иерархии могут быть собраны задачи из различных категорий. Источником данных для иерархии является хранимая процедура, поэтому в иерархию может быть заложена любая логика связи между родительским и дочерними объектами. Чаще всего иерархии используются для работы с задачами, но в общем случае иерархии могут отображать любые объекты (например, орг. структуру, состав вложенных групп и т.п.)
В иерархии можно:
-
Скрывать/раскрывать отдельные ветви,
-
Менять текст и отдельные параметры задач,
-
Перемещать или копировать задачи в другую ветку,
-
Открывать карточки задач для просмотра и редактирования.
Эти возможности описаны в Руководстве пользователя.
В пользовательском режиме интерфейс доступен по ссылке: https://адрес_1Формы/spa/task-hierarchy/{id}
где id — это идентификационный номер иерархии.
Пример иерархии:
Как правило, иерархия используется для отображения задач (в настройках такой иерархии параметр "Тип данных" имеет значение "Задача"). Задачи могут быть связаны между собой по принципу "родительская — подчиненная" или по ссылке через ДП Lookup. Кроме того, иерархия может использоваться и для представления других "древовидных" структур — например, организационной структуры (в настройках такой иерархии параметр "Тип данных" имеет значение "Прочее").
Иерархия может включать в себя только обычные, статические столбцы, а может также дополняться динамическими столбцами. Динамические столбцы создаются в момент получения данных для иерархии, и количество этих столбцов зависит от полученных данных. Например, в иерархии отображаются данные по проектам. В этом случае в строках иерархии перечисляются проекты и их этапы, а столбцах — данные по месяцам (на скриншоте ниже это цветовой идентификатор статуса риска). Количество месяцев зависит от длительности конкретного проекта, при настройке иерархии это количество неизвестно, поэтому столбцы с этими данными формируются динамически.
Список иерархий задач¶
Настроенные иерархии доступны в разделе администрирования Пользовательский интерфейс. В верхнем правом углу находится кнопка Выгрузить в Excel. Нажатие на нее позволяет скачать файл с содержимым иерархии в формате XLSX без учета фильтрации на форме. Вы можете отфильтровать данные в самом Excel-файле.
Для создания новой иерархии нажмите на кнопку Создать над таблицей.
Настройка иерархии¶
Окно настройки иерархии задач:
Параметр
Описание
Имя
Название иерархии
Хранимая процедура получения данных
Для MSSQL
Процедура, которая возвращает данные для статических столбцов. Процедура вызывается рекурсивно — сначала для головной задачи, потом для каждой дочерней и т.д.
Входящие параметры:
@TaskId int = null,
@RootTaskId int = null,
@SessionUserId int,
@XmlParam xml = null,
@OnlyOneRow bit = 0,
@DataType varchar (20) = 'GetChilds'
-
\@TaskId (int) — ID текущей задачи (используется для реализации рекурсии),
-
\@RootTaskId (int) — ID корневой задачи (вершины иерархии),
-
\@SessionUserId (int) — ID пользователя, который просматривает иерархию (необходим для контроля прав доступа),
-
\@XmlParam (xml) — фильтр,
-
\@OnlyOneRow (bit) — служебный параметр, признак получения полного/тестового набора данных. Значение этого параметра заполняется автоматически, достаточно определить его в хранимой процедуре (в общем случае в этот параметр передается значение 0; если передается 1, то возвращается не вся выборка для иерархии, а только одна запись с тестовыми данными, необходимая для настройки таблицы "Настройки вывода колонок", см. ниже),
-
\@DataType (varchar (20)), значение по умолчанию \'GetChilds\' — служебный параметр, необходим для обновления иерархии. Значение этого параметра заполняется автоматически. Если параметр имеет значение \'GetChilds\', то процедура возвращает все дочерние задачи для \@TaskID; если параметр имеет значение \'GetItem\', то процедура возвращает данные конкретной задачи \@TaskId.
ℹ️ Параметр \@RootTaskId может быть задан статически, в настройках иерархии (см. ниже настройку "Id корневой задачи"), а может передаваться в процедуру динамически, при вызове иерархии. Если этот параметр передается динамически, то статический параметр игнорируется. Параметр \@TaskId на первой итерации выполнения процедуры равен null, на последующих итерациях --- нет.
Список полей, возвращаемых процедурой, может меняться. Обязательные поля:
-
Id (int) — ID задачи,
-
ParentId (int) — ID родительской задачи,
-
IsEncrypted (bit) — признак зашифрованности задачи,
-
HasChildren (bit) — признак наличия у данной задачи подчиненных задач.
ℹ️ Названия возвращаемых полей регистрозависимые, т.е. должно возвращаться именно поле Id, а не ID или id
Для PG
ℹ️ Обязательно ознакомьтесь с рекомендациями для работы с PostgreSQL при создании функций, таблиц и представлений
На PG вместо хранимой процедуры для получения данных задается функция. Пример функции см.ниже
Хранимая процедура получения списка категорий для постановки задачи
Необязательный параметр
Процедура, которая возвращает список категорий, в которые пользователи смогут поставить подзадачи через контекстное меню.
Входящие параметры:
@HierarchyId int = null,
@TaskId int = null,
@SessionUserId int,
@XmlParam xml = null
-
\@HierarchyId (int) — ID иерархии,
-
\@TaskId (int) — ID корневой задачи (вершины иерархии),
-
\@SessionUserId (int) — ID пользователя, который просматривает иерархию (необходим для контроля прав доступа),
-
\@XmlParam (xml) — фильтр.
Процедура должна возвращать поля:
-
SubcatId (int) — ID категории,
-
Description (text) — название категории
Хранимая процедура получения динамических данных
Необязательный параметр
Процедура, которая формирует динамические столбцы. В качестве динамического может быть указан только один столбец, который "тиражируется". Например, динамический столбец содержит данные о проценте выполнения задачи и "тиражируется" по месяцам.
Входящие параметры:
@TaskId int = null,
@RootTaskId int = null,
@SessionUserId int,
@XmlParam xml = null,
@OnlyOneRow bit = 0,
@DataType varchar (20) = 'GetChilds'
-
\@TaskId (int) — ID текущей задачи (используется для реализации рекурсии),
-
\@RootTaskId (int) — ID корневой задачи (вершины иерархии),
-
\@SessionUserId (int) — ID пользователя, который просматривает иерархию (необходим для контроля прав доступа),
-
\@XmlParam (xml) — фильтр,
-
\@OnlyOneRow (bit) — признак получения полного/тестового набора данных. Значение этого параметра заполняется автоматически, достаточно определить его в хранимой процедуре (в общем случае в этот параметр передается значение 0; если передается 1, то возвращается не вся выборка для иерархии, а только одна запись с тестовыми данными, необходимая для настройки таблицы "Настройки вывода динамических колонок", см. ниже),
-
\@DataType varchar (20), значение по умолчанию \'GetChilds\' — служебный параметр, необходим для обновления иерархии. Значение этого параметра заполняется автоматически. Если параметр имеет значение \'GetChilds\', то процедура возвращает все дочерние задачи для \@TaskID; если параметр имеет значение \'GetItem\', то процедура возвращает данные конкретной задачи \@TaskId.
Процедура должна возвращать поля (названия полей могут быть другими):
-
Id (int) — ключ, по которому будет происходить объединение с набором данных для статических столбцов (также по столбцу Id),
-
СolName (text) — заголовок динамического столбца, который будет отображаться в пользовательском интерфейсе,
-
ColFieldName (text) — название динамического столбца; должно начинаться с латинской буквы, может содержать латинские буквы и цифры (название не должно соответствовать какой-либо колонке данных, возвращаемых хранимой процедурой, оно используется для внутренней логики и большого значения не имеет),
-
ColValue (тип зависит от значения) — значения в ячейках динамического столбца,
-
ColOrder (int) — порядок динамического столбца (столбцы будут отображаться слева направо по возрастанию этого значения),
-
ColStyle (text) — описание стиля ячейки динамического столбца (см. ниже),
-
ColLink (text) — ссылка, которая будет открываться по клику на ячейку динамического столбца.
Значение этой колонки будет записано в свойство href тега \<a>.
Чтобы открыть задачу в модальном окне, в данное поле надо записать следующее
'javascript:void(window.static.taskClick(' +
cast(%ID_задачи_которую_надо_открыть% as nvarchar(10)) + ',' +
cast(%ID_задачи_для_данной_строки% as nvarchar(10)) + '))'
Если по клику на задачу должна открываться карточка этой задачи, то первый и второй параметры совпадают.
Передача двух разных параметров позволяет реализовать такой сценарий: по клику на задачу в иерархии открывается другая задача, связанная с ней какой-то бизнес-логикой (например, через ДП Lookup).
Например, в иерархии "Подразделения" -> "Вакансии" -> "Анкеты кандидатов" по клику на вакансию открывается карточка приказа, утверждающего новое штатное расписание. В этом случае в первый параметр передается ID задачи с приказом, а во второй параметр — ID задачи с вакансией.
Второй пример — иерархия "Совещания" -> "Вопросы повестки" -> "Решения по вопросам повестки". В карточке вопроса указывается проект, на котором возник этот вопрос. В иерархии по клику на строку с вопросом открывается карточка проекта. В этом случае в первый параметр передается ID проекта, а во второй параметр — ID задачи с вопросом
- ColIco (text) — колонка, содержащая адрес иконки для ячейки динамического столбца.
Если в данной настройке есть значение, то будут использоваться указанные иконки. Путь к иконке может указываться относительно приложения, например: \'../img/icon1.png\'
Id корневой задачи
Необязательный параметр
ID задачи, которая является вершиной иерархии (параметр \@RootTaskId, см. выше)
Тип данных
Возможные значения:
-
Задача — если иерархия строится по задачам,
-
Прочее — если иерархия строится по другим объектам системы (например, по элементам орг.структуры)
Разрешить drag-and-drop
Если параметр включен, то пользователь сможет менять порядок задач в иерархии (т.е. менять родительские задачи), перетаскивая строки мышью.
ℹ️ Опция доступна только если "Тип данных" имеет значение "Задача"
ℹ️ Режим drag-and-drop корректно работает только если иерархия строится по связям "родительская->дочерняя" — в этом случае при перетаскивании задачи у нее меняется родительская задача. Если же иерархия строится по ссылкам в ДП Lookup или по какой-то иной логике, то при перетаскивании задач эта логика не поддерживается
Загружать все дерево сразу
Если параметр включен, то дерево загружается/обновляется целиком, рекурсивно вызывая обновление каждого узла, у которого есть подчиненные задачи. В этом случае дерево после загрузки отображается полностью раскрытым.
Если параметр отключен, то дерево загружается частями, при открытии ветки подгружается ее содержимое
Разрешить пользователям изменять отображение
Если параметр включен, то пользователи могут менять список и порядок отображаемых столбцов (кроме закрепленных). В пользовательском интерфейсе отображается кнопка Поля.
Разрешить инлайн редактирование
Если параметр включен, то для иерархии с типом данных "Задачи" в пользовательском интерфейсе по двойному клику на поле с типом TaskText поле переходит в режим редактирования, и после сохранения (клавишей "Ввод") исправления вносятся в текст задачи
Передавать в ХП полный путь
Если настройка включена, динамически формируется текстовая переменная, которая включает себя полный путь кликов пользователя, и передаётся в API метод /app/v1.2/api/tasksHierarchies/{taskhierarhyid}/nodes
Это позволяет отображать в иерархии набор данных при раскрытии 2-3 уровня, в зависимости от того, откуда пользователь попал на этот уровень.
ID внешнего объекта
Присваивается автоматически при первом сохранении настроек иерархии
Открыть настройки фильтрации
Отображается после первого сохранения настроек иерархии. По клику на ссылку открывается окно для выбора фильтра.
Параметры фильтрации передаются в хранимую процедуру в параметре @XmlParam в виде XML-структуры.
Если для иерархии настроена фильтрация, в пользовательском интерфейсе отображается кнопка Фильтр
Кнопки управления
В таблице отображается список кнопок, которые будут отображаться в пользовательском интерфейсе в виде контекстного подменю "Совершить действие для выбранных".
Настройка кнопки описана здесь.
Настройки вывода колонок
При сохранении иерархии в таблицу автоматически добавляются все поля, возвращаемые хранимой процедурой (каждое поле — отдельная строка таблицы). После этого в таблице можно настроить внешний вид выводимых полей — цвет, выравнивание и пр., по аналогии с портальным блоком "Таблица".
Чтобы изменить порядок следования колонок в иерархии, перетащите строки таблицы настроек в нужном порядке.
Отображать
Если параметр отключен, то колонка не будет отображаться (по умолчанию отображаются все колонки).
Столбец из хранимой процедуры
Название колонки в SQL-процедуре
Заголовок колонки
Название колонки, как оно должно отображаться в иерархии
Подсказка для наименования колонки
Всплывающая подсказка, которая будет отображаться при наведении курсора мыши на название колонки
Ширина колонки в %, px
Ширина колонки в % от общей ширины иерархии или в px (указывается слитно, без пробела)
Выравнивание текста
Выберите один из доступных вариантов выравнивания текста (по левому краю, по центру, по правому краю)
Брать ссылку из столбца
Выберите колонку, содержащую ссылку, которая будет открываться по клику мыши.
Значение этой колонки будет записано в свойство href тега \<a>.
Чтобы открыть задачу в модальном окне, в данное поле надо записать следующее
'javascript:void(window.static.taskClick(' +
cast(%ID_задачи_которую_надо_открыть% as nvarchar(10)) + ',' +
cast(%ID_задачи_для_данной_строки% as nvarchar(10)) + '))'
Если по клику на задачу должна открываться карточка этой задачи, то первый и второй параметры совпадают.
Передача двух разных параметров позволяет реализовать такой сценарий: по клику на задачу в иерархии открывается другая задача, связанная с ней какой-то бизнес-логикой (например, через ДП Lookup).
Например, в иерархии "Подразделения" -> "Вакансии" -> "Анкеты кандидатов" по клику на вакансию открывается карточка приказа, утверждающего новое штатное расписание. В этом случае в первый параметр передается ID задачи с приказом, а во второй параметр — ID задачи с вакансией.
Второй пример — иерархия "Совещания" -> "Вопросы повестки" -> "Решения по вопросам повестки". В карточке вопроса указывается проект, на котором возник этот вопрос. В иерархии по клику на строку с вопросом открывается карточка проекта. В этом случае в первый параметр передается ID проекта, а во второй параметр — ID задачи с вопросом
Брать стилизацию из столбца
Если в данной настройке есть значение, то текст в этой колонке будет выводиться с указанными атрибутами форматирования (вместо форматирования по умолчанию)
Брать иконку из столбца
Для дополнительной визуализации в иерархии могут использоваться иконки. Использование для строки той или иной иконки прописывается в хранимой процедуре, поэтому для визуализации может использоваться любая бизнес-логика — например, иконка может соответствовать статусу задачи, принадлежности к категории, значению определенного параметра и т.п.
Чтобы использовать иконки, в хранимой процедуре необходимо возвращать текстовую колонку с URL иконки (адрес может быть относительным для приложения).
Пример:
...
CASE
WHEN t.SubcatID = 1111 THEN '../img/crown.png'
WHEN t.SubcatID = 2222 THEN '../img/trophy.png'
WHEN t.SubcatID = 3333 THEN '../img/list.png'
WHEN t.SubcatID = 4444 THEN '../img/task.png'
ELSE NULL END
as MainIconUrl,
...
Тип колонки
Возможные значения:
-
Text,
-
TaskText,
-
Html,
-
UserId,
-
Date,
-
DateTime,
-
Percent,
-
Number,
-
Money,
-
Boolean.
ℹ️ В любой иерархии должна быть одна колонка с типом TaskText. Тип TaskText рекомендуется указывать для колонки с текстом задачи (для типа данных "Задача") или названием объекта (для типа данных "Прочее"). Во-первых, слева от такой колонки отображается символ стрелки, по нажатию на нее раскрывается/сворачивается ветвь иерархии. Во-вторых, текст задачи можно редактировать непосредственно из иерархии (при включенном параметре Разрешить инлайн редактирование, см. выше)
Формат вывода данных
Максимальное количество выводимых символов
Действует для колонок с типом Text и TaskText. Если значение не указано — текст отображается полностью.
Вместо обрезанных символов выводится многоточие. При наведении курсора на поле во всплывающей подсказке отображается полный текст
Закрепленная
Одну или несколько первых (левых) колонок можно закрепить, это удобно если в иерархии отображается много колонок и требуется горизонтальная прокрутка, или если есть динамические колонки, количество которых заранее не известно. Закрепленные колонки не участвуют в горизонтальной прокрутке и всегда остаются видны.
Если параметр включен, колонка закреплена.
ℹ️ При закреплении хотя бы одной видимой колонки, у всех видимых колонок должна быть задана ширина в пикселях
Доступно пользователям
Если параметр включен, а также включена настройка "Разрешить пользователям изменять отображение" (см. выше), то пользователи смогут включать/отключать отображение данного столбца (с помощью кнопки Поля), менять ширину столбца и порядок следования незакрепленных столбцов.
Настройки вывода динамических колонок
Брать порядок из столбца
Колонка ColOrder из хранимой процедуры
Брать имя поля из столбца
Колонка ColFieldName из хранимой процедуры
Брать заголовок из столбца
Колонка ColName из хранимой процедуры
Брать подсказку для наименования колонки из столбца
Колонка с текстом, который будет отображаться во всплывающем окне при наведении курсора мыши на название динамической колонки
Брать значение из столбца
Колонка ColValue из хранимой процедуры
Ширина колонки в %, px
Ширина колонки в % от общей ширины иерархии или в px (указывается слитно, без пробела)
Выравнивание текста
Выберите один из доступных вариантов выравнивания текста (по левому краю, по центру, по правому краю)
Брать ссылку из столбца
Необязательный параметр. Колонка ColLink из хранимой процедуры
Брать стилизацию из столбца
Необязательный параметр. Колонка ColStyle из хранимой процедуры
Брать иконку из столбца
Необязательный параметр. Колонка ColIco из хранимой процедуры
Тип колонки
Возможные значения:
-
Text,
-
TaskText,
-
Html,
-
UserId,
-
Date,
-
DateTime,
-
Percent,
-
Number,
-
Money,
-
Boolean.
Формат вывода данных
Необязательный параметр
Доступно пользователям
Если параметр включен, и включена настройка Разрешить пользователям изменять отображение (см. выше), то пользователи смогут включать/отключать отображение динамических колонок (с помощью кнопки Поля).
Основная колонка¶
Одна из колонок, отображаемых в иерархии, выбирается в качестве основной (в иерархии задач такая колонка обычно соответствует тексту задачи). Для такой колонки в настройках вывода колонок надо указать тип TaskText.
Слева от такой колонки отображается символ стрелки, по нажатию на нее раскрывается/сворачивается ветвь иерархии.
Настройка стиля¶
Для описания стилей могут использоваться следующие типовые значения:
Значение CSS стиль, который соответствует данному значению Default Нет стиля Success background-color:#dff0d8 (зеленый) Info background-color:#d9edf7 (голубой) Warning background-color:#fcf8e3 (желтый) Danger background-color:#f2dede (розовый) TotalsRow font-weight: bold BackRed background-color: pink BackGreen background-color: lightgreen BackBlue background-color: lightblue BackYellow background-color: gold TextRed color: red TextGreen color: green
ℹ️ Если необходимо задать несколько атрибутов, их надо перечислить через пробел.
Помимо типовых значений для задания стиля можно использовать любые значения цвета и фона в формате \'Color#ХХХХХХ\' для цвета текста и \'Background#ХХХХХХ\' для цвета фона (где ХХХХХХ — шестизначное обозначение цвета в формате HEX).
Аналогичным образом можно указывать значение высоты строки в формате \'HeightXXXpx\' (где ХXХ — количество px).
Если необходимо задать несколько значений, их можно перечислить через запятую. Например, \'Color#ff0000,Background#00ff00\' или \'Color#ff0000,Height40px\'
Кроме того, для отображения задач в иерархии могут использоваться стили из табличного представления категорий:
Значение Описание CSS
task-closed для завершенных задач — серый шрифт color: gray task-rejected для отклоненных задач — серый перечеркнутый шрифт color: gray; text-decoration: line-through task-new для новых задач — жирный шрифт font-weight: bold task-overdue для просроченных задач — красный шрифт color: red
В дополнение к этим стилям может использоваться стиль task-state, который отображает текст одной строкой без переносов (white-space: nowrap). Например, \'task-state task-closed\'. Этот стиль действует для колонок с типом Html.
ℹ️ Для колонки с типом TaskText всегда применяется стиль с автоматическим переносом строки, который имеет преимущество (white-space: normal !important).
Настройка отображения столбцов¶
Первоначально при загрузке иерархии отображаются только те статические колонки, для которых включен параметр Отображать, а также динамические колонки (если они настроены).
Если для иерархии включена настройка Разрешить пользователям изменять отображение, то пользователи могут менять список отображаемых колонок, их порядок и ширину. В пользовательском интерфейсе в правом верхнем углу иерархии будет отображаться кнопка Поля. По клику на кнопку открывается окно со списком доступных для отображения колонок, в котором пользователь может выбрать нужные ему колонки. Для выбора доступны только те колонки (статические и динамические), для которых включен параметр Доступно пользователям.
ℹ️ Для статических колонок с включенной настройкой Закрепленная возможности управления видимостью, порядком и шириной не действуют.
Обработка параметров фильтра¶
Если для иерархии настроен фильтр, в процедуру будут передаваться параметры и значения фильтра в формате XML. Имя параметра передается как атрибут Name. Для периода передаются два значения — From и To, для остальных параметров передается значение Value.
Для обработки параметров фильтра на MS SQL удобно использовать процедуру crm_repGetParams.
В процедуре для построения иерархии обращение к этой процедуре может выглядеть следующим образом
declare @StartDate date = null, @EndDate date = null, @Filial int = null
declare @Params table ([Name] varchar(max), [From] varchar(max), [To] varchar(max), [Value] varchar(max))
insert into @Params ([Name], [From], [To], [Value])
exec crm_repGetParams @XML = @XmlParam
select @StartDate = cast([From] as varchar(max)), @EndDate = cast([To] as varchar(max))
from @Params where Name = 'Period'
select @Filial = cast([Value] as varchar(max))
from @Params where Name = 'Filial'
Для PG процедура crm_repGetParams не используется. Пример (ниже) передачи параметра для PG.
DECLARE
d1 DATE := NULL;
d2 DATE := NULL;
BEGIN
SELECT a.from_val, a.to_val into d1, d2 FROM dbo.ssl_get_filter_param_by_name(xmlparam::xml, 'period') as a;
Примеры хранимых процедур для иерархий (MSSQL)¶
Пример процедуры отбора данных по подзадачам:
ALTER procedure [dbo].[TasksHierarchy]
(
@TaskId int = null,
@RootTaskId int = null,
@SessionUserId int,
@XmlParam xml = null,
@OnlyOneRow bit = 0,
@DataType varchar (20) = 'GetChilds'
)
as
begin
select
t.TaskId AS Id,
t.ParentTaskId AS ParentId,
t.[Description] as TaskName,
t.IsOverdue,
t.IsClosed,
states.FinishWork as IsWorkFinished,
states.WorkNotStarted as IsWorkNotStarted,
t.IsEncrypted,
states.[Description] as StateName,
subcats.SubcatID as SubcategoryId,
subcats.[Description] as SubcategoryName,
t.PlannedStart as PlanStart,
t.OrderedTime as PlanFinish,
t.TaskStartTime as FactStart,
t.EndTime as FactFinish,
CASE
WHEN t.SubcatID = 1111 THEN '../img/crown.png'
WHEN t.SubcatID = 2222 THEN '../img/trophy.png'
WHEN t.SubcatID = 3333 THEN '../img/list.png'
WHEN t.SubcatID = 4444 THEN '../img/task.png'
ELSE NULL END
as MainIconUrl,
cast (isnull(t.PercentDone, 0) as smallint) as PercentDone,
th.UserId as PerformerId,
cast(isnull((select top 1 1 from Tasks as p where t.TaskId = p.ParentTaskID), 0) as bit) as HasChildren
from tasks as t WITH(NOLOCK)
join States states with(nolock) on states.StateId=t.StateId
join Subcategories subcats with(nolock) on subcats.SubcatId=t.SubcatId
left join TaskHelpers th with(nolock) on th.TaskId=t.TaskId and th.IsResponsible=1
where ((@TaskId is null AND t.SubcatID = 1234 AND t.IsClosed = 0) or (t.ParentTaskId=@TaskId and @TaskId is not null))
order by subcats.[Description], t.TaskId asc;
end;
Пример иерархии вакансий в подразделениях (по ссылкам Lookup):
Иерархия строится по трем категориям: Подразделения, Вакансии (содержит ДП "Подразделение") и Анкеты кандидатов (содержит ДП "Вакансия"). Для иерархии настроен фильтр, который отбирает вакансии, которые относятся к выбранному региональному филиалу и должны быть закрыты в выбранный период времени. Если для иерархии задан номер корневой задачи, то процедура отбора возвращает данные по одному подразделению, чей номер (ID задачи) передается в параметре RootTaskID. Если номер корневой задачи не задан, то строится иерархия по всем подразделениям.
ALTER PROCEDURE [dbo].[cv]
(
@TaskId int = null,
@RootTaskId int = null,
@SessionUserId int,
@XmlParam xml = null,
@OnlyOneRow bit = 0,
@DataType varchar (20) = 'GetChilds'
)
AS
BEGIN
SET NOCOUNT ON;
-- параметры из фильтра (используются для отбора вакансий по сроку, к которому необходимо найти сотрудника)
declare @StartDate date = null, @EndDate date = null
declare @Params table ([Name] varchar(max), [From] varchar(max), [To] varchar(max), [Value] varchar(max))
insert into @Params ([Name], [From], [To], [Value])
exec crm_repGetParams @XML = @XmlParam
select @StartDate = cast([From] as varchar(max)), @EndDate = cast([To] as varchar(max))
from @Params where Name = 'Period'
-- данные
CREATE TABLE #t (ParentId int, Id int, TaskText text, IsEncrypted bit, HasChildren bit, Icon text, Duedate datetime, TaskStatus text, Style text)
-- подразделение, категория 11
INSERT INTO #t (ParentId, Id, TaskText, IsEncrypted, HasChildren, Icon, Duedate, TaskStatus, Style)
SELECT null, t.TaskID, t.TaskText,
t.IsEncrypted,
cast(IsNull((select top 1 1 from dbo.TasksInSubcat22Denormalized as p
where t.TaskID = p.ExtParam21NativeValue), 0) as bit),
'../img/insert.gif',
null, t.StateName, ''
FROM dbo.TasksInSubcat11Denormalized t
WHERE t.IsClosed = 0
AND (t.TaskId = @RootTaskId or @RootTaskId is null) -- по одному подразделению или по всем
AND @TaskId is null; -- смотреть подразделения только на первой итерации
-- вакансии, категория 22, содержит ДП "Подраздление" с ID=21
INSERT INTO #t (ParentId, Id, TaskText, IsEncrypted, HasChildren, Icon, Duedate, TaskStatus, Style)
SELECT @TaskID, t.TaskID, t.TaskText,
t.IsEncrypted,
cast(isnull((select top 1 1 from dbo.TasksInSubcat33Denormalized as p
where t.TaskId = p.ExtParam32NativeValue), 0) as bit),
'../img/new.gif',
t.OrderedTime, t.StateName,
case when t.IsClosed = 1 then 'task-state task-closed' else '' end
FROM dbo.TasksInSubcat22Denormalized t
WHERE (t.ExtParam21NativeValue = @TaskId)
AND ((t.OrderedTime >= @StartDate) OR (@StartDate is null))
AND ((t.OrderedTime <= @EndDate) OR (@EndDate is null));
-- анкеты, категория 33, содержит ДП "Вакансия" с ID=32
INSERT INTO #t (ParentId, Id, TaskText, IsEncrypted, HasChildren, Icon, Duedate, TaskStatus, Style)
SELECT @TaskID, t.TaskID, t.TaskText,
t.IsEncrypted, 0,
'../img/addperf.gif',
t.OrderedTime, t.StateName,
case when t.IsClosed = 1 then 'task-state task-closed' else '' end
FROM dbo.TasksInSubcat33Denormalized t
WHERE (t.ExtParam32NativeValue = @TaskId)
SELECT ParentId, Id, TaskText, IsEncrypted, HasChildren, Icon, Duedate, TaskStatus, Style FROM #t
DROP TABLE #t
END
Пример процедуры, возвращающей список категорий для постановки подзадач:
Если иерархия "Подразделения -> Вакансии -> Анкеты кандидатов" (см. предыдущий пример) строится не на основе ссылок через Lookup, а на основе связей "родительская задача — подчиненная задача", то в иерархии может быть включен режим drag-and-drop, когда задачи перемещаются между ветвями иерархии с помощью перетаскивания. Также в этом режиме возможна постановка подзадач непосредственно из иерархии. Процедура, формирующая список категорий для постановки подзадач в иерархии определяет категорию текущей задачи (ее номер передается в параметре TaskId) и в зависимости от нее выбирает категорию для постановки подзадачи:
ALTER PROCEDURE [dbo].[cv_cr_catId]
(
@HierarchyId int =null,
@TaskId int = null,
@RootTaskId int = null,
@SessionUserId int=null,
@XmlParam xml = null
)
AS
BEGIN
select
case Tasks.SubcatID when 11 then 22 when 22 then 33 end as SubcatId,
case Tasks.SubcatID when 11 then 'Вакансии' when 22 then 'Анкеты кандидатов' end as Description
from Tasks where Tasks.TaskID = @TaskId
END
Пример процедуры для формирования иерархии орг.структуры:
ALTER PROCEDURE [dbo].[hierarchy_org]
(
@TaskId int = null,
@RootTaskId int = null,
@SessionUserId int,
@XmlParam xml = null,
@OnlyOneRow bit = 0,
@DataType varchar (20) = 'GetChilds'
)
as
BEGIN
SELECT id as Id, parentid as ParentId, name as divisionname, CAST(0 as bit) IsEncrypted, CAST(1 as bit) HasChildren
FROM OrgStructureUnit
WHERE (@TaskId is null) AND (Id = @RootTaskId)
UNION ALL
SELECT id as Id, parentid as ParentId, name as divisionname, CAST(0 as bit) IsEncrypted, CAST(1 as bit) HasChildren
FROM OrgStructureUnit
WHERE (@TaskId is not null) AND (ParentId = @TaskId)
END
Примеры функции для иерархий (PG)¶
ℹ️ Обязательно ознакомьтесь с рекомендациями для работы с PostgreSQL при создании функций, таблиц и представлений
Пример функции:
CREATE OR REPLACE FUNCTION dbo.cm[_hierarchy]_brief(p_roottaskid integer DEFAULT NULL::integer, p_taskid integer DEFAULT NULL::integer, p_sessionuserid integer DEFAULT NULL::integer, p_xmlparam xml DEFAULT NULL::xml, p_onlyonerow boolean DEFAULT false, p_datatype character varying DEFAULT 'GetChilds'::character varying)
RETURNS TABLE(id integer
,parentid integer
,taskurl character varying
,taskname character varying
,statename character varying
,createdtime character varying
,orderedtime character varying
,thelpers character varying
,haschildren boolean)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
--Категории:
--33. Прод бриф
--34. Заявки на закупку
--Отображаемые колонки:
--1. Статус
--2. Дата создания
--3. Срок
--4. Исполнители
RETURN QUERY
select ch.TaskId::integer AS Id
,p.taskid::integer AS ParentId
,concat('javascript:void(window.static.taskClick(',ch.TaskId,',',ch.TaskId,'))' )::character varying AS TaskUrl
,ch.TaskText::character varying as TaskName
,ch.statename::character varying as StateName
,to_char(ch.createdtime, 'DD.MM.YYYY')::character varying as CreatedTime
,to_char(ch.orderedtime, 'DD.MM.YYYY')::character varying as OrderedTime
,string_agg(u.displayname,',')::character varying as THelpers
,false as HasChildren
from tasksinsubcat33denormalized p
left join tasksinsubcat34denormalized ch on p.taskid = ch.extparam86nativevalue
left join taskhelpers th on ch.taskid = th.taskid
join users u on u.userid = th.userid
where p_taskid IS NOT NULL and p_taskid = p.taskid
group by ch.taskid, p.taskid
union all
select t.taskid::integer as Id
,null::integer as ParentId
,concat('javascript:void(window.static.taskClick(',t.TaskId,',',t.TaskId,'))' )::character varying as TaskUrl
,t.tasktext::character varying as TaskName
,t.statename::character varying as StateName
,to_char(t.createdtime, 'DD.MM.YYYY')::character varying as CreatedTime
,to_char(t.orderedtime, 'DD.MM.YYYY')::character varying as OrderedTime
,string_agg(u.displayname,',')::character varying as THelpers
,true HasChildren
from tasksinsubcat33denormalized t
left join taskhelpers th on t.taskid = th.taskid
join users u on u.userid = th.userid
where p_taskid IS NULL
group by t.taskid
;
END;
$BODY$
;
Описание настроек иерархии задач в прежнем интерфейсе администрирования