Как запретить создание Приходного кассового ордера и Эквайринговой операции на основании Заказа клиента в 1С:УТ 11.5?

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

Приветствуем, коллеги! В процессе работы с конфигурацией 1С:Управление торговлей 11.5 часто возникает необходимость тонкой настройки поведения системы. Одной из таких задач может быть ограничение возможности создания определенных документов на основании других. Рассмотрим ситуацию, когда требуется запретить пользователям создавать Приходные кассовые ордера (ПКО) и Эквайринговые операции на основании документа «Заказ клиента», но при этом сохранить возможность их создания на основании, например, «Реализации товаров и услуг». Мы разберем два основных подхода к решению этой задачи, используя расширения конфигурации, чтобы минимизировать проблемы при последующих обновлениях.

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

Мы рассмотрим два эффективных метода, которые можно реализовать с помощью расширений:

  1. Запрет создания в модуле формы целевого документа (ПКО или Эквайринговая операция) при проверке его основания.
  2. Модификация списка команд «Создать на основании» в модуле менеджера документа «Заказ клиента» для скрытия ненужных пунктов.

Оба этих метода позволяют добиться желаемого результата, но имеют свои особенности и применимость.

Подход 1: Запрет создания в форме нового документа (ПКО, Эквайринговая операция)

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

Разберем по шагам, как это реализовать:

  1. Создаем расширение. Прежде всего, необходимо создать новое расширение конфигурации в режиме «Конфигуратор».
  2. Добавляем формы целевых документов. В наше расширение мы добавляем формы документов, создание которых хотим запретить: «Приходный кассовый ордер» (Документ.ПриходныйКассовыйОрдер.Форма.ФормаДокумента) и «Операция по платежной карте» (Документ.ОперацияПоПлатежнойКарте.Форма.ФормаДокумента). Для этого в окне расширения кликните правой кнопкой мыши на ветке «Документы», выберите «Добавить из конфигурации», найдите нужные документы и добавьте их формы.
  3. Подписываемся на событие `ПриСозданииНаСервере`. В модуле каждой из этих форм (в расширении) мы должны подписаться на событие ПриСозданииНаСервере. Это событие вызывается на сервере при создании формы документа, что позволяет нам проверить переданные параметры до того, как форма будет полностью инициализирована и отображена пользователю. Для этого в расширении открываем форму, переходим на вкладку «События» и для процедуры ПриСозданииНаСервере создаем обработчик.
  4. Пишем код проверки основания. В созданном обработчике процедуры ПриСозданииНаСервере мы будем проверять, является ли основание для создания текущего документа «Заказом клиента». Если это так, мы устанавливаем параметр Отказ в значение Истина, что предотвращает дальнейшее создание формы, и выводим пользователю информационное сообщение.
  5. Учитываем лучшие практики. Важно следовать рекомендациям по написанию кода для управляемых форм. В частности, сначала проверяйте ИмяФормы, затем Основание. Также убедитесь, что ваш код срабатывает только при создании нового документа, а не при открытии уже существующего. Для этого используйте проверку не ЗначениеЗаполнено(Форма.Объект.Ссылка), которая возвращает Истина, если объект еще не записан в базу данных. Это особенно актуально, так как ПриСозданииНаСервере вызывается и при открытии существующего документа.
  6. Рефакторинг кода. Для улучшения читаемости и поддерживаемости кода, особенно если таких проверок будет много, рекомендуется вынести логику в отдельную процедуру или функцию, которая будет вызываться из обработчика ПриСозданииНаСервере.

Приведем пример кода, который можно использовать в расширении. Предположим, вы создали в расширении общий модуль, например, Расш_МодификацияФорм, куда вынесли основную логику. Тогда код в модуле формы документа (например, Документ.ПриходныйКассовыйОрдер.Форма.ФормаДокумента) будет выглядеть так:


// В модуле формы Документ.ПриходныйКассовыйОрдер.Форма.ФормаДокумента (в расширении)
// Подписываемся на событие ПриСозданииНаСервере

&После("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка)
    Расш_МодификацияФорм.ОграничитьСозданиеПлатежныхДокументовНаОснованииЗаказа(Форма, Отказ);
КонецПроцедуры

А в общем модуле Расш_МодификацияФорм (также в расширении) разместим основную логику:


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

    // Проверяем, что это создание нового документа
    Если НЕ ЗначениеЗаполнено(Форма.Объект.Ссылка) Тогда

        // Сначала проверяем имя формы для конкретики
        Если Форма.ИмяФормы = "Документ.ПриходныйКассовыйОрдер.Форма.ФормаДокумента"
         ИЛИ Форма.ИмяФормы = "Документ.ОперацияПоПлатежнойКарте.Форма.ФормаДокумента" Тогда

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

Давайте поясним некоторые моменты:

Относительно проблемы «возврата эквайринга», где Форма.Основание может быть не заполнено: если при создании документа «Операция по платежной карте» (возврат) платформа не заполняет параметр Основание, то проверка ТипЗнч(Форма.Основание) = Тип("ДокументСсылка.ЗаказКлиента") не сработает. В таком случае вам потребуется более глубокий анализ: возможно, у документа «Операция по платежной карте» есть другие реквизиты (например, ДокументОснование, ДокументРасчетовСКлиентом или какой-то служебный реквизит, указывающий на исходный заказ или реализацию), которые нужно будет проверять. Это потребует дополнительного изучения структуры данных конкретной операции возврата.

Подход 2: Модификация списка команд «Создать на основании» в документе Заказ клиента

Этот подход направлен на скрытие пунктов меню «Создать на основании» непосредственно в документе «Заказ клиента». Он более «мягкий», так как он лишь убирает команды из интерфейса, но не препятствует программному созданию документа, если кто-то обойдет интерфейс. Однако для большинства пользователей это будет достаточно, поскольку они взаимодействуют с системой через визуальный интерфейс.

Для конфигурации УТ 11.5.12.73, как было отмечено в исходной теме, процедура ДобавитьКомандыСозданияНаОсновании в модуле менеджера документа «Заказ клиента» может отсутствовать. Однако, это стандартный механизм для многих конфигураций и версий платформы 1С:Предприятие 8.3. Если в вашей версии эта процедура все же присутствует (или появится в будущих версиях), этот метод является очень чистым и рекомендуемым для управления списком команд.

Рассмотрим шаги для реализации этого подхода (при условии наличия процедуры ДобавитьКомандыСозданияНаОсновании):

  1. Создаем расширение. Как и в первом подходе, начинаем с создания нового расширения.
  2. Добавляем модуль менеджера документа «Заказ клиента». В расширение добавляем объект «Документ.ЗаказКлиента», и в нем – модуль менеджера. Для этого в окне расширения кликните правой кнопкой мыши на ветке «Документы», выберите «Добавить из конфигурации», найдите «Заказ клиента» и добавьте его модуль менеджера.
  3. Переопределяем процедуру `ДобавитьКомандыСозданияНаОсновании`. В модуле менеджера документа «Заказ клиента» (в расширении) мы должны переопределить процедуру ДобавитьКомандыСозданияНаОсновании. Эта процедура получает список команд, которые будут отображены в меню «Создать на основании», и мы можем удалить из него ненужные нам пункты. Для переопределения используем директиву `&После`.
  4. Удаляем ненужные команды. Внутри переопределенной процедуры мы используем методы списка команд для поиска и удаления элементов, соответствующих ПКО и Эквайринговой операции.

Пример кода, который можно использовать в модуле менеджера документа «ЗаказКлиента» (в расширении):


// В модуле менеджера Документ.ЗаказКлиента (в расширении)

&После("ДобавитьКомандыСозданияНаОсновании")
Процедура Расш_ДобавитьКомандыСозданияНаОсновании(КомандыСозданияНаОсновании, Параметры)
    // Исключаем команду создания Приходного кассового ордера
    Индекс = КомандыСозданияНаОсновании.Найти("Документ.ПриходныйКассовыйОрдер", "Идентификатор");
    Если Индекс <> Неопределено Тогда
        КомандыСозданияНаОсновании.Удалить(Индекс);
    КонецЕсли;

    // Исключаем команду создания Операции по платежной карте
    Индекс = КомандыСозданияНаОсновании.Найти("Документ.ОперацияПоПлатежнойКарте", "Идентификатор");
    Если Индекс <> Неопределено Тогда
        КомандыСозданияНаОсновании.Удалить(Индекс);
    КонецЕсли;
КонецПроцедуры

Пояснения к коду:

Если в вашей версии УТ 11.5 (как в случае автора) процедура ДобавитьКомандыСозданияНаОсновании отсутствует, этот подход не применим. В этом случае вам придется ориентироваться на механизмы, которые используются в вашей версии для формирования команд. Часто это может быть функциональность ПодключаемыеКомандыКлиентСервер.ОбновитьКоманды или другие общие модули, но их модификация может быть сложнее и менее универсальна. Однако для большинства современных конфигураций метод с ДобавитьКомандыСозданияНаОсновании является стандартным и предпочтительным.

Почему расширения - лучший выбор

Использование расширений является критически важным для обеспечения беспроблемного обновления типовой конфигурации. Расширения позволяют вносить изменения в функциональность системы, не затрагивая основную конфигурацию. Это означает, что при выходе новых версий УТ вы сможете обновиться, не опасаясь, что ваши доработки будут перезаписаны или вызовут конфликты. Все описанные выше методы должны быть реализованы исключительно в расширении.

Заключение

Мы рассмотрели два основных подхода к запрету создания Приходных кассовых ордеров и Эквайринговых операций на основании Заказов клиента в 1С:УТ 11.5. Оба метода имеют свои преимущества:

В случае, когда первый подход не охватывает все сценарии (например, при специфичных операциях возврата, где Основание может быть пустым), потребуется дополнительный анализ структуры данных и реквизитов документа «Операция по платежной карте» для выявления связи с «Заказом клиента». Для большинства же стандартных случаев, когда документ создается явно «на основании», предложенные решения будут эффективны.

Рекомендуем использовать первый подход как основной, если необходимо гарантировать невозможность создания документа при любых обстоятельствах. Если же процедура ДобавитьКомандыСозданияНаОсновании доступна в вашей версии, вы можете использовать ее в качестве дополнительного средства для улучшения интерфейса, скрывая ненужные команды из списка.

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

← На главную