Планирование отпусков
На этой странице описано, как организовать ежегодное планирование отпусков в HRlink: загрузить доступные сотрудникам дни, открыть выбор дат, согласовать график с руководителями и выгрузить утверждённые периоды в кадровую систему. Отдельный раздел объясняет, как вернуть в HRlink изменения, внесённые в кадровой системе.
Что получится в конце
HRlink сохранит плановые периоды основного и дополнительного отпусков. Интеграция сможет выгрузить график с фильтрами по сотрудникам, отделам, юрлицам, датам и статусу согласования.
Что нужно заранее
| Что нужно | Где получить или настроить |
|---|---|
tenantHost | Адрес тенантаTenantЭкземпляр системы HRlink на отдельном домене (например, company.hr-link.ru). Внутри одного тенанта может быть несколько пространств клиентов. HRlink |
clientId | Текущий пользователь |
| Токен | Аутентификация |
| Функциональность «График отпусков» | Должна быть включена для тенантаTenantЭкземпляр системы HRlink на отдельном домене (например, company.hr-link.ru). Внутри одного тенанта может быть несколько пространств клиентов. |
| Пользователи и сотрудники | Загрузите заранее по гайду Синхронизация сотрудников |
| Год планирования | Текущий или следующий календарный год |
Если запрос выполняется по мастер-токенуMaster-Api-TokenМастер-токен для M2M-интеграций. Позволяет выполнять запросы от имени любого пользователя системы через заголовки Impersonated-User-Id. Получается через ESA с помощью сертификата интегратора., передайте заголовки impersonation.
Права доступа
| Операция | Право |
|---|---|
| Загрузить доступные дни или периоды отпусков | BULK_DATA_SYNC_TASKS_CREATE |
| Включить или выключить планирование | VACATIONS_CHANGE_PLANNING_STATE |
| Получить запланированные периоды | EMPLOYEE_PLANNED_VACATIONS |
| Загрузить исправленный график | VACATIONS_CREATE_AND_UPDATE в дополнение к BULK_DATA_SYNC_TASKS_CREATE |
| Загрузить региональные календари | CALENDAR_CREATE и CALENDAR_YEARS_EDIT в дополнение к BULK_DATA_SYNC_TASKS_CREATE |
HRlink проверяет права у пользователя клиента и его сотрудников. Набор доступных записей также зависит от юрлиц и отделов, к которым у пользователя есть доступ.
Какие идентификаторы использовать
В процессе участвуют две разные сущности:
| Поле | Какую сущность идентифицирует | Операции |
|---|---|---|
externalId сотрудника | Место работы пользователя в конкретном юрлице | EMPLOYEE_VACATIONS_PLANNING, фильтр employees при выгрузке |
externalId пользователя клиента | Физическое лицо внутри клиента | CLIENT_USER_VACATIONS |
Периоды отпуска принадлежат пользователю клиента. Если у пользователя несколько активных сотрудников, HRlink показывает одинаковые периоды для всех мест работы. mainWorkplace указывать необязательно. HRlink использует доступные дни и календарь сотрудника с признаком mainWorkplace: true. Если признак не задан, HRlink выбирает сотрудника с наибольшим количеством доступных дней для планирования, а при равенстве — сотрудника, которого загрузили раньше.
Какие методы используются
| Шаг | Метод |
|---|---|
| Загрузить календари, доступные дни или исправленный график | Создать задачу синхронизации |
| Проверить задачу синхронизации | Получить статус задачи синхронизации |
| Открыть или закрыть планирование | Изменить состояние планирования |
| Выгрузить график | Получить запланированные отпуска |
Порядок действий
Не запускайте следующий шаг, пока задача bulk sync предыдущего шага не перешла в конечное состояние и интеграция не проверила результат каждого элемента.
Шаг 1. Подготовить сотрудников и календари
Сначала загрузите пользователей и сотрудников. Чтобы HRlink не выбирал место работы автоматически, передайте mainWorkplace: true только для одного активного сотрудника пользователя.
Региональные производственные календари
Этот этап нужен, если сотрудники работают по разным производственным календарям. Сначала создайте задачу CALENDARS, затем укажите календарь в employees[].calendar.externalId задачи CLIENT_USERS_V6.
{
"type": "CALENDARS",
"data": [
{
"externalId": "CAL-TATARSTAN",
"name": "Республика Татарстан",
"years": [
{
"year": 2027,
"dates": [
{
"date": "2027-08-30",
"type": "HOLIDAY"
}
]
}
]
}
]
}
Поле type даты принимает HOLIDAY, WORKDAY, DAYOFF или DAY_BEFORE_HOLIDAY. HRlink не учитывает HOLIDAY при расчёте продолжительности отпуска. Обычные выходные с типом DAYOFF входят в календарные дни отпуска.
Шаг 2. Загрузить доступные дни
Создайте задачу EMPLOYEE_VACATIONS_PLANNING через метод Создать задачу синхронизации.
curl -X POST "https://{tenantHost}/api/v1/clients/{clientId}/bulkDataSyncTasks" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "User-Api-Token: {token}" \
-d '{
"type": "EMPLOYEE_VACATIONS_PLANNING",
"data": [
{
"externalId": "EMP-001",
"legalEntityExternalId": "LE-001",
"availableVacationsPlanning": [
{
"planningYear": 2027,
"basicVacationDayCount": 28,
"additionalVacationDayCount": 3
}
]
}
]
}'
| Поле | Значение |
|---|---|
externalId | Внешний идентификаторexternalIdВнешний идентификатор сущности — произвольная строка, задаваемая интегратором при создании. Связывает сущность HRlink с записью во внешней системе (1С, SAP и др.) без хранения маппинга UUID. сотрудника |
legalEntityExternalId | Внешний идентификаторexternalIdВнешний идентификатор сущности — произвольная строка, задаваемая интегратором при создании. Связывает сущность HRlink с записью во внешней системе (1С, SAP и др.) без хранения маппинга UUID. юрлица; передавайте, если externalId сотрудника не уникален в клиенте |
planningYear | Год, для которого сотрудник распределяет дни |
basicVacationDayCount | Доступные дни основного отпуска |
additionalVacationDayCount | Доступные дни дополнительного отпуска |
В одной задаче можно передать не больше 500 сотрудников. Пара externalId сотрудника и planningYear не должна повторяться. Повторная синхронизация обновляет указанный год и не удаляет значения за другие годы.
HRlink поддерживает два типа отпуска: MAIN и ADDITIONAL. Процесс планирования не обращается к отдельному справочнику типов отпуска.
Сколько дней сотрудник должен распределить
По умолчанию сотрудник должен распределить все загруженные дни. Служба заботы HRlink может задать отдельное обязательное количество дней основного и дополнительного отпуска. Для изменения настройки напишите на help@hr-link.ru.
Как проверить задачу bulk sync
Создать задачу синхронизации возвращает bulkDataSyncTask.id. Передайте этот идентификатор в метод Получить статус задачи синхронизации:
curl "https://{tenantHost}/api/v1/clients/{clientId}/bulkDataSyncTasks/{taskId}" \
-H "Accept: application/json" \
-H "User-Api-Token: {token}"
Задача проходит состояния QUEUED и IN_PROGRESS. Конечные состояния — FINISHED и FAILED.
Состояние FINISHED означает, что обработчик завершил задачу, но не гарантирует успех каждого элемента. Проверьте массив bulkDataSyncTask.data:
| Поле | Что проверить |
|---|---|
state | SYNCED — элемент обработан; FAILED — ошибка; SKIPPED — обработчик пропустил элемент |
result | CREATED, UPDATED или NOT_MODIFIED для обработанного элемента |
errorCode | Публичный код ошибки в формате XX.YYYY |
errorMessage | Описание ошибки |
Интеграция должна считать шаг успешным, только если задача завершилась и каждый ожидаемый элемент обработан без FAILED или SKIPPED.
Шаг 3. Открыть планирование
Вызовите Изменить состояние планирования со значениями planningState=ENABLED и planningYear:
curl -X PUT "https://{tenantHost}/api/v1/clients/{clientId}/vacations/setPlanningState?planningState=ENABLED&planningYear=2027" \
-H "Accept: application/json" \
-H "User-Api-Token: {token}"
Метод принимает текущий или следующий календарный год. Если не передать planningYear, HRlink изменит настройку для следующего года. Передавайте год явно, чтобы интеграция не зависела от даты запуска.
Шаг 4. Запланировать и согласовать периоды
После открытия планирования участники работают в личном кабинете:
- Сотрудник открывает «График отпусков» → «Мой отпуск», добавляет периоды
MAINиADDITIONAL, затем сохраняет график. Инструкция: Заполнить график отпусков. - Руководитель открывает «Отпуска» → «Отпуска подчинённых» и согласует периоды по сотруднику или сразу за месяц. Руководитель также может заполнить график на вкладке «Подчинённые без отпуска». Инструкция: Согласовать график отпусков.
Сотрудник должен запланировать установленное обязательное количество дней. Один период основного отпуска должен длиться не меньше 14 календарных дней.
Пока планирование открыто, сотрудник может менять несогласованные будущие периоды, а руководитель — будущие периоды подчинённых. Пользователь с кадровыми или административными правами может менять периоды независимо от состояния планирования.
Шаг 5. Закрыть планирование
После согласования графика вызовите Изменить состояние планирования со значением DISABLED:
curl -X PUT "https://{tenantHost}/api/v1/clients/{clientId}/vacations/setPlanningState?planningState=DISABLED&planningYear=2027" \
-H "Accept: application/json" \
-H "User-Api-Token: {token}"
После закрытия сотрудники и руководители могут просматривать график, но не могут менять периоды через интерфейс планирования. Кадровики и администраторы сохраняют доступ к редактированию и согласованию.
Закройте планирование до загрузки периодов через CLIENT_USER_VACATIONS. Если планирование открыто хотя бы для одного года из запроса, HRlink отклонит задачу с кодом 13.1713.
Шаг 6. Выгрузить график
Вызовите Получить запланированные отпуска. Поля vacations, employees, department и legalEntity обязательны. Передайте пустые массивы, если фильтр по сотрудникам, отделам или юрлицам не нужен.
curl -X POST "https://{tenantHost}/api/v1/clients/{clientId}/employees/getPlannedVacationPeriod" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "User-Api-Token: {token}" \
-d '{
"vacations": {
"startDateFrom": "2027-01-01",
"startDateTo": "2027-12-31",
"status": "ALL"
},
"employees": [],
"department": [],
"legalEntity": [],
"limit": 100,
"offset": 0,
"withoutDismissedEmployees": true
}'
| Поле | Правило |
|---|---|
vacations.status | ALL, WAITING или APPROVED; если поле не передано, HRlink использует ALL |
startDateFrom, startDateTo | Передавайте обе даты или не передавайте ни одной; фильтр проверяет дату начала отпуска |
employees | Массив объектов с id HRlink или externalId сотрудника |
department, legalEntity | Массив объектов с id HRlink или externalId |
limit | По умолчанию 10, максимум 100 |
offset | По умолчанию 0; увеличивайте на число полученных записей |
Ответ содержит employeePlannedVacationPeriods. Каждый элемент включает id и externalId сотрудника, а также массив periods. Период содержит:
vacationType:MAINилиADDITIONAL;vacationStatus:Ожидает согласованияилиСогласовано;dateFromиdateTo.
Шаг 7. Загрузить исправленный график
Этот шаг нужен, если кадровая система изменила выгруженный график. Создайте задачу CLIENT_USER_VACATIONS методом Создать задачу синхронизации.
curl -X POST "https://{tenantHost}/api/v1/clients/{clientId}/bulkDataSyncTasks" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "User-Api-Token: {token}" \
-d '{
"type": "CLIENT_USER_VACATIONS",
"data": [
{
"externalId": "USER-001",
"year": 2027,
"withApproval": true,
"vacationPeriods": [
{
"startDate": "2027-06-07",
"endDate": "2027-06-20",
"type": "MAIN"
},
{
"startDate": "2027-11-15",
"endDate": "2027-11-28",
"type": "MAIN"
},
{
"startDate": "2027-12-20",
"endDate": "2027-12-22",
"type": "ADDITIONAL"
}
]
}
]
}'
Здесь externalId — идентификатор пользователя клиента, а не сотрудника. withApproval: true создаёт согласованные периоды. При false или без поля HRlink создаёт периоды, которые ожидают согласования.
Полный снимок за год
Каждый элемент CLIENT_USER_VACATIONS задаёт полный требуемый набор периодов одного пользователя за один год:
- HRlink оставляет периоды, которые полностью совпадают с запросом;
- HRlink создаёт новые периоды и обновляет совместимые существующие периоды;
- HRlink удаляет разрешённые для изменения плановые и согласованные периоды, которых нет в запросе;
- HRlink сохраняет перенесённые и подтверждённые сотрудником периоды, а конфликт с активным переносом завершает элемент ошибкой;
- пустой или отсутствующий
vacationPeriodsозначает пустой требуемый снимок и запускает удаление изменяемых периодов за год.
Перед отправкой прочитайте текущий график, примените изменения в кадровой системе и передайте полный снимок. В одной задаче можно передать не больше 500 пар «пользователь — год». Пара externalId пользователя и year не должна повторяться.
Все периоды элемента должны относиться к полю year. Дата начала не может быть позже даты окончания. Один период не может переходить через границу года, а периоды одного пользователя не должны пересекаться.
После создания задачи дождитесь конечного состояния и проверьте каждый элемент по правилам раздела Как проверить задачу bulk sync.
Ошибки синхронизации периодов
| Код | Причина |
|---|---|
13.1713 | Для одного из переданных годов открыто планирование |
13.1714 | В HRlink найдены периоды в состоянии, которое не допускает требуемое изменение |
13.1715 | Входящий период пересекается с целевыми датами активного переноса отпуска |
13.4100 | У пользователя нет права создавать или обновлять отпуска |
13.4101 | Дата начала хотя бы одного периода не относится к полю year |
13.4102 | Дата начала позже даты окончания |
13.4103 | Даты начала и окончания относятся к разным годам |
13.4104 | Периоды пользователя пересекаются |
Изменения после утверждения графика
Сотрудник может запросить перенос отпуска через заявление в HRlink. Процесс подачи описан в инструкции Подать заявление. Активный перенос влияет на синхронизацию CLIENT_USER_VACATIONS: запрос не должен занимать целевые даты переноса или пытаться изменить защищённый период.
Если кадровая система остаётся источником графика после окончания планирования, выполняйте цикл:
- Получите текущие периоды из HRlink.
- Сопоставьте периоды с графиком кадровой системы.
- Сформируйте полный снимок по каждому изменённому пользователю и году.
- Убедитесь, что планирование за год закрыто.
- Отправьте
CLIENT_USER_VACATIONSи проверьте каждый результат задачи.
Контрольный список
- сотрудники загружены, а основное место работы задано;
- региональные календари загружены и назначены до планирования сотрудникам, которые работают не по основному календарю;
EMPLOYEE_VACATIONS_PLANNINGзавершён безFAILEDиSKIPPED;- год явно передан при открытии и закрытии планирования;
- сотрудники распределили обязательные дни, руководители согласовали график;
- перед выгрузкой и обратной синхронизацией планирование закрыто;
- выгрузка прочитана полностью с пагинацией;
CLIENT_USER_VACATIONSсодержит внешние идентификаторыexternalIdВнешний идентификатор сущности — произвольная строка, задаваемая интегратором при создании. Связывает сущность HRlink с записью во внешней системе (1С, SAP и др.) без хранения маппинга UUID. пользователей клиента и полный снимок за год;- интеграция проверила
state,errorCodeиerrorMessageкаждого элемента bulk sync.