Отсутствия

В интранет модуле имеется сущность “Отсутствие” необходимое для контроля состояния сотрудника во времени (в отпуске, на больничном и т.п.). С точки зрения технического воплощения “Отсутствие” разбито на 2 части - одна обеспечивается модулем “Интранет” и представлена через инструмент “График отсутствий”, а вторая является подсистемой модуля “Календарь”. В этой статье мы рассмотрим “Отсутствие” с точки зрения “Графика отсутствий”.

График отсутствий — это инструмент, который помогает организовать рабочий процесс и следить за отсутствием сотрудников на рабочем месте. Он полезен для планирования проектов и распределения задач: всегда видно, когда сотрудники недоступны по различным причинам — отпуск, больничный или командировка.

Архитектура

С точки зрения архитектуры “Отсутствие” - это элемент инфоблока “График отсутствий”. По-умолчанию располагается в типе инфоблоков “Оргструктура”.

Инфоблок “График отсутствий” - может быть сконфигурирован в настройках модуля Интранет. Что это значит? Вы можете взять любой инфоблок, создать необходимые свойства и в настройках модуля Интранет указать что он является “хранителем” отсутствий.

Отсутствие характеризуется следующими полями:

  • Отсутствующий сотрудник (Код свойства: USER, привязка к пользователю)
  • Тип отсутствия (Код свойства: ABSENCE_TYPE, список)
  • Причина отсутствия (Поле NAME - название инфоблока, строка)
  • Период отсутствия: Начало и Окончание (Поля ACTIVE_FROM и ACTIVE_TO - дата)

Примечание к справочнику “Тип отсутствия”: несмотря на то что в инфоблоке есть список который можно дополнять и редактировать, нужно помнить что не все подсистемы модуля Интранет воспринимают новые поля. Может оказаться так что новый добавленный тип не будет учитываться как отсутствие без уважительной причины, отпуск или другое. Дополнять список можно, но не рекомендуется.

API

Мы уже знаем что отсутствие это запись инфоблока, но у каждого сайта в рамках установки это может быть свой инфоблок, поэтому перед началом работы нужно получить идентификатор инфоблока для конкретного сайта. Они хранятся в настройках (b_options, b_option_site) с кодом модуля intranet и названием iblock_absence

use \Bitrix\Main\Config\Option;

// General (default)
$iblockId = Option::get('intranet', 'iblock_absence', '-1');

// Specific site absence iblock id
$siteCo1AbsenceId = Option::get('intranet', 'iblock_absence', '-1', 'co1');

Обратите внимание на трюк со значением по-умолчанию -1. Дело в том что при запросе в CIBlockElement::getList пустое значение (равное нулю) будет проигнорировано. Этот трюк позволяет не беспокоиться в случае технической ошибки и снизить ущерб.

Альтернативный способ получения общего идентификатора графика отсутствий:


use Bitrix\Intranet\UserAbsence;

/**
 * @var int Absence iblock id
 */
$iblockId = UserAbsence::getIblockId();

Помните что UserAbsence::getIblockId при повреждении записей в b_options может вернуть 0

Типы отсутствий

Для получения всех типов отсутствий помимо методов инфоблока можно воспользоваться методом \Bitrix\Intranet\UserAbsence::getVacationTypes:

use \Bitrix\Intranet\UserAbsence;

$vacationTypes = UserAbsence::getVacationTypes();

Пример содержимого:

$vacationTypes = [
    'VACATION' => [
        'ID' => 'VACATION',
        'ENUM_ID' => '1',
        'NAME' => 'отпуск ежегодный',
        'ACTIVE' => true,
    ],
    'ASSIGNMENT' => [
        'ID' => 'ASSIGNMENT',
        'ENUM_ID' => '2',
        'NAME' => 'командировка',
        'ACTIVE' => false,
    ]
];

Описание полей:

  • ID (string) - Символьный код типа отсутствия
  • ENUM_ID (string) - Идентификатор типа отсутствия
  • NAME (string) - Название отсутствия
  • ACTIVE (bool) - Является ли отсутствие отпуском

Отсутствия текущего месяца

Помимо методов инфоблоков для получения информации есть кешируемый метод, который позволяет получить отсутствия в текущем месяце. За счет кеширования выборка данных на текущем месяце будет быстрее.

use \Bitrix\Intranet\UserAbsence;

$currentMonthAbsences = UserAbsence::getCurrentMonth();

Результирующий массив имеет многомерную структуру: ID сотрудника -> Порядковый номер отсутствия (с 0) -> Отсутствие. Пример:

$currentMonthAbsences = [
    1 => [
        0 => [
            "ID"               => 2,
            "USER_ID"          => 1,
            "ENTRY_TYPE"       => "VACATION",
            "ENTRY_TYPE_ID"    => 1,
            "ENTRY_TYPE_VALUE" => "отпуск ежегодный",
            "IS_VACATION"      => true,
            "DATE_FROM_TS"     => 1703451600
            "DATE_TO_TS"       => 1703538000
        ],
    ]
]

Описание структуры:

  • ID (int) - Идентификатор отсутствия (элемента инфоблока)
  • USER_ID (int) - Идентификатор сотрудника
  • ENTRY_TYPE (string) - Симв.код типа отсутствия
  • ENTRY_TYPE_ID (int) - Идентификатор типа отсутствия
  • ENTRY_TYPE_VALUE (string) - Название типа отсутствия
  • IS_VACATION (bool) - Является отпуском
  • DATE_FROM_TS (int) - Временная метка начала
  • DATE_TO_TS (int) - Временная метка окончания

Проверка отсутствия

Существует так же способ проверить отсутствие пользователя в момент выполнения кода CIntranetUtils::IsUserAbsent($USER_ID):


/**
 * @var int Employee identifier to check absence
 */
$userId = 123; 

/**
 * @var bool True if user is absent
 */
$isUserAbsence = \CIntranetUtils::IsUserAbsent($userId);

И его более сложный аналог - проверка отсутствия в определенный момент \CIntranetUtils::GetAbsenceData($arParams = array(), $MODE = BX_INTRANET_ABSENCE_ALL). Метод принимает на вход 2 аргумента:

  • $arParams (array) - параметры конфигурирующие запрос
  • $mode (int) - режим запроса

На текущий момент поддерживается 2 режима работы:

  • BX_INTRANET_ABSENCE_ALL - отсутствия И из календаря И из графика отсутствий
  • BX_INTRANET_ABSENCE_HR - отсутствия ТОЛЬКО из графика отсутствий

Параметры конфигурирующие запрос:

  • DATE_START (string) - дата начала в формате сайта (Для РФ: d.m.Y H:i:s)
  • DATE_FINISH (string) - дата окончания в формате сайта (Для РФ: d.m.Y H:i:s)
  • USERS (array) - Массив идентификаторов сотрудников для поиска. Пустой массив - без фильтра по сотрудникам
  • PER_USER (bool) - Группировать результат по сотрудникам

Например, для получения отсутствия зарегистрированного для сотрудника ID:1 в пределах дат 10.10.2023 - 12.10.2023 можно использовать такой код:

$absenceList = \CIntranetUtils::GetAbsenceData([
    'DATE_START'  => '10.10.2023 00:00:00',
    'DATE_FINISH' => '12.10.2023 23:59:59',
    'USERS'       => [1],
]);

События

Отдельных событий на создание/редактирование/удаления отсутствий нет - следует использовать события информационных блоков для работы.

Однако в подсистеме существует несколько полезных событий которые можно использовать в своей работе.

Начало и Окончание

Подсистема выбрасывает события начала (OnStartAbsence) и окончания отпуска (OnEndAbsence).

Параметр Значение
USER_ID ID сотрудника (число)
ABSENCE_TYPE Тип отпуска (число)
START Дата начала (строка)
END Дата окончания (строка)
DURATION Длительность (число, сек.)

Возвращаемые значения не обрабатываются.

Пример подписки на событие:

use \Bitrix\Main\Event;
use \Bitrix\Main\EventResult;
use \Bitrix\Main\EventManager;

$eventManager = EventManager::getInstance();

$eventManager->addEventHandler(
    'crm',
    'OnStartAbsence',
    function( Event $event )
    {
        \Bitrix\Main\Diag\Debug::dumpToFile(
            $event->getParameters(),
            date('d.m.Y H:i:s'),
            str_replace($_SERVER['DOCUMENT_ROOT'], '', __DIR__.'/log.log')
        );

        return new EventResult();
    }
);