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