В торговых компаниях часто возникает необходимость ограничить полномочия менеджеров по продажам. Типичная задача — запретить отгрузку товаров, если общая сумма документа превышает установленный лимит (например, 100 000 рублей), и при этом информировать пользователя о превышении еще в процессе подбора товаров. В этой статье мы подробно разберем, как реализовать такой функционал в конфигурации «1С:Управление торговлей 11.4» (УТ 11.4), используя механизмы расширений и обработчики событий.
Для качественной реализации нам необходимо решить две подзадачи:
Рассмотрим пошагово, как это реализовать наиболее правильным с точки зрения архитектуры 1С способом.
Прежде всего, не стоит «зашивать» сумму 100 000 прямо в программный код. Это плохая практика, так как лимит может измениться. Мы создадим константу, которую администратор сможет редактировать без участия программиста.
В расширении создадим константу СуммаЛимитаДляКонтроляРеализации с типом Число (15, 2). Теперь в коде мы будем обращаться к ней:
Лимит = Константы.СуммаЛимитаДляКонтроляРеализации.Получить();
Чтобы менеджер видел предупреждение в момент набора товара, нам нужно вклиниться в процесс пересчета итогов формы. В УТ 11.4 в документе «Реализация товаров и услуг» за расчет итогов отвечает процедура РассчитатьИтоговыеПоказателиРеализации. Проанализируем ситуацию: нам лучше всего использовать расширение для этой процедуры.
В расширении формы документа добавим метод &После для этой процедуры:
&НаКлиенте
Процедура Расшир_РассчитатьИтоговыеПоказателиРеализацииПосле(Форма)
СуммаДокумента = Форма.Объект.Товары.Итог("СуммаСНДС"); // Или другой реквизит итога
Лимит = 100000; // Здесь лучше вызвать серверную функцию получения константы
Если СуммаДокумента > Лимит Тогда
// Используем оповещение, чтобы не блокировать работу модальным окном
ТекстСообщения = "Внимание! Сумма документа превысила лимит " + Строка(Лимит);
ПоказатьОповещениеПользователя("Превышение лимита", , ТекстСообщения, СтатусОповещения.Важное);
КонецЕсли;
КонецПроцедуры
Обратите внимание, что мы используем ПоказатьОповещениеПользователя. Это позволяет пользователю продолжить работу, не закрывая лишние окна, но при этом информирует его о проблеме.
Как справедливо было замечено в обсуждении, проверка в форме не спасет, если пользователь решит провести документ из формы списка или если документ будет создаваться внешней обработкой. Поэтому основной контроль мы разместим в Модуле объекта или через Подписку на событие.
Разберем вариант с расширением модуля объекта. Нам понадобится обработчик ПередЗаписью. Выясним причину выбора именно этого события: оно срабатывает всегда перед фиксацией данных в базе, и в нем у нас есть параметр Отказ.
&Перед("ПередЗаписью")
Процедура Расшир_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, что это именно проведение
Если РежимПроведения = РежимПроведенияДанных.Проведение Тогда
Лимит = Константы.СуммаЛимитаДляКонтроляРеализации.Получить();
ТекущаяСумма = ЭтотОбъект.Товары.Итог("СуммаСНДС");
Если ТекущаяСумма > Лимит Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
СтрШаблон("Проведение запрещено! Сумма документа (%1) превышает лимит (%2).",
ТекущаяСумма, Лимит)
);
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В реальных условиях часто требуется, чтобы руководители или старшие менеджеры могли обходить этот запрет. Проанализируем, как это добавить. Мы можем проверять наличие определенной роли у текущего пользователя.
Добавим в условие проверку роли:
Если ТекущаяСумма > Лимит И НЕ РольДоступна("ПолныеПрава") И НЕ РольДоступна("РазрешитьПревышениеЛимитаСуммы") Тогда
// Блокируем проведение
Отказ = Истина;
КонецЕсли;
При реализации подобного контроля важно учитывать несколько технических нюансов:
ПередЗаписью можно использовать метод ОбработкаПроверкиЗаполнения. Платформа сама вызовет его при нажатии «Провести», и если вы добавите реквизит СуммаДокумента в список проверяемых, система подсветит его красным.Подводя итог, мы выяснили, что для полноценного решения задачи необходимо сочетать клиентские методы для удобства работы (оповещения в форме) и серверные методы для обеспечения безопасности данных (контроль в модуле объекта через расширение или подписку на событие). Такой подход гарантирует, что установленный бизнес-лимит не будет нарушен ни при каких обстоятельствах.