Возможность запрета передачи обращений на конкретную группу

Цель: запретить указывать 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

  1. Language en “Reassignment to this group is prohibited”
  2. Language ru “Переназначение на данную группу запрещено”

После создания Business Rule, будет запрещено переназначение на группы из property itsm_request.prohibited_assignment_group
В агентском интерфейсе при попытке назначить данную группу
будет показано сообщение-предупреждение

4 лайка

Круть! Спасибо, что делитесь наработками с сообществом 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]

C уважением, Никита

3 лайка

И поделюсь еще одним вариантом с ограничением, при котором исполнитель даже не увидит запрещенные группы для назначения и не будет соблазна их выбрать). Можно добавить флаг на уровне Группы “Запретить назначение” и через column override переопределить reference qualifier на поле assignment_group таким образом, чтобы исключить группы, где установлен данный флаг.
А сам флаг возможно и в аналитке в дальнейшем пригодится).
Либо, если флаг лишнее, все в том же reference qualifier опираться на пропертис.

7 лайков

Разовью идею Алексея, и расскажу как фильтрацию групп
делаем мы.

Т.к. справочник групп универсальный и может использоваться в разных процессах (IM, Req, ChM) и даже механизмах (группы согласования, например), чтобы ограничить список доступных пользователю значений для выбора, в группу добавляется классификатор, который определяет список объектов для которых текущая группа будет доступна: инциденты, проблемы, запросы, группа согласования и т.п.

Далее для поля Рабочая группа в динамическом фильтре таблицы, как правило, Task, задаём свои условия фильтрации с учётом процесса. Т.к. нужно будет заменять вендорский скрипт фильтра (“динамический определитель ссылок”) на свой, к которому нет доступа в Task-е, используем переопределение для поля рабочая группа.

Такой вариант не сложен при расширении функционала, и в дальнейшем проще в сопровождении.

4 лайка

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

Это текущий скрипт настройки динамических фильтров, его надо дополнить, но как?

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 '()';

})(current)

Если вопрос еще актуален, то я бы сделал так) Поскольку групп может быть сколько угодно я бы изначально всё это обернул во внешний скрипт, чтобы мы случайно не уперлись в максимальную длину 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;
}
1 лайк