При автоматизации бизнес-процессов часто возникает задача классификации клиентуры: например, установить контрагенту статус «Постоянный», если совокупная сумма оплат от него превысила 100 000 рублей, и оставить статус «Разовый» по умолчанию. Рассмотрим, как правильно реализовать эту логику в конфигурации «Управление торговлей» редакции 10.3, избежав типовых ошибок начинающих разработчиков.
Первая мысль, которая возникает у начинающего разработчика — добавить обработку в процедуру проведения документа ПриходныйКассовыйОрдер. Однако этот подход содержит критические недостатки:
ПлатежноеПоручениеВходящее, ПлатежныйОрдерПоступлениеДенежныхСредств, а также зачеты авансов через КорректировкаДолга. Если привязаться только к кассовым ордерам, расчет совокупных оплат будет некорректным.Контрагенты внутри транзакции проведения документа приводит к блокировке элемента. Если параллельно другой пользователь открывает карточку этого контрагента или проводит по нему документ, возникают ожидания и ошибки блокировок.Наиболее надежный и производительный способ — расчёт накопительных сумм и обновление статусов с помощью регламентного задания, запускаемого во внерабочее время (например, ночью) или с заданной периодичностью.
Рассмотрим алгоритм работы регламентного задания по шагам:
ВзаиморасчетыСКонтрагентами для получения сумм поступивших оплат по контрагентам со статусом «Разовый».СтатусКонтрагента на «Постоянный» и записываем элемент.Проанализируем пример кода процедуры, которая может вызываться из модуля регламентного задания:
Процедура ОбновитьСтатусыКонтрагентов() Экспорт
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Взаиморасчеты.Контрагент КАК Контрагент,
| СУММА(Взаиморасчеты.СуммаВзаиморасчетовКредит) КАК СуммаОплат
|ИЗ
| РегистрНакопления.ВзаиморасчетыСКонтрагентами.Обороты(, , Авто, Контрагент.СтатусКонтрагента = Значение(Перечисление.СтатусыКонтрагентов.Разовый)) КАК Взаиморасчеты
|СГРУППИРОВАТЬ ПО
| Взаиморасчеты.Контрагент
|ИМЕЮЩИЕ
| СУММА(Взаиморасчеты.СуммаВзаиморасчетовКредит) >= 100000";
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетали = РезультатЗапроса.Выбрать();
Пока ВыборкаДетали.Следующий() Цикл
ОбъектКонтрагент = ВыборкаДетали.Контрагент.ПолучитьОбъект();
Если ОбъектКонтрагент <> Неопределено Тогда
ОбъектКонтрагент.СтатусКонтрагента = Перечисления.СтатусыКонтрагентов.Постоянный;
Попытка
ОбъектКонтрагент.Записать();
Исключение
ЗаписьЖурналаРегистрации("Обновление статуса контрагента",
УровеньЖурналаРегистрации.Ошибка,
,
,
ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Обратите внимание на использование метода УстановитьПривилегированныйРежим(Истина) — он позволяет фоновому заданию вносить изменения в данные независимо от ограничений прав конкретного сеанса.
Если бизнес-требования требуют мгновенного изменения статуса сразу после проведения платежного документа, следует использовать механизмы платформы — подписку на событие.
Разберем порядок настройки этого варианта:
ПодпискаНаСобытие.ВзаиморасчетыСКонтрагентами (например, ПриходныйКассовыйОрдер, ПлатежноеПоручениеВходящее и др.).ОбработкаПроведения.Постоянный.При таком подходе мы обращаемся к фактическим движениям в регистре накопления, а не к табличным частям конкретных документов, что обеспечивает корректность расчетов при любом источнике поступления средств.
Для реализации логики смены статуса контрагента в УТ 10.3 рекомендуем:
1. Брать данные о поступивших оплатах из регистра накопления ВзаиморасчетыСКонтрагентами (обороты по кредиту), а не из отдельных документов оплат.
2. Отдать предпочтение регламентному заданию, так как оно снижает риск возникновение транзакционных блокировок и не замедляет работу пользователей в течение рабочего дня.