Сообщение Создание своей сущности. Упаковываем модуль, создаем таблицы и ORM-сущности. Часть 1. появились сначала на Crazy Chipmunk.
]]>├── .settings.php
├── install
│ ├── files
│ ├── index.php
│ └── version.php
├── lang
│ └── ru
└── lib
├── Access
├── Controller
├── Dto
├── Entities
├── Handler
├── Migrations
├── Service
├── TagSelector
└── Validator
Прочитать настройки из .settings.php можно следующим образом:
\Bitrix\Main\Config\Configuration::getInstance($module)
Файл install.php будет состоять из нижеперечисленных методов:

<?php
use Bitrix\Main\Loader;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\ModuleManager;
use Chipmunk\News\Migrations\AddTestNews;
use Chipmunk\News\Migrations\CreateNewsTable;
use Chipmunk\News\Migrations\CreateNewsTagsTable;
use Chipmunk\News\Migrations\CreateTagsTable;
defined('B_PROLOG_INCLUDED') || die;
final class chipmunk_news extends CModule
{
public function __construct()
{
$this->MODULE_ID = 'chipmunk.news';
$this->MODULE_NAME = Loc::getMessage('CHIPMUNK.NEWS_NAME');
$this->MODULE_DESCRIPTION = Loc::getMessage('CHIPMUNK.NEWS_DESCR');
$this->PARTNER_NAME = Loc::getMessage('CHIPMUNK.NEWS_PARTNER_NAME');
$this->PARTNER_URI = Loc::getMessage('CHIPMUNK.NEWS_PARTNER_URL');
$version = include __DIR__ . '/version.php';
$this->MODULE_VERSION = $version['MODULE_VERSION'];
$this->MODULE_VERSION_DATE = $version['MODULE_VERSION_DATE'];
}
public function DoInstall(): bool
{
global $APPLICATION;
$application = \Bitrix\Main\Application::getInstance();
$connection = $application->getConnection();
try {
$connection->startTransaction();
ModuleManager::registerModule($this->MODULE_ID);
Loader::requireModule($this->MODULE_ID);
$this->installMigrations();
$connection->commitTransaction();
} catch (\Exception $e) {
$connection->rollbackTransaction();
$this->unInstallMigrations();
$APPLICATION->ThrowException(Loc::getMessage('CHIPMUNK.NEWS_INSTALL_ERROR') . $e->getMessage());
ModuleManager::unRegisterModule($this->MODULE_ID);
return false;
}
return true;
}
public function installMigrations(): void
{
foreach ($this->getMigrations() as $migration) {
$migration->up();
}
}
public function DoUninstall(): bool
{
global $APPLICATION;
Loader::requireModule($this->MODULE_ID);
$application = \Bitrix\Main\Application::getInstance();
$connection = $application->getConnection();
try {
$connection->startTransaction();
$this->unInstallMigrations();
$connection->commitTransaction();
} catch (\Exception $e) {
$connection->rollbackTransaction();
$APPLICATION->ThrowException("Ошибка удаления модуля: " . $e->getMessage());
return false;
} finally {
ModuleManager::unRegisterModule($this->MODULE_ID);
Loader::clearModuleCache($this->MODULE_ID);
}
return true;
}
public function unInstallMigrations(): void
{
$migrations = array_reverse($this->getMigrations());
foreach ($migrations as $migration) {
$migration->down();
}
}
public function UnInstallDB(): void
{
Loader::requireModule($this->MODULE_ID);
$this->unInstallMigrations();
ModuleManager::unRegisterModule($this->MODULE_ID);
}
public function getMigrations(): array
{
return [
new CreateNewsTable(),
new CreateTagsTable(),
new CreateNewsTagsTable(),
new AddTestNews()
];
}
}
Пошаговое описание каждого метода класса chipmunk_news:
__construct() — конструктор класса, инициализирует основные свойства модуля
MODULE_ID – идентификатор модуля (chipmunk.news)MODULE_NAME – название модуля (из языковых файлов)MODULE_DESCRIPTION – описание модуля (из языковых файлов)PARTNER_NAME – название партнёра (из языковых файлов)PARTNER_URI – URL партнёра ( из языковых файлов)MODULE_VERSION и MODULE_VERSION_DATE – версия и дата версии модуля (из файла version.php)DoInstall(): bool — основной метод установки модуля
ModuleManager::registerModule()Loader::requireModule()installMigrations() для применения миграцийcommitTransaction())rollbackTransaction())unInstallMigrations())ModuleManager::unRegisterModule())installMigrations(): void — накатывает миграции
getMigrations()up() (создание таблиц/заполнение данными)DoUninstall(): bool — основной метод удаления модуля
Loader::requireModule()unInstallMigrations() для отката миграцийcommitTransaction())rollbackTransaction())falseModuleManager::unRegisterModule())unInstallMigrations(): void — откатывает все миграции
getMigrations() (в обратном порядке)down() (удаление таблиц/данных)getMigrations(): array — возвращает массив объектов миграций в порядке их выполнения
CreateNewsTable – создание таблицы новостейCreateTagsTable – создание таблицы теговCreateNewsTagsTable – создание связующей таблицы новости-тегиAddTestNews – добавление тестовых данныхДля начала работы над модулем нам понадобятся 3 таблицы и ORM модели к ним:
<?php
namespace Chipmunk\News\Migrations;
use Bitrix\Main\Application;
use Bitrix\Main\Entity\Base;
use Chipmunk\News\Entities\NewsTable;
class CreateNewsTable
{
public static function up(): void
{
$connection = Application::getConnection();
if (!$connection->isTableExists(NewsTable::getTableName())) {
try {
Base::getInstance(NewsTable::class)->createDbTable();
} catch (\Exception $e) {
throw new \Exception($e);
}
}
}
public static function down(): void
{
$connection = Application::getConnection();
try {
$connection->queryExecute('DROP TABLE IF EXISTS ' . NewsTable::getTableName());
}
catch (\Exception $e) {
throw new \Exception($e);
}
}
}
Описание класса CreateNewsTable и его методов:
up(): voidНазначение:
Создает таблицу новостей в БД, если она не существует.
Логика работы:
Application::getConnection().$connection->isTableExists(), используя имя таблицы из NewsTable::getTableName().Base::getInstance(NewsTable::class)->createDbTable().Пример вызова:
Выполняется при установке модуля или применении миграций.
down(): voidНазначение:
Удаляет таблицу новостей из БД.
Логика работы:
DROP TABLE IF EXISTS <имя_таблицы>.Пример вызова:
Выполняется при удалении модуля или откате миграций.
<?
namespace Chipmunk\News\Entities;
use Bitrix\Main\Entity;
use Bitrix\Main\Type;
use Bitrix\Main\ORM\Fields\Relations\ManyToMany;
use Bitrix\Main\UserTable;
class NewsTable extends Entity\DataManager
{
public static function getTableName()
{
return 'b_chipmunk_news';
}
public static function getMap()
{
return [
(new Entity\IntegerField('ID'))
->configureAutocomplete()
->configurePrimary(),
(new Entity\StringField('TITLE', [
'validation' => function () {
return [
new Entity\Validator\Length(null, 255)
];
}
]))->configureRequired(),
(new Entity\TextField('TEXT'))->configureRequired(),
(new Entity\IntegerField('IMAGE_ID'))->configureRequired(),
(new Entity\IntegerField('AUTHOR_ID'))->configureRequired(),
new Entity\ReferenceField(
'AUTHOR',
UserTable::class,
['=this.AUTHOR_ID' => 'ref.ID'],
['join_type' => 'LEFT']
),
(new Entity\DatetimeField('DATE_CREATE'))
->configureDefaultValue(new Type\DateTime),
(new Entity\DatetimeField('DATE_UPDATE')),
(new ManyToMany('TAGS', TagTable::class))
->configureTableName('b_chipmunk_news_tags')
->configureLocalPrimary('ID', 'NEWS_ID')
->configureLocalReference('NEWS')
->configureRemotePrimary('ID', 'TAG_ID')
->configureRemoteReference('TAG'),
];
}
}
Ниже детальное описание класса NewsTable и его методов:
getTableName(): stringНазначение:
Возвращает имя таблицы в базе данных.
Возвращаемое значение:'b_chipmunk_news' — таблица будет создана с этим именем в БД.
getMap(): arrayНазначение:
Определяет структуру таблицы и связи между сущностями.
Возвращаемое значение:
Массив с описанием полей таблицы и связей.
Описание полей:
ID:
IntegerFieldconfigureAutocomplete() — автоинкрементconfigurePrimary() — первичный ключTITLE:
StringFieldconfigureRequired() — обязательное полеTEXT:
TextFieldconfigureRequired()IMAGE_ID:
IntegerFieldconfigureRequired()AUTHOR_ID:
IntegerFieldconfigureRequired()Связь AUTHOR:
ReferenceFieldUserTable)AUTHOR_ID = ID из UserTableLEFT JOINDATE_CREATE:
DatetimeFieldDATE_UPDATE:
DatetimeFieldСвязь TAGS (ManyToMany):
TagTable)b_chipmunk_news_tagsID (из NewsTable) → NEWS_ID (в промежуточной таблице)ID (из TagTable) → TAG_ID (в промежуточной таблице)<?php
namespace Chipmunk\News\Migrations;
use Bitrix\Main\Application;
use Bitrix\Main\Entity\Base;
use Chipmunk\News\Entities\TagTable;
class CreateTagsTable
{
public static function up(): void
{
$conn = Application::getConnection();
if (!$conn->isTableExists(TagTable::getTableName())) {
try {
Base::getInstance(TagTable::class)->createDbTable();
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
}
public static function down(): void
{
$conn = Application::getConnection();
try {
$conn->queryExecute('DROP TABLE IF EXISTS ' . TagTable::getTableName());
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
}
<?
namespace Chipmunk\News\Entities;
use Bitrix\Main\Entity;
use Bitrix\Main\ORM\Fields\Relations\ManyToMany;
class TagTable extends Entity\DataManager
{
public static function getTableName()
{
return 'b_chipmunk_tags';
}
public static function getMap()
{
return [
(new Entity\IntegerField('ID'))
->configurePrimary()
->configureAutocomplete(),
(new Entity\StringField('NAME', [
'validation' => function() {
return [
new Entity\Validator\Length(null, 255)
];
}
]))->configureRequired(),
(new ManyToMany('NEWS', NewsTable::class))
->configureTableName('b_chipmunk_news_tags')
->configureLocalPrimary('ID', 'TAG_ID')
->configureLocalReference('TAG')
->configureRemotePrimary('ID', 'NEWS_ID')
->configureRemoteReference('NEWS')
];
}
}
<?php
namespace Chipmunk\News\Migrations;
use Bitrix\Main\Application;
class CreateNewsTagsTable
{
protected const TABLE_NAME = 'b_chipmunk_news_tags';
public static function up(): void
{
$conn = Application::getConnection();
if (!$conn->isTableExists(self::TABLE_NAME)) {
try {
$conn->queryExecute("
CREATE TABLE " . self::TABLE_NAME . " (
NEWS_ID INT NOT NULL, TAG_ID INT NOT NULL, PRIMARY KEY (NEWS_ID, TAG_ID),
FOREIGN KEY (NEWS_ID) REFERENCES b_chipmunk_news(ID) ON DELETE CASCADE,
FOREIGN KEY (TAG_ID) REFERENCES b_chipmunk_tags(ID) ON DELETE CASCADE
) ");
} catch (\Exception $e) {
throw new \Exception($e);
}
}
}
public static function down(): void
{
$conn = Application::getConnection();
try {
$conn->queryExecute('DROP TABLE IF EXISTS ' . self::TABLE_NAME);
} catch (\Exception $e) {
throw new \Exception($e);
}
}
}
up(): voidisTableExists())Структура таблицы:
NEWS_ID → b_chipmunk_news(ID)TAG_ID → b_chipmunk_tags(ID)down(): voidСообщение Создание своей сущности. Упаковываем модуль, создаем таблицы и ORM-сущности. Часть 1. появились сначала на Crazy Chipmunk.
]]>Сообщение Создание своей сущности в Битрикс24 появились сначала на Crazy Chipmunk.
]]>В этой статье рассмотрим создание своей сущности в Битрикс24.
Сообщение Создание своей сущности в Битрикс24 появились сначала на Crazy Chipmunk.
]]>Сообщение Api модуля humanresources. Сотрудники. Часть 3 появились сначала на Crazy Chipmunk.
]]>Существует 2 метода: getAllEmployees и getPagedEmployees.
Отличие в том, что метод getAllEmployees вернёт список всех сотрудников подразделения, а метод getPagedEmployees— только ограниченное количество сотрудников с постраничной навигацией, что удобно при работе с большими структурами. Параметр $withAllChildNodes позволяет учесть подчиненные отделы.
Метод getById класса RoleHelperService вернет роль сотрудника в данном подразделении. Роли хранятся в таблице b_hr_structure_role:
use Bitrix\HumanResources\Service\NodeMemberService;
use Bitrix\HumanResources\Service\RoleHelperService;
$departmentId = 3;
$modeMemberService = new NodeMemberService();
$roleHelperService = new RoleHelperService();
// Получить всех сотрудников
$result = $modeMemberService
->getAllEmployees(
$departmentId,
false,
false
)
->getItemMap();
// Получить сотрудников с пагинацией
$result = $modeMemberService
->getPagedEmployees(
$departmentId,
false,
0,
100,
true
)
->getItemMap();
foreach ($result as $item) {
$memberId = $item->id;
foreach ($item->roles as $role) {
// получить роль сотрудника в данном подразделении
$role = $roleHelperService->getById($role);
}
}
Результирующий объект представляет собой экземпляр класса Bitrix\HumanResources\Item\NodeMember.
Свойство id этого объекта указывает на идентификатор сотрудника в контексте конкретного подразделения(memberId).
В свойстве entityId хранится id пользователя.
Этот id отличается от стандартного id пользователя.
Рассмотрим объект Bitrix\HumanResources\Item\NodeMember
| Свойство | Описание |
|---|---|
entityType | Тип сущности, в данном случае это перечисление Bitrix\HumanResources\Type\MemberEntityType |
entityId | Идентификатор сущности (пользователя) |
nodeId | Идентификатор отдела |
active | Статус активности (1 — активен, 0 — неактивен) |
roles | Список ролей |
icon | Иконка |
id | Уникальный идентификатор сотрудника |
addedBy | Идентификатор пользователя, который добавил сотрудника |
createdAt | Дата и время создания сущности (DateTime) |
updatedAt | Дата и время последнего обновления сущности (DateTime) |
use Bitrix\HumanResources\Service\NodeMemberService;
$memberId = 3;
$targetMemberId = 11;
$result = $modeMemberService
->getMemberSubordination(
$memberId,
$targetMemberId
);
Отношения между сотрудниками в Битрикс24 хранятся в перечислении (enum) Bitrix\HumanResources\Type\MemberSubordinateRelationType.
| Enum | Значение | Описание |
|---|---|---|
| RELATION_ITSELF | 0 | Один и тот же человек |
| RELATION_HIGHER | 1 | Сотрудник выше по иерархии (руководитель) |
| RELATION_EQUAL | 2 | Сотрудники на одном уровне (коллеги) |
| RELATION_LOWER | 3 | Сотрудник ниже по иерархии (подчинённый) |
| RELATION_OTHER | 4 | Связь не найдена |
| RELATION_OTHER_STRUCTURE | 5 | Сотрудники из разных структур |
use Bitrix\HumanResources\Service\NodeMemberService;
$departmentId = 3;
$result = $nodeMemberService
->getDefaultHeadRoleEmployees($departmentId)
->getItemMap();
use Bitrix\HumanResources\Exception\CreationFailedException;
use Bitrix\HumanResources\Item\NodeMember;
use Bitrix\HumanResources\Repository\NodeMemberRepository;
use Bitrix\HumanResources\Type\MemberEntityType;
$userId = 1;
$targetDepartmentId = 3;
$member = new NodeMember(
MemberEntityType::USER,
$userId,
$targetDepartmentId,
true,
role: 1 // руководитель
);
$nodeMemberRepository = new NodeMemberRepository();
try {
$nodeMemberRepository->create($member);
} catch (CreationFailedException $e) {
print_r($e->getErrors()->toArray());
}
use Bitrix\HumanResources\Repository\NodeMemberRepository;
use Bitrix\HumanResources\Repository\NodeRepository;
use Bitrix\HumanResources\Service\NodeMemberService;
use Bitrix\Intranet\Exception\UpdateFailedException;
$modeMemberService = new NodeMemberService();
$nodeRepository = new NodeRepository();
$memberRepository = new NodeMemberRepository();
$targetDepartmentId = 3;
$memberId = 9;
$node = $nodeRepository->getById($targetDepartmentId);
$member = $memberRepository->findById($memberId);
// изменить роль на заместителя если требуется
$member->role = 3;
try {
$result = $modeMemberService->moveMember($member, $node);
} catch (UpdateFailedException $e) {
print $e->getErrors()->toArray();
}
При удалении сотрудник будет перемещён в корневое подразделение.
use Bitrix\HumanResources\Exception\WrongStructureItemException;
use Bitrix\HumanResources\Repository\NodeMemberRepository;
use Bitrix\HumanResources\Repository\NodeRepository;
use Bitrix\HumanResources\Service\NodeMemberService;
use Bitrix\Intranet\Exception\UpdateFailedException;
$modeMemberService = new NodeMemberService();
$nodeRepository = new NodeRepository();
$memberRepository = new NodeMemberRepository();
$targetDepartmentId = 3;
$memberId = 9;
$member = $memberRepository->findById($memberId);
try {
$result = $modeMemberService->removeUserMemberFromDepartment($member);
} catch (UpdateFailedException $e) {
print_r($e->getErrors()->toArray());
} catch (WrongStructureItemException $e) {
print_r($e->getErrors()->toArray());
}
Сообщение Api модуля humanresources. Сотрудники. Часть 3 появились сначала на Crazy Chipmunk.
]]>Сообщение Api модуля humanresources. Отделы. Часть 2. появились сначала на Crazy Chipmunk.
]]>
use Bitrix\HumanResources\Service\NodeService;
$nodeService = new NodeService();
$nodeId = 1;
$nodes = $nodeService->getNodeChildNodes($nodeId)->getItemMap();
$arResult = [];
foreach ($nodes as $node) {
$arResult[$node->id] = $node->name;
}
Метод getNodeChildNodes()Bitrix\HumanResources\Item\Collection\NodeCollection
Описание методов коллекции
| Метод | Описание |
|---|---|
| getItemMap() | массив объектов Bitrix\HumanResources\Item\Node |
| getIterator() | вернет экземпляр класса ArrayIterator |
| getFirst() | вернет первый объект коллекции Bitrix\HumanResources\Item\Node |
| getItemById($id) | вернет объект коллекции Bitrix\HumanResources\Item\Node по id |
| filter(\Closure $rule) | вернет отфильтрованную коллекцию |
| count() | количество элементов в коллекции |
$nodeService
->getNodeChildNodes($nodeId)
->filter(fn($node) => $node->id === 1);
Рассмотрим объект класса Bitrix\HumanResources\Item\Node
| Свойство | Описание |
|---|---|
| name | Название отдела |
| type | Тип, перечисление Bitrix\HumanResources\Type\NodeEntityType |
| structureId | Идентификатор структуры, к которому относится отдел |
| accessCode | Код доступа |
| id | Уникальный идентификатор |
| parentId | Идентификатор родительского узла. 0 указывает на корневую сущность |
| depth | Глубина структуры. 0 указывает на верхний уровень |
| createdBy | Идентификатор пользователя, создавшего отдел |
| createdAt | Дата и время создания |
| updatedAt | Дата и время последнего обновления |
| xmlId | Внешний идентификатор |
| active | Активность (1 — активен, 0 — неактивен) |
| globalActive | Глобальный статус активности (1 — активен, 0 — неактивен) |
| sort | Порядок сортировки |
| description | Описание |
use Bitrix\HumanResources\Model\NodeTable;
$nodeId = 3;
$structureId = 1;
$nodes = NodeTable::getList([
'select' => ['*'],
'filter' => ['=PARENT_ID' => $nodeId, '=STRUCTURE_ID' => $structureId],
])->fetchAll();
use Bitrix\HumanResources\Model\NodeMemberTable;
use Bitrix\HumanResources\Model\NodeTable;
use Bitrix\Main\Engine\CurrentUser;
use Bitrix\Main\ORM\Query\Join;
use Bitrix\HumanResources\Service\NodeService;
// через api
$nodeService = new NodeService();
$result = $nodeService->getNodesByUserId(1);
// через таблицы
$nodes = NodeMemberTable::getList([
'filter' => ['ENTITY_ID' => CurrentUser::get()->getId(), 'ACTIVE' => 'Y'],
'select' => ['ID', 'DEPARTMENT'],
'runtime' => [
'DEPARTMENT' =>
[
'data_type' => NodeTable::class,
'reference' => ['=this.NODE_ID' => 'ref.ID'],
'join_type' => Join::TYPE_LEFT
]
]
])->FetchCollection();
foreach ($nodes as $node) {
echo $node->get('DEPARTMENT')->getName();
echo '<br>';
}
use Bitrix\HumanResources\Exception\CreationFailedException;
use Bitrix\HumanResources\Item\Node;
use Bitrix\HumanResources\Service\NodeService;
use Bitrix\HumanResources\Type\NodeEntityType;
/** на вход свойства объекта Bitrix\HumanResources\Item\Node
* @param string $name
* @param NodeEntityType = DEPARTMENT
* @param int $structureId =1
* @param ?string $accessCode
* @param ?int $id
* @param ?int $parentId
*/
$node = new Node(
'It-отдел',
NodeEntityType::DEPARTMENT,
1,
null,
null,
1
);
try {
$nodeService->insertNode($node);
} catch (Exception $e) {
print_r($e->getErrors()->toArray());
}
use Bitrix\HumanResources\Repository\NodeRepository;
use Bitrix\HumanResources\Service\NodeService;
$nodeService = new NodeService();
$nodeRepository = new NodeRepository();
$departmentId = 9;
$node = $nodeRepository->getById($departmentId);
$node->description = "Просто какое-то описание";
$node->parentId = 2;
try {
$nodeService->updateNode($node);
} catch (Exception $e) {
print_r($e->getErrors()->toArray());
}
use Bitrix\HumanResources\Exception\DeleteFailedException;
use Bitrix\HumanResources\Repository\NodeRepository;
use Bitrix\HumanResources\Service\NodeService;
$nodeService = new NodeService();
$nodeRepository = new NodeRepository();
$departmentId = 9;
$node = $nodeRepository->getById($departmentId);
try {
$nodeService->removeNode($node);
} catch (DeleteFailedException $e) {
print $e->getErrors()->toArray();
}
Сообщение Api модуля humanresources. Отделы. Часть 2. появились сначала на Crazy Chipmunk.
]]>Сообщение Новая структура компании в Битрикс24. Часть 1 появились сначала на Crazy Chipmunk.
]]>Ранее данные об организационной структуре хранились в инфоблоках, но в текущей версии модуля реализовано хранение в собственных таблицах.
Модуль позволяет:
Страница создания и изменения структуры компании расположена по адресу: /hr/structure/

На странице также можно гибко настроить права доступа к редактированию структуры.
Настройки позволяют гибко управлять правами редактирования и просмотра организационной структуры.

На данный момент (апрель 2025) реализована обратная совместимость модуля HR: При добавлении подразделения через модуль, подразделение добавляется и в инфоблоки (и наоборот). Важно: В будущем планируется полный переход на новую модель без обратной совместимости.
В прошлой версии для хранения древовидной структуры использовался механизм разделов инфоблоков, основанный на методе Nested Sets.
Nested Sets — это один из методов хранения иерархических данных (например, деревьев или структур с родительскими и дочерними элементами) в базе данных. Этот подход основан на использовании двух числовых значений (обычно называемых LEFT_MARGIN и RIGHT_MARGIN) для каждого узла в дереве.
В новой версии используется комбинация методов Closure Table и Adjacency List.
Каждый узел в дереве сохраняет ссылку на своего родителя, обычно с использованием поля parent_id.
Каждый узел хранит свой уникальный идентификатор (например, id) и идентификатор родительского узла (parent_id), который указывает на родительский элемент в дереве. Для корневых узлов значение parent_id будет равно NULL или 0.
Хранит не только родителя каждого узла, но и все возможные отношения между узлами. То есть для каждого узла сохраняются все его предки и сам он. Это достигается за счет использования дополнительной таблицы, которая хранит пары «потомок-родитель» для всех уровней иерархии.
В Closure Table создается таблица, где каждая строка содержит два столбца: ancestor (предок) и descendant (потомок). Таблица хранит все возможные пути от каждого потомка к его предкам.
| Таблица | Назначение |
|---|---|
| b_hr_access_permission | Права доступа, привязанные к ролям |
| b_hr_access_role | Список всех ролей в системе (например, Администратор, Руководитель, Сотрудник). Создать роль можно на странице настроек прав доступа |
| b_hr_access_role_relation | Связь ролей с пользователями, подразделениями, группами |
| b_hr_structure | Структуры компании (задел на будущее, на данный момент не реализовано) |
| b_hr_structure_node | Конкретные узлы структуры (отделы), реализация метода Adjacency List |
| b_hr_structure_node_member | Сотрудники, прикрепленные к отделам |
| b_hr_structure_node_path | Для хранения узлов дерева, реализация метода Closure Table |
| b_hr_structure_node_relation | Для хранения всех возможных путей между узлами |
| b_hr_log | Логи ошибок |
| b_hr_structure_node_member_role | Конкретные роли сотрудников в рамках их подразделений. |
Сообщение Новая структура компании в Битрикс24. Часть 1 появились сначала на Crazy Chipmunk.
]]>