# Настройки переходов: полный справочник

Каждый переход в маршруте категории — это строка в таблице `dbo.StatesRoutesInSubcat`. Переход определяет: из какого статуса в какой идёт задача, кто видит кнопку, что происходит автоматически при нажатии. Настройки перехода доступны в админке: **Категория → Бизнес-процесс → Маршрут → клик на переход → вкладка «Настройки»**. Первичный ключ — `StepID` (автоинкремент), переход привязан к категории (`SubcatID`). Документ описывает все колонки таблицы `StatesRoutesInSubcat`, связанные таблицы, CHECK-ограничения, UI-вкладки, последовательность действий при переходе и полезные SQL-запросы.

---

## Таблица StatesRoutesInSubcat — все колонки

### Идентификация и маршрут

Идентификаторы перехода и его привязка к статусам и категории:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `StepID` | INT (PK, IDENTITY) | авто | Переход | Уникальный ID перехода |
| `StateID` | INT (FK → States) | — | Из статуса | Статус-источник |
| `StateNextID` | INT (FK → States) | — | В статус | Целевой статус |
| `SubcatID` | INT (FK → Subcategories) | — | — | Категория, которой принадлежит переход. CASCADE DELETE |
| `ActionID` | INT (FK → Actions, NULL) | NULL | Право (легаси, скрыта с 2.268.x) | ID действия из `dbo.Actions`. До 2.268.x значение `Actions.Description` отображалось в админском гриде переходов категории (`/spa/administration/subcategory-route-states/{subcatId}`) в колонке «Право». Колонка скрыта как неинформативная: значение не отражает реальные настройки прав на переходе — они задаются через карточку перехода, роли (`BpRoles`/`BpRolesSteps`) и переопределение доступа категории. Прямые правки `StatesRoutesInSubcat.ActionID` в БД на отображение в админке не влияют. Само поле БД сохранено для обратной совместимости. |
| `GUID` | UNIQUEIDENTIFIER | newsequentialid() | — | Глобальный идентификатор для миграции |
| `OrderId` | INT (NULL) | NULL | Порядок кнопки перехода | Порядок отображения кнопок на карточке задачи |
| `row_version` | ROWVERSION | авто | — | Версия строки для оптимистичной блокировки |

В выпадающих списках «Из статуса» (`StateID`) и «В статус» (`StateNextID`) каждый статус отображается в формате «Название (ID): Описание» — название, идентификатор в круглых скобках и описание (поле `Description` таблицы `States`). Если у статуса описание не заполнено, отображается только «Название (ID)». Формат единообразен в выпадающем списке и в значении поля после сохранения перехода.

Поле «Произвольный статус начала маршрута» категории использует тот же формат — см. [business.md § Статусы задач](https://help.1forma.ru/domains/categories/business.md#статусы-задач).

### Название и подсказки

Текст кнопки перехода и всплывающие подсказки:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `StepDescr` | VARCHAR(100) | — | Название кнопки | Текст кнопки перехода на карточке задачи |
| `StepToolTip` | VARCHAR(400) | NULL | Подсказка для кнопки | Всплывающая подсказка при наведении |
| `StepOwnerToolTip` | VARCHAR(400) | NULL | Подсказка для заказчика | Подсказка, видимая только заказчику задачи |
| `StepUserToolTip` | VARCHAR(400) | NULL | Подсказка для исполнителя | Подсказка, видимая только исполнителю задачи |
| `LocalizedStepDescrId` | INT (FK → LocalizedBusinessObjects, NULL) | NULL | (мультиязычность) | Локализованное название кнопки |
| `LocalizedStepTooltipId` | INT (FK, NULL) | NULL | (мультиязычность) | Локализованная подсказка кнопки |
| `LocalizedStepOwnerTooltipId` | INT (FK, NULL) | NULL | (мультиязычность) | Локализованная подсказка для заказчика |
| `LocalizedStepUserTooltipId` | INT (FK, NULL) | NULL | (мультиязычность) | Локализованная подсказка для исполнителя |
| `LocalizedConfirmTextId` | INT (FK, NULL) | NULL | (мультиязычность) | Локализованный текст подтверждения |

### Автоисполнитель

Автоматическое назначение исполнителя при переходе:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `IsButtonPresserAutoPerformer` | BIT | 0 | Автоисполнитель: «Нажавший на кнопку» | Нажавший кнопку перехода автоматически назначается исполнителем |
| `AutoPerformerSignatureID` | INT (NULL) | NULL | Автоисполнитель (роль) | ID роли, члены которой назначаются исполнителями на данном шаге |
| `AutoPerformerSourceExtParamID` | INT (FK → ExtParams, NULL) | NULL | Автоисполнитель берётся из ДП | Исполнителем назначается пользователь, чей ID хранится в значении указанного ДП. Требования к типу и настройкам ДП — ниже, «Как отрабатывает автоназначение» |
| `AutoperformerAssingAction` | INT (NULL) | NULL | Действия при автоматическом назначении исполнителя | Что делать со старыми исполнителями и с признаком ответственного. Значения: **0** = удалять старых и назначать ответственным, **1** = не удалять старых, не назначать ответственным, **2** = не удалять старых, назначать ответственным, **3** = удалять из исполнителей и подписчиков старых, назначить ответственным. При NULL действует вариант **1** |
| `AutoAssignCustomer` | BIT | 0 | Назначить заказчика исполнителем; пункт «Заказчик» в списке «Автоисполнитель» | При переходе заказчик задачи добавляется в исполнители. Не зависит от того, сработал ли источник автоисполнителя |

**Как отрабатывает автоназначение**

Источник автоисполнителя срабатывает один, в порядке приоритета: роль (`AutoPerformerSignatureID`) → ДП (`AutoPerformerSourceExtParamID`) → нажавший кнопку (`IsButtonPresserAutoPerformer`).

Значение ДП-источника читается по нативной колонке типа: у «Выпадающего списка» — `ExtParamValues.DataSourceItemID`, у «Выбора пользователей» — `ExtParamValues.SelectUserValue`. У «Выпадающего списка с редактированием» нативной колонки нет, поэтому берётся текстовое `ExtParamValues.ExtParamValue`. В любом случае значение должно разбираться в целое число — ID пользователя. ДП типа «Выбор пользователей» принимается источником только при настройках `SingleUserMode = 1`, `AllowUsers = 1`, `AllowGroups = 0`, `AllowOrgUnits = 0`: лишь при такой конфигурации `SelectUserValue` содержит ID пользователя, а не группы или оргединицы. Для ДП других типов настройки не проверяются. В карточке перехода в админке в выпадающий список попадают ДП типов «Выпадающий список» и «Выпадающий список с редактированием», а также ДП «Выбор пользователей» с такими настройками.

В карточке перехода пункт «Заказчик» в списке «Автоисполнитель» и чекбокс «Назначить заказчика исполнителем» держатся согласованными: выбор пункта включает признак, уход с пункта снимает его, если признак числится за пунктом — им он становится и при открытии карточки с уже включённым `AutoAssignCustomer = 1`, и при включении чекбокса вручную до выбора пункта, поэтому уход снимает и такой чекбокс, а снятие чекбокса при выбранном пункте сбрасывает выбор в списке «Автоисполнитель». При открытии карточки пункт «Заказчик» подставляется, когда `IsButtonPresserAutoPerformer = 0` и `AutoAssignCustomer = 1`; при `IsButtonPresserAutoPerformer = 1` в списке показывается «Нажавший на кнопку», а признак заказчика остаётся за чекбоксом. Запрет сохранять «Автоисполнитель» вместе с источником из ДП действует только для пункта «Нажавший на кнопку» — пункт «Заказчик» с ДП-источником сочетается.

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

Заказчик по `AutoAssignCustomer = 1` добавляется в список назначаемых, если его там ещё нет, — в том числе когда ДП-источник был пропущен или источник не настроен вовсе.

Признак ответственного исполнителя (варианты **0**, **2**, **3**) получает только первый пользователь списка, остальные добавляются обычными исполнителями. Пользователь, уже числящийся исполнителем, повторно не добавляется, но признак ответственного к нему применяется. Удаление старых исполнителей (варианты **0** и **3**) выполняется до формирования списка. Блок автоназначения запускается, если задана роль, включён «нажавший кнопку», включён `AutoAssignCustomer` либо ДП-источник дал корректный ID: роль и оба флага проверяются по факту настройки, а ДП — по результату разбора значения. Поэтому при заданной роли, не вернувшей ни одного пользователя, блок всё равно отрабатывает: старые исполнители удаляются, новых не добавляется. Если роль и оба флага не заданы, а ДП-источник был пропущен, блок не выполняется — старые исполнители остаются.

### Сроки и время

Срок этапа и его источник:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `TermMinutes` | INT (NULL) | NULL | Срок перехода | Время на выполнение этапа (в минутах). Отображается в скобках на кнопке перехода |
| `TermDateSourceExtParamID` | INT (FK → ExtParams, NULL) | NULL | Срок перехода берётся из ДП | Значение ДП задаёт срок перехода. Взаимоисключающе с `TermMinutes` (CHECK constraint) |
| `OnOverduePerformStepID` | INT (FK → StatesRoutesInSubcat, NULL) | NULL | Альтернативный переход (выполнить когда просрочен) | Переход, выполняемый автоматически по истечении `TermMinutes`. Если не задан — просроченный срок отображается красным |
| `ResetDueTime` | BIT | 0 | Сбросить срок | При переходе поле «Срок» очищается. В просроченных задачах запрашивается причина |
| `RequireChangeDateBefore` | BIT | 0 | Требовать смену срока перед переходом | Перед переходом появляется окно смены срока задачи |

### Дата начала работы

Что происходит с полем «Дата начала работы» при переходе:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `TaskStartTimeAction` | TINYINT | 0 | Действие с датой начала работы | Что делать с полем «Дата начала работы» при переходе. Значения: **0** = Не менять, **1** = Очищать, **2** = Заполнять текущим временем, **3** = Заполнять текущим временем, если пустая |
| `AskPermissionToPerformTSTAction` | BIT | 0 | Запрашивать подтверждение действия с датой начала работы | Если включено, при переходе у пользователя запрашивается подтверждение для изменения даты начала работы |

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

**Каким временем заполняется.** Для значений **2** и **3** «текущее время» берётся из серверных часов, а не из часового пояса профиля пользователя, выполняющего переход: часовой пояс профиля на записанное значение не влияет.

**Важно: «Разрешить ставить дату начала работы в прошлом»** — это настройка **категории** (`Subcategories.AllowSetStartTimeInPast`), а не перехода. См. раздел ниже.

### Согласование и подписи

Поведение согласования и подписей на переходе:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `TransparentApproval` | BIT | 0 | Сквозное согласование | Переход выполняется вне зависимости от решения акцептантов. Взаимоисключающе с `CycleApproval` (CHECK constraint) |
| `CycleApproval` | BIT | 0 | Разовое согласование | Акцептант, давший положительную резолюцию, не получает повторный запрос подписи на новом цикле. Процесс продолжается, пока все подписи не акцептованы |
| `RequestDirectorSignatureOnReject` | BIT | 0 | Эскалировать при отклонении | При отклонении подписи запрашивается подпись руководителя отклонившего |
| `DisallowRevisionsOnSign` | BIT | 0 | Запретить отправлять на согласование документы с непринятыми правками | Если вложен файл с непринятыми правками, подпись не запрашивается — показывается предупреждение |
| `RemoveCommentsOnSignWhenEP` | INT (NULL) | NULL | Удалять примечания из docx, когда проставлен ДП | Если вложен docx с примечаниями и значение указанного ДП ненулевое, примечания удаляются из файла |

### Текст и подтверждение

Комментарии, подтверждение и автогенерация текста задачи:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `ForceComment` | BIT | 0 | Требовать написания комментария при переходе | Перед переходом отображается окно «Требуется комментарий». Переход заблокирован, пока комментарий не введён. Введённый текст сохраняется в ленте задачи как обычный комментарий автора перехода и одновременно передаётся в поле «Причина запроса» (`TaskSignatures.Reason`) **всех** подписей, запрошенных на этом переходе. Для аналогичного поведения **на стороне подписи** (только обрабатываемой) — опция `RequestReasonOnAccept` в `StatesRoutesSignatures`, см. [бизнес-документацию подписей](https://help.1forma.ru/domains/signatures/business.md) |
| `ConfirmText` | VARCHAR(200) | NULL | Текст подтверждения | Комментарий, добавляемый в задачу после перехода |
| `StepConfirmationMode` | INT | 0 | Режим подтверждения | Режим текста подтверждения: **0** = Нет подтверждения, **1** = Фиксированное значение (используется `ConfirmText`), **2** = Смарт-выражение (используется `StepConfirmationSmartExpressionId`) |
| `StepConfirmationSmartExpressionId` | INT (FK → SmartExpressions, NULL) | NULL | Смарт-выражение для подтверждения | Смарт-выражение, генерирующее текст подтверждения (при `StepConfirmationMode = 2`) |
| `ChangeTaskText` | BIT | 0 | Изменить текст задачи | При переходе текст задачи меняется по шаблону из `ChangeTaskTextTemplate` |
| `ChangeTaskTextTemplate` | NVARCHAR(MAX) | NULL | Шаблон для автогенерации текста задачи | Шаблон с макросами `$ExtНомерДП` и `$Text`. Работает только при включённом `ChangeTaskText` |

### Видимость кнопки и права

Кому видна кнопка перехода:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `HiddenStep` | BIT (NULL) | 0 | Кнопка скрыта | Кнопка не отображается на карточке задачи. Переход доступен только программно, через смарты или через ленту основного маршрута (если переход входит в основной маршрут). API: параметр `HiddenStep` в DTO обязателен как `bool` (не nullable). При создании перехода через `POST /api/admin/subcategories/steps` без указания `HiddenStep` применяется `false`. В БД колонка остаётся `BIT NULL DEFAULT(0)`, но бэкенд гарантирует запись `0` при отсутствии значения. Пользовательский запрос `POST /api/tasks/{taskId}/change-step` скрытие не обходит: переход с `HiddenStep = 1` вне основного маршрута при таком вызове отклоняется без изменения статуса задачи. Смарты и настроенные автоматические переходы идут программными путями и этим ограничением не затронуты. |
| `OwnerOnly` | BIT | 0 | Для заказчика | Хранится в БД, на видимость кнопки не влияет: проверка по флажку отключена |
| `UserOnly` | BIT | 0 | Для пользователя | Хранится в БД, на видимость кнопки не влияет: проверка по флажку отключена |
| `ForAdmin` | BIT | 0 | Для администратора | Хранится в БД, на видимость кнопки не влияет: проверка по флажку отключена |
| `ForViewver` | BIT | 0 | Для просматривающего | Хранится в БД, на видимость кнопки не влияет: проверка по флажку отключена |
| `ForPerfRight` | BIT | 0 | Для права «Исполнять» | Хранится в БД, на видимость кнопки не влияет: проверка по флажку отключена |
| `ForAddRight` | BIT | 0 | Для права «Создавать» | Хранится в БД, на видимость кнопки не влияет: проверка по флажку отключена |
| `ForResponsiblePerformer` | BIT | 0 | Для ответственного исполнителя | Хранится в БД, на видимость кнопки не влияет: проверка по флажку отключена |
| `VisibilitySmartFilterID` | INT (FK → SmartExpressions, NULL) | NULL | Смарт-фильтр видимости кнопки | Смарт-выражение, определяющее видимость кнопки. Если результат false — кнопка скрыта |

Если контроль доступа снят, кнопка перехода видна любому пользователю, у которого есть доступ к задаче. Если контроль включён, а матрица не привязана или пуста, кнопка скрыта для всех, кроме Робот1Ф. Если матрица настроена, доступ считается по ней, причём строка «По умолчанию» для перехода действует только у пользователей с правом «Исполнять».

### Автоматизация

Автоматическое выполнение перехода и хранимые процедуры:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `AutoPerformStepOnSubtasksClose` | BIT | 0 | Автоматически делать переход при завершении всех подзадач | Переход выполняется автоматически, когда все подзадачи в текущем статусе завершены |
| `IsAutoPerfomedOnPostTask` | BIT | 0 | (Шаг при постановке) | Переход выполняется автоматически после создания задачи. Только один переход в категории может иметь этот флаг (UNIQUE filtered index). Пользователь должен иметь право на переход |
| `StoredProcedures` | VARCHAR(100) | NULL | Процедура при переходе (SQL) | Имя хранимой процедуры, вызываемой при переходе. Параметр: `@TaskID int`. Использование — только после сертификации |

### Уведомления

Почтовые и внутренние уведомления при переходе:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `DisableMail` | BIT | 0 | Отключить посылку писем | Почтовые уведомления не отправляются при выполнении перехода |
| `NotifyUsersInSubcat` | BIT | 0 | Уведомить пользователей в категории | Уведомление о переходе отправляется всем, кто имеет право просмотра задач в категории |
| `NotifyUsersInSubcatGroupID` | INT (NULL) | NULL | Только группу | Ограничивает уведомление указанной группой (работает при `NotifyUsersInSubcat = 1`) |
| `NotifyUsersInSubcatText` | VARCHAR(8000) | NULL | Текст уведомления | Текст уведомления для пользователей, не подписанных на задачу |

### Основной маршрут

Принадлежность перехода к основному (эталонному) маршруту:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `IsMainRouteStep` | BIT | 0 | Основной маршрут | Переход входит в основной (эталонный) маршрут. Основной маршрут визуализируется лентой на карточке задачи |
| `IsMainRouteAvailable` | BIT | 0 | Доступен через Ленту маршрута | Устаревшая настройка. Определяла, можно ли выполнить переход через ленту основного маршрута |

### Побочные эффекты

Прочие эффекты перехода:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `DoSetComplainted` | BIT | 0 | Становится обжалованной | После перехода исполнители, ранее завершившие задачу, перестают отображаться зачёркнутым — задача снова видна в «Мои задачи». Дублирует глобальную настройку — действует, если хотя бы одна из двух включена |
| `ActionsWithExtParams` | INT | 0 | Действия с ДП | Количество настроенных действий с ДП (формирование файлов по шаблону). Значение > 0 = есть действия |
| `RedirectUrlAfterStepSmartExpressionID` | INT (FK → SmartExpressions, NULL) | NULL | Перейти по ссылке после перехода | Смарт-выражение, генерирующее URL. После перехода браузер откроет эту ссылку. Может возвращать номер задачи (откроется карточка) или строку-URL в кавычках |

### Матрица доступа к переходу

Управление доступом к переходу через матрицу доступа к сущностям задачи:

| Колонка | Тип | По умолчанию | UI-название | Описание |
|---------|-----|-------------|-------------|----------|
| `TaskEntityPermissionControl` | BIT | 0 | Ограничить доступ | Включает контроль доступа к переходу. При снятом флажке переход виден всем, у кого есть доступ к задаче. При включённом без матрицы переход скрыт для всех, кроме Робот1Ф |
| `TaskEntityPermissionSetID` | INT (FK → TaskEntityPermissionsSet, NULL) | NULL | Набор прав доступа | ID набора прав, определяющего доступ к переходу по статусам, группам, ролям и правам |

---

## Связанная настройка категории: «Разрешить ставить дату начала работы в прошлом»

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

**Таблица:** `dbo.Subcategories`
**Колонка:** `AllowSetStartTimeInPast` (BIT, по умолчанию 0)
**Добавлена:** в версии v2.267

**Что контролирует:** разрешает или запрещает устанавливать дату начала работы (`TaskStartTime`) раньше даты создания задачи (`CreationDate`). Если флаг выключен (по умолчанию) и пользователь пытается поставить дату начала работы в прошлом — система блокирует это.

**Где найти в UI:** Настройки категории → раздел сроков.

**Связанный флаг:** `AllowSetTimeParamsInPast` (тоже в `Subcategories`) — разрешает ставить **срок** (`DueDate`) в прошлом. При добавлении `AllowSetStartTimeInPast` начальное значение инициализируется из `AllowSetTimeParamsInPast` (миграция копирует значение).

**Логика проверки:**
```
Если новая дата начала < даты создания задачи И AllowSetStartTimeInPast = false
  → блокировка с ошибкой
```

Проверка срабатывает при ручном изменении даты начала, при изменении через переход (когда `TaskStartTimeAction = 2`, «Заполнять текущим временем») и при создании задачи через чат.

---

## Связанные таблицы и CHECK-ограничения

Переход связан с несколькими таблицами:

| Таблица | Связь | Что хранит |
|---------|-------|-----------|
| `StatesRoutesSignatures` | FK StepID → StepID | Подписи на переходе |
| `StepSubTask` | FK StepID → StepID | Подзадачи, создаваемые при переходе. Значение «от кого» — колонка `FromWhom`, на неё наложено CHECK-ограничение `CK_StepSubTask_FromWhom` |
| `StepExtParamRestrictions` | FK StepId → StepID | Обязательные ДП на переходе |
| `ExtParamsInSubcatValidatorStep` | FK StepId → StepID | Валидаторы ДП, проверяемые перед переходом |
| `BpRolesSteps` | FK StepId → StepID | Роли на переходе (вход/выход/условие) |
| `StepLog` | FK StepId → StepID | Журнал выполнения переходов |
| `TaskSignaturesQueue` | FK StepID → StepID | Очередь запрошенных подписей |
| `StatesRoutesSignaturesService` | FK Id → StepID | Настройки сервиса подписей на переходе |
| `SmartExpressions` | FK через VisibilitySmartFilterID, RedirectUrlAfterStepSmartExpressionID, StepConfirmationSmartExpressionId | Смарт-выражения |

CHECK-ограничения, наложенные на таблицу `StatesRoutesInSubcat`:

1. `CK_StatesRoutesInSubcat` — `CycleApproval = 0 OR TransparentApproval = 0`. Нельзя одновременно включить сквозное и разовое согласование.
2. `CK_StatesRoutesInSubcat_1` — `TermDateSourceExtParamID IS NULL OR TermMinutes IS NULL`. Срок перехода задаётся либо в минутах, либо из ДП — не одновременно.

**Проверка значения «от кого» в подзадачах перехода.** Колонка `FromWhom` таблицы `StepSubTask` (`FK StepID → StepID`) хранит значение «от кого» для подзадачи, создаваемой при переходе, и принимает три значения — `0`, `1`, `2` (в интерфейсе это варианты «От исполнителя», «От заказчика», «От нажавшего кнопку»). На колонку наложено CHECK-ограничение `CK_StepSubTask_FromWhom` (MSSQL) / `ck_stepsubtask_fromwhom` (PostgreSQL) — `FromWhom IN (0, 1, 2)`; добавлено с `WITH NOCHECK` (MSSQL) и `NOT VALID` (PostgreSQL), поэтому строки, сохранённые до его появления, не проверяются, а последующие записи и обновления — проверяются. То же значение проверяется до записи: в сервисе настройки подзадач перехода (`POST`, `PUT`) и в обработчике универсальной формы таблицы `StepSubTask` — недопустимое значение отклоняется с сообщением об ошибке и в базу не попадает. Если в сохранённой строке значение вне набора, подзадача по ней не создаётся: переход выполняется, настройка пропускается, а в задачу добавляется сообщение об ошибке; при копировании перехода такая строка в копию не переносится.

---

## Вкладки настройки перехода (UI)

Кроме описанных выше колонок, у каждого перехода есть вкладки в админке:

| Вкладка | Что настраивает | Связанная таблица |
|---------|----------------|-------------------|
| Настройки | Все колонки `StatesRoutesInSubcat` (эта страница) | — |
| Подзадачи на переходе | Автосоздание подзадач/связанных задач с синхронизацией ДП | `StepSubTask` |
| [Подписи на переходе](https://help.1forma.ru/domains/signatures/admin.md#подписи-на-шагах-маршрута-statesroutessignatures) | Запрос подписей, список акцептантов. Окно «Редактирование подписи при переходе» с вкладками «Обязательные ДП», «Информационные ДП» и «Условия запроса» описано там же | `StatesRoutesSignatures` |
| Доп. параметры | Обязательные ДП при переходе | `StepExtParamRestrictions` |
| Действия с ДП | Формирование файлов по шаблону | (настройки в `ActionsWithExtParams`) |
| Смарты на переходе | Смарт-действия на событиях «Перед переходом» и «После перехода»; привязанные правила видны на карте маршрута — см. «Панель правил автоматизации на карте маршрута» в [«Категории» — администрирование](https://help.1forma.ru/domains/categories/admin.md#панель-правил-автоматизации-на-карте-маршрута) | (через event-систему) |

---

## Последовательность действий при переходе

При нажатии кнопки перехода система выполняет шаги (сокращённо):

1. Проверка статуса подзадач
2. Проверка доступа к задаче и к переходу (контроль доступа и матрица: `TaskEntityPermissionControl`, `TaskEntityPermissionSetID`), затем смарт-фильтр видимости (`VisibilitySmartFilterID`). Флажки `OwnerOnly`, `UserOnly`, `ForAdmin`, `ForPerfRight`, `ForAddRight`, `ForResponsiblePerformer`, `ForViewver` не проверяются
3. Проверка обязательных ДП (`StepExtParamRestrictions`)
4. Проверки динамических подписей, затем валидаторов ДП перехода (`ExtParamsInSubcatValidatorStep`)
5. Выполнение смартов «перед сменой статуса»
6. Запрос подписей (если настроены)
7. Запрос комментария (если `ForceComment = 1`)
8. Выполнение перехода, запись в `StepLog`
9. Действия с датой начала работы (`TaskStartTimeAction`)
10. Действия с текстом задачи (`ChangeTaskText` + `ChangeTaskTextTemplate`)
11. Сброс срока (если `ResetDueTime = 1`)
12. Назначение автоисполнителя
13. Текст подтверждения (`ConfirmText`)
14. Уведомления
15. Создание подзадач на переходе
16. Хранимая процедура (`StoredProcedures`)
17. Смарты «после перехода»
18. Обновление денормализации

**Смена статуса из смарта во время перехода.** Если смарт, выполняемый при обработке перехода (например, на событии «После перехода»), переводит ту же задачу в другой статус, эта вторая смена статуса выполняется сразу: статус записывается, и смарты «После перехода» второй смены отрабатывают немедленно. Остальная обработка второй смены — вызов 1С-коннектора, смарты на событиях «После смены статуса (в т. ч. принудительно)» и «После изменения состояния связанной задачи», обновление денормализации и вызов коннекторов — выполняется только после того, как ту же обработку закончит первая смена. Поэтому действия, которые в том же пакете идут после перехода, ещё не видят результатов этих шагов второй смены, а смарты «После смены статуса (в т. ч. принудительно)» срабатывают в порядке смены статусов. Параметры этого события относятся к той смене, которая его вызвала: к моменту выполнения смарта текущий статус задачи может быть уже другим. Тот же порядок действует для принудительной смены статуса и для смены статуса при отклонении подписи.

**Принудительная смена статуса** (через редактирование поля «Статус» администратором) не выполняет этот маршрут. При этом выполняются смарты на событиях «После принудительной смены статуса» и «После смены статуса (в т. ч. принудительно)», обновляется денормализация и вызываются коннекторы.

```mermaid
flowchart TD
    A["Нажата кнопка перехода"] --> B{"Проверки: подзадачи, права, обязательные ДП, динамические подписи"}
    B -- "не пройдены" --> X["Переход заблокирован"]
    B -- "пройдены" --> C["Смарты «перед сменой статуса»"]
    C --> D{"Подписи и комментарий, если настроены"}
    D -- "отклонено или нет комментария" --> X
    D -- "ок" --> E["Выполнение перехода и запись в StepLog"]
    E --> F["Автоматизации: дата начала, текст задачи, сброс срока, автоисполнитель, подтверждение"]
    F --> G["Уведомления, подзадачи, хранимая процедура, смарты «после перехода»"]
    G --> H["Обновление денормализации"]
Z["Принудительная смена статуса администратором"] --> Y["Статус изменён без маршрута; срабатывают смарты смены статуса и коннекторы"]
```

---

## Полезные запросы и связанные документы

Все переходы категории:
```sql
SELECT s.StepID, st1.Description AS [Из], st2.Description AS [В], s.StepDescr AS [Кнопка],
       s.HiddenStep, s.TaskStartTimeAction, s.AutoPerformStepOnSubtasksClose
FROM StatesRoutesInSubcat s
JOIN States st1 ON st1.StateID = s.StateID
JOIN States st2 ON st2.StateID = s.StateNextID
WHERE s.SubcatID = @SubcatID
ORDER BY s.OrderId, s.StepID
```

Переходы с автодействиями по дате начала работы:
```sql
SELECT s.StepID, s.StepDescr, s.TaskStartTimeAction, s.AskPermissionToPerformTSTAction
FROM StatesRoutesInSubcat s
WHERE s.SubcatID = @SubcatID AND s.TaskStartTimeAction > 0
```

Категории с разрешённой датой начала в прошлом:
```sql
SELECT SubcatID, Description
FROM Subcategories
WHERE AllowSetStartTimeInPast = 1
```

Связанные документы:

- [Маршруты и статусы (бизнес)](https://help.1forma.ru/domains/categories/business.md#маршруты-и-статусы) — обзор маршрутов
- [Настройки перехода](https://help.1forma.ru/domains/categories/admin.md#настройка-перехода) — описание настроек с иллюстрациями
- [Подписи на переходах](https://help.1forma.ru/domains/signatures/admin.md)
- [Подзадачи на переходе](https://help.1forma.ru/domains/categories/admin.md#подзадачи-на-переходе)
- [Смарты на переходе](https://help.1forma.ru/domains/smart-actions/admin.md)
