Загрузка данных
Процедура ЗаполнитьНоменклатуруЧеков(ДанныеДокументов)
Расход = Новый Соответствие;
ПересчитанныйТовар = Новый Массив;
Для Каждого СтрокаДокумента Из ДанныеДокументов Цикл
СкладБП = СкладБППоСкладуЗПЧ(СтрокаДокумента.Склад);
СоответствиеСкладовЧекиОбработка(СтрокаДокумента);
Для Каждого СтрокаТовара Из СтрокаДокумента.Товары Цикл
ПересчитанныйТовар.Добавить(СтрокаТовара);
ДатаОстатков = Дата(СтрокаДокумента.ДатаДокумента);
ЗапрашиваемоеКоличество = СтрокаТовара.Количество;
Кандидаты = КандидатыНоменклатуры(СтрокаТовара,СкладБП,ДатаОстатков);
Для Каждого Кандидат Из Кандидаты Цикл
НайденнаяНоменклатура = Расход.Получить(Кандидат.Номенклатура);
Если НайденнаяНоменклатура = Неопределено Тогда
Расход.Вставить(Кандидат.Номенклатура,Кандидат.Остаток);
Иначе
Сообщить("Номенклатура: " + Кандидат.Номенклатура);
КонецЕсли;
Если Кандидат.Наименование = СтрокаТовара.Номенклатура Тогда
Кандидат.Приоритет = 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].СкладБП;
КонецЕсли;
Возврат Справочники.Склады.ПустаяСсылка();
КонецФункции