Механизм бизнес-событий на конкретном примере

18.02.19

Архитектура

Есть в системе 1С:Документооборот механизм бизнес-событий. Когда мне понадобилось решить конкретную задачу, гугление ни к чему конкретному не привело. Хотелось так «вжух» и всё понять про данный механизм, но в итоге пришлось лезть в код 1С и смотреть реализацию данного механизма. В данной публикации поделюсь результатами исследований, может, кому-то это поможет быстро и легко во всём разобраться.

На днях попросили меня сделать одну на первый взгляд простую и полезную настройку в 1С:Документооборот: если новый входящий документ пришёл в ответ на исходящий, то автора исходящего необходимо оповестить о новом документе не дожидаясь резолюции руководства.

Вроде всё просто: отлавливаем создание вида связи «В ответ на» и запускаем бизнес-процесс «Ознакомление» с нужными параметрами. Но, зайдя в справочник «Виды бизнес-событий» ничего похожего на создание связи не обнаруживаем. Нам подходит только бизнес событие «Изменение входящего документа», в котором мы уже ручками будем отслеживать создание связи и запускать бизнес процесс.

Как механизм бизнес-событий работает в 1С:Документооборот? Рассмотрим на примере «Изменения входящего документа»:

  1. В модуле объекта процедурой «При записи» проверяется новый ли это документ. Если новый, то регистрируется бизнес событие «СозданиеВходящегоДокумента», если нет, то «ИзменениеВходящегоДокумента». Событие регистрируется процедурой БизнесСобытияВызовСервера.ЗарегистрироватьСобытие, где первым параметром указывается ссылка на объект.
  2. Процедура регистрации бизнес-событий создаёт событию уникальный идентификатор и пишет все данные в регистр сведений «ПроизошедшиеБизнесСобытия». На этом обработка в контексте объекта прекращается.
  3. Дальше с действие вступает регламентное задание «Обработка произошедших бизнес-событий», по умолчанию запускаемое каждые 59 секунд. Оно запускает процедуру «ОбработкаПроизошедшихБизнесСобытий», которая выбирает из регистра сведений «ПроизошедшиеБизнесСобытия» все не обработанные события и начинает их обрабатывать.
  4. Программа проверяет кто является потребителем данного бизнес-события (автозапуск бизнес-процесса, пользовательский обработчик или рассылка уведомлений) и запускает соответствующую процедуру. Дальше по коду идёт обработка исключений и очистка регистра «ПроизошедшиеБизнесСобытия».
  5. Выполнение пользовательского обработчика осуществляется в процедуре «ОбработатьСобытиеПользовательскаяОбработкаСобытий», которая выбирает все пользовательские обработчики, связанные с данным видом бизнес-события и выполняет их код. В качестве параметра «Событие» передаётся строка регистра сведений «ПроизошедшиеБизнесСобытия».

Вот такой несложный механизм.

Получается, что нам нужно всю логику разместить в дополнительном обработчике бизнес события для вида бизнес события «Изменение входящего документа» и «Создание входящего документа» т. к. при создании входящего документа на основании исходящего предварительной записи карточки документа перед созданием связи не производится.

Итак, начнём.

 
 Код дополнительного обработчика бизнес-события
Отладка = Ложь;
	
Если Отладка Тогда
	ЗаписьЖурналаРегистрации("Обработка создания связи входящего документа", УровеньЖурналаРегистрации.Информация,,,
	"Процесс запущен");
КонецЕсли;	
// (1)
СвязьДокумента = Справочники.ТипыСвязей.ПолученВОтветНа;
// ищем связанные документы (2)
Запрос = Новый Запрос;
Запрос.Текст = 
	"ВЫБРАТЬ
	|	СвязиДокументов.СвязанныйДокумент
	|ИЗ
	|	РегистрСведений.СвязиДокументов КАК СвязиДокументов
	|ГДЕ
	|	СвязиДокументов.Документ = &Документ
	|	И СвязиДокументов.ТипСвязи = &ТипСвязи
	|
	|УПОРЯДОЧИТЬ ПО
	|	СвязиДокументов.ДатаУстановки";

Запрос.УстановитьПараметр("Документ", Событие.Источник);
Запрос.УстановитьПараметр("ТипСвязи", СвязьДокумента);

РезультатЗапроса = Запрос.Выполнить();

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

ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
	СвязанныйДокумент = ВыборкаДетальныеЗаписи.СвязанныйДокумент;
	// проверяем наличие процесса ознакомление у нового документа
	// он может быть завершён, но главное, чтобы он был (3)
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
				   |	ОзнакомлениеПредметы.Ссылка КАК Ссылка
				   |ИЗ
				   |	БизнесПроцесс.Ознакомление.Предметы КАК ОзнакомлениеПредметы
				   |ГДЕ
				   |	НЕ ОзнакомлениеПредметы.Ссылка.ПометкаУдаления
				   |	И ОзнакомлениеПредметы.Предмет = &Предмет
				   |	И ОзнакомлениеПредметы.РольПредмета = ЗНАЧЕНИЕ(Перечисление.РолиПредметов.Основной)";
	
	Запрос.УстановитьПараметр("Предмет", Событие.Источник);
	РезультатЗапроса = Запрос.Выполнить();
	// если это только что внесённый документ, то по нему нет ознакомлений
	НоваяСвязь = РезультатЗапроса.Пустой();
	
	Если НоваяСвязь Тогда							
		// создаём бизнес процесс Ознакомление (4)
		БизнесПроцесс = БизнесПроцессы.Ознакомление.СоздатьБизнесПроцесс();
		БизнесПроцесс.Автор = Событие.Автор;
		БизнесПроцесс.Наименование = НСтр("ru='Ознакомиться с входящим документом ""'") + Строка(Событие.Источник) + """";
		БизнесПроцесс.Описание = НСтр("ru = 'На Ваш исходящий документ '")
			+ Строка(СвязанныйДокумент) + НСтр("ru = ', был получен ответ, Вам рекомендовано ознакомиться с ним.'");
		Мультипредметность.ДобавитьПредмет(БизнесПроцесс, Событие.Источник);
		БизнесПроцесс.Дата = ТекущаяДата();
		БизнесПроцесс.СрокИсполненияПроцесса = БизнесПроцесс.Дата + 3 * 86400;
		БизнесПроцесс.Состояние =  Перечисления.СостоянияБизнесПроцессов.Активен;
		
		НоваяСтрока = БизнесПроцесс.Исполнители.Добавить();
		НоваяСтрока.Исполнитель = СвязанныйДокумент.Подготовил;
		
		Попытка
			БизнесПроцесс.Записать();
			БизнесПроцесс.Старт();
			
			ЗаписьЖурналаРегистрации("Обработка создания связи входящего документа", УровеньЖурналаРегистрации.Информация,
				Метаданные.БизнесПроцессы.Исполнение, БизнесПроцесс.Ссылка,
					"Создан процесс ознакомления на основе связи с документом " + Строка(СвязанныйДокумент));
		Исключение
			ЗаписьЖурналаРегистрации("Обработка создания связи входящего документа", УровеньЖурналаРегистрации.Ошибка,,,
				"Процесс ознакомления не был создан, ошибка " + ОписаниеОшибки());
		КонецПопытки;					
	Иначе	
		Если Отладка Тогда
			ЗаписьЖурналаРегистрации("Обработка создания связи входящего документа", УровеньЖурналаРегистрации.Информация,
				Метаданные.Справочники.ВнутренниеДокументы, Событие.Источник,
				"Установлено, что связь уже была обработана");
		КонецЕсли;		
	КонецЕсли;			
КонецЦикла;		


Если Отладка Тогда
	ЗаписьЖурналаРегистрации("Обработка создания связи входящего документа", УровеньЖурналаРегистрации.Информация,,,
		"Процесс завершён");
КонецЕсли;

 

Первым делом получим ссылку на нужный тип связи (1).

Дальше проверим установлена ли эта связь у данного документа (2).

А дальше нам необходимо установить, что данная связь является новой, чтобы не генерировать оповещения каждый раз при сохранении карточки документа.

Алгоритм, который я предлагаю не самый точный, но рабочий.  Мы проверяем не было ли по новому документу когда-либо сформировано бизнес-процессов «Ознакомление» (3). Этот подход будет верным если при создании входящих документов автоматически не стартуют иные процессы «Ознакомление».

Ну и наконец создаём новый бизнес-процесс «Ознакомление», прикрепляем в качестве основного предмета новый документ и стартуем его выбрав в качестве исполнителя автора документа.

И всё, все счастливы, особенно исполнители исходящих запросов.

Документооборот бизнес-процесс бизнес-событие

См. также

Архитектура решений Программист Платформа 1С v8.3 Бесплатно (free)

В статье расскажу про относительно уникальное явление на рынке. EmplDos - полноценный сервис, который в качестве Backend использует платформу 1С. Речь пойдёт не только о технической и архитектурной стороне вопроса, а ещё и о всех трудностях и граблях, которые пришлось и до сих пор приходится преодолевать на пути к успеху.

14.10.2024    4159    0    comol    28    

28

Кейсы автоматизации Платформа 1С v8.3 1С:Документооборот Бесплатно (free)

Компания «Уралхим» использует 1С:Документооборот не только для хранения и согласования документов, но и для централизованного управления НСИ между 47 системами (не только на 1С); для бэкенда к мобильным приложениям охранников; и в качестве сервиса заказа справок для сотрудников. О деталях реализации нестандартных решений, разработанных в компании «Уралхим» на базе 1С:Документооборот, пойдет речь в статье.

02.08.2024    3566    0    Novattor    1    

16

Кейсы автоматизации Платформа 1С v8.3 Энергетика и ЖКХ Россия Бесплатно (free)

Делимся опытом автоматизации учета башни раздачи воды.

27.12.2023    2232    0    slavik27    7    

15

Отчеты и дашборды Бизнес-аналитик Бухгалтер Пользователь Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бухгалтерский учет Бесплатно (free)

Если вы привыкли выгружать бухгалтерские операции в Excel и дополнять их там управленческой информацией, вы сможете значительно сэкономить время, получая нужные управленческие отчеты в бухгалтерской программе сразу, без лишних движений. Представляем решение для самостоятельного внедрения управленческого учета в 1С:Бухгалтерии.

11.12.2023    2968    0    Serg_Tangatarov    2    

16

Архитектура решений Программист Бесплатно (free)

Рассмотрим применение архитектурной проверки задач в процессе разработки.

30.10.2023    5711    0    ivanov660    10    

35

Кейсы автоматизации Работа с требованиями Анализ бизнес-процессов Бесплатно (free)

Автоматизировать производственные процессы в 1С:ERP без доработки типовых механизмов очень сложно. А дорабатывать типовые механизмы 1С:ERP не всегда оправданно. Решением может стать технология разработки Рабочих мест, которая позволяет автоматизировать самые сложные участки последовательно – шаг за шагом, процесс за процессом. Расскажем о том, как помочь пользователям вводить большое количество данных, не нарушая порядок ввода и полноту заполнения всех необходимых реквизитов, и как вовлечь сотрудников Заказчика в разработку и тестирование функционала Рабочих мест.

26.10.2023    3016    0    user1754524    15    

17

Кейсы автоматизации Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Когда проект внедрения ERP в крупном холдинге захлебывается в проблемах производительности и в отчаянии пользователей, нужен комплексный подход. Расскажем о битве за производительность и об организационных мероприятиях по наведению порядка в системе и коллективе.

29.08.2023    3559    0    ke_almaty    0    

15
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. sulig 66 03.12.20 10:19 Сейчас в теме
Спасибо. Кратко и понятно.
2. e-9 60 01.09.21 18:35 Сейчас в теме
Коллеги, не совсем по теме, но около: есть тестовые базы ДО на двух проектах; на одном работает ЗаписьЖурналаРегистрации (в доп. обработчике, как в этой статье) , на другом, в точно таком же простейшем обработчике - нет. Почему? Ведение ЖР включено на обеих базах, другие события активно пишутся.

Вот этот простейший обработчик (подписка - на изменение внутреннего документа, в той и другой базе):
	ИмяСобытия = "ююю";
	УровеньИнфо = УровеньЖурналаРегистрации.Информация;
	Объект = Событие.Источник;
	Инфо = "тестттт";
	ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньИнфо, , Объект, Инфо);
3. hrom 69 20.11.21 20:15 Сейчас в теме
Простите, что не в тему "Документооборота", но никого не коробит запрос в цикле?

Почему в первом запросе нельзя было написать левое соединение с БизнесПроцесс.Ознакомление.Предметы и в ГДЕ написать что интересуют только документы с результатом соединения есть Null
4. soulner 465 22.11.21 12:22 Сейчас в теме
(3) Очень коробит. Прямо кушать не могу. Спасает только тот факт, что цикл там бывает редко, примерно никогда.
SkAt91; Raduga; +2 Ответить
Оставьте свое сообщение