Как заблокировать Заказ покупателя для редактирования после создания Реализации в УТ 10.3?

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

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

Рассмотрим ситуацию. Менеджер оформил заказ, согласовал его с клиентом. Кладовщик на основании этого заказа собрал товар и оформил отгрузочные документы. Если после этого менеджер изменит что-либо в исходном заказе (например, количество товара или цену), то возникнет путаница в учете, отчеты по продажам и взаиморасчетам могут показать некорректные данные. Стандартными настройками конфигурации УТ 10.3 такую блокировку "из коробки" установить нельзя. Поэтому решим эту задачу с помощью небольшой программной доработки.

Решение: Блокировка формы документа через код

Самый прямой и быстрый способ реализовать требуемое поведение — добавить программный код в модуль формы документа Заказ покупателя. Логика будет следующей: каждый раз при открытии формы заказа система должна проверять, существуют ли связанные с ним проведенные документы реализации. Если да — форма должна открываться в режиме "только просмотр".

Разберем по шагам, как это сделать.

  1. Открытие конфигуратора.
    Запустите 1С в режиме "Конфигуратор".
  2. Поиск нужного объекта.
    В дереве конфигурации найдите ветку "Документы" и раскройте ее. Найдите документ ЗаказПокупателя и откройте его свойства.
  3. Открытие модуля формы.
    Перейдите на вкладку "Формы" и откройте основную форму документа (обычно она называется ФормаДокумента). В нижней части окна откроется модуль этой формы.
  4. Добавление кода в процедуру ПриОткрытии().
    Нам нужна процедура-обработчик события ПриОткрытии, которая выполняется каждый раз, когда пользователь открывает форму. Если такой процедуры в модуле нет, создайте ее. Внутрь этой процедуры мы и поместим наш код.

Основным инструментом для поиска связанных документов будет Запрос. Он найдет все документы РеализацияТоваровУслуг, у которых в поле Сделка указан наш текущий заказ.

Пример кода для вставки в процедуру ПриОткрытии():


Процедура ПриОткрытии()

    // Проверяем, что документ уже записан в базу данных.
    // Если это новый, еще не записанный документ, то проверок не требуется.
    Если НЕ ЭтотОбъект.ЭтоНовый() Тогда
    
        // Получаем ссылку на текущий заказ, который открывается в форме
        ТекущийЗаказ = ЭтотОбъект.Ссылка; 
    
        // Создаем и настраиваем запрос для поиска связанных реализаций
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ ПЕРВЫЕ 1
            |    РеализацияТоваровУслуг.Ссылка
            |ИЗ
            |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
            |ГДЕ
            |    РеализацияТоваровУслуг.Сделка = &Сделка
            |    И РеализацияТоваровУслуг.Проведен = ИСТИНА
            |    И НЕ РеализацияТоваровУслуг.ПометкаУдаления = ИСТИНА";
    
        Запрос.УстановитьПараметр("Сделка", ТекущийЗаказ);
    
        РезультатЗапроса = Запрос.Выполнить();
    
        // Проверяем, вернул ли запрос хотя бы одну запись
        Если НЕ РезультатЗапроса.Пустой() Тогда
            // Если хотя бы одна проведенная реализация найдена,
            // выводим предупреждение и блокируем форму для редактирования.
            Предупреждение("По данному заказу уже создана реализация. Редактирование запрещено!", 10);
            ЭтаФорма.ТолькоПросмотр = Истина;
        КонецЕсли;
        
    КонецЕсли;

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

Анализ кода и важные моменты

Улучшения и альтернативные подходы

Описанный выше метод прост и эффективен, но для более сложных бизнес-процессов его можно усовершенствовать. Рассмотрим несколько альтернативных и более архитектурно правильных подходов.

Подход 1: Использование статусов заказа

В документе Заказ покупателя есть реквизит для указания его статуса (например, "В работе", "К отгрузке", "Выполнен"). Этот механизм можно использовать для управления блокировкой.

  1. Доработайте процедуру проведения документа Реализация товаров и услуг. Добавьте в нее код, который находит связанный Заказ покупателя и устанавливает ему определенный статус, например, "Отгружен".
  2. В модуле формы Заказа покупателя в процедуре ПриОткрытии() проверяйте уже не наличие реализаций, а статус самого заказа.
    
    Если ЭтотОбъект.СтатусЗаказа = Перечисления.СтатусыЗаказовПокупателей.Закрыт Тогда // Используйте ваше значение статуса
        ЭтаФорма.ТолькоПросмотр = Истина;
    КонецЕсли;
    

Преимущества этого подхода:

Подход 2: Использование подписки на событие

Наиболее правильный с точки зрения архитектуры платформы 1С метод — это использование подписки на событие. Вместо того чтобы писать код в форме (который сработает только при интерактивном открытии), мы можем "перехватывать" попытку записи измененного заказа.

  1. Создайте в конфигураторе новый объект Подписка на событие.
  2. В качестве источника укажите документ ЗаказПокупателя.
  3. В качестве события выберите ПередЗаписью.
  4. Создайте общую процедуру-обработчик в общем модуле, которая будет выполнять ту же самую проверку с помощью запроса, что и в первом варианте.
  5. Если проверка обнаружит проведенную реализацию, в обработчике нужно установить параметр Отказ = Истина; и вывести пользователю сообщение об ошибке.

Преимущества этого подхода:

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

← На главную