Как исправить ошибку отправки оповещений на почту при проведении нового документа в 1С:ERP и БИТ.ФИНАНС

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет IT и автоматизация бизнеса
← На главную

Автоматическая отправка уведомлений по электронной почте — важнейший элемент современных корпоративных систем на базе 1С. В интеграционных решениях, таких как 1С:ERP Управление предприятием совместно с финансовой системой БИТ.ФИНАНС, за отправку писем отвечает мощная подсистема оповещений. Однако разработчики часто сталкиваются с ситуацией, когда для новых документов оповещения упорно отказываются регистрироваться и отправляться в момент проведения. Проанализируем эту проблему, детально разберем механизм работы подсистемы БИТ.ФИНАНС, выявим архитектурные ошибки в коде и найдем надежное решение.

Архитектура механизма оповещений в БИТ.ФИНАНС

Для того чтобы понять, почему оповещение не уходит на почту, разберем по шагам, как устроена подсистема отправки писем в БИТ.ФИНАНС. Этот механизм работает по асинхронной трехступенчатой схеме:

  1. Регистрация события: В момент записи или проведения документа программный код генерирует событие. Данные об этом событии записываются в регистр сведений Регистрация событий для оповещений (техническое имя в системе — бит_фн_РегистрацияСобытийОповещений). Запись создается со статусом «Зарегистрировано».
  2. Обработка событий: Специализированное регламентное задание «Обработка событий регистрации оповещений» с определенной периодичностью считывает новые записи из регистра регистрации, сопоставляет их с настройками из справочника бит_фн_Оповещения, проверяет дополнительные пользовательские условия, формирует списки получателей и текст письма по шаблону. Подготовленные данные переносятся в регистр сведений Оповещения.
  3. Отправка писем: Другое регламентное задание — «Отправка оповещений» — берет готовые пакеты писем из регистра Оповещения, подключается к почтовому серверу через системную учетную запись и производит физическую отправку писем адресатам.

Если на первом этапе запись в регистр бит_фн_РегистрацияСобытийОповещений не попадает, то вся дальнейшая цепочка прерывается. Именно это и происходит у автора обсуждаемой темы.

Анализ исходного кода и выявление ошибок

Посмотрим на пример исходного кода, который автор добавил в модуль объекта документа для перехвата проведения:


Процедура СТ_ОбработкаПроведения(Отказ, РежимПроведения)
    Если Отказ Тогда 
        Возврат; 
    КонецЕсли;
    Если НЕ Отказ Тогда 
        Если Статус = Перечисления.СТ_СтатусыАктовИспытаний.НеРаспределен Тогда 
            Документы.СТ_АктИспытаний.СТ_РегистрацияОповещений(ДополнительныеСвойства, ЭтотОбъект); 
        КонецЕсли; 
    КонецЕсли; 
КонецПроцедуры

И процедура регистрации в модуле менеджера документа:


Процедура СТ_РегистрацияОповещений(ДополнительныеСвойства, ДокументОбъект) Экспорт
    бит_фн_ОповещенияСервер.ЗарегистрироватьПоВидуСобытияДляОповещения(
        ПредопределенноеЗначение("Перечисление.СТ_СобытияОповещений.СТ_АктИспытаний_НеРаспределен"), 
        ДокументОбъект.Ссылка
    ); 
КонецПроцедуры

Проанализируем ситуацию и выделим несколько критических уязвимостей данного решения, из-за которых новые документы не регистрируют события.

Причина №1. Передача Ссылки нового документа в транзакции проведения

Обратите внимание на вызов метода бит_фн_ОповещенияСервер.ЗарегистрироватьПоВидуСобытияДляОповещения. Вторым параметром туда передается ДокументОбъект.Ссылка. На этапе проведения нового документа транзакция записи в базу данных еще не завершена. Ссылка на документ уже сформирована в оперативной памяти платформы, но физической записи в таблицах СУБД для внешних сеансов или определенных видов запросов может еще не существовать (или данные находятся в промежуточном состоянии).

Внутри процедуры регистрации БИТ.ФИНАНС выполняется следующий запрос к справочнику настроек оповещений:


Запрос = Новый Запрос(
    "ВЫБРАТЬ
    |	бит_фн_Оповещения.Ссылка КАК Оповещение,
    |	бит_фн_Оповещения.ВидСобытия КАК ВидСобытия,
    |	бит_фн_Оповещения.Виза КАК Виза,
    |	бит_фн_Оповещения.ПользовательскоеУсловие КАК ПользовательскоеУсловие
    |ИЗ
    |	Справочник.бит_фн_Оповещения КАК бит_фн_Оповещения
    |ГДЕ
    |	бит_фн_Оповещения.СТ_СобытиеОповещения = &СобытиеОповещения
    |	И НЕ бит_фн_Оповещения.ПометкаУдаления"
);

После выборки настроек система БИТ.ФИНАНС выполняет проверку пользовательских условий:


СтруктураКонтекст = Новый Структура("ТекущийОбъект", ОбъектОповещения);
// ...
Если ЗначениеЗаполнено(Выборка.ПользовательскоеУсловие) 
   И Не бит_уп_Сервер.ПроверитьПользовательскоеУсловие(Выборка.ПользовательскоеУсловие, СтруктураКонтекст) Тогда
    Продолжить;
КонецЕсли;

Поскольку в ОбъектОповещения была передана Ссылка, функция ПроверитьПользовательскоеУсловие при вычислении формул (например, при проверке реквизитов документа вроде Организации, Суммы или Статуса) будет обращаться к базе данных через эту ссылку. Так как транзакция проведения нового документа еще не зафиксирована окончательно, СУБД вернет либо пустые значения полей, либо старые данные (если документ ранее уже существовал, но перезаписывается). В результате пользовательское условие вернет Ложь, срабатывает оператор Продолжить, и запись в регистр сведений просто игнорируется.

Причина №2. Несоответствие и неопределенность статусов

Автор указывает, что проблема возникает, когда статус документа равен "НеОпределен". При этом в коде СТ_ОбработкаПроведения стоит жесткое условие:

Если Статус = Перечисления.СТ_СтатусыАктовИспытаний.НеРаспределен Тогда

Если в момент проведения нового документа его статус еще не успел заполниться значением "НеРаспределен" и равен пустому значению (или значению "НеОпределен"), то условие Если... Тогда просто не выполняется, и вызов процедуры регистрации оповещения даже не инициируется. Необходимо четко отслеживать жизненный цикл изменения статусов в документе.

Причина №3. Откат транзакции при проведении

Любая ошибка или принудительная отмена проведения (когда переменная Отказ принимает значение Истина) после вызова вашей процедуры регистрации приведет к полному откату транзакции СУБД. Запись в регистре сведений бит_фн_РегистрацияСобытийОповещений, созданная внутри транзакции проведения, также будет безвозвратно удалена. Поэтому регистрация событий внутри процедуры ОбработкаПроведения всегда сопряжена с риском ложных срабатываний или потерь данных при ошибках проведения других механизмов ERP.

Причина №4. Нюанс с реквизитом «Виза»

В ходе обсуждения на форуме прозвучал вопрос о том, почему в отладчике все поля видны, а поле Виза остается пустым. Разберем этот момент подробнее. В архитектуре БИТ.ФИНАНС измерение Виза в регистрах оповещений заполняется исключительно тогда, когда событие связано с процессами визирования и согласования (например, при установке конкретной визы, направлении на согласование и т.д.). Для обычных кастомных событий (таких как изменение статуса или проведение произвольного документа) отсутствие заполненной визы — это абсолютно штатное поведение системы, не влияющее на отправку писем.

Решение проблемы по шагам

Рассмотрим, как правильно модифицировать код и настройки системы, чтобы оповещения гарантированно регистрировались и уходили адресатам.

Шаг 1. Исправление передачи параметров в процедуру регистрации

Для того чтобы подсистема проверки условий БИТ.ФИНАНС могла анализировать реквизиты нового (еще не записанного в БД) документа непосредственно из оперативной памяти, необходимо передавать в процедуру регистрации сам объект документа, а не его ссылку. Модернизируем процедуру в модуле менеджера следующим образом:


Процедура СТ_РегистрацияОповещений(ДополнительныеСвойства, ДокументОбъект) Экспорт
    // Передаем сам ДокументОбъект вместо ДокументОбъект.Ссылка
    бит_фн_ОповещенияСервер.ЗарегистрироватьПоВидуСобытияДляОповещения(
        ПредопределенноеЗначение("Перечисление.СТ_СобытияОповещений.СТ_АктИспытаний_НеРаспределен"), 
        ДокументОбъект
    ); 
КонецПроцедуры

Теперь внутри метода ЗарегистрироватьПоВидуСобытияДляОповещения переменная ОбъектОповещения будет содержать полноценный объект типа ДокументОбъект.СТ_АктИспытаний. В этом случае проверка условий будет производиться корректно по актуальным данным из памяти сеанса.

Шаг 2. Корректировка проверки статусов

Проанализируем логику установки статусов. Если новый документ при проведении должен автоматически получать статус "НеРаспределен", убедимся, что этот статус присваивается реквизиту до момента вызова регистрации оповещений. Перепишем логику в модуле объекта:


Процедура СТ_ОбработкаПроведения(Отказ, РежимПроведения)
    Если Отказ Тогда 
        Возврат; 
    КонецЕсли;
    
    // Если статус не определен для нового документа, принудительно устанавливаем его
    Если Не ЗначениеЗаполнено(Статус) Или Статус = Перечисления.СТ_СтатусыАктовИспытаний.НеОпределен Тогда
        Статус = Перечисления.СТ_СтатусыАктовИспытаний.НеРаспределен;
    КонецЕсли;

    // Теперь инициируем регистрацию события
    Если Статус = Перечисления.СТ_СтатусыАктовИспытаний.НеРаспределен Тогда 
        Документы.СТ_АктИспытаний.СТ_РегистрацияОповещений(ДополнительныеСвойства, ЭтотОбъект); 
    КонецЕсли; 
КонецПроцедуры

Шаг 3. Перенос регистрации в безопасную фазу записи

Чтобы избежать проблем с транзакционными блокировками и откатами проведения, хорошей практикой является вынос регистрации оповещений в событие модуля объекта ПриЗаписи или использование дополнительных свойств для отложенной обработки. Рассмотрим пример реализации через дополнительные свойства:


// В модуле объекта документа
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // Основная логика проведения...
    
    // Если проведение успешно, помечаем необходимость отправки оповещения
    Если Не Отказ Тогда
        ДополнительныеСвойства.Вставить("СТ_ТребуетсяОповещение_НеРаспределен", Истина);
    КонецЕсли;
КонецПроцедуры

Процедура ПриЗаписи(Отказ)
    Если Отказ Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем флаг, установленный при успешном проведении
    Если ДополнительныеСвойства.Свойство("СТ_ТребуетсяОповещение_НеРаспределен") 
        И ДополнительныеСвойства.СТ_ТребуетсяОповещение_НеРаспределен Тогда
        
        Документы.СТ_АктИспытаний.СТ_РегистрацияОповещений(ДополнительныеСвойства, ЭтотОбъект);
    КонецЕсли;
КонецПроцедуры

Шаг 4. Проверка глобальных настроек БИТ.ФИНАНС

Даже при идеальном коде оповещения не зарегистрируются, если отключена глобальная функциональность в настройках конфигурации. Проверим следующие параметры:

  1. Перейдем в раздел Настройки (БИТ) -> Константы (БИТ) -> закладка Прочее.
  2. Убедимся, что включена константа Использовать механизм оповещений.
  3. В справочнике бит_фн_Оповещения найдем нашу настройку по событию СТ_АктИспытаний_НеРаспределен, проверим, что у нее установлен статус Действует.

Шаг 5. Мониторинг регламентных заданий

После того как код заработает и записи начнут появляться в регистре бит_фн_РегистрацияСобытийОповещений, проконтролируем запуск регламентных заданий. В файловых базах или тестовых контурах они часто выключены по умолчанию. Проверим работу заданий через консоль регламентных заданий 1С:

Применение этого комплексного подхода гарантирует стабильную, отказоустойчивую регистрацию и отправку писем при проведении любых документов в связке 1С:ERP и БИТ.ФИНАНС.

← На главную