Ценовая власть (УТ 11.5) - 3

07.04.24

Разработка - Механизмы типовых конфигураций

Прошли по цепочке процедур обновления цен. Наметили план дальнейших раскопок.

Мы остановились на построении дерева цен.

В дерево добавляем следующие колонки:

  • Номенклатура
  • Характеристика
  • ЕдиницаИзмерения
  • ВидНоменклатуры
  • ХарактеристикаЦО
  • СерияЦО
  • УпаковкаЦО
  • ЦеноваяГруппа

В цикле по ВидЦены из ВыбранныеЦены добавляются колонки:

  • Валюта
  • СтараяЦена
  • Формула
  • ПроцентИзменения
  • СуммаИзменения
  • ИзмененаВручную
  • ФормулаИзмененаВручную
  • ИзмененаАвтоматически
  • ЗапретРедактирования
  • Упаковка (если ИспользоватьУпаковкиНоменклатуры)

И тут нежданная радость. Если тип дерева - из интерфеса, то исполняется та самая простыня кода, которая даже выглядит страшно.

Но мы - на сервере, и дерево у нас - просто дерево.

Поэтому мы копируем дерево с колонками в сформированную ранее структуру и возвращаемся. Ура!

***

Лирическое отступление - 2. Здесь, на ИС, нашелся мануал для пользователя. Особенно приятна заключительная фраза там:

Вот мы с Вами и рассмотрели все нюансы, подводные камни.

И пожелание удачного внедрения - пользователю.

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

***

Однако продолжим наши раскопки.

Мы вернулись с деревом цен из УстановкаЦенСервер.ПостроитьДеревоЦен

Теперь процедура УстановитьЦены вручает нам параметры и отправляет рассчитать цены (наконец-то!)

//	рассчитать цены
ПараметрыРасчета = Новый Структура();
ПараметрыРасчета.Вставить("ВидыЦен",				МассивВидовЦен);
ПараметрыРасчета.Вставить("ТолькоВыделенныеСтроки",	Ложь);
ПараметрыРасчета.Вставить("ТолькоНезаполненные",	Ложь);
ПараметрыРасчета.Вставить("ЗагрузкаСтарыхЦен",		Ложь);
ПараметрыРасчета.Вставить("ОкруглениеРучныхЦен",	Ложь);
ПараметрыРасчета.Вставить("РасчетПоФормулам",		Истина);
	
УстановкаЦенСервер.РассчитатьЦены(СтруктураФормы, ПараметрыРасчета);

Количества букв в этой процедуре не много, но, как и ожидалось, это не конечная глубина вложенности. Начиная с создания кеша (без проверки на Неопределено :) ).

// Рассчитывает цены в таблице цен
//
// Параметры:
//  Форма - см. ПостроитьДеревоЦен.Форма
//  ПараметрыРасчета - Структура - Параметры расчета
//  КэшДанных - см. ИнициализироватьСтруктуруКэшаДанных
//
Процедура РассчитатьЦены(Форма, ПараметрыРасчета, КэшДанных = Неопределено) Экспорт
	
	Форма.Модифицированность = Истина;
	
	КэшДанных = ИнициализироватьСтруктуруКэшаДанных(КэшДанных);
	
	МассивВидовЦен = Новый Массив;
	Для Каждого ВидЦены Из ПараметрыРасчета.ВидыЦен Цикл
		Если ТипЗнч(ВидЦены) = Тип("Структура") Тогда
			МассивВидовЦен.Добавить(УстановкаЦенКлиентСервер.НайтиСтрокуВидаЦен(Форма.ВыбранныеЦены, ВидЦены.ВидЦены));
		Иначе
			МассивВидовЦен.Добавить(УстановкаЦенКлиентСервер.НайтиСтрокуВидаЦен(Форма.ВыбранныеЦены, ВидЦены));
		КонецЕсли;
	КонецЦикла;
	
	Если Не ПараметрыРасчета.ТолькоВыделенныеСтроки Тогда
		
		ТаблицаНоменклатуры = СоздатьТаблицуНоменклатурыПоДеревуЦен(Форма, Ложь);
		
	Иначе
		
		ТаблицаНоменклатуры = СоздатьТаблицуНоменклатуры(Форма);
		Для Каждого ВыделеннаяСтрока Из Форма.Элементы.ДеревоЦен.ВыделенныеСтроки Цикл
			СтрокаТаблицыЦен           = Форма.ДеревоЦен.НайтиПоИдентификатору(ВыделеннаяСтрока);
			НоваяСтрока                = ТаблицаНоменклатуры.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТаблицыЦен);
			Если Форма.ИспользуетсяЦенообразование25 Тогда
				НоваяСтрока.УпаковкаЦОДляСвязи = ?(СтрокаТаблицыЦен.УпаковкаЦО = СтрокаТаблицыЦен.ЕдиницаИзмерения, Справочники.УпаковкиЕдиницыИзмерения.ПустаяСсылка(), СтрокаТаблицыЦен.УпаковкаЦО);
				НоваяСтрока.СерияЦОДляСвязи    = ?(СтрокаТаблицыЦен.СерияЦО.Предопределенный, Справочники.СерииНоменклатурыДляЦенообразования.ПустаяСсылка(), СтрокаТаблицыЦен.СерияЦО);
			КонецЕсли;
		КонецЦикла;
		
	КонецЕсли;
	
	Если ПараметрыРасчета.ЗагрузкаСтарыхЦен Тогда
		
		СтруктураПараметров = Новый Структура();
		СтруктураПараметров.Вставить("МассивСтрокВидовЦен",  МассивВидовЦен);
		СтруктураПараметров.Вставить("ДатаДокумента",        ПараметрыРасчета.ДатаСтарыхЦен);
		СтруктураПараметров.Вставить("ПроцентИзмененияЦены", ПараметрыРасчета.ПроцентИзмененияЦены);
		СтруктураПараметров.Вставить("ПрименятьОкругление",  ПараметрыРасчета.ПрименятьОкругление);
		СтруктураПараметров.Вставить("ТолькоНезаполненные",  ПараметрыРасчета.ТолькоНезаполненные);
	
		ЗагрузитьЗначенияБазовыхЦен(
			Форма,
			ТаблицаНоменклатуры,
			КэшДанных,
			СтруктураПараметров);
			
	КонецЕсли;
	
	Если ПараметрыРасчета.ОкруглениеРучныхЦен Тогда
		ПрименитьОкруглениеКРучнымЦенам(Форма, ТаблицаНоменклатуры, МассивВидовЦен, КэшДанных);
	КонецЕсли;
	
	Если ПараметрыРасчета.РасчетПоФормулам Тогда
		
		Если Не ПараметрыРасчета.ЗагрузкаСтарыхЦен Тогда 
			ЗагрузитьЗначенияБазовыхЦен(Форма, ТаблицаНоменклатуры, КэшДанных);
		КонецЕсли;

		ВычислитьЦеныПоДаннымИБ(Форма, ТаблицаНоменклатуры, МассивВидовЦен, ПараметрыРасчета.ТолькоНезаполненные, КэшДанных);
		
		РассчитатьВычисляемыеЦены(
			Форма,
			ТаблицаНоменклатуры,
			КэшДанных,
			?(Не ПараметрыРасчета.ЗагрузкаСтарыхЦен, МассивВидовЦен, Неопределено),
			ПараметрыРасчета.ТолькоНезаполненные,
			,
			ПараметрыРасчета.ВидыЦен);
		
	КонецЕсли;
	
	Если Форма.РассчитыватьАвтоматически Тогда

		// Список видов цен, которые, которые зависят от изменяемых
		ЗависимыеЦены = ПолучитьСтрокиНастроекЗависимыхВидовЦен(Форма, МассивВидовЦен);
	
		РассчитатьВычисляемыеЦены(
			Форма,
			ТаблицаНоменклатуры,
			КэшДанных,
			ЗависимыеЦены,
			ПараметрыРасчета.ТолькоНезаполненные);
			
	КонецЕсли;
		
	Если ТипЗнч(Форма.ДеревоЦен) = Тип("ДанныеФормыДерево") И ПараметрыРасчета.РасчетПоФормулам Тогда
		Для Каждого ВидЦеныДляОбработки Из МассивВидовЦен Цикл //ДанныеФормыЭлементКоллекции
			УстановитьПометкуИзмененныхФормул(Форма,,ВидЦеныДляОбработки.Ссылка);
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры

Создается таблица с номенклатурой.

Подгружаются (считываются из базы) старые значения цен.

Загадочное "округление ручных цен" - даже знать не хочу, что это.

И - па-бам! - РасчетПоФормулам... две процедуры нам в стек

ВычислитьЦеныПоДаннымИБ(Форма, ТаблицаНоменклатуры, МассивВидовЦен, ПараметрыРасчета.ТолькоНезаполненные, КэшДанных);
		
РассчитатьВычисляемыеЦены(
			Форма,
			ТаблицаНоменклатуры,
			КэшДанных,
			?(Не ПараметрыРасчета.ЗагрузкаСтарыхЦен, МассивВидовЦен, Неопределено),
			ПараметрыРасчета.ТолькоНезаполненные,
			,
			ПараметрыРасчета.ВидыЦен);

ВычислитьЦены вызывается в скриптах 7 раз, 5 - из модуля УстановкаЦенСервер (в том числе из нашей точки), дважды - из формы документа УстановкаЦенНоменклатуры.

Приводить ее листинг не будем, поскольку в ней в цикле по виду цены вызывается ВычислитьЗначенияЦеныПоДаннымИБ2_5.

В последней получаем схему компоновки данных (определенную для вида цены), проверяем ее на вариант ФО_20 и(!) ФО_25, дописываем текст запроса схемы компоновки, добавляем поля и связи по флагам опций (реально функциональных), загружаем настройки, определяем группировки, параметры.

Устанавливаем отбор по сегменту Номенклатуры.

И, наконец, выполняем запрос и выводим в таблицу значений ДанныеОтчета.

Если я правильно помню всю пройденную цепочку, это вообще первый раз мы обратились к базе запросом. В цикле, ага. А как тут без цикла, если схема компоновки у каждого вида цены - своя. Но если она настолько "своя", то как мы сумели каждую из них обработать одним и тем же куском кода?

Терзают автора смутные подозрения.

Отдельно получаем КоэффициентыУпаковокНоменклатурыДереваТоваров.

И - да, да, вы правы - вызываем очередной уровень вложенности: ЗагрузитьЦеныИзТаблицыЗначений.

Оправдывая титул "надменного и неприятного", предложу полюбоваться изящностью выбора "наценивать-не-наценивать":

Если СтрокаВидЦены.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.НаценкаНаЦенуПоступления 
Или СтрокаВидЦены.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.НаценкаНаЦенуВводаОстатков
Или СтрокаВидЦены.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.ЗаполнятьПоДаннымИБПоКонкурентам 
Или СтрокаВидЦены.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.ЗаполнятьПоДаннымИБПоПоставщикам 
Или СтрокаВидЦены.СпособЗаданияЦены = Перечисления.СпособыЗаданияЦен.ЗаполнятьПоДаннымИБПоСебестоимости Тогда

СтруктураПараметров.Вставить("Наценивать", Истина);
ЗагрузитьЦеныИзТаблицыЗначений(
	Форма,
	ДанныеОтчета,
	ТаблицаКоэффициентовУпаковокНоменклатуры,
	КэшДанных,
	СтрокаВидЦены,
	СтруктураПараметров);

Иначе

СтруктураПараметров.Вставить("Наценивать", Ложь);
ЗагрузитьЦеныИзТаблицыЗначений(Форма,
	ДанныеОтчета,
	ТаблицаКоэффициентовУпаковокНоменклатуры,
	КэшДанных,
	СтрокаВидЦены,
	СтруктураПараметров);

КонецЕсли;

Нет, никаких претензий, чисто эстетика, что вы! Короче, я бы этот кусок сделал так:

Запрос = Новый Запрос("Выбрать &СрокаСпособ В (Значение(Перечисление.СпособыЗаданияЦен.НаценкаНаЦенуПоступления),
|                                              Значение(Перечисление.СпособыЗаданияЦен.НаценкаНаЦенуВводаОстатков),
|                                              Значение(Перечисление.СпособыЗаданияЦен.ЗаполнятьПоДаннымИБПоКонкурентам),
|                                              Значение(Перечисление.СпособыЗаданияЦен.ЗаполнятьПоДаннымИБПоПоставщикам),
|                                              Значение(Перечисление.СпособыЗаданияЦен.ЗаполнятьПоДаннымИБПоСебестоимости))
| КАК  НацениватьНеНаценивать");
Запрос.УстановитьПараметр("СрокаСпособ",СтрокаВидЦены.СпособЗаданияЦены);
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
ВыборкаЗапроса.Следующий();
СтруктураПараметров.Вставить("Наценивать", ВыборкаЗапроса.НацениватьНеНаценивать);
	ЗагрузитьЦеныИзТаблицыЗначений(Форма,
		ДанныеОтчета,
		ТаблицаКоэффициентовУпаковокНоменклатуры,
		КэшДанных,
		СтрокаВидЦены,
		СтруктураПараметров);

Если кто-либо из критиков опять потребует замеров (см.комментарии), пусть сделает.

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

А нас ждет ЗагрузитьЦеныИзТаблицыЗначений. И это будет последний листинг в цепочке, которую автор сюда вытаскивает.

Нет, обойдемся без листинга, ничего, требующего особой внимательности там нет. Разве что вот это:

СтрокаТаблицыЦен = НайтиСтрокуДереваЦен(Форма, СтрокаИсточник, КэшДанных);

Для двух переданных параметров ищется вхождение СтрокаИсточник в дереве, входящем в форму.

Воздержусь от комментария, я же белый и приятный.

В общем, там пороги срабатывания, наценки, упаковки, валюта (опять же!).

Теперь рассмотрим РассчитатьВычисляемыеЦены

Там в цикле по Номенклатуре - цикл по ВидЦены, по "БазоваяЦена Из ВидЦены.ВлияющиеЦены":

ЗначениеЦены = ОбщегоНазначения.ВычислитьВБезопасномРежиме(Формула, ПараметрыДляВычисления);

... еще один вложенный уровень. Но там уже просто

Вычислить(Выражение);

**

Рассчитав цены, мы попадаем в попытку (и это здесь наш совсем-совсем последний шаг).

Документы.УстановкаЦенНоменклатуры.ЗаписатьИзмененияЦенНаСервере(СтруктураФормы, ТекстКомментария, 1);

Там в транзакции выполняется цикл проведения сохраненных в СтруктураФормы документов.

**

Итак, что мы увидели?

Во-первых, надо еще посмотреть, какие бывают формулы для Вычислить(Выражение).

Во-вторых, посмотреть, какие бывают схемы (шаблоны схем?) СКД. И почему их обрабатывают в цикле.

Без этого говорить о какой-либо оптимизации не приходится.

В-третьих, надо изобразить диаграмму исследованной нами здесь цепочки вложенных процедур. А то вот так, пробежавшись по тексту, в голове сложилось, конечно, общее представление о том, что происходит, но нужна картинка.

Итак, это план:

- формулы

- схемы СКД

- диаграмма с процедурами обновления цен

- и еще одна диаграмма с объектами конфигурации.

См. также

Ценовая власть. Выносим из цикла схему СКД

Механизмы типовых конфигураций Ценообразование, анализ цен Программист Пользователь Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Россия Абонемент ($m)

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

1 стартмани

11.04.2024    643    tango    1    

3

Формула в реквизите. Приквелл к сериалу "Ценовая власть"

Механизмы типовых конфигураций Программист Платформа 1С v8.3 1С:Управление торговлей 11 Россия Абонемент ($m)

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

10 стартмани

11.04.2024    504    tango    5    

4

Ценовая власть. Второй сезон

Механизмы типовых конфигураций Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Россия Бесплатно (free)

В первом сезоне мы рассмотрели (с точки зрения программиста) внутренний механизм, помещающий цены в регистр "Цены". Из этого регистра цена попадает в исходящие УПД (в продажи). Но эта цена (в прайс-листе) дифференцирована (ценообразована) в разрезах свойств самой номенклатуры. Но стратегия ценообразования, ценовая власть - это в первую очередь о работе с ценами для клиента. И тут вступает в дело второй акт марлезонского, Скидки (наценки) и кешбек.

08.04.2024    865    tango    0    

2

Ценовая власть или Управление ценообразованием (УТ 11.5)

Ценообразование, анализ цен Механизмы типовых конфигураций Программист Бизнес-аналитик Пользователь Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 11 Россия Управленческий учет Абонемент ($m)

Ценовая власть - это способность (возможность) компании изменять в некоторых пределах отпускную цену своего товара (услуг, продукции). Чем в более широких пределах вы можете играть в цену продажи, тем больше этой власти у вас. Если вы не можете управлять отпускной ценой, то это или не ваш бизнес, или не бизнес вовсе. Здесь в рубрике "База знаний аналитика и руководителя проекта" слово проект не ограничено "проектом в 1С". Посмотрим, что для этого есть в УТ 11.5.

1 стартмани

05.04.2024    726    tango    12    

2

Расширяем возможности дополнительных обработок и настраиваем их отладку

БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Уже не одна веб-страница исписана знаниями о дополнительных обработках, как создать, как подключить. Есть масса вариантов, как их можно отладить. Я разобрался в кишках работы библиотеки и покажу, как можно расширить возможности дополнительных отчетов, а также покажу удобный способ отладки.

07.02.2024    2959    YA_418728146    11    

49

Регистры накопления в 1С:КА2 и 1С:ERP для расчета НДФЛ, страховых взносов и взаиморасчетов с сотрудниками на январь 2024 года. Краткое описание

Зарплата Механизмы типовых конфигураций Программист Бухгалтер Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет НДФЛ Абонемент ($m)

Для расчета зарплаты и соответствующих налогов в конфигурациях 1С:КА2 и 1С:ERP используется 22 регистра накопления, 7 регистров сведений, 1 регистр расчета и бухгалтерские проводки. В таблице приведены названия этих регистров, указаны основные регистраторы и виды движений приход/расход. В описании приводится краткое функциональное назначение регистров в основных зарплатных процессах. Описание регистров родилось из черновиков при написании различных отчетов и обработок при эксплуатации 1С-овских конфигураций и исправлении ошибок по НДФЛ, взаиморасчетов с сотрудниками и прочих. Информация не претендует на полноценное описание работы регистров, скорее это дискуссионный материал. Но, возможно, кому-то пригодится и сократит время при подготовке отчетности за непростой (в плане учета зарплаты) 2023 год. А возможно, кто-то поделится своим опытом.

1 стартмани

10.01.2024    1438    9    2ncom    6    

8

Шаблоны новых объектов 1С для 1С:Бухгалтерии предприятия

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Программист Стажер Платформа 1С v8.3 1С:Бухгалтерия 3.0 Бесплатно (free)

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

28.12.2023    5284    mrXoxot    11    

104
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. o.nikolaev 213 07.04.24 21:37 Сейчас в теме
ООП? Не, не слышали.
На старте каждого витка разработки: "ну ребятушки, навалимся людно, конно, оружно да сдюжим!".
Оставьте свое сообщение