В конфигурации 1С:Управление торговлей 11.4 (УТ 11.4) механизм автоматических скидок и наценок является крайне гибким, но в то же время технически сложным. Часто перед разработчиком встает задача: быстро определить, в каких именно правилах ценообразования задействована конкретная позиция номенклатуры. Проблема заключается в том, что условия применения скидок могут храниться в разных структурах данных в зависимости от выбранного пользователем способа настройки.
В этой статье мы подробно разберем, как устроена архитектура хранения скидок, проанализируем работу регистра сведений ДействиеСкидокНаценокПоНоменклатуре и выясним, как программно обрабатывать сложные отборы, созданные через Систему компоновки данных (СКД).
Для начала проанализируем, где именно хранятся условия. В справочнике СкидкиНаценки существует несколько вариантов настройки того, на какие товары распространяется скидка. За это отвечает реквизит ВариантОтбораНоменклатуры. Рассмотрим основные варианты:
Рассмотрим ситуацию, когда условия хранятся в поле ХранилищеНастроекКомпоновкиДанных. При вызове метода Получить() мы получаем структуру, содержащую НастройкиКомпоновкиДанных. Прямой перебор этих настроек вручную — путь тупиковый, так как условия могут содержать вложенные группы "И", "ИЛИ", "НЕ", а также использовать иерархию папок номенклатуры.
Прежде чем писать сложный программный код, проверим наличие данных в специализированном регистре. В УТ 11.4 существует регистр сведений ДействиеСкидокНаценокПоНоменклатуре. Выясним, как он заполняется:
Важно понимать: этот регистр является оптимизационным. Он автоматически заполняется системой только в том случае, если в скидке выбран вариант "Список номенклатуры" или "Сегмент номенклатуры". Если же скидка настроена через "Отбор компоновки данных", записи в этом регистре не создаются, так как отбор может быть динамическим и охватывать тысячи позиций, что сделало бы хранение их списка в регистре избыточным.
Если в вашей базе скидки преимущественно назначаются на конкретные списки или сегменты, вы можете получить данные простым запросом к этому регистру по измерению Номенклатура. Для массового назначения таких правил подойдёт обработка для групповой установки скидок с отбором по номенклатуре.
Если скидки настроены через произвольные отборы, нам необходимо использовать штатные возможности платформы 1С для работы с компоновкой данных. Вместо того чтобы парсить дерево условий, мы заставим систему саму проверить нашу номенклатуру на соответствие фильтрам.
Разберем алгоритм действий по шагам:
Посмотрим на пример логики, которую можно реализовать в общем модуле:
// Примерный алгоритм проверки вхождения номенклатуры в отбор СКД
Функция НоменклатураВходитВОтборСкидки(СсылкаНаСкидку, ИскомаяНоменклатура) Экспорт
НастройкиСтруктура = СсылкаНаСкидку.ХранилищеНастроекКомпоновкиДанных.Получить();
Если НастройкиСтруктура = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Настройки = НастройкиСтруктура.ОтборПоНоменклатуре; // Тип: НастройкиКомпоновкиДанных
// Используем штатный компоновщик для проверки
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
// Загружаем настройки из скидки в компоновщик
Компоновщик.ЗагрузитьНастройки(Настройки);
// Далее необходимо применить эти настройки к запросу или таблице значений
// содержащей текущую номенклатуру.
// Если результат выполнения запроса с данными фильтрами содержит записи,
// значит скидка применима.
КонецФункции
Проанализируем ситуацию: если ваша задача — обеспечить высокую скорость получения списка скидок в интерфейсе, использование произвольных отборов СКД будет существенно замедлять работу системы при большом количестве действующих скидок. Для ускорения типовых механизмов можно использовать расширение для оптимизации расчета скидок.
Рекомендуемый подход: перевести условия из произвольных отборов в Сегменты номенклатуры.
В УТ 11.4 сегменты могут формироваться динамически (по тем же правилам СКД), но информация о вхождении номенклатуры в сегмент кэшируется в регистре сведений НоменклатураСегмента.
В этом случае поиск скидок сводится к двум быстрым шагам:
НоменклатураСегмента).В конфигурациях на базе ERP и УТ 11 существуют мощные инструменты в общих модулях. Рассмотрим модули СкидкиНаценкиСервер и ЦенообразованиеВызовСервера. В них реализованы процедуры расчета скидок для документов (Заказ клиента, Реализация).
Выясним причину, почему это удобно: типовые методы учитывают не только саму номенклатуру, но и характеристики, упаковки, а также условия совместного применения (минимум, максимум, сложение, вытеснение). Если вам нужно не просто найти упоминание товара в скидке, а понять, будет ли она реально применена, лучше имитировать расчет скидок, передав в типовую функцию структуру с одной позицией номенклатуры.
Для поиска механизмов сбора данных рекомендуем изучить код обработки ПечатьСкидокНаценок. Там реализован алгоритм обхода всех доступных скидок и проверки их условий для текущего контекста продажи.
При реализации собственного поиска важно учитывать два критических момента:
Характеристика, иначе вы получите ложноположительные или ложноотрицательные результаты.Подведем итог: Для быстрого решения в небольших базах допустимо использовать перевод скидок на вариант "Список номенклатуры" с последующим чтением регистра ДействиеСкидокНаценокПоНоменклатуре. Для крупных систем с динамическим ценообразованием правильным путем будет использование сегментов номенклатуры или программный вызов компоновщика данных для проверки условий "на лету".