Как связать партнеров и действующие скидки в 1С:Управление торговлей 11 и построить правильный отчет

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

В процессе разработки отчетов в программе «1С:Управление торговлей 11» (а также в сопряженных решениях 1С:ERP и 1С:Комплексная автоматизация 2) программисты часто сталкиваются с задачей сопоставления партнеров и назначенных им скидок. Типичная бизнес-требование — получить простой отчет в две колонки: «Партнер» и «Действующая скидка».

Сложность заключается в том, что в архитектуре 1С:УТ 11 отсутствует прямая связь между справочником Справочник.Партнеры и справочником Справочник.СкидкиНаценки. В этой статье мы подробно разберем, как устроена эта связь, проанализируем типичные ошибки разработчиков и составим правильный, быстродействующий запрос для получения актуальных данных.

Почему нельзя брать данные из заказов клиентов?

Начинающие разработчики часто пытаются решить задачу «в лоб» — анализируют уже оформленные документы продаж или заказы. Посмотрим на пример запроса, который изначально набросал автор темы на форуме:


ВЫБРАТЬ
    ЗаказКлиента.СкидкиНаценки.(
        Ссылка.Партнер.Наименование КАК ПартнерНаименование,
        СкидкаНаценка.ЗначениеСкидкиНаценки КАК СкидкаНаценкаЗначениеСкидкиНаценки,
        Ссылка.Партнер.БизнесРегион.Наименование КАК ПартнерБизнесРегионНаименование
    ) КАК СкидкиНаценки
ИЗ
    Документ.ЗаказКлиента КАК ЗаказКлиента

Выясним, почему такой подход является в корне неверным для отчета по действующим скидкам:

  1. Зависимость от истории продаж: Если по какому-то партнеру еще не было заказов, он вообще не попадет в отчет, хотя скидки для него могут быть назначены и действовать.
  2. Неактуальность данных: В табличную часть ЗаказКлиента.СкидкиНаценки записываются только те скидки, которые были применены в момент проведения конкретного документа. Если скидка была отменена вчера, она все равно отобразится в старых заказах и попадет в ваш отчет как действующая.
  3. Проблема дублирования: В отчет будут выводиться дублирующиеся строки по каждому заказу. Попытка свернуть данные по дате последнего заказа сильно усложнит и замедлит запрос.

Поэтому проанализируем реальную архитектуру связей в системе и научимся извлекать только актуальные данные напрямую из регистров.

Архитектура связи: как на самом деле связаны Партнеры и Скидки

Чтобы связать партнера со скидкой, нам нужно пройти по цепочке метаданных. Связующим звеном здесь выступают Соглашения с клиентами. Скидки в «1С:УТ 11» назначаются не напрямую клиенту, а на источник (соглашение, склад или карту лояльности).

Рассмотрим эту цепочку подробнее:

  1. Индивидуальные соглашения: В карточке индивидуального соглашения (Справочник.СоглашенияСКлиентами) всегда заполнен реквизит Партнер. Здесь связь прямая: Партнер -> Соглашение -> Действующие скидки.
  2. Типовые соглашения: Такие соглашения действуют на сегменты партнеров. Чтобы понять, какие партнеры входят в сегмент, используется регистр сведений РегистрСведений.ПартнерыВСегменте.
  3. Действие скидок: Сам факт того, что скидка активна для конкретного соглашения, фиксируется в периодическом регистре сведений РегистрСведений.ДействиеСкидокНаценок.

Разбираем работу регистра «Действие скидок (наценок)»

Для определения актуальности скидки мы должны использовать именно регистр сведений ДействиеСкидокНаценок. Он хранит историю изменения статусов скидок.

Основные важные поля регистра:

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

Пошаговое построение запроса для отчета

Рассмотрим детально, как объединить все эти таблицы в один эффективный запрос.

Шаг 1. Получаем список партнеров и их соглашений. Для начала выберем всех партнеров и присоединим к ним индивидуальные соглашения. Чтобы отчет был полным, мы можем использовать левое соединение.

Шаг 2. Соединяем с действующими скидками. К полученной таблице присоединяем виртуальную таблицу ДействиеСкидокНаценок.СрезПоследних по условию соответствия источника и соглашения.

Шаг 3. Фильтруем по статусу. Нам нужны только те скидки, статус которых в срезе последних равен «Действует».

Посмотрим на пример готового запроса, который решает поставленную задачу:


ВЫБРАТЬ
    Партнеры.Ссылка КАК Партнер,
    Соглашения.Ссылка КАК Соглашение,
    ДействиеСкидок.СкидкаНаценка КАК СкидкаНаценка,
    ДействиеСкидок.СкидкаНаценка.ЗначениеСкидкиНаценки КАК ПроцентСкидки
ИЗ
    Справочник.Партнеры КАК Партнеры
    
    // Присоединяем индивидуальные соглашения партнеров
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СоглашенияСКлиентами КАК Соглашения
        ПО Соглашения.Партнер = Партнеры.Ссылка
        И Соглашения.ПометкаУдаления = ЛОЖЬ
        И Соглашения.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыСоглашенийСКлиентами.Действует)
        
    // Соединяем со срезом последних регистра действия скидок
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДействиеСкидокНаценок.СрезПоследних(&Период, ) КАК ДействиеСкидок
        ПО ДействиеСкидок.Источник = Соглашения.Ссылка
        И ДействиеСкидок.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДействияСкидок.Действует)
ГДЕ
    Партнеры.ПометкаУдаления = ЛОЖЬ
    И Партнеры.ЭтоГруппа = ЛОЖЬ

Что делать с типовыми соглашениями и сегментами?

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

Давайте усложним наш запрос, чтобы он учитывал также и вхождение партнеров в сегменты через регистр сведений ПартнерыВСегменте. Это позволит построить максимально точный и всеобъемлющий отчет.


ВЫБРАТЬ
    Партнеры.Ссылка КАК Партнер,
    Соглашения.Ссылка КАК Соглашение,
    ДействиеСкидок.СкидкаНаценка КАК СкидкаНаценка
ИЗ
    Справочник.Partners КАК Партнеры
    
    // Временная связь для индивидуальных и типовых соглашений
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СоглашенияСКлиентами КАК Соглашения
        ПО (Соглашения.Партнер = Партнеры.Ссылка) // Индивидуальные
        ИЛИ (Соглашения.СегментПартнеров <> ЗНАЧЕНИЕ(Справочник.СегментыПартнеров.ПустаяСсылка) // Типовые по сегменту
            И Соглашения.СегментПартнеров В 
                (ВЫБРАТЬ Сегменты.Сегмент ИЗ РегистрСведений.ПартнерыВСегменте КАК Сегменты ГДЕ Сегменты.Партнер = Партнеры.Ссылка))
        И Соглашения.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыСоглашенийСКлиентами.Действует)
        И Соглашения.ПометкаУдаления = ЛОЖЬ

    // Получаем действующие скидки
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДействиеСкидокНаценок.СрезПоследних(&Период, ) КАК ДействиеСкидок
        ПО ДействиеСкидок.Источник = Соглашения.Ссылка
        И ДействиеСкидок.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДействияСкидок.Действует)
ГДЕ
    Партнеры.ПометкаУдаления = ЛОЖЬ
    И Партнеры.ЭтоГруппа = ЛОЖЬ

Важные нюансы, о которых нужно помнить

При выводе скидок в реальной базе «1С:Управление торговлей 11» следует учитывать еще несколько важных факторов:

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

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

← На главную