Как сделать автозамену любого блока действий, переменной, условия, константы в бизнес-процессе коробочного Битрикс 24

от автора

Как у меня возникла идея это реализовать?

После очередного обновления коробочного портала Битрикс 24 в марте 2023г, в бизнес процессах, перестала работать модификация типов при присвоении значения строковым переменным.

Например, при присвоении переменной «Variable1» значения «{{Начальная сумма > double}}|{{Валюта > user}}» в блоке «Изменение переменных» бизнес процесса, модификатор » > double» преобразует нам тип поля «Деньги» (вида 100|RUB) по правилам преобразования строки в «Число» — 100, а из поля «Валюта» модификатор » > user» всегда выдавал код валюты — «RUB». Таким образом это преобразование должно присвоить переменной «Variable1» значение вида «100|RUB». А после обновления выдаёт «100|RUB|Российсий рубль«.

Однако после злополучного обновления, и по сей день, кстати, эти модификаторы перестали работать, конкретно при присвоении значения переменной типа «Строка», во всех остальных случаях, включая блок действия «Уведомление» — работает!

Для того чтобы данное преобразование сработало в бизнес процессе после обновления, требуется «обернуть» модификаторы в другую функцию, так как ещё раз повторюсь, не работает модификация только со строковыми переменными.

Я для этого использовал функцию «trim()», в итоге получаем следующую запись:

 {{trim({{Начальная сумма > double}}&"|"&{{Валюта > user}})}}

Такой метод реализации модификаторов работает как «до», так и «после» злополучного обновления.

Отсюда у меня и возникла потребность подменить данную запись у одного из клиентов более, чем в четырехстах бизнес процессах! При этом, многие бизнес-процессы, содержат сотни действий, в десятках веток условий. Вероятность пропустить подобную запись, при ручном изнуряющем редактировании, стремится к 100%!

Порядок реализации автозамены чего-либо в одном, либо во всех бизнес процессах

  1. Получаем шаблон(ы) бизнес процесса в виде многомерного массива.

  2. Используем функцию поиска по нужным критериям и модификации действия.

Реализуем п.1 (получаем шаблоны)

В документации Битрикс 24, ни как не описан функционал получения шаблонов бизнес‑процессов в виде массивов данных, есть только описание, что они именно таким образом хранятся. Поэтому помощь пришла из другой полезной статьи на ХАБРе про перенос бизнес-процессов.

Итак к коду.

Получение одного или нескольких шаблонов бизнес процессов:

$resFields = \CBPWorkflowTemplateLoader::GetList(     [],     ['ID' => 474], //для получения всех шаблонов, оставляем пустым    // ['USER_ID' => 34], //для получения всех шаблонов, одного создателя     false, //arGroupBy - массив группировать "по"     false, //arNavStartParams - навигация по получемым массивам параметров     ['ID', 'NAME', 'TEMPLATE', 'VARIABLES']); //нам нужны только шаблоны,  //однако для фильтрации нужных значений понадобится типы переменных,  //а для отладки ID и имена БП

Дальше перебираем полученный результат:

while ($arFields = $resFields->GetNext()) {     if (!is_array($arFields)) {         echo "Из базы ничего не пришло!";         break;     }     //ниже 4 строчки которыми я убираю дополнительно пришедшие из БД дубликаты массивов     unset($arFields['~ID']);     unset($arFields['~NAME']);     unset($arFields['~TEMPLATE']);     unset($arFields['~VARIABLES']);     //помещаем в отдельные массивы шаблоны и переменные БП     $arTemplate = $arFields['TEMPLATE'];      $arVariables = $arFields['VARIABLES'];     /*дальше я прохожусь функией по всему массиву,      т.к. я не знаю какова страутура многомерного массива,      какие названия переменных и сколько раз им назначаются значения в БП     callback функцию "changeNeedleStringInArray", приведу ниже */     array_walk($arTemplate, 'changeNeedleStringInArray');      $arNewFields['TEMPLATE'] = $arTemplate;     //без поля "MODIFIER_USER" - сохранение не срабатывает, выдаёт ошибку совершенно на этот факт не указывающую     $arNewFields["MODIFIER_USER"] = new \CBPWorkflowTemplateUser(CBPWorkflowTemplateUser::CurrentUser);     \CBPWorkflowTemplateLoader::update($arFields['ID'], $arNewFields);     //чистим память     unset($arFields);     unset($arNewFields);     unset($arTemplate);     unset($arVariables); } //выводим строки для проверки дебага результата echo "<pre>"; if (!empty($convert)) {     print_r(count($convert));     print_r(PHP_EOL);     print_r($convert); } 

Реализуем п.2 (поиск и модификацию)

Выполняем преобразования в функции ‘changeNeedleStringInArray‘, у меня будет ниже 3 примера:
1. Исправляем проблему описанную в начале статьи.{{Начальная сумма > double}}|{{Валюта > user}}преобразуем в {{trim({{Начальная сумма > double}}&"|"&{{Валюта > user}})}}

/*  */ function changeNeedleStringInArray(&$val, $key) {     if (is_array($val)) {         array_walk($val, 'changeNeedleStringInArray'); //заходим этой же функцией во вложенный массив     } elseif (is_string($val)) {         if (stripos($val, '|{=Document:CURRENCY_ID > user')  // ищем нужное значение в действии БП             && !stripos($val, '{{=trim') //проверяем не сделано ли уже нужное нам преобразование             && (isVarTypeString($key)) //проверяем тип переменной (нам надо менять только в строках)         ) {             $val = convertActivityValue($val, $key);         }     } } function isVarTypeString($key) {     global $arVariables;     if ($arVariables[$key]['Type'] == 'string')         return true;     return false;  }  function convertActivityValue($str, $key) {     global $convert, $arFields;     if (!stripos($str, "|")) //проверяем что найдена требуемая нам строка         return $str;     $arHelp = explode("|", $str);     if (stripos($arHelp[0], "=")) {         $resStr = "{{=trim(" . $arHelp[0] . "&\"|\"&" . $arHelp[1] . ")}}";     } else {         $resStr = "{{=trim(\"" . $arHelp[0] . "|\"&" . $arHelp[1] . ")}}";     }     //записываем данные в массив для отладки и тестирования     $convert[$arFields['NAME']][$arFields['ID']][$key][] = $str;     $convert[$arFields['NAME']][$arFields['ID'] . "_new"][$key][] = $resStr;     return $resStr; }
  1. С каким-то из обновлений некоторые REST запросы стали чувствительны к регистру передаваемых параметров, в частности «ID» объектов, теперь работает только в нижнем регистре «id». Точно проверено с методом удаления комментариев в timeline: crm.timeline.comment.delete Так как в некоторых БП я использовал вызовы REST посредствам curl, в качестве асинхронных вызовов, после обновлений пришлось вносить правки и тут. Исправляем '\"ID\"' на '\"id\"‘ в curl

function changeNeedleStringInArray(&$val, $key) {     if (is_array($val)) {         array_walk($val, 'changeNeedleStringInArray'); //заходим этой же функцией во вложенный массив     } elseif (is_string($val)) {         if (stripos($val, 'curl')  // ищем нужное значение в действии БП             && strpos($val, '\"ID\"') // ищем дополнительное нужное значение в действии БП             && ($key == 'ExecuteCode') //проверяем тип переменной (нам надо менять только в PHP блоках)         ) {             $val = convertActivityValue($val, $key);         }     } } function convertActivityValue($str, $key) {     global $convert, $arFields;     $resStr = str_replace('\"ID\"', '\"id\"', $str);     //записываем данные в массив для отладки и тестирования     $convert[$arFields['NAME']][$arFields['ID']][$key][] = $str;     $convert[$arFields['NAME']][$arFields['ID'] . "_new"][$key][] = $resStr;     return $resStr; }
  1. В «Уведомлениях» перестал работать BBCode с указанием цветов по их названию, типа
    [color=red]Текст[/color] — в сообщение выводится без форматирования
    но [color=#ff0000]Текст[/color] — вполне себе работает. Подменяем:

function convertActivityValue($str, $key) {     global $convert, $arFields;     $resStr = str_replace('red', '#db0000', $str);     //записываем данные в массив для отладки и тестирования     $convert[$arFields['NAME']][$arFields['ID']][$key][] = $str;     $convert[$arFields['NAME']][$arFields['ID'] . "_new"][$key][] = $resStr;     return $resStr; }  function changeNeedleStringInArray(&$val, $key) {     if (is_array($val)) {         array_walk($val, 'changeNeedleStringInArray'); //заходим этой же функцией во вложенный массив     } elseif (is_string($val)) {         if (stripos($val, '[color=red]')  // ищем нужное значение в действии БП             && ($key == 'MessageSite') //проверяем тип переменной (нам надо менять только в Уведомлениях)         ) {             $val = convertActivityValue($val, $key);         }     } }

Итоги

Таким образом мы имеем возможность вносить любые изменения в шаблоны бизнес‑процессов массово. Редактировать шаблоны не только из красивого вэб‑интрефейса, но в виде «хардкода». Так же на базе данного кода можно сделать отладку шаблонов бизнес‑процессов, или динамические изменения в них.

Уверен, что с подобными изменениями в работе бизнес процессов, сталкиваются многие интеграторы Б24.

Поэтому, думаю, что существенно облегчил нам наш нелёгкий труд, данной статьёй.


ссылка на оригинал статьи https://habr.com/ru/articles/850910/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *