В процессе сопровождения системы «1С:Зарплата и управление персоналом» часто возникает задача оперативного информирования смежных отделов (IT-службы, службы безопасности, административно-хозяйственного отдела) о кадровых изменениях. Это необходимо для своевременного создания или блокировки учетных записей, подготовки рабочих мест или выдачи пропусков. В данной статье мы подробно разберем, как реализовать механизм отслеживания событий приема, перевода и увольнения сотрудников, а также как организовать надежную рассылку уведомлений.
Перед тем как приступить к написанию кода, проанализируем возможные подходы. Самый простой вариант — отправка письма напрямую из подписки на событие ОбработкаПроведения кадрового документа. Однако этот путь имеет существенные недостатки: если пользователь перепроведет документ 10 раз, получатели получат 10 дублирующих писем. Кроме того, отправка почты — это длительная операция, которая может замедлить работу пользователя.
Поэтому мы рассмотрим более профессиональный подход, который включает три этапа:
Для реализации очереди сообщений нам понадобится новый регистр сведений. Назовем его, например, УведомленияПриемУвольнение. Рассмотрим структуру этого регистра:
КадровыйДокумент (тип: Ссылка на документы приема, перевода, увольнения).ДатаЗаписи (Дата/Время), Отправлен (Булево).Также нам пригодятся типовые возможности системы, такие как ШаблоныСообщений, чтобы не «хардкодить» текст письма в конфигураторе, а дать возможность пользователям редактировать его в режиме «1С:Предприятие».
Для того чтобы
система узнала о проведении документа, создадим подписку на событие ОбработкаПроведения для документов ПриемНаРаботу, Увольнение, КадровыйПеревод (и их списочных аналогов). Выясним причину, по которой стоит использовать именно проведение: это гарантирует, что событие официально зафиксировано в учете.
Разберем пример кода обработчика подписки, который проверяет модифицированность документа и записывает данные в нашу очередь:
Процедура ОповещениеПриПриемеУвольненииОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт
Если Источник.ОбменДанными.Загрузка Или Отказ Тогда
Возврат;
КонецЕсли;
// Проверим, не является ли это простым перепроведением без изменения ключевых данных
// Для этого можно сравнить текущий объект с данными в БД
Если Источник.Проведен И Не Источник.Модифицированность() Тогда
Возврат;
КонецЕсли;
// Записываем событие в регистр очереди
МенеджерЗаписи = РегистрыСведений.рпу_УведомленияПриемУвольнение.СоздатьМенеджерЗаписи();
МенеджерЗаписи.КадровыйДокумент = Источник.Ссылка;
МенеджерЗаписи.ДатаЗаписи = ТекущаяДата();
МенеджерЗаписи.Отправлен = Ложь;
Попытка
МенеджерЗаписи.Записать();
Исключение
ЗаписьЖурналаРегистрации("Уведомления", УровеньЖурналаРегистрации.Ошибка,,, "Ошибка записи в очередь");
КонецПопытки;
КонецПроцедуры
Теперь создадим процедуру, которая будет выполняться на сервере по расписанию. Проанализируем логику ее работы: она должна выбрать все неотправленные записи, сформировать красивые HTML-письма и отправить их через системную учетную запись почты.
Рассмотрим пример формирования тела письма в виде таблицы:
Процедура РассылкаИзОчереди() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Очередь.КадровыйДокумент КАК Документ
|ИЗ
| РегистрСведений.рпу_УведомленияПриемУвольнение КАК Очередь
|ГДЕ
| Очередь.Отправлен = ЛОЖЬ";
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат;
КонецЕсли;
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Формируем текст сообщения
ДанныеДокумента = Выборка.Документ;
ТекстТема = "Кадровое событие: " + Строка(ДанныеДокумента);
ТекстПисьма = "<html><body>";
ТекстПисьма = ТекстПисьма + "<p>Зафиксировано кадровое событие:</p>";
ТекстПисьма = ТекстПисьма + "<li>Сотрудник: " + ДанныеДокумента.Сотрудник + "</li>";
ТекстПисьма = ТекстПисьма + "<li>Организация: " + ДанныеДокумента.Организация + "</li>";
ТекстПисьма = ТекстПисьма + "</body></html>";
// Отправка (используем типовой механизм БСП)
ПараметрыПисьма = Новый Структура;
ПараметрыПисьма.Вставить("Кому", "it-admin@company.com");
ПараметрыПисьма.Вставить("Тема", ТекстТема);
ПараметрыПисьма.Вставить("Тело", ТекстПисьма);
ПараметрыПисьма.Вставить("ТипТекста", "HTML");
Если РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(ПараметрыПисьма) Тогда
// Помечаем как отправленное
Менеджер = РегистрыСведений.рпу_УведомленияПриемУвольнение.СоздатьМенеджерЗаписи();
Менеджер.КадровыйДокумент = ДанныеДокумента;
Менеджер.Прочитать();
Менеджер.Отправлен = Истина;
Менеджер.Записать();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Проанализируем ситуацию, когда кадровых документов много и они могут быть разными (Прием, Прием списком, Кадровый перевод, Перевод списком, Восстановление в должности). Чтобы не вешать подписки на каждый документ, можно использовать один единственный объект — регистр сведений КадроваяИсторияСотрудников.
Этот регистр является «точкой сборки» всех кадровых изменений в ЗУП. Выясним преимущества этого метода: любое событие, изменяющее статус сотрудника, обязательно попадает в этот регистр. Мы можем создать расширение и переопределить метод ПриЗаписи этого регистра. Внутри метода ПриЗаписи мы анализируем набор записей и понимаем, какое именно событие произошло (Прием, Перевод или Увольнение), обращаясь к реквизиту ВидСобытия.
При реализации подобных механизмов рассылки в 1С:ЗУП следует учитывать несколько критически важных моментов:
ИнформационнаяБазаПеремещена(). Это предотвратит отправку «мусорных» писем из тестовых баз, когда программист проверяет работу кода на копии данных.Разберем, как реализовать проверку на изменение конкретных полей (например, только если сменилось подразделение или сотрудник), чтобы не спамить при изменении суммы оклада:
// Пример проверки значимых изменений в ПередЗаписью
Если Источник.Ссылка.Пустая() Тогда // Новый документ
НужноУведомление = Истина;
Иначе
// Проверяем изменение ключевых реквизитов
Если Источник.Подразделение <> Источник.Ссылка.Подразделение
Или Источник.Должность <> Источник.Ссылка.Должность Тогда
НужноУведомление = Истина;
КонецЕсли;
КонецЕсли;
Таким образом, комбинируя использование очередей в регистрах сведений и регламентные задания, мы получаем надежную и производительную систему оповещений, которая легко масштабируется и не мешает оперативной работе кадровиков.