-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #28 from gromdron/intranet_structure
Intranet: structure
- Loading branch information
Showing
1 changed file
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |