Цель: запретить указывать assigned user на itsm_request и itsm_incident, и дочерних таблицах от таблицы itsm_task Причина: Могут быть группы которые нельзя ставить assigned_group, например определенные клиенты
По ошибке исполнитель может поставить данную группу
Мы должны ограничить исполнителя, чтобы он по ошибке не указал запрещенную группу Реализация:
Cоздаем sys_property itsm_request.prohibited_assignment_group
В него пишем как value id через запятую запрещенных групп
Пример Value:
168062193321633404, 158322385617794827, 164397464423049378 Создаем Business Rule Business Rule
Name: Prohibition Assignment Group
Table: itsm_task
Active: true
Inheritance: true
Advanced: true
When : before
order : 999
Action : insert true
Action : Update true
Action : Delete false
Cкрипт в advanced поле:
(function executeRule(current, previous = null /*not null only when action is update*/) {
let assignment_group = current.assignment_group.sys_id;
let prohibitedGroup = ss.getProperty('itsm_request.prohibited_assignment_group');// typeof string
let arrayOfGroups = prohibitedGroup
.replace(/\s/g, "")// Удаляем пробелы
.split(",");// Делаем массив
function isVariableInArray(variable, array) { // Функция для проверки есть ли переменная в массиве
return array.includes(variable);
}
if (isVariableInArray(assignment_group, arrayOfGroups) === true) {
const message = new SimpleMessage();
ss.addErrorMessage(message.getMessage('Reassignment to this group is prohibited'));
current.setAbortAction(true)
}
})(current, previous);
Также создаем source Message “Reassignment to this group is prohibited”
К нему 2 message
Language en “Reassignment to this group is prohibited”
Language ru “Переназначение на данную группу запрещено”
После создания Business Rule, будет запрещено переназначение на группы из property itsm_request.prohibited_assignment_group
В агентском интерфейсе при попытке назначить данную группу
будет показано сообщение-предупреждение
Круть! Спасибо, что делитесь наработками с сообществом SimpleOne!
Небольшой улучшайзинг:
Для того, чтобы этот кусочек кода отрабатывал без ошибок и только, когда нужно, рекомендую в Condition Business Rule (сейчас пустой?) добавить:
Assignment Group CHANGES
AND
Assignment Group is NOT EMPTY
Также, рекомендую изменить Order этого бизнес-правила на более маленький, чтобы не допустить каких-до действий другими onBefore Insert/Update BR до его срабатывания. Например, Order = 10.
[Перфекционизм mode = on]
В строке “current.setAbortAction(true)” не хватает точки с запятой.
[Перфекционизм mode = off]
И поделюсь еще одним вариантом с ограничением, при котором исполнитель даже не увидит запрещенные группы для назначения и не будет соблазна их выбрать). Можно добавить флаг на уровне Группы “Запретить назначение” и через column override переопределить reference qualifier на поле assignment_group таким образом, чтобы исключить группы, где установлен данный флаг.
А сам флаг возможно и в аналитке в дальнейшем пригодится).
Либо, если флаг лишнее, все в том же reference qualifier опираться на пропертис.
Разовью идею Алексея, и расскажу как фильтрацию групп
делаем мы.
Т.к. справочник групп универсальный и может использоваться в разных процессах (IM, Req, ChM) и даже механизмах (группы согласования, например), чтобы ограничить список доступных пользователю значений для выбора, в группу добавляется классификатор, который определяет список объектов для которых текущая группа будет доступна: инциденты, проблемы, запросы, группа согласования и т.п.
Далее для поля Рабочая группа в динамическом фильтре таблицы, как правило, Task, задаём свои условия фильтрации с учётом процесса. Т.к. нужно будет заменять вендорский скрипт фильтра (“динамический определитель ссылок”) на свой, к которому нет доступа в Task-е, используем переопределение для поля рабочая группа.
А как дописать в скрипт к динамическому фильтру, что показывать нужно только группы, где есть пользователи, а если пользователей нет, то группа не доступна для выбора и отображения?
Это текущий скрипт настройки динамических фильтров, его надо дополнить, но как?
if (current.getValue('assigned_user')) {
const listOfGrop = [];
const userHasGroup = new SimpleRecord('sys_user_group');
userHasGroup.addQuery('user_id', current.getValue('assigned_user'));
userHasGroup.query();
while (userHasGroup.next()) {
listOfGrop.push(userHasGroup.getValue('group_id'))
}
return listOfGrop;
}
return '()';
Если вопрос еще актуален, то я бы сделал так) Поскольку групп может быть сколько угодно я бы изначально всё это обернул во внешний скрипт, чтобы мы случайно не уперлись в максимальную длину url запроса, и вызывал бы оттуда.
Сам скрипт динамического фильтра:
(function executeDynamicScript(current = null /*null for scripts used in filters*/ ) {
return `(sys_idINjavascript: { ss.importIncludeScript('getGroupsWithMembers'); return getGroupsWithMembers('${current.getValue("assigned_user")}')})`;
})(current)
И собственно сам внешний скрипт:
function getGroupsWithMembers(userId = null) {
let listOfGrop = [];
if (userId) {
const userHasGroup = new SimpleRecord("sys_user_group");
userHasGroup.addQuery("user_id", userId);
userHasGroup.query();
while (userHasGroup.next()) {
listOfGrop.push(userHasGroup.getValue("group_id"));
}
} else {
const allGroups = new SimpleRecord("sys_user_group");
allGroups.selectAttributes('group_id');
allGroups.query();
const uniqGroups = new Set();
while (allGroups.next()) {
const groupId = allGroups.getValue("group_id");
uniqGroups.add(groupId);
}
listOfGrop = [...uniqGroups];
}
return listOfGrop;
}