# Организационная структура

Руководство по настройке организационной структуры 1Формы — дерева подразделений и должностей компании. Администрирование: **Администрирование → Оргструктура** (`/spa/administration/org-structure`). Описаны типы орг. единиц, карточки единиц, массовые операции, справочник должностей, пользовательские настройки и SQL-диагностика.

Организационная структура — дерево подразделений и должностей компании. Настраивается в администрировании: **Администрирование → Оргструктура** (`/spa/administration/org-structure`). Здесь создаётся дерево единиц, задаются их типы и должности, к единицам привязываются пользователи и группы.

![Страница оргструктуры: дерево подразделений, строка создания единицы и поиск](https://help.1forma.ru/help-images/org-structure/orgstructure_admin_page.png)

Настраивать оргструктуру можно несколькими способами:

| Интерфейс | Путь |
|-----------|------|
| Администрирование (AdminSPA) | Администрирование → Оргструктура — `/spa/administration/org-structure` |
| Admin API | `/api/admin/org-structure/*` |

Подписи страницы оргструктуры и карточки орг. единицы — названия вкладок и полей, подписи кнопок, заголовки колонок, тексты подтверждений и уведомлений — берутся из ресурсных файлов интерфейса и показываются на языке пользователя; см. [Локализация — Администрирование](https://help.1forma.ru/domains/localization/admin.md).

## 1. Типы орг. единиц

**Таблица БД:** `dbo.OrgStructureType`

Тип задаёт уровень и поведение орг. единицы. Поля типа:

| Поле | Назначение |
|------|-----------|
| Name | Название типа (Филиал, Департамент, Отдел, Группа, Должность) |
| Order | Числовой уровень — дочерний элемент должен иметь строго больший Order |
| IsPosition | Признак «должность» — только один тип с этим флагом; элементы этого типа могут иметь Appointment |
| IsCommercialInfo, HideInUserInfo | Флаги видимости |

Типы настраиваются **до создания** оргструктуры.

![Список типов оргструктуры: имя, уровень и признак «Является должностью»](https://help.1forma.ru/help-images/org-structure/types_list.png)

Новый тип создаётся в форме с полями «Имя», «Уровень» и признаком «Является должностью».

![Форма добавления нового типа орг.структуры](https://help.1forma.ru/help-images/org-structure/org_structure_types-02.png)

## 2. Орг. единицы

**Таблица БД:** `dbo.OrgStructureUnit`

Орг. единица — узел структуры (филиал, отдел, должность и т. д.). Создаётся и редактируется через карточку единицы: при создании указываются имя, родитель («Входит в») и тип.

### Вкладки карточки единицы

**Настройки:**

- Имя, Тип, Входит в (ParentId)
- При выборе значения «Входит в» в списке доступны только организационные единицы, которые могут быть родительскими. Единицы типа с флагом `IsPosition` не показываются, потому что должности нельзя использовать как родительские узлы.
- Порядковый номер типа (`Order`) сам по себе не определяет, может ли единица быть родительской. Для фильтрации используется именно признак `IsPosition`, поэтому в списке могут отображаться единицы с любым уровнем, если они не являются должностями.
- Порядок единицы (`Order`) — положение среди соседей с тем же родителем; корневые единицы образуют отдельный уровень. Это не уровень типа: уровень задаётся в справочнике типов и отвечает за допустимость родителя, а порядок — только за место единицы в дереве. Поле выведено на вкладке «Настройки» рядом с «Входит в» и сохраняется вместе с карточкой (`PUT /api/admin/org-structure/orgunit/{unitId}`). Пустое поле сохраняет прежний порядок; при переносе единицы к другому родителю она встаёт в конец нового уровня.
- Дерево оргструктуры в администрировании и окно выбора родителя показывают единицы в этом порядке, а не по алфавиту имени: серверный порядок интерфейс не пересортировывает. Если порядок не задан, элементы остаются в том порядке, в котором пришли. На практике у сохранённых единиц порядок задан всегда: существующие заполнены миграцией, новые встают в конец уровня; совпадения сервер разрешает по порядку, затем по имени, затем по идентификатору.
- Связанная группа (LinkedGroupId) — привязка к группе для автосинхронизации. У связанной группы поле «Название» в админке групп заблокировано (с 2.268.348): при переименовании орг.единицы имя связанной группы обновляется автоматически. Удаление оргединицы удаляет её связанную группу — событие пишется в журнал администрирования с идентификатором администратора; переименование оргединицы обновляет имена связанных групп дочерних единиц и фиксирует их в журнале одной записью со значениями до и после по каждой группе.
- Должность (AppointmentId) — только для типа IsPosition
- Является руководящей (IsDirector) — определяет руководителя подчинённых
- Актуальность (IsActual) — неактуальные отображаются серым
- Не показывать в оргструктуре (DoNotShowInOrgStructure)
- Функциональная (IsFuncGroup)
- Комментарий (Comment) — отображается под названием в UI
- Цвет вертикали (Color) — цвет из фиксированной палитры; на схеме оргструктуры выделяет карточку единицы и все элементы ниже по дереву до единицы с собственным цветом

Цвет орг. единицы доступен и через Admin API: возвращается в списке единиц (`GET /api/admin/org-structure/`) и в карточке (`GET /api/admin/org-structure/orgunit/{unitId}`), изменяется через `PUT /api/admin/org-structure/orgunit/{unitId}`. Обновление поля `Color` частичное — учитывается сам факт передачи поля, а не только его значение:

| Поле `Color` в теле запроса | Результат |
|-----------------------------|-----------|
| Отсутствует | Цвет не изменяется |
| Передано значение из допустимого набора | Цвет устанавливается |
| Передан `null` | Цвет сбрасывается |
| Передано значение вне набора | Запрос отклоняется, сохранённый цвет не меняется |

Допустимые значения: `red`, `orange`, `yellow`, `brown`, `green`, `cyan`, `blue`, `purple`, `pink`, `grey` — строчными буквами, регистр учитывается. Проверка значения выполняется до записи в базу. Остальные сценарии обновления орг. единицы (синхронизация с 1С, связывание и отвязка группы, смарт-действие обновления орг. единицы) поле `Color` не передают и потому цвет не затирают.

![Вкладка «Настройки» карточки орг. единицы: название, тип, родитель, связанная группа и флаги](https://help.1forma.ru/help-images/org-structure/rg_structure_view--05.png)

**Состав:** список пользователей в данной единице (UserOrgStructureUnit).

![Вкладка «Состав» карточки орг. единицы: список сотрудников](https://help.1forma.ru/help-images/org-structure/org_structure_view-04.png)

**Должности:** назначение должности из справочника OrgStructureAppointment.

Над поддеревом оргструктуры доступны массовые операции:

| Операция | API |
|----------|-----|
| Связать поддерево с группами | `POST /api/admin/org-structure/orgunit/{unitId}/link-sub-tree-with-group` |
| Синхронизировать группы | `POST /api/admin/org-structure/syncgroups` |
| Экспорт в Excel | `GET /api/admin/org-structure/export-to-excel?withUsers={bool}` |

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

Справочник должностей (`dbo.OrgStructureAppointment`) — простой справочник (ID, Name). Должность назначается конкретной орг. единице через хранимую процедуру `SetAppointmentForOrgUnit`.

![Карточка типа «Должность»: имя, уровень и признак «Является должностью»](https://help.1forma.ru/help-images/org-structure/type_editor.png)

## Пользовательские настройки, справочник должностей и SQL-диагностика

Поведение оргструктуры можно дополнительно настроить через настройки приложения:

| Настройка | Что делает |
|-----------|-----------|
| `OrgStructure_AllowNonUniqueOrgUnitNames` | Разрешить/запретить дубликаты имён в одной ветке (по умолчанию: разрешено) |
| `CustomUserDirectorIds` | Ручное переопределение руководителя: `userId1:directorId1,userId2:directorId2` |
| `customWorkersDictionarySP` | Пользовательская хранимая процедура (SP) вместо стандартного справочника сотрудников |
| `IsOrgUnitAutoCreationGroup` | При включении создание орг. единицы автоматически создаёт и привязывает к ней связанную группу |

Скрытие пустых узлов на схеме включается в форме «Общие настройки приложения» флагом «Не показывать пустые узлы орг. структуры в интерфейсе пользователя» (`DoNotShowEmptyOrgUnitsInOrgStructureUI`). Какие узлы считаются пустыми — в [business.md](https://help.1forma.ru/domains/org-structure/business.md), «Скрытие пустых узлов».

SQL-диагностика — запросы для проверки состояния оргструктуры (выполняются в базе данных 1Ф):

```sql
-- Дерево единиц — в том порядке, в котором единицы показываются в интерфейсе
SELECT Id, Name, ParentId, [Order], OrgStructureTypeId, LinkedGroupId, IsActual, IsDirector
FROM dbo.OrgStructureUnit
ORDER BY ParentId, [Order], Name, Id;

-- Типы
SELECT * FROM dbo.OrgStructureType ORDER BY [Order];

-- Должности
SELECT * FROM dbo.OrgStructureAppointment;

-- Пользователи в оргструктуре
SELECT u.UserID, u.OrgStructureUnitId, u.IsPrimary, osu.Name
FROM dbo.UserOrgStructureUnit u
JOIN dbo.OrgStructureUnit osu ON osu.Id = u.OrgStructureUnitId;

-- Единицы без связанной группы (потенциальная проблема)
SELECT Id, Name
FROM dbo.OrgStructureUnit
WHERE LinkedGroupId IS NULL AND IsActual = 1;

-- Пользователи без основной единицы
SELECT UserID
FROM dbo.UserOrgStructureUnit
GROUP BY UserID
HAVING SUM(CASE WHEN IsPrimary = 1 THEN 1 ELSE 0 END) = 0;
```

## Связи таблиц: руководители, заместители и роли (модель данных)

Определение руководителей, заместителей и ролей опирается на несколько таблиц вокруг `Users`. Руководители задаются либо ролями (`RoleUser` → `Role`, при `Settings.DirectorsDetectionMode = 0`), либо явно в `UserDirectors` с привязкой к орг.единице (`OrgStructureUnit`, при `DirectorsDetectionMode = 1`). Заместители хранятся в `UserAssistant`. Членство в группах — `UserGroups` → `Groups`; орг.единицы образуют иерархию через само-ссылку `OrgStructureUnit.ParentId`.

```mermaid
graph LR
    U["Users — пользователи"]
    UG["UserGroups — членство в группах"]
    G["Groups — группы"]
    RU["RoleUser — роли в группах"]
    R["Role — справочник ролей"]
    RP["RolePowers — назначения ролей"]
    UA["UserAssistant — заместители"]
    UD["UserDirectors — руководители"]
    OSU["OrgStructureUnit — орг.единицы"]

    UG -- "UserID" --> U
    UG -- "GroupID" --> G
    RU -- "UserID" --> U
    RU -- "GroupID" --> G
    RU -- "RoleID" --> R
    RP -- "RoleID / RolePowerID" --> R
    UA -- "UserId" --> U
    UA -- "AssistantUserID" --> U
    UD -- "UserId" --> U
    UD -- "DirectorId" --> U
    UD -- "OrgUnitId" --> OSU
    OSU -- "ParentId" --> OSU
    OSU -- "LinkedGroupId" --> G
```

Полная версия с колонками и схемы связей других подсистем БД — в [system/db-er-diagrams.md](https://help.1forma.ru/domains/system/db-er-diagrams.md).
