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


Процедура ЗаполнитьНоменклатуруЧеков(ДанныеДокументов)
	
	Расход = Новый Соответствие;	
	ПересчитанныйТовар = Новый Массив;
			
	Для Каждого СтрокаДокумента Из ДанныеДокументов Цикл

 		СкладБП = СкладБППоСкладуЗПЧ(СтрокаДокумента.Склад);
		СоответствиеСкладовЧекиОбработка(СтрокаДокумента);	

		Для Каждого СтрокаТовара Из СтрокаДокумента.Товары Цикл
			ПересчитанныйТовар.Добавить(СтрокаТовара);
			ДатаОстатков = Дата(СтрокаДокумента.ДатаДокумента); 
			ЗапрашиваемоеКоличество = СтрокаТовара.Количество;
			Кандидаты = КандидатыНоменклатуры(СтрокаТовара,СкладБП,ДатаОстатков);
			
			Для Каждого Кандидат Из Кандидаты Цикл
				НайденнаяНоменклатура = Расход.Получить(Кандидат.Номенклатура);
				Если НайденнаяНоменклатура = Неопределено Тогда
					Расход.Вставить(Кандидат.Номенклатура,Кандидат.Остаток); 
				Иначе
					Сообщить("Номенклатура: " + Кандидат.Номенклатура);
				КонецЕсли;
				Если Кандидат.Наименование = СтрокаТовара.Номенклатура Тогда
					Кандидат.Приоритет = 0;
				ИначеЕсли ЗначениеЗаполнено(СтрокаТовара.НоменклатураПоставщика)
					И СтрНайти(НРег(СтрокаТовара.НоменклатураПоставщика), НРег(Кандидат.Наименование)) > 0 Тогда
					Кандидат.Приоритет = 1;
				Иначе
					Кандидат.Приоритет = 2;					
				КонецЕсли;
			КонецЦикла;
			
			Кандидаты.Сортировать("Приоритет Возр, Остаток Убыв"); 
			
			ОбщийОстаток = Кандидаты.Итог("Остаток");
			
			Если ОбщийОстаток < ЗапрашиваемоеКоличество Тогда
				ОбщегоНазначения.СообщитьПользователю(
					СтрШаблон("По номенклатуре %1 запрашиваемое количество: %2 превышает остаток: %3",
						СтрокаТовара.Номенклатура, ОбщийОстаток, ЗапрашиваемоеКоличество));
			КонецЕсли;
			
			Для Каждого Кандидат Из Кандидаты Цикл			
				ОбщийОстаток = ОбщийОстаток - ЗапрашиваемоеКоличество;
				СвободныйОстаток = Кандидат.Остаток - ЗапрашиваемоеКоличество;
				Если ОбщийОстаток >= 0 Тогда
					НайденнаяНоменклатура = Расход.Получить(Кандидат.Номенклатура);
					Если НайденнаяНоменклатура <> Неопределено Тогда
						Расход.Вставить(Кандидат.Номенклатура,СвободныйОстаток);
					Иначе
						Сообщить("Номенклатура: " + Кандидат.Номенклатура);					
					КонецЕсли;
					СтрокаТовара.Вставить("НоменклатураБП",Кандидат.Номенклатура);
					Прервать;
				ИначеЕсли Кандидат.Остаток > 0 И СвободныйОстаток < 0 Тогда
					НайденнаяНоменклатура = Расход.Получить(Кандидат.Номенклатура);
					Если НайденнаяНоменклатура <> Неопределено Тогда
						Расход.Вставить(Кандидат.Номенклатура,0);
					КонецЕсли;
					СтрокаТовара.Вставить(Кандидат.Номенклатура);
					ПересчитанныйТовар.Добавить(СтрокаТовара);
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;
		
	КонецЦикла;

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

&НаСервере
Функция КандидатыНоменклатуры(СтрокаТовара,Склад,ДатаОстатков)
	
	КатНомер 	 = СтрокаТовара.КаталожныйНомерНоменклатуры;
	Номенклатура = СтрокаТовара.Номенклатура;
	
	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить("Номенклатура");
	Результат.Колонки.Добавить("Наименование");
	Результат.Колонки.Добавить("Остаток",       Новый ОписаниеТипов("Число"));
	Результат.Колонки.Добавить("Приоритет",     Новый ОписаниеТипов("Число"));

	ИндексСклада = ИндексСубконтоСклады();
	ПрименятьСклад = (ИндексСклада > 0) И ЗначениеЗаполнено(Склад);

	УсловиеСклада = ?(ПрименятьСклад,СтрШаблон(" И Субконто%1 = &Склад", Строка(ИндексСклада)),"");

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

	Запрос.УстановитьПараметр("КатНомер",     СокрЛП(КатНомер));
	Запрос.УстановитьПараметр("Номенклатура", СокрЛП(Номенклатура));
	Запрос.УстановитьПараметр("ДатаОстатков", ДатаОстатков);
	Запрос.УстановитьПараметр("Счет",         ПланыСчетов.Хозрасчетный.НайтиПоКоду("41.01"));
	Если ПрименятьСклад Тогда
		Запрос.УстановитьПараметр("Склад", Склад);
	КонецЕсли;

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

	Пока Выборка.Следующий() Цикл
		Стр = Результат.Добавить();
		Стр.Номенклатура  = Выборка.Номенклатура;
		Стр.Наименование  = Выборка.Наименование;
		Стр.Остаток       = Выборка.Остаток;
	КонецЦикла;

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

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

&НаСервере
Функция ИндексСубконтоСклады()

	Счет = ПланыСчетов.Хозрасчетный.НайтиПоКоду("41.01");
	Если НЕ ЗначениеЗаполнено(Счет) Тогда
		Возврат 0;
	КонецЕсли;

	ВидСклады = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады;

	Индекс = 0;
	Для Каждого СтрокаСубконто Из Счет.ВидыСубконто Цикл
		Индекс = Индекс + 1;
		Если СтрокаСубконто.ВидСубконто = ВидСклады Тогда
			Возврат Индекс;
		КонецЕсли;
	КонецЦикла;

	Возврат 0;

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

&НаСервере
Функция СкладБППоСкладуЗПЧ(СкладЗПЧ)

	СтрокиСклада = СоответствиеСкладовЧеки.НайтиСтроки(Новый Структура("СкладЗПЧ", СкладЗПЧ));
	Если СтрокиСклада.Количество() > 0 Тогда
		Возврат СтрокиСклада[0].СкладБП;
	КонецЕсли;
	Возврат Справочники.Склады.ПустаяСсылка();

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