Stafftrack 26.600.0: управление офисами и маршруты сотрудников
Ломающее обновление
Удалены или изменены публичные API — прикладной код может перестать работать.
В Stafftrack 26.600.0 офисы редактируются в вебе вместе с геозоной, сотрудниками и фотографиями, руководитель видит на карте сегодняшний маршрут сотрудника, а список сотрудников офиса можно запросить у руководителя. Если вы сохраняли офисы своим кодом или строили карты по отметкам, после обновления этот код перестанет работать: сохранение требует версию карточки, а в маршруте появились маркеры начала и конца рабочего дня.
Новое
Редактируйте офис в слайдере
Форма офиса меняет адрес, точку и радиус на карте, время работы, фотографии и состав сотрудников. Перед сохранением она показывает, кто придёт в офис и кого переведут из других, а при сохранении сверяет переводы с movesFingerprint. Если карточку успел изменить кто-то другой, форма перечитает данные. Ошибки фотографий приходят отдельно, сама карточка при этом уже сохранена. Удаляя офис, сотрудников можно перевести в targetOfficeId: нужно право DELETE на исходный офис и UPDATE на целевой.
DTO Office получил version, canDelete и accessRequestStatus, EmployeeOfficeCard — workingHours. Для своих форм есть OfficeStaffPreviewProvider::preview() и previewMovers() и поиск по $query в OfficeProvider::getEmployeesPage(), в JS — OfficeForm из stafftrack.office-form и OfficeSelector из stafftrack.office-selector.
Форма работает с картой OSM. Кнопку создания видит участник круга управления офисами при настроенной карте (canCreateOffice()), а серверная команда Add проверяет только OfficeAction::ADD. Сами офисы доступны, когда включены чек-ин и флаг офисов и регион разрешён.
Запросите список сотрудников офиса
Список сотрудников офиса видит тот, кто в нём работает, входит в круг управления офисами или получил одобренный запрос. Запрос уходит активным руководителям заявителя, а если их нет, активным администраторам. Решение привязано к редакции запроса, поэтому старое уведомление не подтвердит новый запрос. При деактивации пользователя его запросы и полученный через них доступ отзываются.
Из кода запрос создаёт RequestAccess::execute(OfficeDto), решение принимает DecideAccessRequest::execute($requestId, $revision, $approve) с повторной проверкой роли руководителя или администратора. Принадлежность пользователя к интранету проверяет Controller\Office, а то, что подтверждение в мессенджере нажал нужный человек, проверяет вызывающий мессенджер.
Смотрите маршрут сотрудника за сегодня
Карта ищет офисы и сотрудников и показывает сегодняшний маршрут: точки, временную шкалу, паузы и промежутки без данных. Адреса подтягиваются асинхронно, изменения приходят через Pull. Открыть маршрут можно параметром FOCUS_ROUTE_USER_ID компонента или route_user_id в ссылке. Мини-профиль показывает последнюю точку маршрута, а если маршрут недоступен, офис.
На сервере маршрут отдаёт CheckInRoute::getAction(), снимок последней точки отдаёт getLastPointSnapshotAction(), блок местоположения отдаёт EmployeeLocation::getBlockAction(). Чужой маршрут видит пользователь интранета, если сотрудник активен и это разрешает оргструктура. Эти проверки живут в контроллере и провайдере блока, прямой вызов CheckInProvider их не делает. Для своего интерфейса есть RouteMode, RouteLayer и RouteApi из stafftrack.route-mode, RouteTimeline из stafftrack.route-timeline и stafftrack.route-view, который рисует маршрут целиком.
Покажите присутствие команды
Presence\TeamPresenceProvider::getPresencePortion($viewerId, PresenceListQuery) отдаёт вкладки, счётчики, состояние рабочего дня, паузы, визиты, отсутствия и курсор. На сегодня есть вкладки работающих, с отметками и без, завершивших, не начавших и всех. Отпуск и декрет приходят как vacation, больничный как sick_leave, неоплачиваемый отпуск как time_off. Если обязательный источник данных недостоверен, придёт PRESENCE_INCOMPLETE.
Запрашивать можно только от имени текущего пользователя, страница от 1 до 50 сотрудников (по умолчанию 30), поиск до 100 символов, состав ограничен 1500 пользователями ещё до проверки прав. Проверяются доступность учёта времени, rollout и права на чтение рабочего времени.
CheckInSettingsProvider::isCheckInAvailable() возвращает true, только если выполнены все условия: настройка портала, регион, лицензия timeman, тип пользователя, модули и rollout. DepartmentProvider::getTeamIds() отдаёт кешированный состав команды, права на сотрудника проверяйте через getSubordinateIds() или isAccessibleEmployee().
Передайте чат через QR
QR-код теперь может нести выбранный чат. Контекст активируется после входа, живёт 180 секунд и выдаётся один раз через consumeHandoffIntentAction() или CheckInHandoffProvider::consumeIntent(), членство в чате при этом проверяется заново. Если чат недоступен, придёт только chatExpected=true.
Что сломается
Сохраняйте офис с версией и ключом попытки
Office::updateAction() требует version и saveAttemptKey. В Public\Command\Office\Update::execute() после DTO идут $expectedVersion, $saveAttemptKey и $photoTokens, так что старый вызов с массивом фото вторым аргументом упадёт на типе, а вызов с одним DTO отклонится из-за пустого ключа:
use Bitrix\StaffTrack\Public\Command\Office\Update;
$result = (new Update($userId))->execute(
$officeDto,
expectedVersion: $officeVersion,
saveAttemptKey: $attemptKey,
);
Ключ — от 8 до 64 символов [A-Za-z0-9_-], один на все повторы одной правки: повтор уже записанной попытки вернёт alreadySaved. Чужая версия даст STAFFTRACK_OFFICE_VERSION_CONFLICT. Если новая геозона пересекается с другой, создание и изменение зоны требуют подтверждения: $confirmGeoOverlap=true в команде или confirmGeoOverlap='Y' в AJAX.
Отделяйте маркеры рабочего дня от визитов
CheckInProvider::getEmployeeRoute() и getUserCheckInByDate() теперь возвращают маркеры kind=worktime с subKind=day_start или day_end. У них id, координаты и адрес равны null, и визитами они не считаются. Если вы рисуете карту или считаете отметки по этим методам, отфильтруйте их по kind.
Перепроверьте отсрочку автосбора
isPostponementInForce() теперь возвращает true, когда в подразделениях, где состоит сотрудник, нет разрешения на автосбор, даже если окно согласия ещё не показывали. Подразделения, которыми он только руководит, не учитываются. Разрешение или маркер согласия геотрекера устройства снимают отсрочку, а недоступный регион и непрочитанные настройки положительного ответа не дают.
БД
В b_stafftrack_check_in_daily_stats появился nullable MANUAL_CNT, годовой показатель stafftrack.checkins суммирует его. Пересчёт ручных отметок проходит строки с 2026-01-01 по 20 за шаг. Запросы доступа лежат в b_stafftrack_office_access_request с уникальностью (USER_ID, OFFICE_ID) и полем REVISION. Версия карточки офиса вычисляется из полей, отдельной колонки нет, а попытки сохранения хранятся сутки.
Мелочи и находки
- Границы рабочего дня видны и без геоточек, переходы часовых поясов считаются по полуночи сотрудника. Запрос мини-профиля не создаёт пустую строку статистики.
- Для статистики, последних точек и снимков добавлены
DailyStatsReader,LatestCheckInReaderиPointSnapshot, аDayAddressQueueопределяет адреса в фоне. - Сообщения чек-ина в чат по умолчанию идут в формате V2: значение опции сменилось с
NнаY, нужны модуль IM иMessageBuilder. CheckInFormProvider::load()принимает необязательный$dialogIdи учитывает его, только если у пользователя есть доступ к чату.