Как реализовать автоматическую отправку уведомлений через 2 дня после даты поступления?

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

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

Постановка задачи и анализ условий

Предположим, у нас есть документ ХХХ_ПредварительныйЗаказПоставщику с табличной частью ОтметкиСклада. В этой табличной части присутствуют поля:

  1. ДатаПоступления (тип Дата) — точка отсчета.
  2. Сертификат (тип Булево) — флаг готовности.
  3. ПаспортИзделия (тип Булево) — второй флаг готовности.

Нам необходимо выявить строки, где оба флага имеют значение Ложь, а с момента ДатаПоступления прошло 2 и более дней. Основной вопрос заключается в том, как правильно рассчитать этот момент в запросе и как избежать повторной отправки писем (спама).

Реализация логики в запросе

Для решения задачи мы воспользуемся механизмом запросов. Проанализируем два подхода к расчету разницы дат: использование функции РАЗНОСТЬДАТ и функции ДОБАВИТЬКДАТЕ.

Вариант 1: Использование функции РАЗНОСТЬДАТ

Этот способ интуитивно понятен. Мы вычисляем количество дней между текущей датой и датой из документа. Разберем пример кода:


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

Запрос.УстановитьПараметр("ТекДата", ТекущаяДата());

Вариант 2: Использование функции ДОБАВИТЬКДАТЕ (рекомендуемый)

С точки зрения производительности СУБД, более правильным считается использование функции ДОБАВИТЬКДАТЕ в условии сравнения. Это позволяет оптимизатору запросов более эффективно работать с индексами. Проанализируем ситуацию: мы прибавляем 2 дня к дате поступления и проверяем, не наступил ли этот момент уже сейчас.


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

Обратите внимание на знак сравнения: <= означает, что "контрольная точка" (дата поступления + 2 дня) уже находится в прошлом относительно текущего момента.

Исключение повторных отправки уведомлений

Если регламентное задание запускается ежедневно, то без фиксации факта отправки менеджер будет получать письмо по одному и тому же документу каждый день, пока не проставит нужные галочки. Выясним, как это предотвратить.

Способ А: Реквизит в табличной части

Можно добавить в табличную часть реквизит УведомлениеОтправлено (Булево). После успешной отправки письма программно устанавливаем этот флаг в документе. Минусы: Изменение документа приводит к обновлению версии объекта, изменению даты изменения и может вызвать конфликты блокировок, если документ в этот момент редактирует пользователь.

Способ Б: Независимый регистр сведений (Архитектурно верный)

Рассмотрим создание регистра сведений СостоянияРассылкиУведомлений. В измерениях укажем Документ и КлючСтроки, а в ресурсах — ДатаОтправки. Преимущества очевидны: мы не трогаем сам документ, не меняем его версию и не блокируем его для пользователей. В запрос тогда нужно добавить левое соединение с этим регистром и условие: ГДЕ СостоянияРассылкиУведомлений.Период ЕСТЬ NULL.

Оптимизация работы регламентного задания

Рассмотрим еще несколько важных аспектов, которые помогут сделать решение профессиональным:

  1. Группировка по менеджеру: Чтобы не заваливать почту менеджера сотнями писем (по одному на каждую строку или документ), рекомендуем сначала собрать все просроченные позиции в таблицу, а затем сгруппировать их. В итоге менеджер получит одно письмо со списком всех его проблемных заказов.
  2. Учет рабочих дней: Если товар поступил в пятницу, то 2 календарных дня пройдут в воскресенье. Если вы хотите использовать рабочие дни, функцию ДОБАВИТЬКДАТЕ использовать нельзя. В этом случае нужно использовать производственный календарь. В коде 1С (при наличии БСП) это делается через КалендарныеГрафики.ПолучитьДатуЗавершенияСрока(ДатаПоступления, 2). Полученную дату передаем в запрос как параметр.
  3. Параметризация: Не "зашивайте" количество дней (2) жестко в код. Разумнее вынести этот параметр в константу или настройку программы, чтобы бизнес-логику можно было менять без участия программиста.

Итоговый алгоритм работы регламентного задания

Разберем по шагам, как должен выглядеть код в модуле менеджера или общем модуле:


// 1. Подготовка параметров (например, расчет даты с учетом рабочих дней)
ГраничнаяДата = ТекущаяДата(); // Или расчет через календарь

// 2. Выполнение запроса
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ... (запрос с условиями на даты и флаги)";
Запрос.УстановитьПараметр("ТекДата", ГраничнаяДата);
Результат = Запрос.Выполнить();

// 3. Обход выборки и формирование писем
Если Не Результат.Пустой() Тогда
    Выборка = Результат.Выбрать();
    Пока Выборка.Следующий() Цикл
        // Здесь логика отправки почты или формирования таблицы для групповой отправки
        // 4. Фиксация факта отправки в регистре или реквизите
        ЗафиксироватьОтправку(Выборка.Ссылка);
    КонецЦикла;
КонецЕсли;

Использование функции ДОБАВИТЬКДАТЕ совместно с надежным механизмом фиксации состояния (регистром сведений) обеспечит стабильную работу системы уведомлений и лояльность пользователей, которые не будут страдать от лишнего спама.

← На главную