Как реализовать контроль суммы документа и запрет проведения при превышении лимита в 1С:УТ 11.4

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

В торговых компаниях часто возникает необходимость ограничить полномочия менеджеров по продажам. Типичная задача — запретить отгрузку товаров, если общая сумма документа превышает установленный лимит (например, 100 000 рублей), и при этом информировать пользователя о превышении еще в процессе подбора товаров. В этой статье мы подробно разберем, как реализовать такой функционал в конфигурации «1С:Управление торговлей 11.4» (УТ 11.4), используя механизмы расширений и обработчики событий.

Анализ задачи и выбор архитектуры решения

Для качественной реализации нам необходимо решить две подзадачи:

  1. Интерактивный контроль: Вывод предупреждения менеджеру сразу, как только сумма в табличной части превысила лимит. Это делается для удобства пользователя.
  2. Жесткий контроль: Запрет проведения документа, если условие не соблюдено. Это должно работать даже в том случае, если документ записывается программно или из формы списка.

Рассмотрим пошагово, как это реализовать наиболее правильным с точки зрения архитектуры 1С способом.

Шаг 1. Создание константы для хранения лимита

Прежде всего, не стоит «зашивать» сумму 100 000 прямо в программный код. Это плохая практика, так как лимит может измениться. Мы создадим константу, которую администратор сможет редактировать без участия программиста.

В расширении создадим константу СуммаЛимитаДляКонтроляРеализации с типом Число (15, 2). Теперь в коде мы будем обращаться к ней:

Лимит = Константы.СуммаЛимитаДляКонтроляРеализации.Получить();

Шаг 2. Реализация интерактивного предупреждения в форме

Чтобы менеджер видел предупреждение в момент набора товара, нам нужно вклиниться в процесс пересчета итогов формы. В УТ 11.4 в документе «Реализация товаров и услуг» за расчет итогов отвечает процедура РассчитатьИтоговыеПоказателиРеализации. Проанализируем ситуацию: нам лучше всего использовать расширение для этой процедуры.

В расширении формы документа добавим метод &После для этой процедуры:


&НаКлиенте
Процедура Расшир_РассчитатьИтоговыеПоказателиРеализацииПосле(Форма)
    
    СуммаДокумента = Форма.Объект.Товары.Итог("СуммаСНДС"); // Или другой реквизит итога
    Лимит = 100000; // Здесь лучше вызвать серверную функцию получения константы
    
    Если СуммаДокумента > Лимит Тогда
        // Используем оповещение, чтобы не блокировать работу модальным окном
        ТекстСообщения = "Внимание! Сумма документа превысила лимит " + Строка(Лимит);
        ПоказатьОповещениеПользователя("Превышение лимита", , ТекстСообщения, СтатусОповещения.Важное);
    КонецЕсли;

КонецПроцедуры

Обратите внимание, что мы используем ПоказатьОповещениеПользователя. Это позволяет пользователю продолжить работу, не закрывая лишние окна, но при этом информирует его о проблеме.

Шаг 3. Жесткий контроль проведения в модуле объекта

Как справедливо было замечено в обсуждении, проверка в форме не спасет, если пользователь решит провести документ из формы списка или если документ будет создаваться внешней обработкой. Поэтому основной контроль мы разместим в Модуле объекта или через Подписку на событие.

Разберем вариант с расширением модуля объекта. Нам понадобится обработчик ПередЗаписью. Выясним причину выбора именно этого события: оно срабатывает всегда перед фиксацией данных в базе, и в нем у нас есть параметр Отказ.


&Перед("ПередЗаписью")
Процедура Расшир_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Проверяем, что это именно проведение
    Если РежимПроведения = РежимПроведенияДанных.Проведение Тогда
        
        Лимит = Константы.СуммаЛимитаДляКонтроляРеализации.Получить();
        ТекущаяСумма = ЭтотОбъект.Товары.Итог("СуммаСНДС");
        
        Если ТекущаяСумма > Лимит Тогда
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
                СтрШаблон("Проведение запрещено! Сумма документа (%1) превышает лимит (%2).", 
                ТекущаяСумма, Лимит)
            );
            Отказ = Истина;
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Шаг 4. Учет прав доступа

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

Добавим в условие проверку роли:


Если ТекущаяСумма > Лимит И НЕ РольДоступна("ПолныеПрава") И НЕ РольДоступна("РазрешитьПревышениеЛимитаСуммы") Тогда
    // Блокируем проведение
    Отказ = Истина;
КонецЕсли;

Дополнительные рекомендации

При реализации подобного контроля важно учитывать несколько технических нюансов:

Подводя итог, мы выяснили, что для полноценного решения задачи необходимо сочетать клиентские методы для удобства работы (оповещения в форме) и серверные методы для обеспечения безопасности данных (контроль в модуле объекта через расширение или подписку на событие). Такой подход гарантирует, что установленный бизнес-лимит не будет нарушен ни при каких обстоятельствах.

← На главную