Вступительное слово
Типовые средства платформы не предоставляют события "После проведения", хотя данная тема весьма популярна в поисковиках.
Что же можно использовать из типовых возможностей? Событие "ПослеЗаписиНаСервере" формы объекта документа: "жирный" минус - актуально только для интерактивного проведения из формы объекта. Отчасти можно использовать в каких-то локальных случаях. Но для широкого применения, прежде всего при программном создании документов, данное событие не подходит.
А есть ли что-то в типовых конфигурациях? Если взять семейство конфигурация УТК/КА/ERP, то там можно найти функционал автоматического формирования расходных ордеров на товары. Вкратце алгоритм приблизительно следующий:
- Формируется таблица изменений движений документа по регистру накопления ТоварыКОтгрузке
- В событии ПриЗаписи модуля набора записей регистра накопления ТоварыКОтгрузке вызывается процедура переоформления ордеров:
- Выполняется запись в специальный регистр сведений ОчередьПереоформленияРасходныхОрдеров
- В фоновом режиме (в файловом варианте работы не в фоне) запускается процедура переоформления ордеров
- После успешного переоформления ордеров регистр сведений ОчередьПереоформленияРасходныхОрдеров очищается
Это уже ближе к тому, что можно использовать, но не хватает универсальности: в общем случае мы не знаем, какие движения у нас должны быть триггером.
Практическое применение
Так для чего же нужно отлавливать событие ПослеПроведения? Пример - под спойлером!
Первое приближение
Первое, что пришло в голову - пробуем установить на документ исключительную блокировку: получилось - транзакция проведения завершена. Частично это проблему решило:
- блокировку установили --> исходный документ проведен --> выполняем нужные действия
- блокировку установить не удалось --> записываем ссылку на исходный документ в регистр очереди --> регламентным заданием выполняем нужные действия
Но при таком алгоритме действий в час-пик мы получаем вываливание всех документов в очередь с последующей обработкой регламентным заданием. Менеджеры сразу впали в глубокую тоску.
Итоговый костыль
Идею попытки установки исключительной блокировки требовалось развить, так как пока это единственный универсальный "железный" метод проверки окончания проведения документа (коллеги, буду рад другим вариантам!). Логично, что необходимо в случае неудачной блокировки сделать паузу и попытаться заблокировать еще раз. Опять приплыли: нативной паузы в платформе нет. На счастье параллельно велась разработка обмена с http-сервисом и на ум пришло http-соединение с указанием таймаута. Как оказалось в последствие, идея оказалась не нова) Итого сложилась следующая картина:
- Назначаем количество попыток блокировки документа, чтобы в случае чего не уйти в бесконечный цикл
- Определяемся с паузой между попытками блокировки
- В качестве паузы используем http-запрос на недоступный ip-адрес
Итоговая функция для проверки окончания проведения документа
Функция ДождатьсяЗавершенияПроведения(ИсходныйДокумент, Попыток = 5, Таймаут = 5) Экспорт
СоединениеФиктивное = Новый HTTPСоединение("1.2.3.4",,,,,Таймаут);
ЗапросФиктивный = Новый HTTPЗапрос("/example");
Для К = 1 По Попыток Цикл
Попытка
НачатьТранзакцию(РежимУправленияБлокировкойДанных.Управляемый);
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Документ."+ИсходныйДокумент.Метаданные().Имя);
ЭлементБлокировки.УстановитьЗначение("Ссылка", ИсходныйДокумент);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
ЗафиксироватьТранзакцию();
// если удалось заблокировать, то проведение закончено
Возврат Истина;
Исключение
ОтменитьТранзакцию();
КонецПопытки;
Попытка
// Перед следующей попыткой блокировки документа
// делаем паузу длительностью в Таймаут секунд
ОтветПауза = СоединениеФиктивное.Получить(ЗапросФиктивный);
Исключение
КонецПопытки;
КонецЦикла;
Возврат Ложь;
КонецФункции
Естественно, большое ограничение на использование - вызываться она должна вне транзакции записи документа. Плюс не дает 100% гарантии, если мы ограничиваем количество попыток установки блокировки. Для приведенного ранее практического применения это вполне подходило, так как все действия, которые необходимо было выполнять после проведения, производились в отдельном сеансе фонового задания.
Данное решение не претендует на "истину в первой инстанции", так что с удовольствием почитаю как критику (не спорю, возможно что-то мог важное упустить), так и альтернативные варианты решения данной задачи!