При автоматизации кадрового учета в ЗУП 3.1 часто возникает задача программного определения статуса дня: является ли конкретная дата рабочим днем, выходным или праздником для конкретного сотрудника. Прямое обращение к производственному календарю не всегда дает верный результат, так как у сотрудников могут быть разные графики работы, индивидуальные корректировки или особые условия труда.
Рассмотрим, как правильно решить эту задачу, используя механизмы платформы и типовые объекты конфигурации.
Производственный календарь в 1С:ЗУП отражает общую норму времени для РФ или конкретного региона. Однако учет рабочего времени сотрудников ведется в разрезе Графиков работы. В системе могут существовать индивидуальные графики, сменные режимы работы или документы Индивидуальный график, которые переопределяют статус дня для конкретного физического лица. Следовательно, для получения достоверных данных мы должны обращаться к данным конкретного графика сотрудника.
Самым надежным способом получения статуса дня является обращение к регистру сведений ГрафикиРаботыПоВидамВремени. Именно в этом регистре хранятся итоговые данные о том, как распределено рабочее время, включая все праздничные дни и выходные, с учетом назначенных сотруднику графиков.
Разберем реализацию функции, которая проверяет, является ли день выходным или праздничным.
Шаги реализации:
КадровыйУчет.ГрафикиРаботыПоВидамВремени.ВидУчетаВремени для выбранной даты.Ниже представлен пример кода функции для проверки:
Функция РаботаВПраздничныйИлиВыходнойДень(Сотрудник, РабочаяДата)
// Получаем график работы сотрудника на указанную дату
КадровыеДанные = КадровыйУчет.КадровыеДанныеСотрудников(Истина, Сотрудник, "ГрафикРаботы", РабочаяДата);
Если КадровыеДанные.Количество() = 1 Тогда
ГрафикРаботы = КадровыеДанные[0].ГрафикРаботы;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ГрафикиРаботыПоВидамВремени.ВидУчетаВремени.ОсновноеВремя КАК ОсновноеВремя
|ИЗ
| РегистрСведений.ГрафикиРаботыПоВидамВремени КАК ГрафикиРаботыПоВидамВремени
|ГДЕ
| ГрафикиРаботыПоВидамВремени.ГрафикРаботы = &ГрафикРаботы
| И ГрафикиРаботыПоВидамВремени.Дата = &Дата";
Запрос.УстановитьПараметр("ГрафикРаботы", ГрафикРаботы);
Запрос.УстановитьПараметр("Дата", РабочаяДата);
РезультатЗапроса = Запрос.Выполнить().Выбрать();
Если РезультатЗапроса.Следующий() Тогда
// Проверяем, является ли основной вид времени выходным или праздником
Возврат ((РезультатЗапроса.ОсновноеВремя = Справочники.ВидыИспользованияРабочегоВремени.ВыходныеДни)
ИЛИ (РезультатЗапроса.ОсновноеВремя = Справочники.ВидыИспользованияРабочегоВремени.Праздники));
Иначе
Возврат Ложь;
КонецЕсли;
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
При использовании данного подхода необходимо учитывать следующие моменты:
Индивидуальный график. Это делает решение универсальным.КалендарныеГрафики.ПрочитатьГрафикРаботы. Этот метод возвращает структуру, содержащую детализированную информацию о типе дня, что может быть более эффективно в сложных алгоритмах расчета зарплаты.ВидыИспользованияРабочегоВремени. Это предопределенные элементы, такие как ВыходныеДни и Праздники.Для поиска ближайших рабочих дат или анализа структуры календаря можно воспользоваться функционалом общего модуля КалендарныеГрафики. Например, метод ДатыБлижайшихРабочихДней позволяет определить рабочий день, ближайший к указанной дате. Однако для прямого ответа на вопрос «Является ли сегодня праздник» запрос к регистру сведений ГрафикиРаботыПоВидамВремени остается наиболее прозрачным и легко поддерживаемым решением.
Мы проанализировали задачу и пришли к выводу, что использование запроса к регистру сведений является «кошерным» решением в архитектуре ЗУП 3.1, так как оно опирается на актуальные данные графиков работы, которые уже прошли процедуру заполнения и корректировки пользователем. Для быстрой сверки и отладки данных при разработке подобных алгоритмов можно использовать вспомогательную обработку для просмотра отработанного времени.