From 312ac000f916191ff1c67c05fbe011b89573ef62 Mon Sep 17 00:00:00 2001 From: Andrei Date: Mon, 25 Dec 2023 16:55:10 +0300 Subject: [PATCH] Intranet: structure --- ...20\272\321\202\321\203\321\200\320\260.md" | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 "docs/05_\320\234\320\276\320\264\321\203\320\273\321\214_\320\230\320\275\321\202\321\200\320\260\320\275\320\265\321\202/05_\320\236\321\200\320\263\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260.md" diff --git "a/docs/05_\320\234\320\276\320\264\321\203\320\273\321\214_\320\230\320\275\321\202\321\200\320\260\320\275\320\265\321\202/05_\320\236\321\200\320\263\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260.md" "b/docs/05_\320\234\320\276\320\264\321\203\320\273\321\214_\320\230\320\275\321\202\321\200\320\260\320\275\320\265\321\202/05_\320\236\321\200\320\263\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260.md" new file mode 100644 index 0000000..934dbd8 --- /dev/null +++ "b/docs/05_\320\234\320\276\320\264\321\203\320\273\321\214_\320\230\320\275\321\202\321\200\320\260\320\275\320\265\321\202/05_\320\236\321\200\320\263\321\201\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260.md" @@ -0,0 +1,213 @@ +# Организационная структура + +[TOC] + +Организационная структура (Оргструктура, структура компании) – это организационная схема, которая показывает отношения между подразделениями компании, а также распределяет роли (руководитель-подчиненный)в ней. Многие инструменты Битрикс24 работают, основываясь на структуре компании. Так, например, только руководители видят отчёты подчиненных и время, которое они отработали за определенный период. Настраивая права доступа, вы можете дать права не отдельным сотрудникам, а сразу распределить их по отделам. Так сотрудники будут видеть только нужную информацию, не будут отвлекаться на посторонний шум, а также не будут иметь доступа к конфиденциальной информации. + +В формировании организационной структуры участвую 2 структурные единицы - Подразделение и Сотрудник. В данной статье мы будем рассматривать работу "Подразделений" + +## Архитектура + +Подразделения представляю собой древовидный классификатор построенный на базе разделов информационного блока "Оргструктура". На одном портале может быть только одно корневое подразделение. В отличии от [Отсутствий](./Отсутствия) информационный блок для Оргструктуры единый для всего портала. + +Каждое подразделение характерируется следующими свойствами: +- Активность (Да/Нет) +- Название подразделения (строка) +- Руководитель (привязка к сотруднику) +- Вышестоящее подразделение: (привязка к разделам инфоблока Оргструктуры) + +Дополнительно, каждое подразделение (раздел инфоблока) имеет следующие свойства: +- Учет рабочего времени +- Максимальное время начала рабочего дня +- Минимальное время завершения рабочего дня +- Минимальная продолжительность рабочего дня +- Отчет за день +- Шаблоны отчета +- Свободный график + +Эти свойства используются для учета рабочего времени и для базовых возможностей не являются необходимыми. + +## API + +Поскольку организационная структура построена на базе разделов информационного блока "Оргструктура", API для CRUD-действий аналогичный работе с инфоблоками. +Перед началом работы с API инфоблоков нужно получить идентификатор инфоблока для конкретного сайта. Они хранятся в настройках (`b_options`, `b_option_site`) с кодом модуля `intranet` и названием `iblock_structure` + +```php +use \Bitrix\Main\Config\Option; + +// General (default) +$iblockId = Option::get('intranet', 'iblock_structure', '-1'); + +// Specific site absence iblock id +$siteCo1StructureId = Option::get('intranet', 'iblock_structure', '-1', 'co1'); + +// Old api +$iblockId = \COption::GetOptionInt('intranet', 'iblock_structure', -1); +``` + +>Обратите внимание на трюк с значением по-умолчанию `-1`. Дело в том что при работе с инфоблоками пустое значение (равное нулю) в getList будет проигнорировано. Этот трюк позволяет не беспокоиться в случае технической ошибки и снизить ущерб. + + +>Обратите внимание: в Битрикс24 модуль `intranet` автоматически подключен к порталу, поэтому методы интранета можно вызывать без подключения модуля + + +### Получение дерева + +Не смотря на то что архитектурно дерево подразделений устроено на базе информационных блоков, работать с чтением напрямую из инфоблока не рекомендуется и нет такой необходимости. Существует метод для получения объемного и полного дерева подразделений - `CIntranetUtils::GetStructure()`. + +Пример возвращаемой структуры: +```php +/** + * @var array Cached structure + */ +$structure = \CIntranetUtils::GetStructure(); + +/** + * The same as: + */ +$structure = [ + "TREE" => [ + 0 => ["1"], + 1 => ["2", "4", "3"] + ], + "DATA" => [ + 1 => [ + "ID" => "1", + "NAME" => "DEMO", + "IBLOCK_SECTION_ID" => 0, + "UF_HEAD" => NULL, + "SECTION_PAGE_URL" => "#SITE_DIR#company/structure.php?set_filter_structure=Y&structure_UF_DEPARTMENT=#ID#", + "DEPTH_LEVEL" => "1", + "EMPLOYEES" => ["1"] + ], + 2 => [ + "ID" => "2", + "NAME" => "Бухгалтерия", + "IBLOCK_SECTION_ID" => "1", + "UF_HEAD" => NULL, + "SECTION_PAGE_URL" => "#SITE_DIR#company/structure.php?set_filter_structure=Y&structure_UF_DEPARTMENT=#ID#", + "DEPTH_LEVEL" => "2", + "EMPLOYEES" => ["3"] + ], + 4 => [ + "ID" => "4", + "NAME" => "Отдел маркетинга и рекламы", + "IBLOCK_SECTION_ID" => "1", + "UF_HEAD" => NULL, + "SECTION_PAGE_URL" => "#SITE_DIR#company/structure.php?set_filter_structure=Y&structure_UF_DEPARTMENT=#ID#", + "DEPTH_LEVEL" => "2", + "EMPLOYEES" => [] + ], + 3 => [ + "ID" => "3", + "NAME" => "Отдел продаж", + "IBLOCK_SECTION_ID" => "1", + "UF_HEAD" => NULL, + "SECTION_PAGE_URL" => "#SITE_DIR#company/structure.php?set_filter_structure=Y&structure_UF_DEPARTMENT=#ID#", + "DEPTH_LEVEL" => "2", + "EMPLOYEES" => ["4"] + ], + ], +]; +``` + +`CIntranetUtils::GetStructure()` всегда возвращает структуру из двух элементов: +- Ключ `THREE` - содержит ассоциативный массив где ключи это ID родительского подразделения, а значения это массив из ID вложенных подразделений +- Ключ `DATA` - содержит ассоциативный массив где ключи это идентификаторы подразделений, а значения это структура опсиывающая подразделение + +Разберем структуру ключа `DATA`: +- `ID` (string) - строковое представление идентификатора подразделения +- `NAME` (string) - название подразделения +- `IBLOCK_SECTION_ID` (int|string) - `0` или строковое представление идентификатора родительского подразделения +- `UF_HEAD` (null|string) - `null` или строковое представление идентификатора сотрудника который является руководителем подразделения +- `SECTION_PAGE_URL` (`string`) - шаблон ссылки на детальную страницу подразделения. +- `DEPTH_LEVEL` (`string`) - Уровень вложенности подразделения (от 1 и выше) +- `EMPLOYEES` (`array`) - Массив строковых представлений идентификаторов сотрудников которые входят в данное подразделение + +### Дочерние подразделения + +Существует несколько способов получить дочерние подразделения для указанного. + +*Массовый способ*: если у вас есть список подразделений и вам нужно получить общий список всех вложенных подразделений, то лучше воспользоваться методом `CIntranetUtils::GetIBlockSectionChildren($arSections)`, где `$arSections` - массив идентификаторов подразделений. +Метод использует запросы в цикле, поэтому старайтесь избегать большого количества подразделений в списке. + +Пример поиска: +```php + +$searchSections = [1, 2, 3]; + +/** + * @var array List of department ids + */ +$result = \CIntranetUtils::GetIBlockSectionChildren($searchSections); + +/* +$result = [ + 0 => 1, + 1 => 2, + 2 => 3, + 5 => 4 +]; + */ +``` + +>Обратите внимание на измененный порядок ключей - он получается в результате комбинации array_unique + array_merge, когда подразделения 2 и 3 вложенные в подразделение 1 были запрошены дополнительно. Никогда не опирайтесь на ключи этого метода + +*Точечный способ*: если у вас есть конкретное подразделение и вы хотите получить либо дерево вложенных, либо плоскую структуру, то можете воспользоваться методом `\CIntranetUtils::GetDeparmentsTree($section_id = 0, $bFlat = false)`. + +Пример: + +```php +// Non flat + +$result = \CIntranetUtils::GetDeparmentsTree(1); + +/* +$result = [ + 1 => ["2", "4", "3"] +]; + */ + +// Flat +$result = \CIntranetUtils::GetDeparmentsTree(1, true); +/* +$result = ["2", "4", "3"]; + */ +``` + +>Обратите внимание на вывод в зависимости от параметра `$bFlat` + +### Сотрудники подразделения + +Для получения списка сотрудников подразделения можно воспользоваться методом: `\Bitrix\Intranet\Util::getDepartmentEmployees( $params )`. +Структура `$params` представляет из себя ассоциативный массив, который состоит из следующих ключей: +- `DEPARTMENTS` (`array`) - список идентификаторов подразделений, для которых выполняется поиск +- `RECURSIVE` (`string`) - `Y` / `N` (по-умолчанию `N`) - нужно ли вычислять сотрудников вложенных подразделений +- `ACTIVE` (`string`) - `Y` / `N` включать в список только действующих сотрудников (флаг активности = да) +- `SKIP` (`int`) - идентификатор сотрудника, которого не нужно включать в список. +- `SELECT` (`array`) - набор полей, которые нужно запросить из базы данных + +Результатом работы метода будет наследник `CDBResult`, который можно проитерировать. +Пример: + +```php +use \Bitrix\Intranet\Util; + +$resUsers = Util::getDepartmentEmployees([ + 'DEPARTMENTS' => [1], + 'RECURSIVE' => 'N', +]); + +while( $arUser = $resUsers->fetch() ) +{ + var_dump($arUser); +} +``` + +В настоящий момент функция `CIntranetUtils::getDepartmentEmployees($arDepartments, $bRecursive = false, $bSkipSelf = false, $onlyActive = 'Y', $arSelect = null)` которая оставлена для обратной совместимости и является прокси-функцией в исходную `\Bitrix\Intranet\Util::getDepartmentEmployees` и ее использование не рекомендуется. + + +## Полезная литература + +[Структура компании](https://helpdesk.bitrix24.ru/open/17961850/) +[Связь структуры компании с инструментами Битрикс24](https://helpdesk.bitrix24.ru/open/18002680) \ No newline at end of file