Цель статьи
Показать, как можно реализовать сохранение важных оповещений пользователя в центре уведомлений 1С даже после перезапуска сеанса.
Введение и проблематика
В управляемом приложении 1С важные события часто выводятся пользователю через механизм оповещений: программа показывает сообщение в центре уведомлений, пользователь кликает по нему и переходит к нужному объекту или форме.
Для многих сценариев этого достаточно. Если напоминание касается обычной задачи или календарного события, его можно показать один раз и отключить. Но в интеграционных и фоновых процессах встречаются ситуации, когда оповещение нельзя потерять: ошибка обмена, не загруженная оплата, результат регламентного задания, необходимость ручной проверки данных.
Проблема проявляется в том, что типовая подсистема напоминаний БСП формирует пользовательское оповещение, но после вывода оно может быть отключено и больше не появиться. Если пользователь закрыл сеанс, пропустил всплывающее окно или перезапустил клиент, важное сообщение может не дойти до адресата.
В нашей задаче такая потребность возникла при обработке оплат через СБП. Фоновая загрузка могла успешно получить оплату от сервиса, но не всегда могла корректно отразить ее в учетных документах. В этом случае важно не просто записать ошибку в журнал регистрации, а гарантированно показать ответственному пользователю или администратору сохраняемое оповещение с переходом к месту анализа проблемы.
Ниже разберем подход, который позволяет оставить типовую механику БСП, но расширить ее для важных оповещений: такие уведомления сохраняются между сеансами и отключаются только после открытия пользователем.
Решение
Идея решения состоит в том, чтобы разделить два действия, которые в типовом механизме часто выполняются вместе:
- показать пользователю оповещение;
- отключить напоминание, из которого это оповещение сформировано.
Для обычных напоминаний такое поведение корректно: пользователь получил сообщение, запись можно отключить. Но для важных уведомлений лучше сохранить запись до явного действия пользователя. Поэтому мы оставляем типовой механизм для большинства сценариев и добавляем точечное исключение для важных оповещений.
Общая схема работы
- При возникновении важного события создаем напоминание пользователя.
- В тексте или идентификаторе напоминания фиксируем технический признак типа события.
- При обновлении центра оповещений определяем, относится ли напоминание к важным.
- Если оповещение важное, показываем его пользователю, но не отключаем запись напоминания автоматически.
- При клике по оповещению открываем нужную навигационную ссылку и только после этого отключаем напоминание.
Такой подход сохраняет совместимость с БСП: мы не меняем структуру регистра напоминаний и не переписываем общий механизм установки напоминаний. Доработка сосредоточена в местах, где формируется текст важного события и где центр оповещений принимает решение, отключать запись сразу или оставить ее до открытия пользователем.
Формирование важного напоминания
При создании напоминания важно заполнить не только текст, но и устойчивый идентификатор. По нему форма оповещений сможет определить тип события, подобрать картинку и решить, нужно ли сохранять запись между сеансами.
Пример формирования описания напоминания:
ОписаниеНапоминания = НапоминанияПользователяКлиентСервер.ОписаниеНапоминания(, Истина);
ОписаниеНапоминания.Пользователь = Ответственный;
ОписаниеНапоминания.ВремяСобытия = ДатаНапоминания;
ОписаниеНапоминания.СрокНапоминания = ДатаНапоминания;
ОписаниеНапоминания.Источник = ИсточникОповещения;
ОписаниеНапоминания.Описание = ТекстОповещения;
ОписаниеНапоминания.Идентификатор = ИдентификаторОповещения;
ОписаниеНапоминания.Вставить("Заголовок", НСтр("ru = 'Важное оповещение'"));
ОписаниеНапоминания.Вставить("Текст", ТекстОповещения);
НапоминанияПользователяСлужебный.ПодключитьНапоминание(ОписаниеНапоминания);В качестве идентификатора можно использовать собственный префикс, например Оплата через СБП: или Оплата через СБП с ошибкой:. Главное, чтобы этот признак был стабильным и не зависел от пользовательского текста.
Определение важных оповещений
Чтобы не размазывать проверки по коду, удобно вынести ключи и функции определения типа оповещения в отдельный клиент-серверный общий модуль.
Например:
Функция КлючИдентификатораОповещенияОбОшибочнойОплатеЧерезСБП() Экспорт
Возврат "Оплата через СБП с ошибкой:";
КонецФункции
Функция ЭтоОповещениеОбОшибочнойЗагрузкеОплатыСБП(ОписаниеОповещения) Экспорт
Возврат СтрНачинаетсяС(
ОписаниеОповещения,
КлючИдентификатораОповещенияОбОшибочнойОплатеЧерезСБП());
КонецФункцииПроверка через начало строки предпочтительнее поиска по всему тексту: так меньше риск ошибочно классифицировать обычное сообщение как важное.
Доработка формы центра оповещений
В форме оповещений БСП при обновлении таблицы напоминаний каждое текущее напоминание преобразуется в пользовательское оповещение. В типовом варианте после показа вызывается отключение повторного оповещения. Именно этот момент нужно изменить.
Типовая логика:
ПоказатьОповещениеПользователя(...);
ОтключитьПовторноеОповещениеПользователю(Контекст);Доработанная логика:
ПоказатьОповещениеПользователя(...);
Если ЭтоВажноеОповещение(Напоминание) Тогда
НапоминанияПользователяКлиент.УдалитьЗаписьИзКэшаОповещений(
ПараметрыНапоминания);
Иначе
ОтключитьПовторноеОповещениеПользователю(Контекст);
КонецЕсли;Здесь принципиально важно не отключать само напоминание для важных событий. Мы очищаем только клиентский кэш, чтобы оповещение не появлялось повторно в этом же цикле обновления. Запись в регистре остается, поэтому после перезапуска сеанса ее можно снова прочитать и показать пользователю.
Отключение при открытии оповещения
Чтобы важное оповещение не висело бесконечно, его нужно отключать в момент осознанного действия пользователя — при клике по уведомлению.
В обработчике открытия оповещения можно выполнить переход по навигационной ссылке, а затем отключить запись:
Если ЭтоВажноеОповещение(Контекст.Описание) Тогда
ПараметрыНапоминания =
НапоминанияПользователяКлиентСервер.ОписаниеНапоминания(Контекст);
ОповещенияПользователейОСобытияхВызовСервера.ОтключитьОповещение(
ПараметрыНапоминания);
КонецЕсли;Если в идентификаторе или в дополнительном реквизите хранится навигационная ссылка, ее можно использовать для перехода к объекту, форме списка или журналу регистрации.
Результат
После доработки важное оповещение работает как устойчивое сообщение с подтверждением прочтения.
Если пользователь находится в текущем сеансе, он видит оповещение в центре уведомлений. Если пользователь закрыл 1С до момента показа или перезапустил клиент, запись остается в регистре напоминаний и будет показана при следующем обновлении формы оповещений.
При этом обычные напоминания продолжают работать типовым образом: они показываются и автоматически отключаются после вывода. Изменение затрагивает только те оповещения, которые мы явно классифицируем как важные.
Для пользователя сценарий выглядит так:
- Фоновая операция завершилась успешно или с ошибкой.
- В центре уведомлений появляется важное оповещение.
- Если сеанс был закрыт, оповещение сохраняется и появляется после повторного входа.
- При нажатии на оповещение открывается связанный объект, форма или журнал регистрации.
- После перехода оповещение отключается и больше не показывается.
Такой результат особенно полезен для интеграционных механизмов. Например, при загрузке оплат через СБП можно отдельно уведомить ответственного пользователя об успешной загрузке оплаты, а администратора — об ошибке обработки с переходом в журнал регистрации.
Заключение
Для сценариев, где важно не просто показать пользователю всплывающее сообщение, а гарантированно донести до него результат фоновой обработки, стандартного поведения оповещений может быть недостаточно.
Решение можно построить без отдельного регистра и без собственной подсистемы уведомлений: использовать существующие напоминания пользователей как постоянное хранилище важных событий, а форму центра оповещений доработать так, чтобы для выбранных событий не выполнялось автоматическое отключение при первом показе.
В результате пользователь видит важное оповещение после перезапуска сеанса, может открыть связанный объект или журнал регистрации, а система удаляет уведомление только после осознанного действия пользователя. Такой подход хорошо подходит для уведомлений о результатах фоновых обменов, загрузок, регламентных заданий и других операций, которые нельзя потерять из-за закрытия клиентского приложения.