timemanmobile 26.400.0 Заметное

Timemanmobile 26.0.0–26.400.0: окно «Начало рабочего дня» и рабочие отчёты в мобильном Битрикс24

4 мин чтения
Узнавайте о ломающих изменениях Битрикса раньше, чем они доедут до прода: свежие разборы — в канале @bxmax_updates

Новый модуль timemanmobile («Мобильный учёт рабочего времени») пришёл в коробочный Битрикс24 сразу пятью версиями: 26.0.0, 26.100.0, 26.200.0, 26.300.0 и 26.400.0. Он добавляет в мобильное приложение окно «Начало рабочего дня», рабочие отчёты, экран «Рабочие дни» и плашку рабочего дня. Все версии ставятся одним обновлением, поэтому в разборе итоговое состояние 26.400.0, а в скобках указана версия, где функция появилась.

Новое

Проверьте, что стоят mobile, mobileapp и timeman (26.0.0)

include.php требует все три модуля через Loader::requireModule(), так что Loader::includeModule('timemanmobile') без любого из них бросит исключение, а без timeman модуль не установится (ошибка TIMEMANMOBILE_MODULE_INSTALL_ERROR_TIMEMAN). Свои JN-компоненты и расширения модуль кладёт в /bitrix/mobileapp/timemanmobile/ и отдаёт этот путь приложению через событие mobileapp:onJNComponentWorkspaceGet.

Окно «Начало рабочего дня» включает руководитель отдела (26.200.0)

Окно появилось в 26.100.0 и открывается само при переходах в приложении: переключении вкладок, закрытии карточки CRM, задачи, события календаря или диалога мессенджера. Сотрудник выбирает рабочий день или выходной, а если такие типы отсутствий есть на портале, ещё отгул, отпуск или больничный. Предвыбранный вариант с 26.400.0 определяет сервер по отсутствиям на сегодня и графику сотрудника. После старта дня окно предлагает открыть план на день и рекомендации CoPilot в чате с ботом бизнес-процессов.

Все экшены окна закрыты атрибутом #[ShiftsEnabled] из timeman (26.200.0). Запрос пройдёт, только если у отдела сотрудника включена настройка «Отмечать рабочие смены» (NodeSettingsType::WelcomeBox в humanresources). Руководитель отдела или его заместитель переключает её в настройках экрана «Рабочие дни» сразу для всех отделов, которыми управляет, вместе с их подотделами. Руководители подотделов могут выключить её у себя.

Кроме настройки, все экшены окна требуют доступа к учёту времени с телефона (canUseTimeman() и canManageWorktimeOnMobile() из RecordProvider timeman), иначе вернут access_denied или canOpen: false. Само окно откроется, только если день закрыт и его можно открыть. Экстранет-пользователь получит 403 от #[IntranetOnly].

С 26.400.0 момент показа тоже решает сервер. Расписание хранит timeman: границы периода, лимиты показов и отказов, интервал повтора, общий для всех устройств сотрудника. Клиент получает его в блоке schedule ответа getWorkdayIntentBoxData, по нему планирует следующий запрос, а о показе и исходе (dismiss или targetAction) сообщает экшенами registerShow и registerOutcome. Серверную часть, RecordIntent, мы разбирали в timeman 26.100.0, тогда у неё ещё не было клиента.

Отгул, отпуск или больничный из окна ставится одной записью на целевую смену из RecordIntentProvider::getSchedule() timeman. Параметр $shifts у timemanmobile.WorkdayIntent.addAbsence остался в сигнатуре, но на интервал не влияет. Если целевой смены нет, отсутствие не создаётся, ответ при этом успешный, с absences: [].

Включите рабочие отчёты флагом (26.100.0)

В приложении есть дневной отчёт, полный отчёт с отправкой руководителю, отчёты подчинённых с одобрением и обсуждением, а при закрытии дня открывается шторка с итогами. С 26.200.0 карточка отчёта бывает двух видов, GPT и «робот», и есть режим без ИИ. Руководитель включает отчёты для своих отделов настройкой «Включить план на день и отчёты» (26.200.0).

На портале отчёты по умолчанию выключены флагами из секции feature-flags в .settings.php модуля. Это WorkReportsFeature на опции timemanmobile:work_reports_enabled и WorkReportsWithoutAiFeature на timemanmobile:work_reports_without_ai_enabled (26.200.0), обе опции по умолчанию N. Реестр Bitrix\Mobile\Config\Feature собирает такие классы у всех установленных модулей, а на неизвестный класс отвечает заглушкой, которая всегда выключена. Включённый флаг сработает, только если стоят stafftrack и stafftrackmobile и включён CheckInFeature из stafftrackmobile.

        <?php declare(strict_types=1);

use Bitrix\Main\Loader;
use Bitrix\Mobile\Config\Feature;
use Bitrix\TimemanMobile\Public\Features\WorkReportsFeature;
use Bitrix\TimemanMobile\Public\Features\WorkReportsWithoutAiFeature;

Loader::requireModule('timemanmobile');

$withoutAi = false;

$flag = $withoutAi ? new WorkReportsWithoutAiFeature() : new WorkReportsFeature();
$flag->enable(); // WorkReportsWithoutAiFeature::enable() включает и WorkReportsFeature

if (Feature::isDisabled(WorkReportsFeature::class)) {
    echo 'Опция записана, но нет stafftrack/stafftrackmobile или выключен CheckInFeature', PHP_EOL;
}

    

В режиме без ИИ блок settings в ответах контроллеров отчётов фиксирован: isReportsSettingTurnedOn равен true, isReportGenerationAvailable и hasAiReportAccess равны false.

Экран «Рабочие дни» и плашка дня (26.200.0)

Экран показывает календарь записей рабочего времени, отчётов и отсутствий с легендой, списком и фильтром по сотруднику, там же настройки смен. Данные отдаёт timemanmobile.WorkDays.getData(userId, dateFrom, dateTo): до 500 записей за период, отчёты к ним, отсутствия и карточку пользователя. Записи и отчёты придут, если их разрешает UserPermissionsManager::canReadWorktime($userId) и доступен инструмент worktime. Отсутствия и карточку проверяет canViewUser(). Себя видно всегда, интранет-пользователю видны все, экстранет-пользователю только участники его групп и публичные пользователи. С 26.300.0 дни до регистрации сотрудника не помечаются пропущенными.

У плашки рабочего дня есть меню «старт / перерыв / завершение», эти команды приложение шлёт напрямую в timeman.V2.Record.start|pause|continue|stop. В 26.400.0 добавилась панель рабочего дня, а состояние дня приложение обновляет по pull-событиям timeman.

Какие экшены есть в модуле

Префикс у всех timemanmobile.:

  • WorkdayIntent: getWorkdayIntentBoxData, addAbsence, registerShow, registerOutcome;
  • WorkDays: getData, getSettings, enableWorkShiftOption, disableWorkShiftOption;
  • WorkReport: getSettings, enableWorkReportOption, disableWorkReportOption;
  • Report.getUserReports и FullReport: getUserReports, getReportToSend, getReportSettings, getSubordinateUserReports.

Report и FullReport, кроме getReportSettings, передают вызов в контроллеры timeman V2 через $this->forward(). Модуль берёт экшен timeman целиком, с правами, фильтрами и привязкой параметров, и меняет только форму ответа. Report.getUserReports, FullReport.getReportToSend и getSubordinateUserReports добавляют блок settings, а последний ещё и разворачивает страницу отчётов в плоский список с hasMore и nextOffset.

Экшены enable* и disable* права не проверяют, а timeman сам записывает настройку только в отделы, где текущий пользователь руководитель или заместитель, и во все их подотделы.

Повесьте свой фильтр на экшен атрибутом

#[IntranetOnly] в модуле — это класс с FilterAttributeInterface, который отдаёт фильтр. На метод он вешается одной строкой, без configureActions(). В WorkDays::getData аргументы проверяет #[PositiveNumber] прямо в сигнатуре, без Request-DTO. В своём модуле так можно закрыть экшен опцией и отсечь нулевой userId ещё до вызова метода.

        <?php declare(strict_types=1);

// lib/Infrastructure/Controller/Filter/OptionEnabledFilter.php
namespace Acme\Worklog\Infrastructure\Controller\Filter;

use Bitrix\Main\Config\Option;
use Bitrix\Main\Engine\ActionFilter\Base;
use Bitrix\Main\Error;
use Bitrix\Main\Event;
use Bitrix\Main\EventResult;

final class OptionEnabledFilter extends Base
{
    public function __construct(
        private readonly string $moduleId,
        private readonly string $optionName,
    ) {
        parent::__construct();
    }

    public function onBeforeAction(Event $event): ?EventResult
    {
        if (Option::get($this->moduleId, $this->optionName, 'N') === 'Y') {
            return null;
        }

        $this->addError(new Error('Функция выключена', 403));

        return new EventResult(EventResult::ERROR, null, null, $this);
    }
}

// lib/Infrastructure/Controller/Filter/OptionEnabled.php
namespace Acme\Worklog\Infrastructure\Controller\Filter;

use Attribute;
use Bitrix\Main\Engine\ActionFilter\Attribute\FilterAttributeInterface;
use Bitrix\Main\Engine\ActionFilter\FilterType;

#[Attribute(Attribute::TARGET_METHOD)]
final class OptionEnabled implements FilterAttributeInterface
{
    public function __construct(
        private readonly string $moduleId,
        private readonly string $optionName,
    ) {}

    public function getFilters(): array
    {
        return [new OptionEnabledFilter($this->moduleId, $this->optionName)];
    }

    public function getType(): FilterType
    {
        // EnablePrefilter дописывает фильтр к getDefaultPreFilters(),
        // Prefilter заменил бы их целиком, вместе с Authentication и Csrf
        return FilterType::EnablePrefilter;
    }
}

// lib/Infrastructure/Controller/Timesheet.php
namespace Acme\Worklog\Infrastructure\Controller;

use Acme\Worklog\Infrastructure\Controller\Filter\OptionEnabled;
use Bitrix\Main\Engine\Controller;
use Bitrix\Main\Validation\Rule\PositiveNumber;

final class Timesheet extends Controller
{
    #[OptionEnabled('acme.worklog', 'timesheet_enabled')]
    public function getAction(
        #[PositiveNumber] int $userId,
        #[PositiveNumber] int $dateFrom,
        #[PositiveNumber] int $dateTo,
    ): array {
        return ['userId' => $userId, 'period' => [$dateFrom, $dateTo]];
    }
}

    

Мелочи и находки

  • addAbsence() не сверяет тип отсутствия со списком вариантов окна. Тип приходит с клиента и уходит в AbsenceProvider::addUserAbsence() как есть, а отсутствие ставится только текущему пользователю (26.100.0).
  • С 26.400.0 обработчик mobileapp:onJNComponentWorkspaceGet описан в декларативном install/migrations/events.php, и installDB() применяет его через CModule::installMigrations(). JN-файлы апдейтер копирует по installDirectoriesMapping из migration_config.json. Пригодится как образец для своего модуля без таблиц.
  • При сменном графике, где в ближайшие сутки несколько смен, окно после выбора отсутствия всё ещё показывает шаг «Выбор смены», но сервер выбранные смены не читает и ставит отсутствие на целевую смену из расписания timeman (26.400.0).

Новая версия вышла — разбор уже в Telegram

В канале @bxmax_updates публикуем каждый свежий разбор: что сломается, что устарело и что появилось в API. Узнаете до того, как обновите прод.

Подписаться

Читайте дальше

tasksmobile 26.900.0 Заметное Свежее

Tasksmobile 26.900.0: новый чек-лист в приложении, фильтр на телефоне и кеш счётчиков «Сроков»

В tasksmobile 26.900.0 (сборка от 29 июля 2026 года) мобильный чек-лист задачи переписан, доска «Сроки» начала кешировать счётчики стадий, а приложение научилось добавлять наблюдателя по ссылке. Код интеграторов это задевает, только если он сам вызывает мобильные экшены модуля или подключает его JS-…

3 мин
tasks 26.600.0 Ломающее Свежее

Tasks 26.600.0: наблюдатель по запросу доступа, эпики в новой карточке и аватарки чатов на всех порталах

В задачах 26.600.0 для коробочного Битрикс24 сотрудника, который запросил доступ, можно добавить в наблюдатели прямо из уведомления, эпики создаются из новой карточки, а задачи завершаются из «Моего плана». Заодно обновление само включает статусные аватарки чатов задач, начинает отклонять пустые рез…

4 мин
sign 26.900.0 Заметное Свежее

Sign 26.900.0: представитель компании подписывает кадровые документы Госключом

Sign 26.900.0 для коробочного Битрикс24 добавляет в мастер КЭДО выбор, чем подписывает представитель компании: УКЭП или Госключом. Выбор появится только у компаний с провайдером goskey-lite и только там, где его открыл сервис подписи. Ещё переписали повторную отправку документа из таймлайна, и uid у…

3 мин
lists 26.400.0 Безопасность Свежее

Lists 26.300.0–26.400.0: закрыты XSS в Живой ленте и удаление чужих процессов, notifyAdmin пишет только администраторам

Модуль lists вышел двумя версиями, 26.300.0 и 26.400.0, и обе закрывают дыры. В 26.300.0 закрыли XSS при создании процесса из Живой ленты и уведомления «администратору», которые уходили любому сотруднику с любой ссылкой. В 26.400.0 сотрудник больше не удалит бизнес-процесс чужого документа. Перед об…

2 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…

Можно закрыть чат и перейти на другую страницу. Когда ответ будет готов, на кнопке Домового появится отметка.

Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти