Маршрут «Активация»: интерфейс и логика настройки
============================

На этом этапе мы настраиваем путь заявки при её подаче, то есть маршрут, по которому заявка пойдёт после создания и активации.

Для этого используется маршрут типа **«Активация»**.

.. admonition:: Основная рабочая область. 
    
    Редактор маршрутов состоит из трёх панелей, каждая из которых отвечает за свой тип этапов маршрута.
    
    **Панели редактора маршрутов**

    **Предварительные этапы** - содержат только стандартные процессы, которые выполняются до основных действий:

    * Работа
    * Согласование
    * Утверждение
    * Ознакомление
    * Отправка документа
    * Регистрация
    * Маршрут

    **Действия**  - ключевая часть маршрута.

    Этапы в этой панели:

    * могут автоматически получать данные из формы (по кодам компонентов);
    * изменяют объекты и состояние процесса в системе;
    * выполняются только после успешного завершения предварительных этапов (если они есть).
    
    **Последующие этапы** - также содержат только стандартные процессы и выполняются после действий (при необходимости).

Введение
----------------

Перед настройкой маршрута важно понять:

Любой шаг процесса всегда содержит 4 основные вещи:

* Роль → кто?
* Действие → что делает?
* Данные → с чем работает?
* Результат → что получается?

В системе каждый шаг бизнес-процесса превращается в:

* этап маршрута
* с ответственным
* с типом действия
* с результатом выполнения

Для того чтобы в ходе обучения не привязываться к процессу который здесь используется как пример, а закрепить знания для будущих процессов перед добавлением каждого этапа задавай себе:

* Какой это шаг процесса?
* Кто его выполняет?
* Что должно измениться после него?
* Какой нужен результат (подпись, комментарий, файл)?

.. important:: 
  Система ничего не «придумывает» сама. Задача аналитика преобразовать бизнес процесс в исполняемую логику, задав системе сценарий выполнения и необходимые данные.
    
Переход к созданию маршрута
----------------------------

**Шаг 1.** По нажатию на кнопку "+" в разделе **"Маршруты реестра"**, в выпаждающем списке выбрать тип маршрута **"Активация"**

**Шаг 2.** В открывшемся окне перейти к редактированию маршрута активации нажав кнопку редактирования:

.. image:: ../resources/img/edit.jpeg

**Шаг 3.** На панеле "Действия" нажимаем кнопку **"+"** чтобы добавить новый этап

.. figure:: ../resources/img/actions_panel.jpeg

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/YvHfLJxfkCI"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


**Шаг 4.** В открывшейся справа панели настройки этапа необходимо настроить этап в соответствии с ордером.

Каждый этап имеет свой результат выполнения (подписание, ввод комментария, автоматическое системное действие и другие операции, необходимые для бизнес-процесса)

Для того, чтобы понять какой именно тип действия нам необходим на каждом этапе, мы обращаемся к пункту ордера **2. Диаграмма процесса и шаги процесса** 

.. figure:: ../resources/img/order_process_steps.jpeg

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

Этап 1. Заполнение заявки
---------------------------

**Вход** - форма заявки, разработанная в системе и данные клиента, которые он вносит при заполнении формы.

**Выход** - заполненная по форме заявка на услугу.

На этом этапе не нужен дополнительный шаг процесса, т.к отправка заявки и будет являться первым шагом процесса.

Этап 2. Отправка заявки.
------------------------

**Вход** - подписание заявки при помощи ЭЦП.

**Выход** - заявка подписанная в системе.

Для реализации данного этапа нам потребуется тип действия **"Работа по форме"** с типом **"Согласование"**

Данный тип этапа требует указания поля из заявки, в котором будет находится текущий пользователь, создающий заявку.

Предварительная настройка
^^^^^^^^^^^^^^^^^^^^^^

**Шаг 1.** Возвращаемся в форму заявки

**Шаг 2.** Добавляем на форму компонент таблицы, и включаем для нее настройки скрытности, чтобы системные поля не отображались пользователю

**Шаг 3.** Внутрь таблицы добавляем компонент **"Объекты Synergy"**

* задаем ему код например "entity_author"

* включаем настройку **"Заполнять текущим пользователем"**

**Шаг 4.** Полю задаем наименование "Автор"

**Шаг 5.** Сохраняем изменения
    
В результате этого, поле автоматически будет заполняться учетной записью пользователя, создавшего заявку.

Создание этапа маршрута
^^^^^^^^^^^^^^^^^^^^^

**Шаг 1.** В настройках этапа указываем 

* Тип действия - "Работа по форме"
* Название этапа - указываем согласно логике шага, например "Подписание заявки"
* Код этапа - необязательно, используется при обращении к этапу в скриптах или условиях.
* Ответственный - здесь необходимо указать код поля в котором будет находится автор заявки (entity_author) его мы создали в предварительном шаге 
* Тип работы - согласование
* Возврат - в этом поле указывается этап маршрута, к которому необходимо вернуться в случае отказа в согласовании (при необходимости). В нашем случае может оставить пустым.

**Шаг 2.** Сохраняем этап, нажав на иконку дискеты в панели настроек этапа.

.. figure:: ../resources/img/step1.jpeg

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/f2suSkpjfIs"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


.. note::

    Дополнительно о том как подключить модуль подписания ЭЦП http://rtd.lan.arta.kz/docs/docs-po-platforme-arta-synergy/ru/latest/signing.html

Этап 3. Регистрация заявки
----------------------------

**Вход** - подписанная в системе заявка

**Выход** - заявка со сформированным регистрационным номером

Формирование номера заявки в системе осуществляется на основе **счётчика**.

.. note:: 

    **Счётчик** — это базовая сущность системы, предназначенная для генерации последовательных числовых значений.
    Он используется для нумерации заявок, документов и других объектов.
    
Создание счетчика
^^^^^^^^^^^^^^^^^
    
**Шаг 1.** В дереве приложений выбираем папку в которой будут храниться счетчики

**Шаг 2.** Кликаем правой кнопкой мыши и выбираем Добавить → Базовые сущности → Счётчик 

**Шаг 3.** Открывается панель редактирования информации о счётчике:

.. figure:: ../resources/img/counter_new.jpeg

* **Код** - Обязательное поле. Используется для обращения к счётчику в шаблоне номера.
* **Начальное значение** - значение, с которого начинается нумерация.
* **Следующее значение** - должно быть не меньше начального.
* **Период сброса** - определяет, когда следующее значение будет сбрасываться к начальному.
Возможные варианты:

    * Никогда (по умолчанию)
    * Каждый день
    * Каждую неделю
    * Каждый месяц
    * Каждый год

**Шаг 4.** Вводим необходимые значения и нажимаем кнопку "Сохранить"

.. figure:: ../resources/img/counter.jpeg

После создания счетчика нам необходимо привязать его к шаблону номера, который мы потом поместим на форму.

Привязка счетчика к шаблону номера
^^^^^^^^^^^^^

**Шаг 1.** Выбрав нужную папку кликаем по ней правой кнопкой мыши Добавить → Документооборот → Шаблон номера

**Шаг 2.** В открывшемся окне создания шаблона номера указываем:

    * Наименование - название счетчика или его назначение (например "Номер заявки на услуги ATLAS")
    * Код - ставим логический код или оставляем автоматически сгенерированный транслит
    * Значение - помещаем сюда код ранее созданного нами счетчика в формате {код_счетчика}

.. figure:: ../resources/img/number_template.jpeg

**Шаг 3.** Сохраняем шаблон номера.

Добавление шаблона номера на форму
^^^^^^^^^^^^^^^^^

**Шаг 1.** Возвращаемся к форме заявки

**Шаг 2.** В поле **"Порядковый номер заявки"** выделяем его компонент **"Номер"**

**Шаг 3.** В строке **"Шаблон номера"** выбираем созданный нами шаблон

.. figure:: ../resources/img/number_template_in_form.jpeg

**Шаг 4.** Сохраняем форму

Сгенирированный автоматически номер будет являться регистрацией заявки в системе.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/he_OPl19sXU"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


Этап 3. Отправка уведомления о номере заказа.
----------------------------------------------

**Вход** - подписанная ЭЦП и зарегистрированная в системе заявка на услугу

**Выход** - уведомление на почту клиента

 На данном этапе на почту клиента отправляется уведомление о регистрации заявки с указанием её номера.
 
**Шаг 1.** В редакторе маршрута нажимаем кнопку "+" для добавления нового этапа
 
**Шаг 2.** В настройках этапа выбираем тип действия **"Отправка письма на почту"**
 
**Шаг 3.** Указываем:
 
 * Наименование этапа, например **"Отправка уведомления о номере заказа"**
 * Код - указывается при необходимости
 * Код поля на форме - подразумевает поле на форме с почтой клиента, на которую необходимо отправить уведомление. У нас например это textbox_mail
 * Тема письма с поддержкой HTML разметки - будет содержать тему письма
 * Тело письма с поддержкой HTML разметки - будет содержать основной текст письма с данными из нужных нам полей
 
 В нашем случае, согласно ТЗ (ордера) HTML шаблон письма будет выглядеть следующим образом:
 
 ``Ваша заявка на “ +  $listbox_type + ” зарегистрирована под номером “  + $counter_number + ”.``
 
* где ``listbox_type`` - код поля **"Тип заявки"**
* ``counter_number`` - код поля **"Номер заявки"**
*  **"Ваша заявка на"** и **"зарегистрирована под номером"** - это статический текст, который будет одинаковым в каждом письме.
* Символ $ - обращение к переменной.
Символ $ обязательный и означает, что далее указывается переменная, значение которой будет взято из данных заявки:

    *	$listbox_type — значение поля Тип заявки
    *	$counter_number — значение номера заявки, сформированного счётчиком

Во время отправки письма система автоматически подставляет фактические значения этих полей из данных заявки.

.. figure:: ../resources/img/step3_notification.jpeg

**Шаг 3.** Проверяем корректность письма и сохраняем этап.
 
.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/b3G2c7BuYlA"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>
 
 
 .. note::
    Кнопка **«Отправить тестовое письмо»** позволяет проверить работу уведомления прямо из маршрута, отправкой уведомления на почту. (Для этого в приложении должна быть настроена почтовая служба). После нажатия на кнопку система предложит выбрать уже созданную заявку в реестре, для того чтобы отправить письмо на указанную в заявке почту.

Этап 4. Назначение исполнителя
-------------------------------

**Вход** - заявка поступившая менеджеру

**Выход** - заявка с назначенным по ней исполнителем

Для реализации данного шага, будем использовать тип **"Работа по форме"**

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

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

Предварительная настройка
^^^^^^^^^^^^^^^^^

**Шаг 1.** Возвращаемся на форму

**Шаг 2.** В скрытой таблице под полем "Автор" добавляем еще одно поле **"Менеджер"** с компонентом **"Объекты Synergy"**

**Шаг 3.** В настройках компонента присваиваем ему код содержащий смысловую нагрузку (например entity_manager) и в настройке **"Тип данных"** выбираем тип "Пользователь", «Должности» либо «Подразделения».

.. note:: 
    Если мы хотим чтобы заявка на данном этапе падала конкретному человеку  – мы прикрепляем к заявке конкретно его учетную запись, выбрав для этого тип данных **«Пользователь»** и выбрав в поле конкретного человека.
    
    Если же, в системе имеется должность, с назначенными на нее пользователями, отвечающими за определенную работу, то используется тип данных **«Должности»**, в котором указывается должность и работа будет падать всем пользователям, состоящим на данной должности.
    
    Если необходимо направлять работу целому подразделению, с вложенными в него должностями, то используется тип данных **«Подразделения»**, тогда работа будет поступать всем людям, состоящим на всех вложенных должностях выбранного подразделения.

.. figure:: ../resources/img/field_manager.jpeg

    Пример созданного поля с предзаполненным пользователем
    
**Шаг 4.** Сохраняем форму

Создание этапа маршрута
^^^^^^^^^^^^^^^^^

**Шаг 1.** В редакторе маршрута нажимаем кнопку **"+"** на панели "Действия"

**Шаг 2.** В настройках этапа указываем:

* Тип действия - работа по форме
* Название этапа - назначение исполнителя
* Ответственный - указываем код созданного нами поля с менеджером (например у нас это entity_manager)
* Тип работы - "Работа"
* Включаем настройку "Использовать форму завершения"

.. admonition:: Форма завершения.

    Форма завершения — это модальное окно, которое открывается при выполнении работы и определяет, что должен сделать пользователь для завершения этапа.
    Существует несколько типов форм завершения:
    
    * Комментарий — результатом является комментарий.
    * Файл — результатом является файл (с устройства, из хранилища или из приложений работы).
    * Документ — выбор или создание документа, связанного с работой.
    * Форма — заполнение отдельной формы (используется в нашем случае).
    * Без результата — завершение без результата.
    
    Подробнее о формах завершения http://rtd.lan.arta.kz/docs/docs-po-platforme-arta-synergy/ru/latest/completion_form.html
    
Создание формы завершения
^^^^^^^^^^^^^^^^^^^^

**Шаг 1.** Создаем отдельную форму кликнув правой кнопкой мыши по нужной папке → Добавить → Базовые сущности → Форма.

**Шаг 2.** Задаем форме:

* понятное наименование, отличающее её от основной формы
* аналогичный код

**Шаг 3.** Добавляем поле для указания исполнителя:

* Наименование - Исполнитель
* компонент «Объекты Synergy»

.. figure:: ../resources/img/completion_form.jpeg

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

**Шаг 4.** Сохраняем форму. 

Привязка формы завершения к этапу
^^^^^^^^^^^^^^^

**Шаг 1.** Возвращаемся к настройке этапа **"Назначение исполнителя"**

**Шаг 2.** В строке **«Форма завершения»** нажимаем кнопку «+».
В открывшемся окне:

* выбираем тип завершения «Форма»;
* задаём код и наименование (для удобства делаем их аналогичными созданной форме);
* в поле «Форма» выбираем созданную форму.

.. figure:: ../resources/img/step_fz.jpeg

**Шаг 3.** Сохраняем этап.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/OSBg56P0-ik"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


.. important:: 
    Если работа направляется на **должность** или **подразделение** необходимо включить настройку: **«Прервать выполнение параллельных этапов после завершения одного из них»**.
    Иначе каждому пользователю потребуется выполнить назначение исполнителя, прежде чем маршрут продолжится.
    
.. admonition:: ПРИМЕЧАНИЕ

    Т.к форма завершения является отдельной сущностью, данные, введенные в форму завершения не попадают в основную форму автоматически. Для дальнейшего использования данных, введенных в форму завершения, их нужно перенести в основную форму при помощи отдельного этапа **«Блокирующий процесс»**. Подробно будет описано в этапе 5
    
Этап 5. Смена статуса заявки
-----------------------------

**Вход** - заявка с назначенным по ней исполнителем

**Выход** - заявка со статусом "в работе"

Смена статуса выполняется автоматически с помощью скрипта интерпретатора, запускаемого этапом маршрута типа **«Блокирующий процесс»**.

.. note:: **Скрипт интерпретатора** - это программный код на JavaScript внутри системы Synergy, который выполняется без компиляции и позволяет автоматизировать логику работы системы.
    Он используется для расчетов, обработки данных форм и карточек, а также для реакции на внутренние события системы.
    Скрипт выполняется сразу при запуске или событии и возвращает результат выполнения системе.

    Подробнее о том, что такое скрипт интерпретатора http://rtd.lan.arta.kz/docs/guide/ru/minsky/interpreter.html
    
Создание скрипта интерпретатора
^^^^^^^^^^^^^^^^^^^^^^^^^^

**Шаг 1.** В дереве приложения выбираем папку для хранения скриптов.
Для удобства это может быть:

* папка integrations,
* либо можно создать отдельную папку block_processes.    

**Шаг 2.** Кликаем по папке правой кнопкой мыши → Добавить → Интеграция → Скрипт интерпретатора.

**Шаг 3.** В открывшемся окне редактирования кода указываем:

* Наименование - Система автоматически задаёт базовый префикс ``event.blocking.interpreter``
Необходимо дополнить наименование и код, используя латинские буквы и отражая логику работы скрипта. Например ``event.blocking.interpreter.change.status_work``

* Код - формируется автоматически из наименования
* Описание - добавляется при необходимости для пояснения логики работы скрипта
* Комментарий по умолчанию - обязательная настройка, это сообщение которое система выведет после выполнения скрипта. (например "ОК" или "Статус изменен")
* Авторизация - скрипту для срабатывания необходимы права доступа. Здесь имеется два варианта 
        * По логину и паролю - понадобится логин и пароль учетной записи с правами администратора
        * По ключу - понадобится ключ администратора
        
**Шаг 4.** Выбираем тип авторизации **"По логину и паролю"** и указываем учетную запись администратора

.. important:: При смене логина и пароля учетной записи администратора логин и пароль нужно будет обновить во всех скриптах интерпретатора, использующих эту учетную запись

**Шаг 5.** В редактор кода вставляем стандартный скрипт для смены статуса

.. code-block:: javascript

 var result = true;
 var message = 'Смена значения статуса';
  try {
    var form = platform.getFormsManager().getFormData(dataUUID);
    form.load();
    form.setValue('код справочника', 'код значения');
    form.save();
 } catch (e) {
   result = false;
   message = e.message;
 }

**Шаг 3.** Вместо слов:

*  **"код справочника"** - указываем код поля в котором находится выпадающий список статусов, например у нас это ``listbox_status``
*  **"код значения"** - значение, на которое должен смениться статус, согласно справочнику у нас это значение 4 ("В работе")

.. figure:: ../resources/img/listbox_status.jpeg

Если все сделано правильно, код будет выглядеть так:

.. figure:: ../resources/img/script_status_work.jpeg

**Шаг 4.** Сохраняем скрипт интерпретатора и возвращаемся к настройке этапа

Создание этапа маршрута
^^^^^^^^^^^^^^^^^^^

**Шаг 1.** В маршруте добавляем новый этап.

**Шаг 2.** В настройках этапа:

* указываем наименование этапа (например, «Смена статуса на "В работе"»);
* в поле **«Событие»** вставляем название созданного скрипта интерпретатора.

.. figure:: ../resources/img/step_status_work.jpeg

**Шаг 3.** Сохраняем этап.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/veKH-nlP9pw"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


Скрипт интерпретатора для этапа 4
^^^^^^^^^^^^^^^^^^^^^^^^

Теперь когда мы умеем добавлять блокирующий процесс в маршрут, создаем еще один скрипт интерпретатора для переноса данных из формы завершения этапа 4 в основную форму.

**Шаг 1.** Для начала добавляем на основную форму заявки поле **«Исполнитель»** из формы завершения. Поле должно иметь аналогичный код.

.. figure:: ../resources/img/entity_responsible.jpeg


**Шаг 2.** Сохраняем форму заявки

**Шаг 3.** Правой кнопкой мыши по нужной папке → добавить → интеграция → скрипт интерпретатора

**Шаг 4.** В редактор кода добавляем скрипт, который переносит данные с формы завершения на основную форму:

Пример такого блокирующего процесса:

.. code-block:: javascript

   var result = true;
   var message = 'ok';

   function getHttpClient() {
     let client = new org.apache.commons.httpclient.HttpClient();
     let creds = new org.apache.commons.httpclient.UsernamePasswordCredentials(login, password);
     client.getParams().setAuthenticationPreemptive(true);
     client.getState().setCredentials(org.apache.commons.httpclient.auth.AuthScope.ANY, creds);
     return client;
   }

   function httpGetMethod(methods, type) {
     let client = getHttpClient();
     let get = new org.apache.commons.httpclient.methods.GetMethod(
       "http://127.0.0.1:8080/Synergy/" + methods
     );
     get.setRequestHeader("Content-type", "application/json");
     client.executeMethod(get);
     let resp = get.getResponseBodyAsString();
     get.releaseConnection();
     return type == 'text' ? resp : JSON.parse(resp);
   }

   function httpPostMethod(methods, params, contentType) {
     let client = getHttpClient();
     let post = new org.apache.commons.httpclient.methods.PostMethod(
       "http://127.0.0.1:8080/Synergy/" + methods
     );

     if (contentType) {
       post.setRequestBody(JSON.stringify(params));
     } else {
       for (let key in params) post.addParameter(key, params[key]);
     }

     post.setRequestHeader(
       "Content-type",
       contentType || "application/x-www-form-urlencoded; charset=utf-8"
     );

     let resp = client.executeMethod(post);

     if (contentType) {
       resp = JSON.parse(post.getResponseBodyAsString());
     }

     post.releaseConnection();
     return resp;
   }

   function getProcesses(documentID) {
     return httpGetMethod("rest/api/workflow/get_execution_process?documentID=" + documentID);
   }

   function getWorkCompletionData(workID) {
     return httpGetMethod("rest/api/workflow/work/get_completion_data?workID=" + workID);
   }

   function getFormData(asfDataId) {
     return httpGetMethod("rest/api/asforms/data/" + asfDataId);
   }

   function mergeFormData(uuid, data) {
     return httpPostMethod(
       "rest/api/asforms/data/merge",
       {
         uuid: uuid,
         data: data
       },
       "application/json; charset=utf-8"
     );
   }

   let UTILS = {
     createField: function (fieldData) {
       let field = {};
       for (let key in fieldData) field[key] = fieldData[key];
       return field;
     },

     getValue: function (data, cmpID) {
       data = data.data ? data.data : data;
       for (let i = 0; i < data.length; i++) {
         if (data[i].id === cmpID) return data[i];
       }
       return null;
     },

     setValue: function (asfData, cmpID, data) {
       let field = this.getValue(asfData, cmpID);

       if (field) {
         for (let key in data) {
           if (key === 'id' || key === 'type') continue;
           field[key] = data[key];
         }
         return field;
       } else {
         asfData = asfData.data ? asfData.data : asfData;
         field = this.createField(data);
         field.id = cmpID;
         asfData.push(field);
         return field;
       }
     }
   };

   function processesFilter(processes) {
     let result = [];

     function search(p) {
       p.forEach(function (x) {
         if (x.typeID == 'ASSIGNMENT_ITEM' && x.finished) result.push(x);
         if (x.subProcesses.length > 0) search(x.subProcesses);
       });
     }

     search(processes);

     return result.sort(function (a, b) {
       return new Date(b.finished) - new Date(a.finished);
     });
   }

   try {
     let processes = processesFilter(getProcesses(documentID));

     if (!processes.length) throw new Error('Не найденно завершенной работы');

     let resultFormWork = getWorkCompletionData(processes[0].actionID);

     if (!resultFormWork || !resultFormWork.result.hasOwnProperty('dataUUID')) {
       throw new Error('Не найдена форма завершения');
     }

     let completionFormData = getFormData(resultFormWork.result.dataUUID);

     let newFormData = [];
     let matching = [];

     // поля для сопоставления с фз на основную форму
     matching.push({ from: 'поле на форме завершения', to: 'поле основной формы' });

     matching.forEach(function (id) {
       let fromData = UTILS.getValue(completionFormData, id.from);
       if (fromData) UTILS.setValue(newFormData, id.to, fromData);
     });

     mergeFormData(dataUUID, newFormData);

   } catch (err) {
     message = err.message;
   }
   
.. figure:: ../resources/img/meme_script.jpg   

**Шаг 5.** Находим в скрипте блок сопоставления полей matching и заменяем текст внутри кавычек

* from - код поля "Исполнитель" в форме завершения 
* to - код поля "Исполнитель" в осноной форме, куда переносим значение

Пример:

До:

.. figure:: ../resources/img/matching_before.jpeg

После: 

.. figure:: ../resources/img/matching_after.jpeg


**Шаг 6.** Присваиваем скрипту интерпретатора наименование, например ``event.blocking.interpreter.completion_form_responsible``

**Шаг 7.** При необходимости добавляем описание и указываем авторизационные данные как мы это делали ранее

**Шаг 8.** После того как все готово, сохраняем сущность и переходим к добавлению этапа в маршрут.

Добавление дополнительного шага для этапа 4
------------------------------------------

**Шаг 1.** Добавляем этап с типом действия "Блокирующий процесс":

* Наименование - перенос данных с формы завершения
* Событие - вставляем код созданного нами скрипта интерпретатора для переноса данных из формы завершения (``event.blocking.interpreter.completion_form_responsible``)

.. figure:: ../resources/img/step4.jpeg

**Шаг 2.** Сохраняем этап и переходим к формированию правильного порядка этапов. Нам необходимо передвинуть этап с переносом формы завершения непосредственно под этап с формой завершения.

**Шаг 3.** Для переноса этапа зажимаем кнопку переноса этапа рядом с цифрой этапа

.. image:: ../resources/img/button_dragndrop.jpeg

и двигая строку в нужное место

.. figure:: ../resources/img/steps.jpeg

Теперь все этапы располагаются в правильном порядке.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/CgS9Mpe6nIA"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>

Этап 6. Отправка уведомления заявителю о смене статуса заявки
--------------------------------------------------

**Вход** - заявка со статусом "В работе"

**Выход** - уведомление заявителю о смене статуса

Здесь мы используем уже знакомый нам этап **"Отправка письма на почту"**

**Шаг 1.** В редакторе маршрута нажимаем кнопку «+» для добавления нового этапа.

**Шаг 2.** В настройках этапа выбираем:

* Тип действия — Отправка письма на почту;
* Название этапа — "Уведомление о смене статуса заявки";
* Код этапа — при необходимости.
* Код поля на форме- Указываем поле формы, содержащее адрес электронной почты заявителя. В нашем случае — ``textbox_mail``.
* Тема письма (с поддержкой HTML-разметки) - "Изменен статус заявки на услуги компании Atlas"
* Тело письма (с поддержкой HTML-разметки) - "Ваша заявка на " + $listbox_type + " под номером " + $counter_number + " принята в работу"

.. figure:: ../resources/img/step6.jpeg

**Шаг 3.** Сохраняем этап

Этап 7. Проверка типа услуги
-----------------------------

На данном этапе система автоматически определяет тип услуги, указанный в заявке, и направляет её по соответствующему сценарию обработки.

**Вход** - поданная в системе заявка с указанным типом услуги.

**Выход** - 

* если тип услуги — «Подписка на обслуживание», заявка направляется на этап создания договора
* если другой тип услуги - направляется в работу исполнителю

Этот этап используется для реализации ветвления бизнес-процесса в зависимости от значений полей формы заявки.

Для этого применяется тип действия **«Условный переход»**. Данный тип действия выполняется системой и подразумевает собой некую «проверку», считывающую условия на форме заявки (по умолчанию) либо с формы завершения, и отправляющую заявку на один из этапов маршрута.

**Шаг 1.** В редакторе маршрута добавляем новый этап, нажав кнопку «+».

**Шаг 2.** В настройках этапа выбираем:

* Тип действия — Условный переход;
* Название этапа — Проверка типа услуги;
* Код этапа — при необходимости

**Шаг 3.** Открываем вкладку "Переходы". 
Вкладка «Переходы» содержит:

    * кнопку добавить переход;
    * добавить переход по умолчанию.

.. figure:: ../resources/img/transitions.jpeg

**Шаг 4.** Во вкладке "Переходы" нажимаем **Добавить переход"**

.. figure:: ../resources/img/transition_edit.jpeg

**Шаг 5.** В левом операнде указываем код поля, которое проверяем — мы проверяем, в данном случае **«Вид услуги»**.

**Шаг 6.** В операторе сравнения выбираем **"="**, т.к нам нужно осуществлять переход случае если Вид услуги = определенному какому-то значению

**Шаг 7.** В правом операнде нам необходимо указать значение, которое должно быть выбрано в нашем поле **«Вид услуги»**, для осуществления перехода. Для этого мы обращаемся к колонке справочника, в которой указано значение услуги.

.. figure:: ../resources/img/type_of_service.jpeg

* если выбрано значение 2 – Подписка на обслуживание, нам нужно отправить заявку на создание договора.
Для этого в правом операнде мы указываем значение **2**

**Шаг 8.** Настройка действия **"То"**. При выполнении условия доступны два варианта:

    * Запустить маршрут по шаблону;
    * Перейти к этапу.

В нашем случае требуется переход к этапу создания договора, поэтому:

* выбираем **«Перейти к этапу»**;
* указываем код будущего этапа, например: ``create_agreement``

.. admonition:: Что происходит при такой настройке

    система считывает значение поля **«Вид услуги»**;

    если значение = **«Подписка на обслуживание»**,
    маршрут переходит к этапу создания договора.
    
**Шаг 9.** Во вкладке **«Переходы»** нажимаем **«Добавить переход по умолчанию»**.

.. admonition:: Зачем нужен переход по умолчанию

    Если указано только одно условие, а оно не выполняется, маршрут не продолжится.
    Поэтому необходимо задать альтернативный путь.
    
**Шаг 10.** В переходе по умолчанию указываем действие **"перейти к этапу"**

**Шаг 11.** Вводим код этапа будущей работы исполнителя, например: ``work_executor``

.. figure:: ../resources/img/default_transition.jpeg

**Шаг 12.** Сохраняем настройки условных переходов и сам этап.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/DOgTjs9aY3s"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


.. note:: Подробнее об условных переходах http://rtd.lan.arta.kz/docs/docs-po-platforme-arta-synergy/ru/latest/conditional_transitions.html

Этап 8. Формирование договора
------------------------------

**Вход** - заявка на услугу с типом «Подписка на обслуживание».

**Выход** - созданный в системе договор на оказание услуг.

На данном этапе система автоматически формирует договор на оказание услуг. Для этого будем использовать тип действия маршрута **"Создать запись в реестре"**

Этап используется для создания новой записи в отдельном реестре договоров на основании данных заявки.

**Шаг 1.** В редакторе маршрута добавляем новый этап, нажав кнопку **«+»**.

**Шаг 2.** В настройках этапа указываем:

* Тип действия - Создать запись в реестре;
* Наименование - Формирование договора;
* Код - ``create_agreement`` (тот же код, который был указан в этапе условного перехода).
* Поле **«Реестр, в котором необходимо создать запись»** на данном этапе оставляем пустым.
Оно будет заполнено после создания формы и реестра договоров.

* В поле **«От кого совершается действие»** указываем пользователя, от имени которого будут создаваться записи в реестре договоров. Как правило, используется учетная записи с правами администратора.
* Отмечаем галочкой настройку **"Активировать запись реестра"**, если необходимо чтобы запись после создания отправлялась по маршруту

.. figure:: ../resources/img/step8.jpeg

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/synUBfG2BSk"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


Этап 8.1. Завершение работы исполнителем
-----------------------------------------

**Вход** - заявка, обработанная исполнителем.

**Выход** - завершённая заявка и отправка уведомления на электронную почту.

Для удобства, вынесем эту ветвь процесса в отдельный **"Шаблон маршрута"**.

.. admonition:: Шаблон маршрута:
   
    Представляет собой вложенный маршрут, который может использоваться одновременно в нескольких реестрах.
    Настройки маршрута в шаблоне почти не отличается от настройки маршрута в реестре, за исключением отсутствия предварительных и последующих этапов.
    
    Подробнее о том что такое шаблон маршрута http://rtd.lan.arta.kz/docs/docs-po-platforme-arta-synergy/ru/latest/route_template.html

**Шаг 1.** Кликаем правой кнопкой мыши по удобной для нас папке и выбираем:
Добавить → Процессы → Шаблон маршрута.

**Шаг 2.** В открывшейся странице указываем:

* наименование шаблона маршрута
* соответствующий код

.. figure:: ../resources/img/route_template_new.jpeg

.. figure:: ../resources/img/route_template_saved.jpeg

**Шаг 4.** Нажимаем **«+»** и добавляем этап работы исполнителя:

* Тип действия - работа по форме
* Ответственный - код поля, в котором указывается исполнитель, назначенный менеджером. 
* Тип работы - работа
* включаем настройку "Использовать форму завершения" и выбираем форму завершения "Комментарий"

.. figure:: ../resources/img/work_executor.jpeg

**Шаг 5.** Сохраняем шаблон маршрута.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/T3J9ihl59a8"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


Этап 8.2. Смена статуса заявки на "Выполнена"
----------------------------------------------

**Вход** - заявка с выполненной работой исполнителя.

**Выход** - заявка со статусом **«Выполнена»**.

Для смены статуса используется уже известный нам скрипт интерпретатора.

Для удобства возьмем уже созданный скрипт интерпретатора с похожей логикой и сделаем его копию с некоторыми изменениями.

**Шаг 1.** В дереве объектов находим ранее созданный скрипт интерпретатора смены статуса.
 
**Шаг 2.** Кликаем по нему правой кнопкой мыши и выбираем «Сделать копию».

.. figure:: ../resources/img/create_copy.jpeg

**Шаг 3.** Открываем созданную копию и в коде скрипта меняем значение статуса на нужное, в нашем случае нужно поменять значение 4 (статус в работе) на 5 (выполнена).

**Шаг 4.** Изменяем наименование и код скрипта, на соответствующее логике например ``event.blocking.interpreter.change.status_ready``

.. figure:: ../resources/img/script_status_ready.jpeg

**Шаг 5.** Сохраняем скрипт.

**Шаг 6.** Возвращаемся в шаблон маршрута и добавляем новый этап:

* Тип действия - блокирующий процесс
* Наименование - "Смена статуса заявки на "Выполнена""
* Событие - вставляем наименование созданного нами скрипта

.. figure:: ../resources/img/step_status_ready.jpeg

**Шаг 7.** Сохраняем этап

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/Wfr1vgUFgSM"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


Этап 8.3. Отправка уведомления о статусе заявки
-------------------------------------

После смены статуса необходимо уведомить заявителя, что его заявка выполнена.

**Шаг 1.** В том же шаблоне маршрута добавляем новый этап:

* Тип действия - "Отправка письма на почту"
* Код поля формы с почтой заявителя — ``textbox_mail``
* Тема письма - "Ваша заявка на услуги компании ATLAS выполнена"
* Тело письма - "Ваша заявка на " + $listbox_type + "под номером " + $counter_number + " выполнена."

.. figure:: ../resources/img/step_ready_notification.jpeg

**Шаг 2.** Сохраняем этап и шаблон маршрута.

Привязка шаблона маршрута к реестру
----------------------------------------

Теперь созданный шаблон необходимо подключить к основному маршруту заявки через условный переход.

**Шаг 1.** Возвращаемя в основной маршрут и выделяем этап «Условный переход».

**Шаг 2.** Открываем вкладку «Переходы»

**Шаг 3.** В разделе «Переход по умолчанию» выбираем вариант «Запустить маршрут по шаблону» 

**Шаг 4.** Из открывшегося списка выбираем созданный нами шаблон маршрута

**Шаг 5.** Переходим во вкладку настроек рядом с этапом условного перехода

.. figure:: ../resources/img/settings_icon.jpeg 

**Шаг 6.** В параметре «После выполнения» выбираем «Перейти к этапу» и указываем код этапа ``end``.

.. note::
    Так мы уточняем что после завершения маршрута в шаблоне, основной маршрут заявки должен перейти к опреденному этапу (в данном случае - в конец), а не на следующие по порядку этапы.

**Шаг 7.** Нажимаем «ОК» и сохраняем этап.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/o2AfUB3xhOA"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>


Этап 9. Создание подпроцесса "Формирование договора"
-----------------------------------------------------

В ордере №2 описан подпроцесс создания договора на основании заявки.

:download:`Ордер №2 <../resources/img/Order_2_agreement_ATLAS.docx>`

Подготовка формы и реестра договора
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Создаем форму и реестр будущего подпроцесса согласно ордеру №2
(Процесс создания формы и реестра уже был рассмотрен ранее.)

**Шаг 1.** Возвращаемся в маршрут основной заявки к этапу "Создать запись в реестре": 

* Тип действия - "Создать запись в реестре"
* Код этапа - create_agreement (указанный нами ранее в условном переходе)
* Реестр в котором необходимо создать запись - указываем созданный нами реестр договора.
* Если нам необходимо чтобы созданный документ сразу после создания отправлялся по маршруту, делаем активной галочку **“Активировать запись реестра”**

**Шаг 2.** Ниже переходим во вкладку **"Настроить сопоставления"**

**Шаг 3.** В открывшемся окне нажимаем **«+ Добавить сопоставление».**

**Шаг 4.** В открывшихся выпадающих списках выбираем поля откуда и куда попадут данные:

* Слева - поля заявки (from - откуда)
* Справа - поля договора (to - куда)

.. figure:: ../resources/img/matching_registries.jpeg

    Пример сопоставления ИИН

**Шаг 5.** После настройки всех сопоставлений нажимаем «Сохранить» в модальном окне.

**Шаг 6.** Сохраняем этап маршрута.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/tks2dlXMbL8"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>
   

Этап 10. Конец маршрута.
-------------------------

**Вход** - заявка, прошедшая все предусмотренные этапы маршрута.
**Выход** - завершённый процесс.

Данный этап завершает выполнение бизнес-процесса заявки.

**Шаг 1.** В редакторе маршрута нажимаем кнопку **«+»** для добавления нового этапа.

**Шаг 2.** В настройках этапа указываем:

* Тип действия — Конец маршрута;
* Наименование — Конец маршрута;
* Код этапа — end (указанный нами ранее в условном переходе)

.. figure:: ../resources/img/step_end.jpeg

**Шаг 3.** Сохраняем этап.

.. raw:: html

   <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; margin-top:20px;">
       <iframe src="https://www.youtube.com/embed/Nwp07z4Cbw0"
           style="position: absolute; top:0; left:0; width:100%; height:100%;"
           frameborder="0"
           allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
           allowfullscreen>
       </iframe>
   </div>

