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



//++Варнин А.А. Задача №72300 - 24.07.26
 
#Область РегламентноеЗадание_кор_ВыгрузкаЗакупочныхЦен 

Процедура ВыполнитьВыгрузкуЗакупочныхЦен() Экспорт
	
	ЦеныТЗ = СформироватьТаблицуЦен();	
	ОтправитьВKafka(ЦеныТЗ);
	ВыгрузитьВExcel(ЦеныТЗ);
	
КонецПроцедуры

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

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

Функция ТекстЗапросаСНДС()
	
	Возврат
	
		"ВЫБРАТЬ
		|	ОстаткиТоваров.Номенклатура КАК Номенклатура,
		|	ОстаткиТоваров.ВНаличииОстаток КАК Остаток
		|ПОМЕСТИТЬ ВТ_Остатки
		|ИЗ
		|	РегистрНакопления.ТоварыНаСкладах.Остатки(&КонецПериода, ) КАК ОстаткиТоваров
		|ГДЕ
		|	ОстаткиТоваров.ВНаличииОстаток > 0
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
		|	ЦеныНоменклатуры.Цена КАК Цена,
		|	ЦеныНоменклатуры.Период КАК Период
		|ПОМЕСТИТЬ ВТ_ЦеныПоПриобретениям
		|ИЗ
		|	РегистрСведений.ЦеныНоменклатуры25 КАК ЦеныНоменклатуры
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.УстановкаЦенНоменклатуры КАК УстановкаЦен
		|		ПО ЦеныНоменклатуры.Регистратор = УстановкаЦен.Ссылка
		|ГДЕ
		|	УстановкаЦен.Проведен
		|	И УстановкаЦен.ДокументОснование ССЫЛКА Документ.ПриобретениеТоваровУслуг
		|	И ЦеныНоменклатуры.Цена > 0
		|	И ЦеныНоменклатуры.ВидЦены = &ВидЦены
		|	И ЦеныНоменклатуры.Номенклатура В
		|			(ВЫБРАТЬ
		|				ВТ_Остатки.Номенклатура
		|			ИЗ
		|				ВТ_Остатки)
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ВТ.Номенклатура КАК Номенклатура,
		|	СРЕДНЕЕ(ВТ.Цена) КАК СредняяЦена
		|ПОМЕСТИТЬ ВТ_СредняяЦена
		|ИЗ
		|	ВТ_ЦеныПоПриобретениям КАК ВТ
		|
		|СГРУППИРОВАТЬ ПО
		|	ВТ.Номенклатура
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ЦеныСрез.Номенклатура КАК Номенклатура,
		|	ЦеныСрез.Номенклатура.Код КАК Код,
		|	ЦеныСрез.Номенклатура.Артикул КАК Артикул,
		|	ЦеныСрез.Номенклатура.Марка КАК Марка,
		|	ЦеныСрез.Цена КАК Цена,
		|	ВЫРАЗИТЬ(ЕСТЬNULL(ВТ_СредняяЦена.СредняяЦена, ЦеныСрез.Цена) КАК ЧИСЛО(15, 2)) КАК СредняяЦена
		|ИЗ
		|	РегистрСведений.ЦеныНоменклатуры25.СрезПоследних(&КонецПериода, ВидЦены = &ВидЦены) КАК ЦеныСрез
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_СредняяЦена КАК ВТ_СредняяЦена
		|		ПО ЦеныСрез.Номенклатура = ВТ_СредняяЦена.Номенклатура
		|ГДЕ
		|	ЦеныСрез.Цена <> 0";

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

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

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

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

Процедура ОтправитьВKafka(ЦеныТЗ)
		
	Сообщения = Новый Массив;
	
	Для Каждого СтрЦена Из ЦеныТЗ Цикл		
		
		Гуид = Строка(СтрЦена.Номенклатура.УникальныйИдентификатор()); 
		
		Элемент = Новый Структура;
		Элемент.Вставить("name", СокрЛП(Строка(СтрЦена.Номенклатура))); 
		Элемент.Вставить("code", СокрЛП(СтрЦена.Код));
		Элемент.Вставить("brand", СокрЛП(Строка(СтрЦена.Марка)));
		Элемент.Вставить("article", СокрЛП(СтрЦена.Артикул));
		Элемент.Вставить("article_mp",СокрЛП(СтрЦена.АртикулМаркетплейса));
		Элемент.Вставить("oem",СокрЛП(СтрЦена.OEMНомер));		
		Элемент.Вставить("last_price", СтрЦена.Цена);
		Элемент.Вставить("avg_price", СтрЦена.СредняяЦена);
		
		ТелоJSON = ОбщегоНазначения.ЗначениеВJSON(Элемент);
		Сообщения.Добавить(Новый Структура("Ключ, Тело", Гуид, ТелоJSON));
		
	КонецЦикла;
		
	РезультатОтправки = кор_HTTPКоннектор.ОтправитьВКафку(Сообщения);
//	Сообщить(РезультатОтправки.Текст);

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

Процедура ВыгрузитьВExcel(ЦеныТЗ)
	
	ТабДок = Новый ТабличныйДокумент;
	Построитель = Новый ПостроительОтчета;
	Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЦеныТЗ);
	Построитель.Выполнить();
	Построитель.Вывести(ТабДок);
	
	Попытка
//		ТабДок.Записать("C:\Users\USR1CV8.P-1C-TEST-01\AppData\Local\Temp\file.xlsx",ТипФайлаТабличногоДокумента.XLSX); 
	Исключение
		
	КонецПопытки;

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

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


// https://github.com/NuclearAPK/Simple-Kafka_Adapter
#Область Кафка 

//++Варнин А.А. Задача №72300 - 21.07.26

// Общий модуль: КоннекторHTTP Для Кафки
// Настройки хранятся в константах:
//   кор_KafkaБрокеры       (Строка) - "host:port,host:port,..." 
//   кор_KafkaТопик         (Строка) - имя топика
//   кор_KafkaКаталогЛогов  (Строка) - каталог логов компоненты

#Область ПрограммныйИнтерфейс

// Возвращает структуру подключения к Kafka из констант.
//
// Возвращаемое значение:
//   Структура - Брокеры, ИмяТопика, КаталогЛогов
//
Функция ПолучитьСтруктуруПодключения() Экспорт

	СтруктураПодключения = Новый Структура;
	СтруктураПодключения.Вставить("Брокеры",      СокрЛП(Константы.кор_KafkaБрокеры.Получить()));
	СтруктураПодключения.Вставить("ИмяТопика",    СокрЛП(Константы.кор_KafkaТопик.Получить()));
	СтруктураПодключения.Вставить("КаталогЛогов", СокрЛП(Константы.кор_KafkaКаталогЛогов.Получить()));

	Возврат СтруктураПодключения;

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

// Отправляет поток сообщений в Kafka (по одному сообщению на элемент, с ключом).
//
// Параметры:
//   Сообщения - Массив структур - каждый элемент: Ключ (Строка), Тело (Строка JSON)
//
// Возвращаемое значение:
//   Структура - Отправлено (Число), Ошибок (Число), Успех (Булево), Текст (Строка)
//
Функция ОтправитьВКафку(Сообщения) Экспорт

	Результат = Новый Структура("Отправлено, Ошибок, Успех, Текст", 0, 0, Ложь, "");

	Если ТипЗнч(Сообщения) <> Тип("Массив") ИЛИ Сообщения.Количество() = 0 Тогда
		Результат.Текст = "Нет данных для отправки.";
		Возврат Результат;
	КонецЕсли;

	Подключение = ПолучитьСтруктуруПодключения();

	Если НЕ ЗначениеЗаполнено(Подключение.Брокеры) Тогда
		Результат.Текст = "Не заполнена константа кор_KafkaБрокеры.";
		ЗаписьЖурналаРегистрации("Kafka. Отправка цен", УровеньЖурналаРегистрации.Ошибка, , , Результат.Текст);
		Возврат Результат;
	КонецЕсли;

	Если НЕ ЗначениеЗаполнено(Подключение.ИмяТопика) Тогда
		Результат.Текст = "Не заполнена константа кор_KafkaТопик.";
		ЗаписьЖурналаРегистрации("Kafka. Отправка цен", УровеньЖурналаРегистрации.Ошибка, , , Результат.Текст);
		Возврат Результат;
	КонецЕсли;

	Компонента = СоздатьКомпонентуКафкаКлиент();
	Если Компонента = Неопределено Тогда
		Результат.Текст = "Не удалось создать компоненту Kafka.";
		Возврат Результат;
	КонецЕсли;

	Если ЗначениеЗаполнено(Подключение.КаталогЛогов) Тогда
		Попытка
			Компонента.КаталогЛогов = Подключение.КаталогЛогов;
		Исключение
			ЗаписьЖурналаРегистрации("Kafka. Отправка цен",
				УровеньЖурналаРегистрации.Предупреждение, , ,
				"Не удалось установить КаталогЛогов: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецПопытки;
	КонецЕсли;

	РезультатИнициализации = Компонента.ИнициализироватьПродюсера(Подключение.Брокеры);
	Если НЕ РезультатИнициализации Тогда
		Результат.Текст = "Не удалось инициализировать продюсера. Брокеры: " + Подключение.Брокеры
			+ ". " + Компонента.ПолучитьСообщениеОбОшибке();
		ЗаписьЖурналаРегистрации("Kafka. Отправка цен", УровеньЖурналаРегистрации.Ошибка, , , Результат.Текст);
		Компонента = Неопределено;
		Возврат Результат;
	КонецЕсли;

	Топик        = Подключение.ИмяТопика;
	ШагЛога      = 5000;   
	Всего        = Сообщения.Количество();

	Попытка

		Для Каждого Сообщение Из Сообщения Цикл

			Ключ = ?(Сообщение.Свойство("Ключ"), Строка(Сообщение.Ключ), "");
			Тело = ?(Сообщение.Свойство("Тело"), Строка(Сообщение.Тело), "");

			Если НЕ ЗначениеЗаполнено(Тело) Тогда
				Результат.Ошибок = Результат.Ошибок + 1;
				Продолжить;
			КонецЕсли;

			РезультатОтправки = Компонента.ОтправитьСообщение(Тело, Топик, -1, Ключ);

			Если РезультатОтправки Тогда
				Результат.Отправлено = Результат.Отправлено + 1;
			Иначе
				Результат.Ошибок = Результат.Ошибок + 1;
				ЗаписьЖурналаРегистрации("Kafka. Отправка цен",
					УровеньЖурналаРегистрации.Ошибка, , ,
					"Сообщение не отправлено. Ключ: " + Ключ + ". " + Компонента.ПолучитьСообщениеОбОшибке());
			КонецЕсли;

			Если (Результат.Отправлено + Результат.Ошибок) % ШагЛога = 0 Тогда
				ЗаписьЖурналаРегистрации("Kafka. Отправка цен",
					УровеньЖурналаРегистрации.Информация, , ,
					СтрШаблон("Прогресс: %1 из %2 (ошибок: %3)",
						Результат.Отправлено + Результат.Ошибок, Всего, Результат.Ошибок));
			КонецЕсли;

		КонецЦикла;

	Исключение
		Результат.Текст = "Прервано на " + (Результат.Отправлено + Результат.Ошибок) + " из " + Всего
			+ ". " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации("Kafka. Отправка цен", УровеньЖурналаРегистрации.Ошибка, , , Результат.Текст);

		Попытка Компонента.ОстановитьПродюсера(); Исключение КонецПопытки;
		Компонента = Неопределено;
		Возврат Результат;
	КонецПопытки;

	Компонента.ОстановитьПродюсера();
	Компонента = Неопределено;

	Результат.Успех = (Результат.Ошибок = 0);
	Результат.Текст = СтрШаблон("Готово. Отправлено: %1, ошибок: %2, всего: %3",
		Результат.Отправлено, Результат.Ошибок, Всего);
	ЗаписьЖурналаРегистрации("Kafka. Отправка цен",
		?(Результат.Успех, УровеньЖурналаРегистрации.Информация, УровеньЖурналаРегистрации.Предупреждение),
		, , Результат.Текст);

	Возврат Результат;

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

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

#Область СлужебныеПроцедурыИФункции

// Создаёт объект внешней компоненты Kafka из общего макета.
//
// Возвращаемое значение:
//   ВнешняяКомпонента - или Неопределено при ошибке.
//
Функция СоздатьКомпонентуКафкаКлиент()

	Попытка
		Подключено = ПодключитьВнешнююКомпоненту(
			"ОбщийМакет.SimpleKafkaAdapter64",
			"KafkaClient",
			ТипВнешнейКомпоненты.Native,
			ТипПодключенияВнешнейКомпоненты.Изолированно);
	Исключение
		ЗаписьЖурналаРегистрации("Kafka. Подключение компоненты",
			УровеньЖурналаРегистрации.Ошибка, , ,
			ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		Возврат Неопределено;
	КонецПопытки;

	Если НЕ Подключено Тогда
		ЗаписьЖурналаРегистрации("Kafka. Подключение компоненты",
			УровеньЖурналаРегистрации.Ошибка, , ,
			"Не удалось подключить компоненту из общего макета SimpleKafkaAdapter64.");
		Возврат Неопределено;
	КонецЕсли;

	Попытка
		Компонента = Новый("AddIn.KafkaClient.simpleKafka1C");
	Исключение
		ЗаписьЖурналаРегистрации("Kafka. Подключение компоненты",
			УровеньЖурналаРегистрации.Ошибка, , ,
			"Компонента подключилась, но объект не создался: "
				+ ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		Возврат Неопределено;
	КонецПопытки;

	Возврат Компонента;

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

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

 //++Варнин А.А. Задача №72300 - 21.07.26

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