Как исправить некорректный расчет скидок по отмененным позициям заказа в 1С:Управление торговлей 11.5?

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

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

Выясняем суть проблемы: почему скидки применяются к отмененным позициям

Давайте разберем типичный сценарий, который приводит к этой проблеме. Представьте, что у нас настроена скидка: 30% при покупке от 100 штук определенного товара. Мы создаем документ Заказ клиента, добавляем в него 100 штук этого товара, и система автоматически применяет скидку 30%.

Однако далее ситуация меняется: клиент отказывается от части товара, или же его нет на складе. Например, мы разбиваем исходную строку на две: 1 штука и 99 штук. Строку с 99 штуками мы помечаем как "отмененную" (например, устанавливаем статус "Отменено" или "Не обеспечивать", если товар отсутствует). После записи документа мы обнаруживаем, что скидка 30% по-прежнему остается активной, хотя фактически клиент приобретает только 1 штуку, что не соответствует условию предоставления скидки (от 100 штук).

Подобная проблема возникает и с другими видами скидок, например, при условии "при разовой покупке на 10 000 руб. даем скидку 30%". Если клиент сначала набирает товаров на 10 000 руб., скидка срабатывает. Но если позже большая часть этих товаров становится "отмененной" (по причине отсутствия на складе, отказа клиента и т.п.), система все равно может оставить скидку 30% на оставшиеся товары, которые в сумме могут составлять всего 1 000 руб. Это явно противоречит бизнес-логике и условиям предоставления скидки.

Ключевая причина такого поведения кроется в том, как 1С:Управление торговлей версии 11.5 определяет базу для расчета скидок. Если условие скидки установлено "по документу в целом", то на момент первичного расчета система анализирует весь состав документа, не исключая из него строки со статусом "Отменено" или "Не обеспечивать". Механизм пересчета скидок при изменении статуса строк либо не активируется автоматически должным образом, либо не настроен так, чтобы исключать отмененные строки из базы расчета скидки. То есть, условия скидки применяются к документу в том виде, в каком он был на момент их первоначального расчета, без динамического исключения отмененных позиций из объема, который определяет право на скидку.

Последствия некорректного расчета скидок

Неправильное применение скидок к отмененным позициям приводит к ряду серьезных проблем:

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

Официальная позиция 1С и необходимость доработки

Как показывает опыт пользователей и информация с горячей линии 1С, описанное поведение системы часто не признается разработчиками как критическая ошибка ("баг"). Вместо этого оно классифицируется как "пожелание" к доработке, то есть потенциальное улучшение, которое может быть реализовано в будущем при наличии достаточного количества свободных ресурсов. Это означает, что разработчики 1С считают текущую логику работы со скидками, где отмененные строки могут учитываться при определении условий предоставления скидки, допустимой или не критичной для стандартных сценариев. Таким образом, ожидать быстрого исправления этой ситуации в типовой конфигурации не приходится.

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

Разбираем решение проблемы: Модификация запроса через расширение

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

Почему именно расширение конфигурации?

Использование расширений является предпочтительным методом для внесения доработок в типовые конфигурации 1С. Это позволяет сохранить конфигурацию на поддержке, упрощает процесс обновлений и минимизирует риски возникновения конфликтов при переходе на новые версии системы. Мы избегаем непосредственного изменения стандартных объектов конфигурации.

Объект доработки: Функция СкидкиНаценкиСервер.РассчитатьПоЗаказуКлиента

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

Пошаговая инструкция по модификации запроса

Для реализации решения следуем следующим шагам:

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

    Внутри функции РассчитатьПоЗаказуКлиента вы найдете переменную ТекстЗапроса, которая содержит строку с текстом SQL-запроса. Нам нужно найти конкретное место в этом запросе и добавить условие для исключения отмененных строк. Мы будем искать секцию, где формируется временная таблица ВТТовары, а затем уточнять условия отбора для основной выборки.

    Ищите фрагмент запроса, аналогичный следующему:

    
    ТекстЗапроса = "ВЫБРАТЬ
    |	Товары.КлючСвязи КАК КлючСвязи,
    |	&ПоляНабора,
    |	Товары.Номенклатура КАК Номенклатура,
    |	Товары.Характеристика КАК Характеристика,
    |	Товары.Упаковка КАК Упаковка,
    |	Товары.Серия КАК Серия,
    |	Товары.Склад КАК Склад,
    |	Товары.ВидЦены КАК ВидЦены,
    |	Товары.Количество КАК Количество,
    |	Товары.Отменено КАК Отменено,
    |	Товары.КоличествоУпаковок КАК КоличествоУпаковок,
    |	Товары.Цена КАК Цена,
    |	Товары.Цена * Товары.КоличествоУпаковок КАК Сумма
    |ПОМЕСТИТЬ ВТТовары
    |ИЗ
    |	&Товары КАК Товары
    |;
    |
    |//////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    |	Таблица.КлючСвязи,
    |	&ПоляТаблицы,
    |	Таблица.Номенклатура,
    |	Таблица.Характеристика,
    |	Таблица.Упаковка,
    |	Таблица.Серия,
    |	Таблица.Склад,
    |	Таблица.ВидЦены,
    |	СправочникНоменклатура.ЦеноваяГруппа КАК ЦеноваяГруппа,
    |	Таблица.Количество,
    |	Таблица.КоличествоУпаковок,
    |	Таблица.Цена,
    |	Таблица.Сумма
    |	,&ИмяВременнойТаблицы
    |ИЗ
    |	ВТТовары КАК Таблица
    |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СправочникНоменклатура
    |		ПО СправочникНоменклатура.Ссылка = Таблица.Номенклатура
    |	,&Соединение
    |ГДЕ
    |	ВЫБОР
    |		КОГДА &ВозвратТары ТОГДА
    |			Таблица.Номенклатура.ТипНоменклатуры <> ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.МногооборотнаяТара)
    |		ИНАЧЕ
    |			ИСТИНА
    |	КОНЕЦ
    |	И НЕ Таблица.Отменено
    |;
    |ВЫБРАТЬ &ЗапросНаборы
    |";
    

    В приведенном коде уже внесены изменения, но мы укажем, куда именно нужно добавить условие И НЕ Таблица.Отменено. Вам нужно найти блок ГДЕ во втором операторе ВЫБРАТЬ, который обращается к временной таблице ВТТовары (здесь она называется Таблица).

    Исходный код без доработки мог выглядеть так:

    
    // ...
    |ГДЕ
    |	ВЫБОР
    |		КОГДА &ВозвратТары ТОГДА
    |			Таблица.Номенклатура.ТипНоменклатуры <> ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.МногооборотнаяТара)
    |		ИНАЧЕ
    |			ИСТИНА
    |	КОНЕЦ
    // Здесь должно быть добавлено наше условие
    |;
    

    Именно в это место (после блока КОНЕЦ и перед точкой с запятой, закрывающей второй оператор ВЫБРАТЬ) необходимо добавить строку:

    И НЕ Таблица.Отменено

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

  5. Сохраните изменения и обновите базу:
    • Сохраните изменения в модуле расширения.
    • Обновите конфигурацию базы данных (F7 или "Обновить конфигурацию базы данных").
  6. Проверьте результат:

    После внедрения расширения и обновления базы данных, создайте новый Заказ клиента или откройте существующий, в котором есть отмененные позиции. Пересчитайте скидки в документе. Вы должны убедиться, что скидки теперь рассчитываются только на те позиции, которые не помечены как "Отменено" и соответствуют условиям предоставления скидки.

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

Альтернативные подходы и обходные пути (менее предпочтительные)

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

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

Заключение

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

← На главную