﻿# Делегированное действие

> [HTML Version](delegated-activities.html)

Этот тип действия** **позволяет передать данные из ELMA365 внешнему сервису, обработать их и получить ответ. 

Делегированные действия передаются в сторонний микросервис по стандартизированному [Web API](https://api.elma365.com/ru/) (HTTP REST). Один сервис может реализовывать несколько действий, которые разделяются кодом. 

Данное действие не использует скрипты, поэтому настраивается только на вкладках **Настройки** и **Контекст**.

## Вкладка «Настройки»

Заполните поля на вкладке **Настройки**:

**(delegated-activity-1.png)**

- **Название** — наименование действия в настройках модуля и в дизайнере бизнес-процессов;

- **Название по умолчанию** — наименование элемента, отображающееся при его добавлении на схему процесса;

- **Цвет блока** — цвет блока на схеме процесса;

- **Описание** — описание функциональных возможностей действия и его особенностей;

- **Устаревшее** — опция позволяет скрыть элемент из дизайнера бизнес-процессов, чтобы пользователи не смогли добавлять его на схемы новых процессов. Устаревшие действия продолжат работать без изменений в уже созданных процессах. Например, можно включить опцию для блока после обновления модуля;

- **URL делегирования** — адрес внешнего сервиса с указанием кода определённого действия в виде:\[OBJECT\]. Нажмите значок **\{+\}** в поле, чтобы использовать в адресе переменные, созданные в пользовательском модуле на вкладке [Настройки](extention-settings.md). С помощью значка **f(x)** в адрес можно добавить функцию [DateTime()](360027003711.md#datetime-function);

- **Количество повторов при ошибке **— количество попыток выполнения действия;

- **Пауза между повторами при ошибке (сек)\*** — частота попыток выполнения действия при возникновении ошибки.

## Вкладка «Контекст»

Добавьте переменные, которые будут использоваться в настройках элемента на схеме бизнес-процесса. Контекст можно запросить из внешнего сервиса‑исполнителя или создать вручную, нажав **+ Добавить **для каждой переменной. Подробнее о типах переменных читайте в статье [«Типы данных в системе»](360009707032.md).

Отметьте, какие переменные являются входными и выходными. Это позволит сопоставить контекст действия и процесса, в котором оно используется.

Вы также можете настроить пользовательскую форму сопоставления, т. е. окно настроек блока действия. Оно откроется при добавлении блока на схему бизнес‑процесса. Например, на форме можно отобразить информационное поле с подсказками.

Подробнее о биндинге переменных читайте в статье [«Биндинг переменных для действий в бизнес‑процессах»](activities-features.md).

Обратите внимание, если на вкладке **Контекст** вы хотите удалить неиспользуемые переменные из списка, убедитесь, что они не добавлены на пользовательскую форму сопоставления как отдельное поле или внутрь виджета. Иначе появится сообщение об ошибке.

После внесения данных на вкладках нажмите **Сохранить** и **Опубликовать** на верхней панели окна настроек действия. При включённом модуле действие появится в [дизайнере бизнес-процессов](360012265552.md#process-page) на вкладке **Интеграции**. Блок можно добавить на схему процесса и [задать настройки для его выполнения](module-action.md).

## Принцип работы действия

Делегированное действие выполняется по следующему алгоритму:

1. Заданный в настройках действия** URL делегирования** считывается **сервисом-processor** и вызывается его метод \[OBJECT\]. В теле запроса передаются **Исполнители** и **Контекст** — значения входных контекстных переменных из настроек действия. 

2. Когда **сервису-исполнителю** передаётся запрос на \[OBJECT\], происходит одно из следующих действий:

- действие выполняется, и выдаётся результат; 

- запрашиваются дополнительные данные из **сервиса-processor**;

- при наличии всех данных, но невозможности синхронного выполнения действия, информация сохраняется, например, в базе данных. В **сервис-processor** отправляется ответ о том, что действие принято к исполнению, и передаётся URL метода, по которому отправляется идентификатор точки восстановления;

- при возникновении ошибки возвращается оповещение об этом.

3. В зависимости от полученного ответа от **сервиса-исполнителя**, со стороны **сервиса-processor **происходит одно из следующих действий:

- при выполненном действии результат записывается в выходные переменные, настроенные в контексте действия. Выполнение бизнес-процесса продолжается;

- при необходимости запроса дополнительных данных, [создаётся пользовательская задача](#user-task). После её выполнения снова вызывается метод \[OBJECT\];

- если действие было принято к исполнению, [создаётся точка восстановления](#await). Её идентификатор передаётся в **сервис-исполнитель** с помощью полученного **URL**;

- в случае ошибки происходит её анализ. Отправляется повторный запрос, согласно указанным в действии настройкам. С помощью [шлюза](360012495911.md) в процессе можно также настроить дополнительную ветку, по которой продолжится ход в случае возникновения ошибки.   

### Запрос дополнительных данных в задаче

Для выполнения действия **сервису-исполнителю** могут потребоваться дополнительные данные от пользователя, например, электронная подпись. Тогда в ответ на вызов \[OBJECT\]**_ _сервис-исполнитель** возвращает код **201**. Инициатору процесса приходит задача, в которой прописываются: исполнители, контекст (данные), описание полей формы для задачи, список допустимых переходов.

Пользователь указывает нужную информацию. Затем **сервис-processor** снова вызывает метод \[OBJECT\] и передаёт **сервису-исполнителю** данные формы, выбранный переход, идентификатор исполнителя задачи. После этого **сервис-исполнитель** выполняет действие повторно. 

### Ожидание выполнения действия

В случае создания точки восстановления процесс останавливается до выполнения делегированного действия **сервисом-исполнителем**. Если на схеме процесса после действия настроено [промежуточное событие-таймер](360012496011.md#timer), ожидание прервётся по истечении установленного времени. 

После получения **сервисом-исполнителем** идентификатора точки восстановления он сохраняется, например, в базе данных. Затем происходит выполнение действия. 

По окончании действия в **сервис-processor** передаётся информация о необходимости продолжения бизнес-процесса с точки восстановления. Для передачи результата делегированному действию используется метод Web API:

````
POST /pub/v1/bpm/restore-point/\{id\}/restore

````
В теле запроса передаётся обновленный контекст действия. Подробнее о продолжении процесса с точки восстановления читайте в [справке по публичному API ELMA365](https://api.elma365.com/ru/public-api/reference/bpm/bpmrestorepointrestore/).

Полученные данные записываются **сервисом-processor** в выходные переменные, настроенные в элементе, и процесс продолжается.

### Прерывание выполнения действия

Прерывание или отмена делегированного действия происходит:

- при прерывании бизнес-процесса; 

- при эскалации по таймеру. 

Инициатором прерывания действия является **сервис-processor**. Он удаляет созданную точку восстановления и информирует **сервис-исполнитель** о необходимости отмены действия с помощью вызова.

## API сервиса-исполнителя

Подробное описание интерфейса **сервиса-исполнителя** вы можете посмотреть в OpenAPI-схеме:

OpenAPI-схема

````
openapi: 3.0.0  
info:  
  title: perfomer-service  
  description: Сервис-исполнитель для делегированного действия  
  version: 1.0.0  
servers:  
  - url: schema://domain:port/base/path  
paths:  
  /\{action-code\}/context:  
    get:  
      summary: Получить описание контекста  
      description: Метод предназначен для загрузки описания контекста из сервиса-исполнителя в элемент делегированного действия на этапе его создания блока  
      operationId: getContext  
      tags:  
        - Context  
      parameters:  
        - name: action-code  
          in: path  
          description: Код действия  
          required: true  
          schema:  
            type: string  
      responses:  
        '200':  
          description: Описание контекста действия в виде массива свойств  
          content:  
            application/json:  
              example: \[  
                \{  
                  "code": "firstName",  
                  "type": "STRING",  
                  "searchable": false,  
                  "indexed": false,  
                  "deleted": false,  
                  "array": false,  
                  "required": false,  
                  "single": true,  
                  "defaultValue": null,  
                  "calcByFormula": false,  
                  "formula": "",  
                  "data": null,  
                  "view": \{  
                    "name": "Имя",  
                    "tooltip": "Имя без сокращений",  
                    "data": \{  
                      "input": true  
                    \}  
                  \}  
                \},  
                \{  
                  "code": "lastName",  
                  "type": "STRING",  
                  "searchable": false,  
                  "indexed": false,  
                  "deleted": false,  
                  "array": false,  
                  "required": false,  
                  "single": true,  
                  "defaultValue": null,  
                  "calcByFormula": false,  
                  "formula": "",  
                  "data": null,  
                  "view": \{  
                    "name": "Фамилия",  
                    "tooltip": "Фамилия без сокращений",  
                    "data": \{  
                      "input": true  
                    \}  
                  \}  
                \},  
                \{  
                  "code": "fullName",  
                  "type": "STRING",  
                  "searchable": false,  
                  "indexed": false,  
                  "deleted": false,  
                  "array": false,  
                  "required": false,  
                  "single": true,  
                  "defaultValue": null,  
                  "calcByFormula": false,  
                  "formula": "",  
                  "data": null,  
                  "view": \{  
                    "name": "Полное имя",  
                    "tooltip": "Фамилия и имя без сокращений",  
                    "data": \{  
                      "output": true  
                    \}  
                  \}  
                \}  
              \]  
  /\{action-code\}/validate:  
    post:  
      summary: Проверить биндинги  
      operationId: validateBingings  
      tags:  
        - Validation  
      parameters:  
        - name: action-code  
          in: path  
          description: Код действия  
          required: true  
          schema:  
            type: string  
      requestBody:  
          description: ""  
          content:  
            application/json:  
              schema:  
                \$ref: '#/components/schemas/Bindings'  
      responses:  
        '200':  
          description: Успешная валидация  
          content:  
            application/json:  
              schema:  
                \$ref: '#/components/schemas/ValidationResult'  
        '400':  
          description: Ошибка при валидации  
  /\{action-code\}/requests:  
    post:  
      summary: Выполнить действия  
      operationId: runActionRequest  
      tags:  
        - Action  
      parameters:  
        - name: action-code  
          in: path  
          description: Код действия  
          required: true  
          schema:  
            type: string  
        - name: x-company-alias  
          in: header  
          required: true  
          schema:  
            type: string  
        - name: x-user-id  
          in: header  
          description: Текущий пользователь — в случае выполнения пользовательской задачи  
          required: false  
          schema:  
            type: string  
        - name: x-correlation-id  
          in: header  
          description: CorrelationID — в случае выполнения пользовательской задачи  
          required: false  
          schema:  
            type: string  
      requestBody:  
        required: true  
        content:  
          application/json:  
            schema:  
              \$ref: '#/components/schemas/CreateAction'  
      responses:  
        '200':  
          description: Задача выполнена  
          content:  
            application/json:  
              schema:  
                \$ref: '#/components/schemas/Result'  
        '201':  
          description: Задача принята к обработке. Необходимо поставить задачу пользователю и после её исполнения повторить запрос  
          content:  
            application/json:  
              schema:  
                \$ref: '#/components/schemas/CreateActionCreateTaskResponse'  
        '202':  
          description: Задача принята к обработке  
          content:  
            application/json:  
              schema:  
                \$ref: '#/components/schemas/CreateActionResponse'  
        '400':  
          description: Ошибка в формате запроса  
          content:  
            application/json:  
              schema:  
                \$ref: '#/components/schemas/BadRequest'  
        '422':  
          description: Ошибка в данных запроса  
          content:  
            application/json:  
              schema:  
                \$ref: '#/components/schemas/BadRequest'  
        '429':  
          description: Необходимо повторить запрос позже  
        '500':  
          description: Внутренняя ошибка сервиса-исполнителя, действие не может быть продолжено  
  /\{action-code\}/requests/\{id\}:  
    delete:  
      tags:  
        - Action  
      summary: Отменяет запрос  
      operationId: cancelAction  
      parameters:  
        - name: action-code  
          in: path  
          description: Код действия  
          required: true  
          schema:  
            type: string  
        - name: id  
          in: path  
          description: ID действия (он же correlationID)  
          required: true  
          schema:  
            type: string  
      responses:  
        '204':  
          description: Действие успешно отменено  
  /\{action-code\}/requests/\{id\}/restore-point:  
    put:  
      summary: Сохраняет точку останова  
      operationId: saveRestorePointID  
      tags:  
        - Action  
        - RestorePoint  
      parameters:  
        - name: action-code  
          in: path  
          description: Код межведа  
          required: true  
          schema:  
            type: string  
        - name: id  
          in: path  
          description: ID действия (он же correlationID)  
          required: true  
          schema:  
            type: string  
      requestBody:  
        required: true  
        content:  
          plain/text:  
            schema:  
              type: string  
              format: uuid  
              description: ID точки останова  
      responses:  
        '200':  
          description: Код сохранён  
        '409':  
          description: ID уже сохранён  
        '400':  
          description: Ошибка в формате запроса  
          content:  
            application/json:  
              schema:  
                \$ref: '#/components/schemas/BadRequest'  
components:  
  schemas:  
    Result:  
      type: object  
      properties:  
        context:  
          type: object  
      example: \{  
        "context": \{  
          "fullName": "Иванов Иван"  
        \}  
      \}  
    Bindings:  
      type: object  
      properties:  
        bindings:  
          type: array  
          items:  
            type: object  
    ValidationResult:  
      type: array  
      items:  
        type: object  
    BadRequest:  
      type: object  
      properties:  
        errors:  
          type: array  
          items:  
            type: object  
            properties:  
              source:  
                type: string  
                description: Указатель на элемент в запросе, где возникла ошибка  
              title:  
                type: string  
                description: Краткое описание ошибки  
              detail:  
                type: string  
                description: Детальное описание ошибки  
              code:  
                type: string  
                description: Машиночитаемый код ошибки  
            required:  
              - code  
              - title  
    CreateAction:  
      type: object  
      properties:  
        id:  
          type: string  
          format: uuid  
          description: ID запроса, должен быть уникальным для каждого запроса. Используется для контроля над повторными запросами  
        performers:  
          type: array  
          description: Исполнители  
          items:  
            type: string  
            format: uuid  
        context:  
          type: object  
          description: Сериализация контекста шага или данные с формы  
        exitID:  
          type: string  
          description: Выбранный переход  
      required:  
        - id  
        - performers  
        - context  
    CreateActionResponse:  
      type: object  
      properties:  
        id:  
          type: string  
          format: uuid  
          description: Уникальный Correlation ID  
        restorePointURL:  
          type: string  
          format: url  
          description: Адрес, на который отправляется restore-point-id  
    CreateActionCreateTaskResponse:  
      type: object  
      properties:  
        performers:  
          type: array  
          description: Исполнители для задачи  
          items:  
            type: string  
            format: uuid  
        context:  
          type: object  
          description: Описание полей и данные  
        formFields:  
          type: array  
          description: Шаблон формы  
          items:  
            type: object  
            description: Структура FormField  
        exitIDs:  
          type: array  
          description: Список допустимых переходов  
          items:  
            type: string  
            format: uuid  
      required:  
        - performers  
        - context  
        - exitIDs
````