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