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


 Остатки складов поставщиков (FBS со склада Берга).

 Остатки Берга не проходят через документы и регистры УТ регламентное задание
 кор_ЗагрузкаОстатковБерга спрашивает их по API и перезаписывает регистр
 кор_ОстаткиПоставщиков, а БИТ.УМ при выгрузке остатков на маркетплейсы берёт их оттуда
 (вставка BSLR в топ_ОбщийМодульСервер.ОстаткиFBS_ПолучитьТекстЗапроса_ВТ_Остатки
 вызывает ДополнитьЗапросОстатковFBS). Какие склады УТ считаются складами поставщика и
 каким складам Берга они соответствуют, задаёт регистр кор_СкладыПоставщиков.

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

 Обработчик регламентного задания кор_ЗагрузкаОстатковБерга.

Процедура ЗагрузитьОстаткиБерга() Экспорт

	ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(
		Метаданные.РегламентныеЗадания.кор_ЗагрузкаОстатковБерга);

	ЗагрузитьОстаткиБергаВРегистр();

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

 Спрашивает у Берга остатки по номенклатуре, выставленной на маркетплейсы со складов
 поставщика, и перезаписывает по этим складам регистр кор_ОстаткиПоставщиков.
 Можно вызывать и вне регламентного задания — например, для отладки.

 Возвращаемое значение
  Структура
    Позиций       - Число - сколько позиций спрошено у Берга.
    Найдено       - Число - позиций, по которым Берг вернул ровно один товар.
    Неоднозначно  - Число - позиций, по которым вернулось несколько товаров; остаток по ним не пишется.
    ПачекСОшибкой - Число
    Текст         - Строка - итог для журнала регистрации.

Функция ЗагрузитьОстаткиБергаВРегистр() Экспорт

	Итоги = Новый Структура(Позиций, Найдено, Неоднозначно, ПачекСОшибкой, Текст, 0, 0, 0, 0, );

	ПараметрыПодключения = кор_БергAPI.НовыеПараметрыПодключения();
	ПараметрыПодключения.Ключ = кор_БергAPI.СохраненныйКлючAPI();
	Если ПустаяСтрока(ПараметрыПодключения.Ключ) Тогда
		Итоги.Текст = НСтр(ru = 'Загрузка остатков Берга пропущена API-ключ не сохранён.');
		ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Предупреждение, Итоги.Текст);
		Возврат Итоги;
	КонецЕсли;

	УстановитьПривилегированныйРежим(Истина);

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

	Если НашиСклады.Количество() = 0 Тогда
		Итоги.Текст = НСтр(ru = 'Загрузка остатков Берга пропущена не заполнен регистр «Склады поставщиков».');
		ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Предупреждение, Итоги.Текст);
		Возврат Итоги;
	КонецЕсли;

	Позиции = ПозицииДляЗапроса(НашиСклады);
	Итоги.Позиций = Позиции.Количество();
	Если Позиции.Количество() = 0 Тогда
		Итоги.Текст = НСтр(ru = 'Загрузка остатков Берга нет товаров маркетплейсов, выставленных со складов поставщика.');
		ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Информация, Итоги.Текст);
		Возврат Итоги;
	КонецЕсли;

	ПозицииAPI = Новый Массив;
	Для Индекс = 0 По Позиции.Количество() - 1 Цикл
		Позиция = Позиции[Индекс];
		ПозицииAPI.Добавить(Новый Структура(Индекс, ResourceID, Артикул, BrandID, Бренд,
			Индекс + 1, Позиция.ИдентификаторТовара, Позиция.Артикул, 0, Позиция.Бренд));
	КонецЦикла;

	 Момент берётся до запроса заказы, созданные, пока идёт опрос, Берг ещё не видит,
	 и запрос выгрузки на МП вычтет их из остатка (см. ТекстЗапросаОстатковПоставщиков).
	МоментЗагрузки = ТекущаяДатаСеанса();
	Ответ = кор_БергAPI.ПолучитьОстатки(ПараметрыПодключения, ПозицииAPI);

	Итоги.ПачекСОшибкой = Ответ.Ошибки.Количество();
	Для Каждого ТекстОшибки Из Ответ.Ошибки Цикл
		ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Ошибка, ТекстОшибки);
	КонецЦикла;

	Если Ответ.КоличествоПачек  0 И Ответ.Ошибки.Количество() = Ответ.КоличествоПачек Тогда
		Итоги.Текст = СтрШаблон(
			НСтр(ru = 'Загрузка остатков Берга ни одна из %1 пачек не загрузилась, регистр не изменён.'),
			Ответ.КоличествоПачек);
		ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Ошибка, Итоги.Текст);
		Возврат Итоги;
	КонецЕсли;

	Записи = НоваяТаблицаЗаписей();
	СтрокиЗаписей = СтрокиЗаписейПоПозициям(Ответ.Предложения, Позиции, НашиСклады, МоментЗагрузки, Записи, Итоги);
	ЗаполнитьЗаписиПоПредложениям(СтрокиЗаписей, Ответ.Предложения, СкладыПоставщика);

	 По позициям из пачек с ошибкой ответа нет оставляем прежние записи с прежней датой,
	 чтобы товар не обнулился на маркетплейсе из-за одного сбойного запроса.
	Если Ответ.ИндексыСОшибкой.Количество()  0 Тогда
		ДобавитьПрежниеЗаписи(Записи, Позиции, Ответ.ИндексыСОшибкой, НашиСклады);
	КонецЕсли;

	ЗаписатьОстатки(Записи, НашиСклады);

	Итоги.Текст = СтрШаблон(
		НСтр(ru = 'Загрузка остатков Берга позиций %1, найдено %2, неоднозначно %3, пачек с ошибкой %4 из %5.'),
		Итоги.Позиций, Итоги.Найдено, Итоги.Неоднозначно, Итоги.ПачекСОшибкой, Ответ.КоличествоПачек);
	ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Информация, Итоги.Текст);

	Возврат Итоги;

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

 Подменяет в запросе остатков FBS БИТ.УМ остатки складов поставщиков для них вместо
 РаспределениеЗапасов берётся регистр кор_ОстаткиПоставщиков за вычетом наших заказов,
 о которых поставщик ещё не знает. Вызывается из вставки BSLR в
 топ_ОбщийМодульСервер.ОстаткиFBS_ПолучитьТекстЗапроса_ВТ_Остатки.

 Параметры
  ТекстыЗапроса - Массив из Строка - пакет запроса БИТ.УМ; последний элемент - запрос,
                  помещающий остатки во временную таблицу ВТ_ОстаткиПредварительная
                  (Номенклатура, Характеристика, Склад, Остаток). Массив меняется на месте.

Процедура ДополнитьЗапросОстатковFBS(ТекстыЗапроса) Экспорт

	 Без права чтения запрос упал бы у пользователя целиком; лучше показать ему
	 остатки без поставщиков. Право даёт роль кор_ЧтениеОстатковПоставщиков.
	Если Не ПравоДоступа(Чтение, Метаданные.РегистрыСведений.кор_СкладыПоставщиков)
		Или Не ПравоДоступа(Чтение, Метаданные.РегистрыСведений.кор_ОстаткиПоставщиков) Тогда
		Возврат;
	КонецЕсли;

	Запрос = Новый Запрос(
	ВЫБРАТЬ ПЕРВЫЕ 1
		ИСТИНА КАК ЕстьСклады
	ИЗ
		РегистрСведений.кор_СкладыПоставщиков КАК СкладыПоставщиков);
	Если Запрос.Выполнить().Пустой() Тогда
		Возврат;
	КонецЕсли;

	ИмяТиповойТаблицы = ВТ_ОстаткиПредварительнаяБезПоставщиков;
	Индекс = ТекстыЗапроса.ВГраница();
	ТекстыЗапроса[Индекс] = СтрЗаменить(ТекстыЗапроса[Индекс],
		ПОМЕСТИТЬ ВТ_ОстаткиПредварительная, ПОМЕСТИТЬ  + ИмяТиповойТаблицы);
	ТекстыЗапроса.Добавить(ТекстЗапросаОстатковПоставщиков(ИмяТиповойТаблицы));
	ТекстыЗапроса.Добавить(УНИЧТОЖИТЬ  + ИмяТиповойТаблицы);

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

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

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

#Область ЗапросВыгрузкиНаМП

Функция ТекстЗапросаОстатковПоставщиков(ИмяТиповойТаблицы)

	 Наши заказы вычитаются, только если созданы после загрузки остатка более ранние
	 поставщик уже учёл (после place_order) — иначе они вычитались бы дважды.
	 Остаток старше срока актуальности склада не выгружается (товар уйдёт в 0), чтобы
	 при остановившейся загрузке не продавать по давно устаревшим цифрам.
	Текст =
	ВЫБРАТЬ
		Т.Номенклатура КАК Номенклатура,
		Т.Характеристика КАК Характеристика,
		Т.Склад КАК Склад,
		Т.Остаток КАК Остаток
	ПОМЕСТИТЬ ВТ_ОстаткиПредварительная
	ИЗ
		&ИмяТиповойТаблицы КАК Т
	ГДЕ
		НЕ Т.Склад В
					(ВЫБРАТЬ РАЗЛИЧНЫЕ
						СкладыПоставщиков.Склад
					ИЗ
						РегистрСведений.кор_СкладыПоставщиков КАК СкладыПоставщиков)
	
	ОБЪЕДИНИТЬ ВСЕ
	
	ВЫБРАТЬ
		Остатки.Номенклатура,
		Остатки.Характеристика,
		Остатки.Склад,
		ВЫБОР
			КОГДА Остатки.Количество - ЕСТЬNULL(Заказы.Количество, 0)  0
				ТОГДА Остатки.Количество - ЕСТЬNULL(Заказы.Количество, 0)
			ИНАЧЕ 0
		КОНЕЦ
	ИЗ
		РегистрСведений.кор_ОстаткиПоставщиков КАК Остатки
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
				СкладыПоставщиков.Склад КАК Склад,
				МАКСИМУМ(СкладыПоставщиков.СрокАктуальностиЧасов) КАК СрокАктуальностиЧасов
			ИЗ
				РегистрСведений.кор_СкладыПоставщиков КАК СкладыПоставщиков
	
			СГРУППИРОВАТЬ ПО
				СкладыПоставщиков.Склад) КАК Склады
			ПО Остатки.Склад = Склады.Склад
			ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
				ОстаткиПоЗаказам.Склад КАК Склад,
				ОстаткиПоЗаказам.Номенклатура КАК Номенклатура,
				ОстаткиПоЗаказам.Характеристика КАК Характеристика,
				СУММА(ТоварыЗаказов.Количество) КАК Количество
			ИЗ
				РегистрСведений.кор_ОстаткиПоставщиков КАК ОстаткиПоЗаказам
					ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента.Товары КАК ТоварыЗаказов
					ПО ОстаткиПоЗаказам.Склад = ТоварыЗаказов.Склад
						И ОстаткиПоЗаказам.Номенклатура = ТоварыЗаказов.Номенклатура
						И ОстаткиПоЗаказам.Характеристика = ТоварыЗаказов.Характеристика
						И (ТоварыЗаказов.Ссылка.Дата = ОстаткиПоЗаказам.ДатаОбновления)
						И (ТоварыЗаказов.Ссылка.Проведен)
						И (НЕ ТоварыЗаказов.Отменено)
						И (ТоварыЗаказов.Ссылка.Статус  ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказовКлиентов.Закрыт))
	
			СГРУППИРОВАТЬ ПО
				ОстаткиПоЗаказам.Склад,
				ОстаткиПоЗаказам.Номенклатура,
				ОстаткиПоЗаказам.Характеристика) КАК Заказы
			ПО Остатки.Склад = Заказы.Склад
				И Остатки.Номенклатура = Заказы.Номенклатура
				И Остатки.Характеристика = Заказы.Характеристика
	ГДЕ
		Остатки.Склад В
				(ВЫБРАТЬ
					Т.Склад
				ИЗ
					ВТ_Склады КАК Т)
		И Остатки.Номенклатура В
				(ВЫБРАТЬ
					Т.НоменклатураОстатков
				ИЗ
					ВТ_Номенклатура КАК Т)
		И (Склады.СрокАктуальностиЧасов = 0
				ИЛИ Остатки.ДатаОбновления = ДОБАВИТЬКДАТЕ(&ТекущаяДата, ЧАС, -Склады.СрокАктуальностиЧасов));

	 Параметры в этот пакет не передать запрос собирает и выполняет БИТ.УМ.
	Текст = СтрЗаменить(Текст, &ИмяТиповойТаблицы, ИмяТиповойТаблицы);
	Текст = СтрЗаменить(Текст, &ТекущаяДата, ЛитералДаты(ТекущаяДатаСеанса()));

	Возврат Текст;

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

Функция ЛитералДаты(Дата)

	Возврат СтрШаблон(ДАТАВРЕМЯ(%1, %2, %3, %4, %5, %6),
		XMLСтрока(Год(Дата)), XMLСтрока(Месяц(Дата)), XMLСтрока(День(Дата)),
		XMLСтрока(Час(Дата)), XMLСтрока(Минута(Дата)), XMLСтрока(Секунда(Дата)));

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

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

#Область ЗагрузкаОстатков

 Возвращаемое значение
  Соответствие - ключ идентификатор склада Берга (Строка), значение СправочникСсылка.Склады.

Функция СкладыПоставщика()

	Запрос = Новый Запрос(
	ВЫБРАТЬ
		СкладыПоставщиков.Склад КАК Склад,
		СкладыПоставщиков.ИдентификаторСкладаПоставщика КАК ИдентификаторСкладаПоставщика
	ИЗ
		РегистрСведений.кор_СкладыПоставщиков КАК СкладыПоставщиков
	ГДЕ
		СкладыПоставщиков.Склад  ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка));

	Результат = Новый Соответствие;
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Результат.Вставить(СокрЛП(Выборка.ИдентификаторСкладаПоставщика), Выборка.Склад);
	КонецЦикла;

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

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

 Номенклатура, сопоставленная с товарами маркетплейсов в тех личных кабинетах,
 где склад поставщика указан среди складов FBS. Только её и имеет смысл спрашивать
 у Берга целого прайса API не отдаёт, а каждая позиция — это часть запроса.

 Возвращаемое значение
  ТаблицаЗначений - Номенклатура, Характеристика, Артикул, Бренд, ИдентификаторТовара.

Функция ПозицииДляЗапроса(НашиСклады)

	Запрос = Новый Запрос(
	ВЫБРАТЬ
		Соответствие.Номенклатура КАК Номенклатура,
		Соответствие.Характеристика КАК Характеристика
	ПОМЕСТИТЬ ВТ_Позиции
	ИЗ
		РегистрСведений.топ_СоответствиеТоваров КАК Соответствие
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.топ_ЛичныеКабинеты.СписокСкладовFBS КАК СкладыFBS
			ПО Соответствие.Товар.ЛичныйКабинет = СкладыFBS.Ссылка
				И (СкладыFBS.Склад В (&Склады))
	ГДЕ
		Соответствие.Товар.Показывается
		И НЕ Соответствие.Товар.ПометкаУдаления
		И НЕ Соответствие.Номенклатура.ПометкаУдаления
	
	СГРУППИРОВАТЬ ПО
		Соответствие.Номенклатура,
		Соответствие.Характеристика
	;
	
	
	ВЫБРАТЬ
		Позиции.Номенклатура КАК Номенклатура,
		Позиции.Характеристика КАК Характеристика,
		Позиции.Номенклатура.Артикул КАК Артикул,
		ЕСТЬNULL(Позиции.Номенклатура.Производитель.Наименование, ) КАК Производитель,
		ЕСТЬNULL(Позиции.Номенклатура.Марка.Наименование, ) КАК Марка,
		ЕСТЬNULL(МАКСИМУМ(Остатки.ИдентификаторТовараПоставщика), 0) КАК ИдентификаторТовара
	ИЗ
		ВТ_Позиции КАК Позиции
			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.кор_ОстаткиПоставщиков КАК Остатки
			ПО Позиции.Номенклатура = Остатки.Номенклатура
				И Позиции.Характеристика = Остатки.Характеристика
				И (Остатки.Склад В (&Склады))
	
	СГРУППИРОВАТЬ ПО
		Позиции.Номенклатура,
		Позиции.Характеристика,
		Позиции.Номенклатура.Артикул,
		ЕСТЬNULL(Позиции.Номенклатура.Производитель.Наименование, ),
		ЕСТЬNULL(Позиции.Номенклатура.Марка.Наименование, ));
	Запрос.УстановитьПараметр(Склады, НашиСклады);

	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить(Номенклатура);
	Результат.Колонки.Добавить(Характеристика);
	Результат.Колонки.Добавить(Артикул, Новый ОписаниеТипов(Строка));
	Результат.Колонки.Добавить(Бренд, Новый ОписаниеТипов(Строка));
	Результат.Колонки.Добавить(ИдентификаторТовара, Новый ОписаниеТипов(Число));

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

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

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

Функция НоваяТаблицаЗаписей()

	Таблица = Новый ТаблицаЗначений;
	Таблица.Колонки.Добавить(Склад);
	Таблица.Колонки.Добавить(Номенклатура);
	Таблица.Колонки.Добавить(Характеристика);
	Таблица.Колонки.Добавить(Количество, Новый ОписаниеТипов(Число));
	Таблица.Колонки.Добавить(Цена, Новый ОписаниеТипов(Число));
	Таблица.Колонки.Добавить(ДоступноБольше, Новый ОписаниеТипов(Булево));
	Таблица.Колонки.Добавить(ИдентификаторТовараПоставщика, Новый ОписаниеТипов(Число));
	Таблица.Колонки.Добавить(ИдентификаторыСкладовПоставщика, Новый ОписаниеТипов(Строка));
	Таблица.Колонки.Добавить(ДатаОбновления, Новый ОписаниеТипов(Дата));

	Возврат Таблица;

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

 Заводит по строке записи на каждый наш склад для каждой позиции, по которой Берг вернул
 ровно один товар, - с нулевым остатком. Нулевая запись нужна она хранит id товара Берга
 для следующих запросов и явно обнуляет товар на маркетплейсе.
 Позиции, по которым товаров несколько, пропускаются чей остаток брать, непонятно.

 Возвращаемое значение
  Соответствие - ключ Индекс позиции, значение Соответствие (Склад - СтрокаТаблицыЗначений).

Функция СтрокиЗаписейПоПозициям(Предложения, Позиции, НашиСклады, МоментЗагрузки, Записи, Итоги)

	ТоварыПозиций = Новый Соответствие;
	Для Каждого Предложение Из Предложения Цикл
		Если Предложение.ИндексПозиции = 0 Или Предложение.ResourceID = 0 Тогда
			Продолжить;
		КонецЕсли;
		Товары = ТоварыПозиций.Получить(Предложение.ИндексПозиции);
		Если Товары = Неопределено Тогда
			Товары = Новый Массив;
			ТоварыПозиций.Вставить(Предложение.ИндексПозиции, Товары);
		КонецЕсли;
		Если Товары.Найти(Предложение.ResourceID) = Неопределено Тогда
			Товары.Добавить(Предложение.ResourceID);
		КонецЕсли;
	КонецЦикла;

	СтрокиЗаписей = Новый Соответствие;
	Для Каждого КлючИЗначение Из ТоварыПозиций Цикл

		Позиция = Позиции[КлючИЗначение.Ключ - 1];
		Товары = КлючИЗначение.Значение;

		Если Товары.Количество()  1 Тогда
			Итоги.Неоднозначно = Итоги.Неоднозначно + 1;
			ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Предупреждение, СтрШаблон(
				НСтр(ru = 'Берг вернул несколько товаров по позиции %1 (артикул %2, бренд %3) %4. Остаток не загружен - уточните бренд.'),
				Позиция.Номенклатура, Позиция.Артикул, Позиция.Бренд, СтрСоединить(Товары, , )));
			Продолжить;
		КонецЕсли;

		Итоги.Найдено = Итоги.Найдено + 1;
		СтрокиПоСкладам = Новый Соответствие;
		Для Каждого Склад Из НашиСклады Цикл
			Запись = Записи.Добавить();
			Запись.Склад = Склад;
			Запись.Номенклатура = Позиция.Номенклатура;
			Запись.Характеристика = Позиция.Характеристика;
			Запись.ИдентификаторТовараПоставщика = Товары[0];
			Запись.ДатаОбновления = МоментЗагрузки;
			СтрокиПоСкладам.Вставить(Склад, Запись);
		КонецЦикла;
		СтрокиЗаписей.Вставить(КлючИЗначение.Ключ, СтрокиПоСкладам);

	КонецЦикла;

	Возврат СтрокиЗаписей;

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

 Складывает предложения складов Берга в записи наших складов по регистру кор_СкладыПоставщиков.
 Если одному нашему складу соответствует несколько складов Берга, количество суммируется,
 а цена берётся минимальная.

Процедура ЗаполнитьЗаписиПоПредложениям(СтрокиЗаписей, Предложения, СкладыПоставщика)

	Для Каждого Предложение Из Предложения Цикл

		СтрокиПоСкладам = СтрокиЗаписей.Получить(Предложение.ИндексПозиции);
		Если СтрокиПоСкладам = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		ИдентификаторСклада = XMLСтрока(Предложение.СкладID);
		Склад = СкладыПоставщика.Получить(ИдентификаторСклада);
		Если Склад = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		Запись = СтрокиПоСкладам.Получить(Склад);
		Запись.Количество = Запись.Количество + Предложение.Количество;
		Если Предложение.Цена  0 И (Запись.Цена = 0 Или Предложение.Цена  Запись.Цена) Тогда
			Запись.Цена = Предложение.Цена;
		КонецЕсли;
		Запись.ДоступноБольше = Запись.ДоступноБольше Или Предложение.БольшеДоступно;

		Если СтрНайти(, + Запись.ИдентификаторыСкладовПоставщика + ,, , + ИдентификаторСклада + ,) = 0 Тогда
			Запись.ИдентификаторыСкладовПоставщика = (ПустаяСтрока(Запись.ИдентификаторыСкладовПоставщика),
				ИдентификаторСклада, Запись.ИдентификаторыСкладовПоставщика + , + ИдентификаторСклада);
		КонецЕсли;

	КонецЦикла;

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

Процедура ДобавитьПрежниеЗаписи(Записи, Позиции, ИндексыСОшибкой, НашиСклады)

	ПозицииСОшибкой = Новый ТаблицаЗначений;
	ПозицииСОшибкой.Колонки.Добавить(Номенклатура, Метаданные.РегистрыСведений.кор_ОстаткиПоставщиков.Измерения.Номенклатура.Тип);
	ПозицииСОшибкой.Колонки.Добавить(Характеристика, Метаданные.РегистрыСведений.кор_ОстаткиПоставщиков.Измерения.Характеристика.Тип);
	Для Каждого Индекс Из ИндексыСОшибкой Цикл
		ЗаполнитьЗначенияСвойств(ПозицииСОшибкой.Добавить(), Позиции[Индекс - 1]);
	КонецЦикла;

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

	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		ЗаполнитьЗначенияСвойств(Записи.Добавить(), Выборка);
	КонецЦикла;

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

 Перезаписывает регистр по каждому нашему складу целиком позиции, которых больше нет
 в ответе Берга (или на маркетплейсах), уходят из регистра, и остаток по ним становится 0.

Процедура ЗаписатьОстатки(Записи, НашиСклады)

	Для Каждого Склад Из НашиСклады Цикл

		Набор = РегистрыСведений.кор_ОстаткиПоставщиков.СоздатьНаборЗаписей();
		Набор.Отбор.Склад.Установить(Склад);
		Для Каждого Строка Из Записи.НайтиСтроки(Новый Структура(Склад, Склад)) Цикл
			ЗаполнитьЗначенияСвойств(Набор.Добавить(), Строка);
		КонецЦикла;

		Попытка
			Набор.Записать();
		Исключение
			ЗаписатьВЖурнал(УровеньЖурналаРегистрации.Ошибка, СтрШаблон(
				НСтр(ru = 'Не удалось записать остатки Берга по складу %1 %2'),
				Склад, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())));
		КонецПопытки;

	КонецЦикла;

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

Процедура ЗаписатьВЖурнал(Уровень, Текст)

	ЗаписьЖурналаРегистрации(кор_БергAPI.ИмяСобытияЖурнала(), Уровень,
		Метаданные.РегистрыСведений.кор_ОстаткиПоставщиков,, Текст);

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

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

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