Бизнес-процесс над элементом списка - поля, раздел, PHP-код
Читаем поля документа в бизнес-процессе, добираем то, чего в них нет, и разбираемся с полями типа «список».
Решение
Получаем раздел элемента действием PHP-код:
// третий элемент идентификатора документа - это номер самого элемента$element = CIBlockElement::GetList([], ['ID' => $this->GetDocumentId()[2]], false, false, ['ID', 'IBLOCK_SECTION_ID'])->Fetch();$section = CIBlockSection::GetByID($element['IBLOCK_SECTION_ID'])->Fetch();$this->SetVariable('SectionName', $section['NAME'] ?? '');Идентификатор документа приходит массивом из трёх частей: модуль, тип документа и сам идентификатор. Третий элемент и есть то, что нужно передавать в выборки.
Читаем поле типа «список» и приводим к подписи:
$value = $this->GetVariable('Status'); // здесь идентификатор значения$enum = CIBlockPropertyEnum::GetByID($value);$this->SetVariable('StatusText', $enum['VALUE'] ?? '');В переменной лежит идентификатор, а не текст. Условие, сравнивающее её со строкой, не сработает никогда, и процесс тихо уйдёт по ветке «иначе».
Ставим задачу участнику и разбираем результат:
// поле задачи «Ответственный» принимает массив вида ['user_12', 'group_5']$this->SetVariable('Approver', ['user_' . $userId]);Задача уходит всем перечисленным, а процесс ждёт ответа. Делегирование меняет исполнителя, но не автора: смотреть, кто фактически ответил, надо в результате задачи, а не в поле ответственного.
Запускаем процесс из кода:
CBPDocument::StartWorkflow( $templateId, ['lists', 'BizprocDocument', $elementId], // тип документа и его идентификатор ['Approver' => ['user_' . $userId]], // параметры запуска $errors);Так процессы стартуют по событию, по расписанию или из внешней системы. Массив ошибок заполняется, если шаблон не найден или параметры не сошлись с его объявлением.
Смотрим, какие процессы уже идут по документу:
$running = CBPStateService::GetDocumentStates(['lists', 'BizprocDocument', $elementId]);foreach ($running as $state) { printf("%-28s шаблон=%s состояние=%s\n", $state['TEMPLATE_NAME'], $state['TEMPLATE_ID'], $state['STATE_TITLE']);}Один документ может быть занят несколькими процессами сразу, и они ничего не знают друг о друге. Проверка перед стартом избавляет от пары одинаковых согласований на одном элементе.
Читаем журнал экземпляра при разборе:
$log = CBPTrackingService::GetList([], ['WORKFLOW_ID' => $workflowId], false, false, ['MODIFIED', 'ACTION_NAME', 'ACTION_NOTE']);while ($row = $log->Fetch()) { printf("%s %-24s %s\n", $row['MODIFIED'], $row['ACTION_NAME'], $row['ACTION_NOTE']);}Каждая строка - шаг экземпляра с параметрами и результатом. По ней видно, какая ветка условия выбрана и с каким значением переменной.
Отладка процессов держится на журнале. Каждый шаг экземпляра пишется туда с параметрами, и по нему видно, какая ветка условия выбрана и с каким значением переменной. Без журнала процесс - чёрный ящик: он либо дошёл до конца, либо нет, а почему свернул не туда, узнать неоткуда.
Типичные проблемы
Условие по полю типа «список» никогда не выполняется.
В переменной идентификатор значения, а в условии написана подпись. Сравнивают идентификаторы либо заранее приводят значение к тексту отдельным шагом.
Правка шаблона не подействовала на идущий процесс.
Экземпляр хранит копию шаблона на момент старта. Новую версию получат только процессы, запущенные после правки: уже идущие доигрывают по старой.
Переменная типа «список» не сохраняется из PHP-кода.
Записывается подпись вместо идентификатора. Тип переменной проверяется при записи, и несовпадение молча даёт пустое значение.
Процесс не видит раздел элемента.
Раздел не входит в поля документа. Его добирают действием PHP-код по идентификатору элемента и кладут в переменную процесса.
Задача ушла не тому.
В поле ответственного передан идентификатор без префикса. Модуль ждёт строку вида user_12 или group_5, а голое число трактует иначе.
Частые вопросы
Что доступно внутри действия PHP-код?
Всё API платформы: код выполняется на сервере в контексте процесса. Через $this доступны переменные процесса и идентификатор документа, остальное берут обычными вызовами.
Как получить элементы списка, не зная их идентификаторов?
Обычной выборкой по инфоблоку списка с нужным фильтром. Списки хранятся в инфоблоках, и весь их API - это API инфоблоков.
Можно ли динамически заполнить варианты у переменной-списка?
Штатно варианты задаются при объявлении переменной. Динамический набор делают строковой переменной и своим действием выбора либо отдельным справочником в списке.
Как узнать, кому делегирована задача?
Из результата задачи: там сохраняется фактический исполнитель. Поле ответственного при делегировании не меняется и продолжает показывать исходного адресата.
Смежное
-
Бизнес-процессы - оглавление подтемы
-
Универсальные списки - где живут документы процессов
-
Бизнес-процессы - устройство модуля целиком
-
Задача в бизнес-процессе: назначение, сроки, ответ участника - как процесс ждёт человека
-
PHP-код в бизнес-процессе: переменные, типы, отладка - свой код внутри схемы
-
Бизнес-процесс не запускается или стоит: разбор причин - когда процесс над списком не стартует
-
Поля документа в процессе: списки, файлы, запись обратно - поля документа и их значения
-
Список как справочник: поля, права, вывод и наполнение - откуда берутся эти элементы
-
Перенос бизнес-процесса между стендами: шаблон, привязка, права - как этот процесс уедет на боевой сайт