Загрузка данных


//++Варнин А.А. Задача №72300 - цены с НДС
//
// ВАРИАНТ А (рекомендую): один запрос считает сразу обе цены.
//   Весь тяжёлый конвейер (остатки, установка цен, поступления, доп. реквизиты)
//   отрабатывает один раз вместо двух, наборы пересчитываются тоже один раз.
//   Отличие от версии без НДС — ровно одна дополнительная СУММА в ВТ_ПоДокументам,
//   дальше вторая цена просто едет параллельно первой.
//
// ВАРИАНТ Б (в конце файла): отдельная функция ТекстЗапросаЦеныСНДС().
//   Нужен, только если выгрузки с НДС и без НДС должны запускаться раздельно.
//   Минус очевидный: две копии одного запроса разъедутся при первой же правке —
//   ровно так уже случилось со старой ТекстЗапросаСНДС.
//
// Колонки результата:
//   Цена, СредняяЦена               - без НДС (имена не менял, вызывающий код цел)
//   ЦенаСНДС, СредняяЦенаСНДС       - с НДС
//
// ВАЖНО про ставку: сумма НДС берётся из документа поступления, то есть цена с НДС
// считается по ставке, действовавшей на момент закупки. Если ставка с тех пор
// менялась, старые поступления попадут в среднюю по старой ставке. Если нужна
// пересчитанная по текущей ставке — это другой расчёт, скажи, переделаю.

#Область ВариантА_ОдинЗапросОбеЦены

Функция ТекстЗапросаЦены()

	Возврат
	
		"ВЫБРАТЬ
		|	Вариант.Владелец КАК Набор,
		|	Вариант.Ссылка КАК Вариант,
		|	Вариант.Наименование КАК ВариантНаименование,
		|	СоставТЧ.НомерСтроки КАК НомерСтроки,
		|	СоставТЧ.Номенклатура КАК Компонент,
		|	СоставТЧ.Количество КАК Количество
		|ПОМЕСТИТЬ ВТ_СоставНаборов
		|ИЗ
		|	Справочник.ВариантыКомплектацииНоменклатуры.Товары КАК СоставТЧ
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ВариантыКомплектацииНоменклатуры КАК Вариант
		|		ПО СоставТЧ.Ссылка = Вариант.Ссылка
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Наборы
		|		ПО (Вариант.Владелец = Наборы.Ссылка)
		|ГДЕ
		|	НЕ Вариант.ПометкаУдаления
		|	И НЕ Наборы.ПометкаУдаления
		|	И Наборы.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Набор)
		|	И СоставТЧ.Количество > 0
		|
		|ИНДЕКСИРОВАТЬ ПО
		|	Набор,
		|	Компонент
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	ВсяНоменклатура.Номенклатура КАК Номенклатура
		|ПОМЕСТИТЬ ВТ_НоменклатураКРасчету
		|ИЗ
		|	(ВЫБРАТЬ
		|		ОстаткиТоваров.Номенклатура КАК Номенклатура
		|	ИЗ
		|		РегистрНакопления.ТоварыНаСкладах.Остатки(&КонецПериода, ) КАК ОстаткиТоваров
		|	ГДЕ
		|		ОстаткиТоваров.ВНаличииОстаток > 0
		|	
		|	ОБЪЕДИНИТЬ ВСЕ
		|	
		|	ВЫБРАТЬ
		|		ВТ_СоставНаборов.Компонент
		|	ИЗ
		|		ВТ_СоставНаборов КАК ВТ_СоставНаборов
		|	
		|	ОБЪЕДИНИТЬ ВСЕ
		|	
		|	ВЫБРАТЬ
		|		ВТ_СоставНаборов.Набор
		|	ИЗ
		|		ВТ_СоставНаборов КАК ВТ_СоставНаборов) КАК ВсяНоменклатура
		|
		|ИНДЕКСИРОВАТЬ ПО
		|	Номенклатура
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	УстановкаЦен.ДокументОснование КАК Основание,
		|	ЦеныНоменклатуры25.Номенклатура КАК Номенклатура,
		|	МАКСИМУМ(ЦеныНоменклатуры25.Период) КАК ПериодУстановки
		|ПОМЕСТИТЬ ВТ_ДокУстановкаЦен
		|ИЗ
		|	РегистрСведений.ЦеныНоменклатуры25 КАК ЦеныНоменклатуры25
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.УстановкаЦенНоменклатуры КАК УстановкаЦен
		|		ПО ЦеныНоменклатуры25.Регистратор = УстановкаЦен.Ссылка
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_НоменклатураКРасчету КАК ВТ_Номенклатура
		|		ПО ЦеныНоменклатуры25.Номенклатура = ВТ_Номенклатура.Номенклатура
		|ГДЕ
		|	УстановкаЦен.Проведен
		|	И УстановкаЦен.ДокументОснование ССЫЛКА Документ.ПриобретениеТоваровУслуг
		|	И ЦеныНоменклатуры25.ВидЦены = &ВидЦены
		|	И ЦеныНоменклатуры25.Цена > 0
		|
		|СГРУППИРОВАТЬ ПО
		|	УстановкаЦен.ДокументОснование,
		|	ЦеныНоменклатуры25.Номенклатура
		|
		|ИНДЕКСИРОВАТЬ ПО
		|	Номенклатура,
		|	Основание
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|// Здесь и только здесь появляется вторая сумма. Логика зеркальная:
		|// если цена в документе уже включает НДС — сумма с НДС это Сумма как есть,
		|// а без НДС это Сумма - СуммаНДС. Если не включает — наоборот.
		|ВЫБРАТЬ
		|	ДокТовары.Номенклатура КАК Номенклатура,
		|	Док.Ссылка КАК Ссылка,
		|	ВТ_ДокУстановкаЦен.ПериодУстановки КАК ПериодУстановки,
		|	СУММА(ВЫБОР
		|			КОГДА Док.ЦенаВключаетНДС
		|				ТОГДА ДокТовары.Сумма - ДокТовары.СуммаНДС
		|			ИНАЧЕ ДокТовары.Сумма
		|		КОНЕЦ) КАК СуммаБезНДС,
		|	СУММА(ВЫБОР
		|			КОГДА Док.ЦенаВключаетНДС
		|				ТОГДА ДокТовары.Сумма
		|			ИНАЧЕ ДокТовары.Сумма + ДокТовары.СуммаНДС
		|		КОНЕЦ) КАК СуммаСНДС,
		|	СУММА(ДокТовары.Количество) КАК Количество
		|ПОМЕСТИТЬ ВТ_ПоДокументам
		|ИЗ
		|	Документ.ПриобретениеТоваровУслуг.Товары КАК ДокТовары
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПриобретениеТоваровУслуг КАК Док
		|		ПО ДокТовары.Ссылка = Док.Ссылка
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ДокУстановкаЦен КАК ВТ_ДокУстановкаЦен
		|		ПО (Док.Ссылка = ВТ_ДокУстановкаЦен.Основание)
		|			И ДокТовары.Номенклатура = ВТ_ДокУстановкаЦен.Номенклатура
		|ГДЕ
		|	Док.Проведен
		|	И ДокТовары.Количество > 0
		|	И ДокТовары.Сумма > 0
		|
		|СГРУППИРОВАТЬ ПО
		|	ДокТовары.Номенклатура,
		|	Док.Ссылка,
		|	ВТ_ДокУстановкаЦен.ПериодУстановки
		|
		|ИНДЕКСИРОВАТЬ ПО
		|	Номенклатура
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ВТ_ПоДокументам.Номенклатура КАК Номенклатура,
		|	ВТ_ПоДокументам.Ссылка КАК Ссылка,
		|	ВТ_ПоДокументам.ПериодУстановки КАК ПериодУстановки,
		|	ВТ_ПоДокументам.СуммаБезНДС / ВТ_ПоДокументам.Количество КАК ЦенаДокумента,
		|	ВТ_ПоДокументам.СуммаСНДС / ВТ_ПоДокументам.Количество КАК ЦенаДокументаСНДС
		|ПОМЕСТИТЬ ВТ_ЦеныДокументов
		|ИЗ
		|	ВТ_ПоДокументам КАК ВТ_ПоДокументам
		|
		|ИНДЕКСИРОВАТЬ ПО
		|	Номенклатура,
		|	ПериодУстановки
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ВТ_ЦеныДокументов.Номенклатура КАК Номенклатура,
		|	СРЕДНЕЕ(ВТ_ЦеныДокументов.ЦенаДокумента) КАК СредняяЦена,
		|	СРЕДНЕЕ(ВТ_ЦеныДокументов.ЦенаДокументаСНДС) КАК СредняяЦенаСНДС,
		|	КОЛИЧЕСТВО(ВТ_ЦеныДокументов.Ссылка) КАК КоличествоДокументов,
		|	МАКСИМУМ(ВТ_ЦеныДокументов.ПериодУстановки) КАК ПериодУстановки
		|ПОМЕСТИТЬ ВТ_СредняяЦена
		|ИЗ
		|	ВТ_ЦеныДокументов КАК ВТ_ЦеныДокументов
		|
		|СГРУППИРОВАТЬ ПО
		|	ВТ_ЦеныДокументов.Номенклатура
		|
		|ИНДЕКСИРОВАТЬ ПО
		|	Номенклатура,
		|	ПериодУстановки
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ВТ_ЦеныДокументов.Номенклатура КАК Номенклатура,
		|	СРЕДНЕЕ(ВТ_ЦеныДокументов.ЦенаДокумента) КАК ТекущаяЦенаБезНДС,
		|	СРЕДНЕЕ(ВТ_ЦеныДокументов.ЦенаДокументаСНДС) КАК ТекущаяЦенаСНДС
		|ПОМЕСТИТЬ ВТ_ПоследняяЦена
		|ИЗ
		|	ВТ_ЦеныДокументов КАК ВТ_ЦеныДокументов
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_СредняяЦена КАК ВТ_СредняяЦена
		|		ПО ВТ_ЦеныДокументов.Номенклатура = ВТ_СредняяЦена.Номенклатура
		|			И ВТ_ЦеныДокументов.ПериодУстановки = ВТ_СредняяЦена.ПериодУстановки
		|
		|СГРУППИРОВАТЬ ПО
		|	ВТ_ЦеныДокументов.Номенклатура
		|
		|ИНДЕКСИРОВАТЬ ПО
		|	Номенклатура
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ДопРеквизиты.Ссылка КАК Номенклатура,
		|	МАКСИМУМ(ВЫБОР
		|			КОГДА ДопРеквизиты.Свойство = &СвойствоOEM
		|				ТОГДА ВЫРАЗИТЬ(ДопРеквизиты.Значение КАК СТРОКА(150))
		|			ИНАЧЕ """"
		|		КОНЕЦ) КАК OEMНомер,
		|	МАКСИМУМ(ВЫБОР
		|			КОГДА ДопРеквизиты.Свойство = &СвойствоАртикулМП
		|				ТОГДА ВЫРАЗИТЬ(ДопРеквизиты.Значение КАК СТРОКА(150))
		|			ИНАЧЕ """"
		|		КОНЕЦ) КАК АртикулМаркетплейса
		|ПОМЕСТИТЬ ВТ_ДопРеквизиты
		|ИЗ
		|	Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_НоменклатураКРасчету КАК ВТ_Номенклатура
		|		ПО ДопРеквизиты.Ссылка = ВТ_Номенклатура.Номенклатура
		|ГДЕ
		|	ДопРеквизиты.Свойство В (&СвойствоOEM, &СвойствоАртикулМП)
		|
		|СГРУППИРОВАТЬ ПО
		|	ДопРеквизиты.Ссылка
		|
		|ИНДЕКСИРОВАТЬ ПО
		|	Номенклатура
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ПРЕДСТАВЛЕНИЕ(Ном.Марка) КАК Марка,
		|	Ном.Артикул КАК Артикул, 
		|	ЕСТЬNULL(ВТ_ДопРеквизиты.АртикулМаркетплейса, """") КАК АртикулМаркетплейса,
		|	Ном.Код КАК Код,
		|	ЕСТЬNULL(ВТ_ДопРеквизиты.OEMНомер, """") КАК OEMНомер,
		|	Ном.Ссылка КАК Номенклатура,
		|	ПРЕДСТАВЛЕНИЕ(Ном.Ссылка) КАК Наименование,
		|	ВТ_ПоследняяЦена.ТекущаяЦенаБезНДС КАК Цена,
		|	ВТ_СредняяЦена.СредняяЦена КАК СредняяЦена,
		|	ВТ_ПоследняяЦена.ТекущаяЦенаСНДС КАК ЦенаСНДС,
		|	ВТ_СредняяЦена.СредняяЦенаСНДС КАК СредняяЦенаСНДС,
		|	ВТ_СредняяЦена.КоличествоДокументов КАК КоличествоДокументов
		|ИЗ
		|	ВТ_СредняяЦена КАК ВТ_СредняяЦена
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ПоследняяЦена КАК ВТ_ПоследняяЦена
		|		ПО ВТ_СредняяЦена.Номенклатура = ВТ_ПоследняяЦена.Номенклатура
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Ном
		|		ПО ВТ_СредняяЦена.Номенклатура = Ном.Ссылка
		|		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДопРеквизиты КАК ВТ_ДопРеквизиты
		|		ПО ВТ_СредняяЦена.Номенклатура = ВТ_ДопРеквизиты.Номенклатура
		|ГДЕ
		|	НЕ Ном.ПометкаУдаления
		|	И ВТ_СредняяЦена.СредняяЦена > 0
		|	И НЕ Ном.Наименование ПОДОБНО &МаскаНоменклатуры
		|	И НЕ Ном.Артикул ПОДОБНО &МаскаНоменклатуры
		|	И Ном.ТипНоменклатуры <> ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Набор)
		|
		|УПОРЯДОЧИТЬ ПО
		|	Код
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ВТ_СоставНаборов.Набор КАК Набор,
		|	ПРЕДСТАВЛЕНИЕ(Ном.Ссылка) КАК Наименование,
		|	Ном.Код КАК Код,
		|	Ном.Артикул КАК Артикул,
		|	ПРЕДСТАВЛЕНИЕ(Ном.Марка) КАК Марка,
		|	ЕСТЬNULL(ВТ_ДопРеквизиты.OEMНомер, """") КАК OEMНомер,
		|	ЕСТЬNULL(ВТ_ДопРеквизиты.АртикулМаркетплейса, """") КАК АртикулМаркетплейса,
		|	ВТ_СоставНаборов.Вариант КАК Вариант,
		|	ВТ_СоставНаборов.ВариантНаименование КАК ВариантНаименование,
		|	ВТ_СоставНаборов.НомерСтроки КАК НомерСтроки,
		|	ВТ_СоставНаборов.Компонент КАК Компонент,
		|	ВТ_СоставНаборов.Количество КАК Количество
		|ИЗ
		|	ВТ_СоставНаборов КАК ВТ_СоставНаборов
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Ном
		|		ПО ВТ_СоставНаборов.Набор = Ном.Ссылка
		|		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДопРеквизиты КАК ВТ_ДопРеквизиты
		|		ПО ВТ_СоставНаборов.Набор = ВТ_ДопРеквизиты.Номенклатура
		|
		|УПОРЯДОЧИТЬ ПО
		|	Набор,
		|	ВариантНаименование,
		|	НомерСтроки";

КонецФункции

#КонецОбласти

#Область ИзмененияВКоде

// Список ценовых колонок вынесен в одно место — дальше весь код работает по нему,
// и добавление третьей цены не потребует править арифметику наборов.
//
Функция ЦеновыеКолонки()

	Возврат СтрРазделить("СредняяЦена,Цена,СредняяЦенаСНДС,ЦенаСНДС", ",");

КонецФункции

Функция СформироватьТаблицуЦен()

	ВидЦены = Справочники.ВидыЦен.НайтиПоРеквизиту("Идентификатор", "ЗакупочнаяЦена");
	Если НЕ ЗначениеЗаполнено(ВидЦены) Тогда
		ВызватьИсключение "Не найден вид цены с идентификатором ""ЗакупочнаяЦена"".";
	КонецЕсли;

	Запрос = Новый Запрос(ТекстЗапросаЦены());
	Запрос.УстановитьПараметр("ВидЦены", ВидЦены);
	Запрос.УстановитьПараметр("КонецПериода", ТекущаяДатаСеанса());
	Запрос.УстановитьПараметр("СвойствоOEM", НайтиДополнительныйРеквизит("OEMНомер"));
	Запрос.УстановитьПараметр("СвойствоАртикулМП", НайтиДополнительныйРеквизит("АртикулМаркетплейсов"));
	Запрос.УстановитьПараметр("МаскаНоменклатуры", "%не использовать%");

	Результаты = Запрос.ВыполнитьПакет();

	ЦеныТЗ   = Результаты[Результаты.Количество() - 2].Выгрузить();
	СоставТЗ = Результаты[Результаты.Количество() - 1].Выгрузить();

	Колонки = ЦеновыеКолонки();

	Для Каждого СтрЦена Из ЦеныТЗ Цикл
		Для Каждого ИмяКолонки Из Колонки Цикл
			СтрЦена[ИмяКолонки] = Окр(СтрЦена[ИмяКолонки], 2, РежимОкругления.Окр15как20);
		КонецЦикла;
	КонецЦикла;

	ДополнитьЦенамиНаборов(ЦеныТЗ, СоставТЗ);

	ЦеныТЗ.Сортировать("Код");

	Возврат ЦеныТЗ;

КонецФункции

Процедура ДополнитьЦенамиНаборов(ЦеныТЗ, СоставТЗ)

	ИмяСобытия = "Выгрузка закупочных цен. Наборы";

	Если СоставТЗ.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	Колонки = ЦеновыеКолонки();

	ИзвестныеЦены = Новый Соответствие;
	Для Каждого СтрЦена Из ЦеныТЗ Цикл
		Цены = Новый Структура;
		Для Каждого ИмяКолонки Из Колонки Цикл
			Цены.Вставить(ИмяКолонки, СтрЦена[ИмяКолонки]);
		КонецЦикла;
		ИзвестныеЦены.Вставить(СтрЦена.Номенклатура, Цены);
	КонецЦикла;

	ВыбранныйВариант = Новый Соответствие;
	НаборыСНесколькимиВариантами = Новый Массив;

	Для Каждого СтрСостав Из СоставТЗ Цикл
		Вариант = ВыбранныйВариант[СтрСостав.Набор];
		Если Вариант = Неопределено Тогда
			ВыбранныйВариант.Вставить(СтрСостав.Набор, СтрСостав.Вариант);
		ИначеЕсли Вариант <> СтрСостав.Вариант
			И НаборыСНесколькимиВариантами.Найти(СтрСостав.Набор) = Неопределено Тогда
			НаборыСНесколькимиВариантами.Добавить(СтрСостав.Набор);
		КонецЕсли;
	КонецЦикла;

	Если НаборыСНесколькимиВариантами.Количество() > 0 Тогда
		ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Предупреждение, , ,
			"У этих наборов несколько вариантов комплектации, взят первый по наименованию:"
				+ Символы.ПС + ПредставлениеСписка(НаборыСНесколькимиВариантами, 30));
	КонецЕсли;

	РеквизитыНаборов = Новый Соответствие;
	СоставНабора = Новый Соответствие;

	Для Каждого СтрСостав Из СоставТЗ Цикл

		Если СтрСостав.Вариант <> ВыбранныйВариант[СтрСостав.Набор] Тогда
			Продолжить;
		КонецЕсли;

		Если РеквизитыНаборов[СтрСостав.Набор] = Неопределено Тогда
			Реквизиты = Новый Структура("Наименование, Код, Артикул, Марка, OEMНомер, АртикулМаркетплейса");
			ЗаполнитьЗначенияСвойств(Реквизиты, СтрСостав);
			РеквизитыНаборов.Вставить(СтрСостав.Набор, Реквизиты);
			СоставНабора.Вставить(СтрСостав.Набор, Новый Массив);
		КонецЕсли;

		СоставНабора[СтрСостав.Набор].Добавить(
			Новый Структура("Компонент, Количество", СтрСостав.Компонент, СтрСостав.Количество));

	КонецЦикла;

	Осталось = Новый Массив;
	Для Каждого КлючЗначение Из СоставНабора Цикл
		Осталось.Добавить(КлючЗначение.Ключ);
	КонецЦикла;

	НомерПрохода = 0;
	ПоследняяПричина = Новый Соответствие;

	Пока Осталось.Количество() > 0 Цикл

		НомерПрохода = НомерПрохода + 1;
		ПосчитаноЗаПроход = 0;
		НеПосчитанные = Новый Массив;

		Для Каждого Набор Из Осталось Цикл

			Итоги = Новый Структура;
			Для Каждого ИмяКолонки Из Колонки Цикл
				Итоги.Вставить(ИмяКолонки, 0);
			КонецЦикла;

			НедостающийКомпонент = Неопределено;

			Для Каждого СтрокаСостава Из СоставНабора[Набор] Цикл

				ЦеныКомпонента = ИзвестныеЦены[СтрокаСостава.Компонент];
				Если ЦеныКомпонента = Неопределено Тогда
					НедостающийКомпонент = СтрокаСостава.Компонент;
					Прервать;
				КонецЕсли;

				Для Каждого ИмяКолонки Из Колонки Цикл
					Итоги[ИмяКолонки] = Итоги[ИмяКолонки]
						+ ЦеныКомпонента[ИмяКолонки] * СтрокаСостава.Количество;
				КонецЦикла;

			КонецЦикла;

			Если НедостающийКомпонент <> Неопределено Тогда
				НеПосчитанные.Добавить(Набор);
				ПоследняяПричина.Вставить(Набор, НедостающийКомпонент);
				Продолжить;
			КонецЕсли;

			// Гейт по цене без НДС: если её нет, набор бессмысленен и с НДС.
			Если Итоги.СредняяЦена <= 0 ИЛИ Итоги.Цена <= 0 Тогда
				ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Предупреждение, , ,
					"Набор " + Строка(Набор) + ": итоговая цена нулевая, в выгрузку не попал.");
				Продолжить;
			КонецЕсли;

			Для Каждого ИмяКолонки Из Колонки Цикл
				Итоги[ИмяКолонки] = Окр(Итоги[ИмяКолонки], 2, РежимОкругления.Окр15как20);
			КонецЦикла;

			НоваяСтрока = ЦеныТЗ.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, РеквизитыНаборов[Набор]);
			ЗаполнитьЗначенияСвойств(НоваяСтрока, Итоги);
			НоваяСтрока.Номенклатура = Набор;
			НоваяСтрока.КоличествоДокументов = 0;

			ИзвестныеЦены.Вставить(Набор, Итоги);
			ПосчитаноЗаПроход = ПосчитаноЗаПроход + 1;

		КонецЦикла;

		Осталось = НеПосчитанные;

		Если ПосчитаноЗаПроход = 0 Тогда
			Прервать;
		КонецЕсли;

		Если НомерПрохода > 10 Тогда
			ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка, , ,
				"Превышено 10 проходов по вложенным наборам. Проверьте состав на цикличность.");
			Прервать;
		КонецЕсли;

	КонецЦикла;

	Если Осталось.Количество() > 0 Тогда
		СтрокиЛога = Новый Массив;
		Для Каждого Набор Из Осталось Цикл
			СтрокиЛога.Добавить(Строка(Набор) + " — нет цены по компоненту: "
				+ Строка(ПоследняяПричина[Набор]));
			Если СтрокиЛога.Количество() >= 50 Тогда
				Прервать;
			КонецЕсли;
		КонецЦикла;
		ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка, , ,
			СтрШаблон("Не посчитано наборов: %1. Они не попали в выгрузку.%2%3",
				Осталось.Количество(), Символы.ПС, СтрСоединить(СтрокиЛога, Символы.ПС)));
	КонецЕсли;

КонецПроцедуры

Функция ОтправитьВKafka(ЦеныТЗ)

	Сообщения = Новый Массив;

	Для Каждого СтрЦена Из ЦеныТЗ Цикл

		Элемент = Новый Структура;
		Элемент.Вставить("name",       СокрЛП(СтрЦена.Наименование));
		Элемент.Вставить("code",       СокрЛП(СтрЦена.Код));
		Элемент.Вставить("brand",      СокрЛП(СтрЦена.Марка));
		Элемент.Вставить("article",    СокрЛП(СтрЦена.Артикул));
		Элемент.Вставить("article_mp", СокрЛП(СтрЦена.АртикулМаркетплейса));
		Элемент.Вставить("oem",        СокрЛП(СтрЦена.OEMНомер));
		Элемент.Вставить("last_price", СтрЦена.Цена);
		Элемент.Вставить("avg_price",  СтрЦена.СредняяЦена);
		Элемент.Вставить("last_price_vat", СтрЦена.ЦенаСНДС);
		Элемент.Вставить("avg_price_vat",  СтрЦена.СредняяЦенаСНДС);

		Сообщение = Новый Структура("Ключ, Тело",
			Строка(СтрЦена.Номенклатура.УникальныйИдентификатор()),
			ОбщегоНазначения.ЗначениеВJSON(Элемент));

		Сообщения.Добавить(Сообщение);

	КонецЦикла;

	Возврат кор_HTTPКоннектор.ОтправитьВКафку(Сообщения);

КонецФункции

// В описание колонок Excel добавить две строки:
//
//	Колонки.Добавить(Новый Структура("Имя, Заголовок, Ширина, Формат, Переносить",
//		"СредняяЦенаСНДС", "Средняя с НДС", 16, "ЧДЦ=2; ЧН=0; ЧРГ=", Ложь));
//	Колонки.Добавить(Новый Структура("Имя, Заголовок, Ширина, Формат, Переносить",
//		"ЦенаСНДС", "Последняя с НДС", 16, "ЧДЦ=2; ЧН=0; ЧРГ=", Ложь));

#КонецОбласти

#Область ВариантБ_ОтдельнаяФункцияСНДС

// Если всё-таки нужна отдельная функция: скопировать ТекстЗапросаЦеныБезНДС()
// целиком и заменить в ней ровно три места.
//
// 1. В ВТ_ПоДокументам заменить блок СуммаБезНДС на:
//
//		|	СУММА(ВЫБОР
//		|			КОГДА Док.ЦенаВключаетНДС
//		|				ТОГДА ДокТовары.Сумма
//		|			ИНАЧЕ ДокТовары.Сумма + ДокТовары.СуммаНДС
//		|		КОНЕЦ) КАК СуммаСНДС,
//
// 2. В ВТ_ЦеныДокументов:
//
//		|	ВТ_ПоДокументам.СуммаСНДС / ВТ_ПоДокументам.Количество КАК ЦенаДокумента
//
// 3. В ВТ_ПоследняяЦена переименовать псевдоним ТекущаяЦенаБезНДС в ТекущаяЦенаСНДС
//    и поправить ссылку на него в финальной выборке.
//
// Больше ничего менять не нужно: остальной пакет от НДС не зависит.
// Вызывающий код при этом придётся развести на две ветки — своя ЦеныТЗ,
// свой пересчёт наборов, свой топик или свой набор полей в сообщении.

#КонецОбласти