Организация функционала наценок по позициям либо сегментам номенклатуры в УТ 11.4

В статье описан один из методов реализации задачи установки скидок/наценок в соответствии с заданным процентом по позициям/сегментам номенклатуры. Так-же продемонстрирован принцип создания произвольного запроса к ИБ в виде цен.
Протестировано на релизе Управление торговлей, редакция 11.4.8.92.

В моей организации отдел маркетинга поставил следующую задачу: необходимо организовать установку цен в соответствии с заданным в настройках процентом для сегмента либо определенной позиции номенклатуры.

Хочу поделиться тем, каким образом данная задача была решена.

Сразу хочу оговориться, что в нашей системе есть справочник так называемых «Собственных констант», куда мы заносим различные предопределенные элементы и другие настройки.

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

Для реализации данного функционала мы добавили в конфигурацию два объекта: Определяемый тип «ОС_СобственныеКонстанты» (в нем задали составной тип, указав справочники «Номенклатура» и «Сегменты номенклатуры») и справочник «ОС_СобственныеКонстанты» с реквизитами Значение и ДополнительноеЗначение (у обоих реквизитов определяемый тип: ОС_СобственныеКонстанты). Так-же добавили табличную часть с аналогичными реквизитами (префикс добавлен чтобы видно было собственные доработки и при обновлении не возник конфликт имен).

Таким образом в данном справочнике можно задавать любые значения, используя их в различных задачах.

Добавим в справочник элемент "Наценка на инструмент". В табличной части зададим сегмент номенклатуры "Инструмент" с наценкой 30% и выделим отдельно позицию "Вентилятор настольный", наценка 25%:

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

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

За основу можно взять любую подходящую СКД.

Логика запроса следующая:

  1. Т.к. наценка будет устанавливаться на базовый вид цены, формируем выборку по регистру сведений "Цены номенклатуры" срез последних, где в условии задаем базовый вид цены;
  2. Выбираем из табличной части справочника "Собственные константы" элементы номенклатуры. В условии задаем ссылку на элемент этого справочника, чтобы для любого вида цены можно было задать свои различные варианты наценок.
  3. Аналогично формируем выборку из нашего справочника по сегментам (при соединении таблиц будет установлен приоритет на элемент).
  4. Соединяем и группируем данные (в моем случае в группировке средняя цена).
  5. И в итоговой таблице считаем цену позиций с учетом полученного процента.

Таблицы запроса:

Часть запроса СКД выложу в виде текста. Вы сможете по этим данным сами соединить таблицы и сформировать итоговый расчет. Готовая СКД есть в прикреплении. Можете ее скачать и просто загрузить в настройках вида цены:

ВЫБРАТЬ РАЗЛИЧНЫЕ
Сегменты.Номенклатура КАК Номенклатура,
Сегменты.Характеристика КАК Характеристика,
ИСТИНА КАК ИспользуетсяОтборПоСегментуНоменклатуры
ПОМЕСТИТЬ ОтборПоСегментуНоменклатуры
ИЗ
РегистрСведений.НоменклатураСегмента КАК Сегменты
{ГДЕ
Сегменты.Сегмент.* КАК СегментНоменклатуры,
Сегменты.Номенклатура.* КАК Номенклатура,
Сегменты.Характеристика.* КАК Характеристика}

ИНДЕКСИРОВАТЬ ПО
Сегменты.Номенклатура,
Сегменты.Характеристика,
ИспользуетсяОтборПоСегментуНоменклатуры
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
ЦеныНоменклатурыСрезПоследних.Характеристика КАК Характеристика,
ЦеныНоменклатурыСрезПоследних.Упаковка КАК Упаковка,
&Валюта КАК Валюта,
1 КАК Коэффициент,
(ВЫРАЗИТЬ(ВЫБОР
КОГДА ВидыЦен.ЦенаВключаетНДС
И ЦеныНоменклатурыСрезПоследних.ВидЦены.ЦенаВключаетНДС
ИЛИ НЕ ВидыЦен.ЦенаВключаетНДС
И НЕ ЦеныНоменклатурыСрезПоследних.ВидЦены.ЦенаВключаетНДС
ТОГДА ЦеныНоменклатурыСрезПоследних.Цена
КОГДА ВидыЦен.ЦенаВключаетНДС
И НЕ ЦеныНоменклатурыСрезПоследних.ВидЦены.ЦенаВключаетНДС
ТОГДА ЦеныНоменклатурыСрезПоследних.Цена + ЦеныНоменклатурыСрезПоследних.Цена * ВЫБОР
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20)
ТОГДА 0.2
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС18)
ТОГДА 0.18
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10)
ТОГДА 0.1
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС0)
ТОГДА 0
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.БезНДС)
ТОГДА 0
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20_120)
ТОГДА 0.2
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС18_118)
ТОГДА 0.18
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10_110)
ТОГДА 0.1
ИНАЧЕ 0
КОНЕЦ
КОГДА НЕ ВидыЦен.ЦенаВключаетНДС
И ЦеныНоменклатурыСрезПоследних.ВидЦены.ЦенаВключаетНДС
ТОГДА ЦеныНоменклатурыСрезПоследних.Цена - ЦеныНоменклатурыСрезПоследних.Цена * ВЫБОР
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20)
ТОГДА 20 / 120
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС18)
ТОГДА 18 / 118
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10)
ТОГДА 10 / 110
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС0)
ТОГДА 0
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.БезНДС)
ТОГДА 0
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20_120)
ТОГДА 20 / 120
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС18_118)
ТОГДА 18 / 118
КОГДА ЦеныНоменклатурыСрезПоследних.Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10_110)
ТОГДА 10 / 110
ИНАЧЕ 0
КОНЕЦ
КОНЕЦ КАК ЧИСЛО(15, 2))) * ВЫБОР
КОГДА &Валюта <> ЦеныНоменклатурыСрезПоследних.Валюта
ТОГДА ВЫБОР
КОГДА ЕСТЬNULL(КурсыВалютыЦены.Кратность, 0) > 0
И ЕСТЬNULL(КурсыВалютыЦены.Курс, 0) > 0
И ЕСТЬNULL(КурсыВалюты.Кратность, 0) > 0
И ЕСТЬNULL(КурсыВалюты.Курс, 0) > 0
ТОГДА КурсыВалютыЦены.Курс * КурсыВалюты.Кратность / (КурсыВалюты.Курс * КурсыВалютыЦены.Кратность)
ИНАЧЕ 0
КОНЕЦ
ИНАЧЕ 1
КОНЕЦ КАК Цена
ПОМЕСТИТЬ ЦеныНоменклатурыПоБазовомуВиду
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних({(КОНЕЦПЕРИОДА(&ДатаДокумента, ДЕНЬ))}, ВидЦены = &БазовыйВидЦены {((Номенклатура, Характеристика) В
(ВЫБРАТЬ
ОтборПоСегментуНоменклатуры.Номенклатура,
ОтборПоСегментуНоменклатуры.Характеристика
ИЗ
ОтборПоСегментуНоменклатуры
ГДЕ
ОтборПоСегментуНоменклатуры.ИспользуетсяОтборПоСегментуНоменклатуры = &ИспользуетсяОтборПоСегментуНоменклатуры))}) КАК ЦеныНоменклатурыСрезПоследних
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних({(КОНЕЦПЕРИОДА(&ДатаДокумента, ДЕНЬ))}, ) КАК КурсыВалютыЦены
ПО ЦеныНоменклатурыСрезПоследних.Валюта = КурсыВалютыЦены.Валюта
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних({(КОНЕЦПЕРИОДА(&ДатаДокумента, ДЕНЬ))}, Валюта = &Валюта) КАК КурсыВалюты
ПО (ИСТИНА)
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыЦен КАК ВидыЦен
ПО (ВидыЦен.Ссылка = &ВидЦены)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОС_СобственныеКонстантыДанные.Значение КАК Номенклатура,
ВЫРАЗИТЬ(ЕСТЬNULL(ОС_СобственныеКонстантыДанные.ДополнительноеЗначение, 0) КАК ЧИСЛО(15, 2)) КАК ПроцентПоНоменклатуре
ПОМЕСТИТЬ ПроцентыПоНоменклатуре
ИЗ
Справочник.ОС_СобственныеКонстанты.Данные КАК ОС_СобственныеКонстантыДанные
ГДЕ
НЕ ОС_СобственныеКонстантыДанные.Значение ССЫЛКА Справочник.СегментыНоменклатуры
И ОС_СобственныеКонстантыДанные.Ссылка = &Наценка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ОС_СобственныеКонстантыДанные.Значение КАК НоменклатураСегмент,
ВЫРАЗИТЬ(ЕСТЬNULL(ОС_СобственныеКонстантыДанные.ДополнительноеЗначение, 0) КАК ЧИСЛО(15, 2)) КАК ПроцентПоСегменту
ПОМЕСТИТЬ ПроцентыПоСегментам
ИЗ
Справочник.ОС_СобственныеКонстанты.Данные КАК ОС_СобственныеКонстантыДанные
ГДЕ
ОС_СобственныеКонстантыДанные.Значение ССЫЛКА Справочник.СегментыНоменклатуры
И ОС_СобственныеКонстантыДанные.Ссылка = &Наценка
;

В параметрах зададим базовый вид цены "Себестоимость" и нашу наценку:

Для простоты примера установил себестоимость вручную для 3-х элементов сегмента и рассчитал данные:

При формировании цен расчет автоматически не выполняется (не могу сказать почему) и для пересчета необходимо выбрать пункт меню "Рассчитать вычисляемые (по данным ИБ и формулам)":

Все три позиции есть в сегменте. Однако 1-й Вентилятор рассчитался исходя из установленной наценки в 25, а не 30%, т.к. он был в справочнике выделен отдельно.

2 Comments

  1. Alexey-Alyosha

    Статья очень помогла. Спасибо!

    Сначала хотел сделать аналогично, но используя доп реквизиты номенклатуры и сегмента, задавая в них процент наценки. Однако в этом случае не получилось бы при расчете нескольких видов цен для одной и той-же позиции либо сегмента номенклатуры задать различные проценты наценок. А так — все универсальненько. И типовые объекты не задеты. Да и справочник «Собственные константы» думаю еще не раз пригодиться. В том числе и при разработке обменов.

    Reply
  2. cheiser1982

    (1) Рад что пригодилась! У нас кстати данный справочник так-же принимает участие в различных обменах между системами.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *