Скидки в 1С УТ 11 — это справочник «Скидки (наценки)», условия предоставления и регистр, где отмечено, для кого скидка действует. Задача приходит в двух видах: «настройте акцию» и «почему скидка не сработала». Ниже — устройство механизма в 1С:Управление торговлей 11.4–11.5 (в КА 2 и ERP 2 он тот же), запросы для проверки и анализа, расчет скидок в заказе, созданном кодом, и внешняя обработка для условия, которого нет в типовой.
Настройка скидок в 1С начинается с опций: «НСИ и администрирование» → «Настройка НСИ и разделов» → «CRM и маркетинг», группа «Управление скидками». Флажки независимы:
Сами скидки — «CRM и маркетинг» → «Скидки (наценки)», условия — там же, «Условия предоставления скидок (наценок)». В карточке скидки задают тип, размер, «Назначается: автоматически или вручную» и номенклатуру: любую, из списка, из сегмента или по отбору. Размер уточняют по ценовым группам, наценка — отрицательное значение.
| Тип скидки | Что делает |
|---|---|
| Скидка (наценка) процентом | процент от суммы строки |
| Скидка (наценка) суммой на документ | сумма распределяется по подходящим строкам |
| Скидка (наценка) суммой для каждой строки | фиксированная сумма в каждой подходящей строке |
| Скидка количеством | «три по цене двух» |
| Специальная цена | цена из указанного вида цен |
| Подарок | товар из сегмента подарков |
| Выдача сообщения, выдача карты лояльности | подсказка менеджеру или кассиру, сумму не меняет |
| Округление суммы документа | округляет итог, в том числе «психологически» |
Условие — отдельный элемент справочника, его подключают к нескольким скидкам. В УТ 11.4 есть: разовый объем продаж (сумма, количество, число разных или одинаковых позиций), накопленный объем по клиенту или соглашению, время продажи, форма и график оплаты, наличие карты лояльности или ее отсутствие, группа пользователей, сегмент клиентов, день рождения клиента. Условия одной скидки проверяются через «И»; для «ИЛИ» заводят две скидки в группе «Максимум».
Группа справочника — категория со своим вариантом совместного применения; скидка обязана лежать в группе. Как сочетаются сами группы, решает вариант предопределенной корневой группы. Пример: карта дает 5 %, акция — 10 %.
| Вариант группы | Итоговая скидка |
|---|---|
| Максимум | 10 % |
| Минимум | 5 % |
| Сложение | 15 % |
| Умножение | 14,5 %: 10 % от цены, затем 5 % от остатка |
| Вытеснение | скидка, которая стоит в группе первой по порядку |
У «Максимума», «Минимума» и «Вытеснения» есть переключатель «Сравнивать»: «По строке» выбирает скидку для каждой строки отдельно, «По документу в целом» — одну скидку с наибольшей (наименьшей) суммой по всему документу.
В расчет попадает только скидка со статусом «Действует» в регистре «Действие скидок (наценок)». Статус ставят в списке «Скидки (наценки)»: общий «Действует» — скидка для всех; общий «Не действует» плюс статус на вкладках справа «На складах», «В видах карт лояльности», «В индивидуальных соглашениях», «В типовых соглашениях» — скидка только там. Команда «Установить статус» задает и даты начала и окончания.
Установить скидки в 1С можно и из карточки соглашения — страница «Скидки (наценки) по этому соглашению». Статус «Не действует» на соглашении общий «Действует» не отменяет: расчету достаточно одного источника, где скидка действует.
Скидка по виду карты работает, только если карта указана в документе (поле «Карта лояльности» или команда «Считать карту лояльности») и вид карты действует на дату документа. Условие «За наличие карты лояльности» другое: проверяет, что у клиента есть действующая карта этого вида, даже если ее не считали.
Потолок ручной скидки задают соглашение («Ограничивать ручные скидки», «Макс. % ручной скидки», «Макс. % ручной наценки») и справочник «Настройки продаж» пользователя или группы пользователей — в УТ 11.4 это команда «Правила продаж» в карточке пользователя.
Расчет в заказе отбирает скидки со статусом «Действует» на дату документа по общему статусу, складу и его группам, соглашению и виду карты. Функция повторяет этот отбор:
// Скидки (наценки) со статусом «Действует» на дату для склада, соглашения
// и карты лояльности - тот же отбор, что делает расчет скидок в заказе УТ 11.
// Условия предоставления функция не проверяет. Контекст: сервер.
Функция ДействующиеСкидкиНаДату(Дата, Склад, Соглашение, КартаЛояльности) Экспорт
// Общий статус скидки хранится с пустым складом в измерении «Источник».
Источники = Новый Массив;
Источники.Добавить(Справочники.Склады.ПустаяСсылка());
// Статус, поставленный на группу складов, действует на все склады группы.
ТекущийСклад = Склад;
Пока ЗначениеЗаполнено(ТекущийСклад) Цикл
Источники.Добавить(ТекущийСклад);
ТекущийСклад = ТекущийСклад.Родитель;
КонецЦикла;
Если ЗначениеЗаполнено(Соглашение) Тогда
Источники.Добавить(Соглашение);
КонецЕсли;
// Скидки вида карты работают, пока действует сам вид карты.
Если ЗначениеЗаполнено(КартаЛояльности) Тогда
ВидКарты = КартаЛояльности.Владелец;
Если ВидКарты.ДатаНачалаДействия <= Дата
И (Не ЗначениеЗаполнено(ВидКарты.ДатаОкончанияДействия)
Или КонецДня(ВидКарты.ДатаОкончанияДействия) >= Дата) Тогда
Источники.Добавить(ВидКарты);
КонецЕсли;
КонецЕсли;
ЗапросСкидок = Новый Запрос;
ЗапросСкидок.Текст =
"ВЫБРАТЬ
| Действие.СкидкаНаценка КАК СкидкаНаценка,
| Действие.Источник КАК Источник,
| Действие.Период КАК ДействуетС,
| СкидкиНаценки.Родитель КАК Группа,
| СкидкиНаценки.Родитель.ВариантСовместногоПрименения КАК ВариантСовместногоПрименения,
| СкидкиНаценки.СпособПредоставления КАК ТипСкидки,
| СкидкиНаценки.ЗначениеСкидкиНаценки КАК Значение,
| СкидкиНаценки.Управляемая КАК НазначаетсяВручную,
| СкидкиНаценки.ПометкаУдаления КАК ПометкаУдаления
|ИЗ
| РегистрСведений.ДействиеСкидокНаценок.СрезПоследних(&Дата, Источник В (&Источники)) КАК Действие
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СкидкиНаценки КАК СкидкиНаценки
| ПО Действие.СкидкаНаценка = СкидкиНаценки.Ссылка
|ГДЕ
| Действие.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДействияСкидок.Действует)
|
|УПОРЯДОЧИТЬ ПО
| Группа,
| СкидкаНаценка";
ЗапросСкидок.УстановитьПараметр("Дата", Дата);
ЗапросСкидок.УстановитьПараметр("Источники", Источники);
Возврат ЗапросСкидок.Выполнить().Выгрузить();
КонецФункции
Если скидка в результате есть, а в документе нет — не выполнено условие или скидку «вручную» не выбрали. Отчет «Примененные скидки в документе», открытый из документа, покажет и непримененные скидки с невыполненными условиями, а двойной щелчок по колонке «% авт.» — расшифровку по строке.
Ручные и автоматические скидки по менеджерам лежат в ресурсах регистра «Выручка и себестоимость продаж». Процент здесь оценочный: скидка считается от цены документа, а выручка — с НДС.
// Ручные и автоматические скидки за период по менеджерам и клиентам.
// Суммы в валюте управленческого учета, возвраты уменьшают обороты.
Функция СкидкиМенеджеровЗаПериод(НачалоПериода, КонецПериода) Экспорт
ЗапросОборотов = Новый Запрос;
ЗапросОборотов.Текст =
"ВЫБРАТЬ
| Продажи.Менеджер КАК Менеджер,
| Продажи.АналитикаУчетаПоПартнерам.Партнер КАК Клиент,
| СУММА(Продажи.СуммаВыручкиОборот) КАК Выручка,
| СУММА(Продажи.СуммаРучнойСкидкиОборот) КАК РучныеСкидки,
| СУММА(Продажи.СуммаАвтоматическойСкидкиОборот) КАК АвтоматическиеСкидки
|ПОМЕСТИТЬ ВТСкидки
|ИЗ
| РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи
|
|СГРУППИРОВАТЬ ПО
| Продажи.Менеджер,
| Продажи.АналитикаУчетаПоПартнерам.Партнер
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТСкидки.Менеджер КАК Менеджер,
| ВТСкидки.Клиент КАК Клиент,
| ВТСкидки.Выручка КАК Выручка,
| ВТСкидки.РучныеСкидки КАК РучныеСкидки,
| ВТСкидки.АвтоматическиеСкидки КАК АвтоматическиеСкидки,
| ВЫБОР
| КОГДА ВТСкидки.Выручка + ВТСкидки.РучныеСкидки + ВТСкидки.АвтоматическиеСкидки = 0
| ТОГДА 0
| ИНАЧЕ ВЫРАЗИТЬ(100 * ВТСкидки.РучныеСкидки
| / (ВТСкидки.Выручка + ВТСкидки.РучныеСкидки + ВТСкидки.АвтоматическиеСкидки) КАК ЧИСЛО(15, 2))
| КОНЕЦ КАК ПроцентРучных
|ИЗ
| ВТСкидки КАК ВТСкидки
|ГДЕ
| ВТСкидки.РучныеСкидки + ВТСкидки.АвтоматическиеСкидки <> 0
|
|УПОРЯДОЧИТЬ ПО
| РучныеСкидки УБЫВ";
ЗапросОборотов.УстановитьПараметр("НачалоПериода", НачалоДня(НачалоПериода));
ЗапросОборотов.УстановитьПараметр("КонецПериода", КонецДня(КонецПериода));
Возврат ЗапросОборотов.Выполнить().Выгрузить();
КонецФункции
Типовой отчет «Примененные скидки в документе» показывает один документ, итоги акции за период берут из табличной части «Скидки (наценки)» реализаций. Оба запроса можно выполнить в консоли запросов.
// Итоги автоматических скидок в проведенных реализациях за период:
// по скидке и номенклатуре. Суммы в валюте документа.
Функция ИтогиАвтоматическихСкидок(НачалоПериода, КонецПериода) Экспорт
ЗапросИтогов = Новый Запрос;
ЗапросИтогов.Текст =
"ВЫБРАТЬ
| Скидки.СкидкаНаценка КАК СкидкаНаценка,
| Товары.Номенклатура КАК Номенклатура,
| Скидки.Ссылка.Валюта КАК Валюта,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Скидки.Ссылка) КАК Документов,
| СУММА(Товары.Количество) КАК Количество,
| СУММА(Скидки.Сумма) КАК СуммаСкидки
|ИЗ
| Документ.РеализацияТоваровУслуг.СкидкиНаценки КАК Скидки
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Товары
| ПО Скидки.Ссылка = Товары.Ссылка
| И Скидки.КлючСвязи = Товары.КлючСвязи
|ГДЕ
| Скидки.Ссылка.Проведен
| И Скидки.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
| И Скидки.КлючСвязи > 0
| И Скидки.СкидкаНаценка.СпособПримененияСкидки <> ЗНАЧЕНИЕ(Перечисление.СпособыПримененияСкидокНаценок.НачислитьБонусныеБаллы)
|
|СГРУППИРОВАТЬ ПО
| Скидки.СкидкаНаценка,
| Товары.Номенклатура,
| Скидки.Ссылка.Валюта
|
|УПОРЯДОЧИТЬ ПО
| СкидкаНаценка,
| СуммаСкидки УБЫВ";
ЗапросИтогов.УстановитьПараметр("НачалоПериода", НачалоДня(НачалоПериода));
ЗапросИтогов.УстановитьПараметр("КонецПериода", КонецДня(КонецПериода));
Возврат ЗапросИтогов.Выполнить().Выгрузить();
КонецФункции
Заказ с сайта или из обработки при включенных автоматических скидках не проводится: флаг «Скидки рассчитаны» ставит форма документа, а код — нет. На сервере расчет вызывают типовой функцией:
// Рассчитывает автоматические скидки в заказе клиента, созданном кодом
// (загрузка с сайта, обмен, обработка), и проводит заказ. Контекст: сервер.
// Цены и виды цен в строках должны быть заполнены: скидка считается от цены.
Процедура РассчитатьСкидкиИПровестиЗаказ(ЗаказОбъект) Экспорт
ВходныеПараметры = Новый Структура;
ВходныеПараметры.Вставить("ПрименятьКОбъекту", Истина);
ВходныеПараметры.Вставить("ТолькоПредварительныйРасчет", Ложь);
// Скидки «Назначается: вручную» в автоматическом сценарии не выбираем.
ВходныеПараметры.Вставить("ВосстанавливатьУправляемыеСкидки", Ложь);
ВходныеПараметры.Вставить("УправляемыеСкидки", Новый СписокЗначений);
// Ключ читает расчет по реализации; заказу он не мешает.
ВходныеПараметры.Вставить("РеализацияСверхЗаказа", Ложь);
// Типовой расчет заполнит табличную часть СкидкиНаценки, пересчитает
// суммы строк и документа и установит СкидкиРассчитаны = Истина.
СкидкиНаценкиСервер.Рассчитать(ЗаказОбъект, ВходныеПараметры);
Попытка
ЗаказОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
ЗаписьЖурналаРегистрации("Скидки.ПроведениеЗаказа", УровеньЖурналаРегистрации.Ошибка,
ЗаказОбъект.Метаданные(), ЗаказОбъект.Ссылка,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
Скидка меняет суммы строк, поэтому этапы графика оплаты заполняйте после расчета. Если цену со скидкой уже посчитал сайт, хватит ЗаказОбъект.СкидкиРассчитаны = Истина, но автоматические скидки УТ тогда не применятся. Как собрать сам документ — в статье о создании документа программно.
Чаще всего просят то, чего нет в списке условий:
Варианты без снятия с поддержки, от простого к сложному:
СпособПрименения() и Рассчитать().Модуль объекта внешней обработки. Расчет вызывает методы по именам, менять имена и параметры нельзя:
// Модуль объекта внешней обработки «Самовывоз» для УТ 11.
// Вид - «Проверка условия предоставления скидки (наценки)»: условие выполнено,
// если в заказе или реализации выбран способ доставки «Самовывоз».
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
// Регистрационные данные для справочника «Дополнительные отчеты и обработки».
Функция СведенияОВнешнейОбработке() Экспорт
Сведения = Новый Структура;
Сведения.Вставить("Вид", Перечисления.ВидыДополнительныхОтчетовИОбработок.ПроверкаУсловияПредоставленияСкидкиНаценки);
Сведения.Вставить("Версия", "1.0");
Сведения.Вставить("Назначение", Новый Массив);
Сведения.Вставить("Наименование", НСтр("ru = 'Самовывоз'"));
Сведения.Вставить("БезопасныйРежим", Истина);
Сведения.Вставить("Информация", НСтр("ru = 'Условие скидки: способ доставки «Самовывоз»'"));
Сведения.Вставить("ВерсияБСП", "2.1.2.1");
Сведения.Вставить("Команды", Новый ТаблицаЗначений);
Возврат Сведения;
КонецФункции
// Текст в карточке условия под полем «Условие предоставления».
Функция ОписаниеДействия(Параметры) Экспорт
Возврат НСтр("ru = 'Скидка, если клиент забирает товар сам (способ доставки «Самовывоз»)'");
КонецФункции
// Наименование, которое форма условия подставит автоматически.
Функция Автонаименование(Параметры) Экспорт
Возврат НСтр("ru = 'При самовывозе'");
КонецФункции
// Формы настроек нет: пустая строка скрывает кнопку настроек.
Функция ИмяФормыНастроек() Экспорт
Возврат "";
КонецФункции
// Неопределено - условие проверяется не запросом, расчет вызовет ПроверитьУсловие().
Функция Запрос(Параметры, ПараметрыРасчета) Экспорт
Возврат Неопределено;
КонецФункции
// Кратность выполнения: 0 - условие не выполнено, -1 - выполнено.
Функция ПроверитьУсловие(Параметры, ПараметрыРасчета) Экспорт
// В Объект лежат данные формы или объект документа; у чека ККМ реквизита нет.
Реквизиты = Новый Структура("СпособДоставки");
Если ПараметрыРасчета.Свойство("Объект") И ПараметрыРасчета.Объект <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(Реквизиты, ПараметрыРасчета.Объект);
КонецЕсли;
Если Реквизиты.СпособДоставки = Перечисления.СпособыДоставки.Самовывоз Тогда
Возврат -1;
КонецЕсли;
Возврат 0;
КонецФункции
#КонецОбласти
#КонецЕсли
Подключение: «НСИ и администрирование» → «Печатные формы, отчеты и обработки» → флажок «Дополнительные отчеты и обработки», по одноименной ссылке — «Создать», публикация «Используется». Затем «Условия предоставления скидок (наценок)» → «Создать»: обработка появится в поле «Условие предоставления». Подробнее — в статье о дополнительных обработках.
Если условию нужны данные базы, функция Запрос возвращает запрос, и расчет выполнит его в общем пакете. Вариант «не меньше трех заказов за 180 дней»:
// Вариант условия по данным базы: у клиента не меньше трех проведенных
// заказов за 180 дней. Заменяет функцию Запрос в модуле выше; пороги можно
// хранить в Параметры, если у обработки есть форма настроек.
Функция Запрос(Параметры, ПараметрыРасчета) Экспорт
МинимумЗаказов = 3;
ДнейИстории = 180;
Если ТипЗнч(Параметры) = Тип("Структура") Тогда
Если Параметры.Свойство("МинимумЗаказов") Тогда
МинимумЗаказов = Параметры.МинимумЗаказов;
КонецЕсли;
Если Параметры.Свойство("ДнейИстории") Тогда
ДнейИстории = Параметры.ДнейИстории;
КонецЕсли;
КонецЕсли;
// Один запрос без «;». Колонка КратностьВыполнения обязательна:
// строка с -1 - условие выполнено, пустой результат - не выполнено.
// После имени параметра - пробел, перевод строки, скобка или запятая:
// по ним расчет находит параметр, когда подставляет значение в текст.
ЗапросУсловия = Новый Запрос;
ЗапросУсловия.Текст =
"ВЫБРАТЬ
| -1 КАК КратностьВыполнения
|ИЗ
| (ВЫБРАТЬ
| КОЛИЧЕСТВО(Заказы.Ссылка) КАК Заказов
| ИЗ
| Документ.ЗаказКлиента КАК Заказы
| ГДЕ
| Заказы.Партнер = &Партнер
| И Заказы.Проведен
| И Заказы.Дата МЕЖДУ &НачалоИстории И &ТекущаяДата
| И Заказы.Ссылка <> &Регистратор) КАК История
|ГДЕ
| &МинимумЗаказов <= История.Заказов";
ЗапросУсловия.УстановитьПараметр("Партнер", ПараметрыРасчета.Партнер);
ЗапросУсловия.УстановитьПараметр("ТекущаяДата", ПараметрыРасчета.ТекущаяДата);
ЗапросУсловия.УстановитьПараметр("НачалоИстории",
НачалоДня(ПараметрыРасчета.ТекущаяДата) - ДнейИстории * 86400);
ЗапросУсловия.УстановитьПараметр("Регистратор", ПараметрыРасчета.Регистратор);
ЗапросУсловия.УстановитьПараметр("МинимумЗаказов", МинимумЗаказов);
Возврат ЗапросУсловия;
КонецФункции
Справочники.Склады.ПустаяСсылка() — так в регистре хранится общий статус скидки.ТекущийСклад.Родитель — статус на группе складов действует на все ее склады.СкидкиНаценки.ПометкаУдаления — расчет пометку удаления не проверяет, скидку выключает только статус «Не действует».Скидки.КлючСвязи > 0 — ключ 0 отмечает выбранные вручную скидки, -1 — сообщения; суммы по строкам товаров — с положительным ключом."РеализацияСверхЗаказа" — заказу не нужен, но расчет реализации читает его без проверки.ЗаполнитьЗначенияСвойств(Реквизиты, ПараметрыРасчета.Объект) — в Объект данные формы или объект документа; у чека ККМ способа доставки нет, условие просто не выполнится.Возврат -1 — условие выполнено, 0 — нет, положительное число — кратность для флажка «Кратно выполнению условий».-1 КАК КратностьВыполнения — колонка обязательна. Запрос — один, без «;»; в пакете итоговый запрос помечают комментарием //#Результат#.&МинимумЗаказов <= История.Заказов — даты и числа расчет подставляет в текст, находя параметр по следующему символу (пробел, перевод строки, скобка, запятая); параметр в конце текста останется без значения.Кроме Объект, в ПараметрыРасчета есть Партнер, Соглашение, КартаЛояльности, ТекущаяДата, Пользователь (менеджер документа), Регистратор и Товары. Методы обработки работают в безопасном режиме: запросы можно, файлы, COM и внешние компоненты — нет.
СведенияОВнешнейОбработке другой вид.Оформите клиенту индивидуальное соглашение, оставьте у скидки общий статус «Не действует» и поставьте «Действует» на странице «Скидки (наценки) по этому соглашению».
Три скидки — 3, 5 и 7 % — с условиями «За разовый объем продаж» не менее 50, 100 и 200 тысяч в группе «Максимум». Сработает наибольшая из выполненных.
«НСИ и администрирование» → «Настройка НСИ и разделов» → «Продажи», поле «Скидки в печатных формах»: выводить, не выводить или выбирать при печати.
Ручную скидку менеджер вводит сам в пределах лимитов. Скидку «вручную» настраивают заранее: менеджер только выбирает ее при расчете, статус и условия проверяются как у автоматической.
Типовые скидки настраиваются без программиста. Свое условие, способ расчета или контроль минимальной цены — это код в обработке или расширении, который надо проверить на ваших соглашениях и картах. Опишите правило скидки в разделе услуг по доработке 1С или разместите задачу: оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.