Самообслуживание партнеров / Остатки по складам / Модуль формы

файл

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	// Пропускаем инициализацию, чтобы гарантировать получение формы при передаче параметра "АвтоТест".
	Если Параметры.Свойство("АвтоТест") Тогда
		Возврат;
	КонецЕсли;
	
	Если Параметры.Свойство("Соглашение") Тогда
		Соглашение = Параметры.Соглашение;
	КонецЕсли;
	
	Если Параметры.Свойство("ДанныеКорзины") Тогда
		КорзинаПокупателя.Загрузить(Параметры.ДанныеКорзины.Выгрузить(,"Номенклатура,Характеристика,Упаковка,КоличествоУпаковок"));
	КонецЕсли;
	
	ДоступенПросмотрОстатков = СамообслуживаниеСервер.ДоступенПросмотрОстатковВПодборе();
	
	Сформировать();
	
КонецПроцедуры

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

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

&НаСервере
Процедура Сформировать()

	СкладСоглашения = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Соглашение, "Склад");

	Запрос = Новый Запрос;

	Корзина = КорзинаПокупателя.Выгрузить();
	Корзина.Свернуть("Номенклатура,Характеристика,Упаковка", "КоличествоУпаковок");
	
	Запрос.УстановитьПараметр("КорзинаПокупателя", Корзина);
	Запрос.УстановитьПараметр("Склад", СкладСоглашения);
	Запрос.УстановитьПараметр("СтрокаДоступноПодЗаказ",НСтр("ru = 'Доступно под заказ'"));  
	Запрос.УстановитьПараметр("СтрокаСогласноГрафика",НСтр("ru = 'Согласно графика'"));
	Запрос.УстановитьПараметр("СтрокаТребуетсяУточнить",НСтр("ru = 'Требует уточнения'"));
	Запрос.УстановитьПараметр("СтрокаУслугаДоступна",НСтр("ru = 'Услуга доступна'"));
	Запрос.УстановитьПараметр("СтрокаРаботаДоступна",НСтр("ru = 'Работа доступна'"));
	Запрос.УстановитьПараметр("ИспользоватьХарактеристикиНоменклатуры", 
	           ПолучитьФункциональнуюОпцию("ИспользоватьХарактеристикиНоменклатуры"));
	Запрос.УстановитьПараметр("ТекущаяДата",      ТекущаяДатаСеанса());
	Запрос.УстановитьПараметр("НачалоТекущегоДня",НачалоДня(ТекущаяДатаСеанса()));
	
	Запрос.Текст = "
	|ВЫБРАТЬ
	|	КорзинаПокупателя.Номенклатура,
	|	КорзинаПокупателя.Характеристика,
	|	КорзинаПокупателя.Упаковка,
	|	КорзинаПокупателя.КоличествоУпаковок
	|ПОМЕСТИТЬ КорзинаПокупателя
	|ИЗ
	|	&КорзинаПокупателя КАК КорзинаПокупателя
	|";
	
	Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();
	Запрос.Выполнить();
	
	Запрос.Текст = "
	|ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
	|	Склады.Ссылка,
	|	Склады.Наименование,
	|	Склады.КонтролироватьСвободныеОстатки,
	|	Склады.ЭтоГруппа
	|ПОМЕСТИТЬ Склады
	|ИЗ
	|	Справочник.Склады КАК Склады
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Склады КАК СкладыПараметр
	|		ПО (ИСТИНА)
	|ГДЕ
	|	ВЫБОР
	|			КОГДА &Склад = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка)
	|				ТОГДА ИСТИНА
	|			ИНАЧЕ ВЫБОР
	|					КОГДА ЕСТЬNULL(СкладыПараметр.ЭтоГруппа, ЛОЖЬ)
	|						ТОГДА Склады.Ссылка В ИЕРАРХИИ (&Склад)
	|					ИНАЧЕ Склады.Ссылка = &Склад
	|				КОНЕЦ
	|		КОНЕЦ
	|	И ВЫБОР
	|			КОГДА &Склад = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка)
	|				ТОГДА ИСТИНА
	|			ИНАЧЕ СкладыПараметр.Ссылка = &Склад
	|		КОНЕЦ
	|	И ВЫБОР
	|			КОГДА Склады.ЭтоГруппа
	|					И Склады.ВыборГруппы = ЗНАЧЕНИЕ(Перечисление.ВыборГруппыСкладов.Запретить)
	|				ТОГДА ЛОЖЬ
	|			ИНАЧЕ ИСТИНА
	|		КОНЕЦ
	|";
	
	Запрос.Выполнить();
	
	Запрос.Текст = "
	|ВЫБРАТЬ РАЗЛИЧНЫЕ 
	|	Склады.Ссылка КАК Склад,
	|	КорзинаПокупателя.Номенклатура,
	|	КорзинаПокупателя.Характеристика
	|ПОМЕСТИТЬ ВсеТоварыИСклады
	|ИЗ
	|	Склады КАК Склады,
	|	КорзинаПокупателя КАК КорзинаПокупателя";

	Запрос.Выполнить();
	
	Тексты = Новый Массив();
	
	Текст = РегистрыСведений.СхемыОбеспечения.ВременнаяТаблицаСпособыОбеспечения("ВЫЧИСЛЯТЬ");
	Текст = СтрЗаменить(Текст, "ВтТовары", "ВсеТоварыИСклады");
	Текст = СтрЗаменить(Текст, "РАЗРЕШЕННЫЕ", "");
	Тексты.Добавить(Текст);
	
	Тексты.Добавить(ОбеспечениеВДокументахСервер.ВременнаяТаблицаГодыГрафикаПредприятия());
	
	Текст =
		"ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	Таблица.СпособОбеспеченияПотребностей КАК СпособОбеспеченияПотребностей
		|ПОМЕСТИТЬ РазличныеСпособыОбеспечения
		|ИЗ
		|	ВтСпособыОбеспечения КАК Таблица
		|ИНДЕКСИРОВАТЬ ПО
		|	СпособОбеспеченияПотребностей
		|;
		|
		|ВЫБРАТЬ
		|	Таблица.СпособОбеспеченияПотребностей КАК СпособОбеспечения,
		|	РасчетДатыПоставкиПереопределяемый.ПлановаяДатаПоставки КАК Дата
		|
		|ПОМЕСТИТЬ ВтДатыПлановойПоставки
		|ИЗ
		|	РазличныеСпособыОбеспечения КАК Таблица
		|		
		|		ЛЕВОЕ СОЕДИНЕНИЕ РасчетДатыПоставкиПереопределяемый ПО ИСТИНА
		|		
		|ИНДЕКСИРОВАТЬ ПО
		|	СпособОбеспечения
		|;
		|УНИЧТОЖИТЬ РазличныеСпособыОбеспечения";
	
	Подстановки = ОбеспечениеВДокументахСервер.ПодстановкиПлановойДатыПоставки(
		"Таблица.СпособОбеспеченияПотребностей", "&НачалоТекущегоДня", Ложь, Истина);
	
	Текст = СтрЗаменить(Текст, "РасчетДатыПоставкиПереопределяемый.ПлановаяДатаПоставки", Подстановки.Поле);
	Текст = СтрЗаменить(Текст, "ЛЕВОЕ СОЕДИНЕНИЕ РасчетДатыПоставкиПереопределяемый ПО ИСТИНА", Подстановки.Соединения);
	
	Тексты.Добавить(Текст);
	
	Запрос.Текст = СтрСоединить(Тексты, ОбщегоНазначения.РазделительПакетаЗапросов());
	УстановитьПривилегированныйРежим(Истина);
	Запрос.Выполнить();
	УстановитьПривилегированныйРежим(Ложь);
	
	Запрос.Текст = Обработки.СамообслуживаниеПартнеров.ВременныеТаблицыДляРасчетаДоступныхОстатков("ВсеТоварыИСклады")
		+ Обработки.СамообслуживаниеПартнеров.ВременнаяТаблицаСвободноДляПродажиСуммарноПоСкладам("ВсеТоварыИСклады")
		+"ВЫБРАТЬ
		|	ВсеТоварыИСклады.Номенклатура,
		|	ВсеТоварыИСклады.Характеристика,
		|	ВсеТоварыИСклады.Склад КАК Склад,
		|	ЕСТЬNULL(ДоступныеОстаткиПоДатам.Количество, 0) КАК Доступно,
		|	ЕСТЬNULL(БлижайшиеДатыДоступности.Дата, ДАТАВРЕМЯ(1, 1, 1)) КАК Период,
		|	ЕСТЬNULL(ТоварныеОграничения.МетодОбеспеченияПотребностей, ЗНАЧЕНИЕ(Перечисление.МетодыОбеспеченияПотребностей.ЗаказПодЗаказ)) КАК МУЗ
		|ПОМЕСТИТЬ ДанныеПоДоступностиИМУЗ
		|ИЗ
		|	ВсеТоварыИСклады КАК ВсеТоварыИСклады
		|		
		|		ЛЕВОЕ СОЕДИНЕНИЕ ВтБлижайшиеДатыДоступности КАК БлижайшиеДатыДоступности
		|		ПО БлижайшиеДатыДоступности.Номенклатура   = ВсеТоварыИСклады.Номенклатура
		|		 И БлижайшиеДатыДоступности.Характеристика = ВсеТоварыИСклады.Характеристика
		|		 И БлижайшиеДатыДоступности.Склад          = ВсеТоварыИСклады.Склад
		|		
		|		ЛЕВОЕ СОЕДИНЕНИЕ ВтДоступныеОстаткиПоДатам КАК ДоступныеОстаткиПоДатам
		|		ПО ДоступныеОстаткиПоДатам.Номенклатура   = ВсеТоварыИСклады.Номенклатура
		|		 И ДоступныеОстаткиПоДатам.Характеристика = ВсеТоварыИСклады.Характеристика
		|		 И ДоступныеОстаткиПоДатам.Склад          = ВсеТоварыИСклады.Склад
		|		 И ДоступныеОстаткиПоДатам.Период         = БлижайшиеДатыДоступности.Дата
		|		
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТоварныеОграничения КАК ТоварныеОграничения
		|		ПО &ПодстановкаТоварногоОграничения
		|;
		|
		|//////////////////////////////////////////////////////////
		|
		|ВЫБРАТЬ
		|	ДанныеПоДоступностиИМУЗ.Склад КАК Склад,
		|	ДанныеПоДоступностиИМУЗ.Номенклатура КАК Номенклатура,
		|	ДанныеПоДоступностиИМУЗ.Характеристика КАК Характеристика,
		|	ДанныеПоДоступностиИМУЗ.Период КАК Период,
		|	ДанныеПоДоступностиИМУЗ.Доступно КАК Доступно,
		|	ДанныеПоДоступностиИМУЗ.Доступно КАК ДоступноСейчас,
		|	ЕСТЬNULL(ДатыПлановойПоставки.Дата, ДАТАВРЕМЯ(1, 1, 1))  КАК ДатаПоставки,
		|	ВЫБОР
		|		КОГДА ВидыНоменклатуры.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Услуга)
		|			ТОГДА &СтрокаУслугаДоступна
		|		КОГДА ВидыНоменклатуры.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Работа)
		|			ТОГДА &СтрокаРаботаДоступна
		|		КОГДА ДанныеПоДоступностиИМУЗ.МУЗ = ЗНАЧЕНИЕ(Перечисление.МетодыОбеспеченияПотребностей.ЗаказПодЗаказ)
		|			ТОГДА &СтрокаДоступноПодЗаказ
		|		КОГДА НЕ ВЫРАЗИТЬ(ДанныеПоДоступностиИМУЗ.Склад КАК Справочник.Склады).КонтролироватьСвободныеОстатки
		|			 ТОГДА &СтрокаТребуетсяУточнить
		|		ИНАЧЕ &СтрокаСогласноГрафика
		|	КОНЕЦ КАК Доступность,
		|	ВЫРАЗИТЬ(ВЫБОР КОГДА ДанныеПоДоступностиИМУЗ.Период = &НачалоТекущегоДня ТОГДА
		|					ЕСТЬNULL(ДанныеПоДоступностиИМУЗ.Доступно, 0)
		|				ИНАЧЕ
		|				0
		|				КОНЕЦ / ЕСТЬNULL(&ТекстЗапросаКоэффициентУпаковки, 1) КАК ЧИСЛО(15, 3)) КАК ДоступныйОстатокСейчас,
		|	КорзинаПокупателя.Упаковка КАК Упаковка,
		|	КорзинаПокупателя.КоличествоУпаковок КАК КоличествоУпаковок,
		|	СправочникНоменклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
		|	ВЫБОР
		|		КОГДА УпаковкиНоменклатуры.Ссылка ЕСТЬ NULL 
		|			ТОГДА КорзинаПокупателя.КоличествоУпаковок
		|		ИНАЧЕ КорзинаПокупателя.КоличествоУпаковок * &ТекстЗапросаКоэффициентУпаковки
		|	КОНЕЦ КАК Количество
		|ИЗ
		|	ДанныеПоДоступностиИМУЗ КАК ДанныеПоДоступностиИМУЗ
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Склады КАК Склады
		|		ПО ДанныеПоДоступностиИМУЗ.Склад = Склады.Ссылка
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ КорзинаПокупателя КАК КорзинаПокупателя
		|			ЛЕВОЕ СОЕДИНЕНИЕ Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиНоменклатуры
		|			ПО КорзинаПокупателя.Упаковка = УпаковкиНоменклатуры.Ссылка
		|		ПО ДанныеПоДоступностиИМУЗ.Номенклатура = КорзинаПокупателя.Номенклатура
		|			И ДанныеПоДоступностиИМУЗ.Характеристика = КорзинаПокупателя.Характеристика
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СправочникНоменклатура
		|			ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыНоменклатуры КАК ВидыНоменклатуры
		|			ПО СправочникНоменклатура.ВидНоменклатуры = ВидыНоменклатуры.Ссылка
		|		ПО ДанныеПоДоступностиИМУЗ.Номенклатура = СправочникНоменклатура.Ссылка
		|		
		|		ЛЕВОЕ СОЕДИНЕНИЕ ВтСпособыОбеспечения КАК СпособыОбеспечения
		|		ПО СпособыОбеспечения.Номенклатура   = ДанныеПоДоступностиИМУЗ.Номенклатура
		|		 И СпособыОбеспечения.Характеристика = ДанныеПоДоступностиИМУЗ.Характеристика
		|		 И СпособыОбеспечения.Склад          = ДанныеПоДоступностиИМУЗ.Склад
		|		
		|		ЛЕВОЕ СОЕДИНЕНИЕ ВтДатыПлановойПоставки КАК ДатыПлановойПоставки
		|		ПО ДатыПлановойПоставки.СпособОбеспечения = СпособыОбеспечения.СпособОбеспеченияПотребностей
		|		
		|УПОРЯДОЧИТЬ ПО
		|	ДанныеПоДоступностиИМУЗ.Склад.Наименование
		|ИТОГИ ПО
		|	Номенклатура,
		|	Характеристика,
		|	Упаковка,
		|	ЕдиницаИзмерения,
		|	КоличествоУпаковок,
		|	Склад";
	Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ТекстЗапросаКоэффициентУпаковки",
			Справочники.УпаковкиЕдиницыИзмерения.ТекстЗапросаКоэффициентаУпаковки(
				"УпаковкиНоменклатуры",
				"СправочникНоменклатура"));
				
	ПоляСоединения = "ВсеТоварыИСклады.Номенклатура,ВсеТоварыИСклады.Характеристика,ВсеТоварыИСклады.Склад";
	Запрос.Текст = РегистрыСведений.ТоварныеОграничения.ПодставитьСоединение(Запрос.Текст, "ПодстановкаТоварногоОграничения", ПоляСоединения);
	
	УстановитьПривилегированныйРежим(Истина);
		Результат = Запрос.Выполнить();
	УстановитьПривилегированныйРежим(Ложь);
	
	Запрос.Текст = "
	|ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	Склады.Ссылка,
	|	Склады.Наименование
	|ИЗ
	|	Склады КАК Склады
	|
	|УПОРЯДОЧИТЬ ПО
	|	Склады.Наименование
	|";

	РезультатСклады = Запрос.Выполнить();
	Запрос.МенеджерВременныхТаблиц.Закрыть();

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


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

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

&НаСервере
Процедура Вывести(РезультатЗапроса,РезультатЗапросаСклады, ТаблицаГруппСкладов)
	
	ТабличныйДокумент.Очистить();
	
	ИспользованиеХарактеристикНоменклатуры = ПолучитьФункциональнуюОпцию("ИспользоватьХарактеристикиНоменклатуры");
	
	Макет = Обработки.СамообслуживаниеПартнеров.ПолучитьМакет("ОстаткиПоСкладам");
	
	ОбластьШапкаНоменклатура              = Макет.ПолучитьОбласть("Шапка|Номенклатура");
	ОбластьШапкаХарактеристика            = Макет.ПолучитьОбласть("Шапка|Характеристика");
	ОбластьШапкаУпаковкаКоличество        = Макет.ПолучитьОбласть("Шапка|УпаковкаКоличество");
	ОбластьШапкаСклад                     = Макет.ПолучитьОбласть(?(ДоступенПросмотрОстатков, "Шапка|СкладОстатки", "Шапка|Склад"));
	
	ОбластьСтрокаНоменклатура             = Макет.ПолучитьОбласть("Строка|Номенклатура");
	ОбластьСтрокаХарактеристика           = Макет.ПолучитьОбласть("Строка|Характеристика");
	ОбластьСтрокаУпаковкаКоличество       = Макет.ПолучитьОбласть("Строка|УпаковкаКоличество");
	ОбластьСтрокаСклад                    = Макет.ПолучитьОбласть(?(ДоступенПросмотрОстатков, "Строка|СкладОстатки", "Строка|Склад"));
	ОбластьСтрокаОтрицательноеСклад       = Макет.ПолучитьОбласть(?(ДоступенПросмотрОстатков, "СтрокаОтрицательноеЧисло|СкладОстатки", "СтрокаОтрицательноеЧисло|Склад"));
	
	// Шапка отчета
	ТабличныйДокумент.Вывести(ОбластьШапкаНоменклатура);
	Если ИспользованиеХарактеристикНоменклатуры Тогда
		ТабличныйДокумент.Присоединить(ОбластьШапкаХарактеристика);
	КонецЕсли;
	
	ТабличныйДокумент.Присоединить(ОбластьШапкаУпаковкаКоличество);
	ВыборкаСклады = РезультатЗапросаСклады.Выбрать();
	Пока ВыборкаСклады.Следующий() Цикл
		
		ОбластьШапкаСклад.Параметры.Склад = ВыборкаСклады.Наименование;
		ТабличныйДокумент.Присоединить(ОбластьШапкаСклад);
		
	КонецЦикла;
	
	НомерСтроки = 0;
	
	ВыборкаНоменклатура = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
	Пока ВыборкаНоменклатура.Следующий() Цикл
		ВыборкаХарактеристика = ВыборкаНоменклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
		Пока ВыборкаХарактеристика.Следующий() Цикл
			ВыборкаУпаковка = ВыборкаХарактеристика.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
			Пока ВыборкаУпаковка.Следующий() Цикл
				ВыборкаЕдИзм = ВыборкаУпаковка.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
				Пока ВыборкаЕдИзм.Следующий() Цикл
					
					ВыборкаКоличество = ВыборкаЕдИзм.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
					Пока ВыборкаКоличество.Следующий() Цикл
						НомерСтроки = НомерСтроки + 1;
						ОбластьСтрокаНоменклатура.Параметры.НомерСтроки  = НомерСтроки;
						ОбластьСтрокаНоменклатура.Параметры.Номенклатура = ВыборкаНоменклатура.Номенклатура;
						ТабличныйДокумент.Вывести(ОбластьСтрокаНоменклатура);
						Если ИспользованиеХарактеристикНоменклатуры Тогда
							ОбластьСтрокаХарактеристика.Параметры.Характеристика = ВыборкаХарактеристика.Характеристика;
							ТабличныйДокумент.Присоединить(ОбластьСтрокаХарактеристика);
						КонецЕсли;
						ОбластьСтрокаУпаковкаКоличество.Параметры.Упаковка = 
						    ?(ВыборкаКоличество.Упаковка = Справочники.УпаковкиЕдиницыИзмерения.ПустаяСсылка(),
						      ВыборкаКоличество.ЕдиницаИзмерения,
						      Строка(ВыборкаКоличество.Упаковка)+ ","+ Строка(ВыборкаКоличество.ЕдиницаИзмерения));
						ОбластьСтрокаУпаковкаКоличество.Параметры.Количество = ВыборкаКоличество.КоличествоУпаковок;
						ТабличныйДокумент.Присоединить(ОбластьСтрокаУпаковкаКоличество);
						ОчиститьЗависимыеКолонкиТаблицаСкладов(ТаблицаГруппСкладов);
						СоответствиеДанныеСклада = Новый Соответствие;
						ВыборкаСклад = ВыборкаКоличество.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
						Пока ВыборкаСклад.Следующий() Цикл
							ВыборкаДетали = ВыборкаСклад.Выбрать();
							Пока ВыборкаДетали.Следующий() Цикл
								ЗначениеДоступность = ВыборкаДетали.Доступность;
								Если ВыборкаДетали.Доступность = НСтр("ru = 'Согласно графика'") Тогда

									Если ВыборкаДетали.Доступно > 0 Тогда

										Если ВыборкаДетали.Период = НачалоДня(ТекущаяДатаСеанса()) Тогда

											Если ВыборкаДетали.Количество/ВыборкаДетали.Доступно < 0.5 Тогда
												ЗначениеДоступность = НСтр("ru = 'В наличии'");
												ДобавитьВСоотвествиеСкладовЗапись(СоответствиеДанныеСклада, ВыборкаДетали.Склад, ЗначениеДоступность, ВыборкаДетали.ДоступныйОстатокСейчас);
											Иначе
												ЗначениеДоступность = НСтр("ru = 'Требует уточнения'");
												ДобавитьВСоотвествиеСкладовЗапись(СоответствиеДанныеСклада, ВыборкаДетали.Склад, ЗначениеДоступность, ВыборкаДетали.ДоступныйОстатокСейчас);
											КонецЕсли;

										Иначе
											ЗначениеДоступность = НСтр("ru = 'Ожидается'") + " " + Формат(ВыборкаДетали.Период,"ДЛФ=D");
											ДобавитьВСоотвествиеСкладовЗапись(СоответствиеДанныеСклада, ВыборкаДетали.Склад, ЗначениеДоступность, ВыборкаДетали.ДоступныйОстатокСейчас, ВыборкаДетали.Период);
										КонецЕсли;

									Иначе

										Если ВыборкаДетали.ДатаПоставки < НачалоДня(ТекущаяДатаСеанса()) Тогда
											ЗначениеДоступность = НСтр("ru = 'Нет на складе'");
											ДобавитьВСоотвествиеСкладовЗапись(СоответствиеДанныеСклада, ВыборкаДетали.Склад, ЗначениеДоступность, ВыборкаДетали.ДоступныйОстатокСейчас);
										Иначе
											ЗначениеДоступность = НСтр("ru = 'Ожидается'") + " " + Формат(ВыборкаДетали.ДатаПоставки,"ДЛФ=D");
											ДобавитьВСоотвествиеСкладовЗапись(СоответствиеДанныеСклада, ВыборкаДетали.Склад, ЗначениеДоступность, ВыборкаДетали.ДоступныйОстатокСейчас, ВыборкаДетали.ДатаПоставки);
										КонецЕсли;

									КонецЕсли;

								Иначе
									ДобавитьВСоотвествиеСкладовЗапись(СоответствиеДанныеСклада, ВыборкаДетали.Склад, ЗначениеДоступность, ВыборкаДетали.ДоступныйОстатокСейчас);
								КонецЕсли;
								
								Если ЗначениеДоступность = НСтр("ru = 'Нет на складе'") Тогда
									ОбластьСтрокаОтрицательноеСклад.Параметры.Доступность = ЗначениеДоступность;
									Если ДоступенПросмотрОстатков Тогда
										ОбластьСтрокаОтрицательноеСклад.Параметры.ДоступноОстаток = ?(ВыборкаДетали.ДоступныйОстатокСейчас < 0, 0, ВыборкаДетали.ДоступныйОстатокСейчас);
									КонецЕсли;
									ОбластьЯчеек = ТабличныйДокумент.Присоединить(ОбластьСтрокаОтрицательноеСклад);
								Иначе
									ОбластьСтрокаСклад.Параметры.Доступность = ЗначениеДоступность;
									Если ДоступенПросмотрОстатков Тогда
										ОбластьСтрокаСклад.Параметры.ДоступноОстаток = ?(ВыборкаДетали.ДоступныйОстатокСейчас < 0, 0, ВыборкаДетали.ДоступныйОстатокСейчас);
									КонецЕсли;
									ОбластьЯчеек = ТабличныйДокумент.Присоединить(ОбластьСтрокаСклад);
								КонецЕсли;
								
								СтрокаТаблицыГруппыСкладов = ТаблицаГруппСкладов.Найти(ВыборкаДетали.Склад, "Склад");
								Если СтрокаТаблицыГруппыСкладов <> Неопределено Тогда
									СтрокаТаблицыГруппыСкладов.Область = ОбластьЯчеек;
								КонецЕсли;
								
							КонецЦикла; //ВыборкаДетали
						КонецЦикла; //ВыборкаСклады
						
						ЗаполнитьДоступностьГруппыСкладов(ТаблицаГруппСкладов, СоответствиеДанныеСклада);
						
					КонецЦикла;
				КонецЦикла;
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
	
	Если ИспользованиеХарактеристикНоменклатуры Тогда
		ТабличныйДокумент.ФиксацияСлева = 3;
	Иначе
		ТабличныйДокумент.ФиксацияСлева = 2;
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
// 	ТаблицаГруппСкладов - см. ТаблицаИерархииСкладов
// 	СоответствиеДанныеСклада - Соответствие - содержит:
//		* Ключ - СправочникСсылка.Склады - 
//		* Значение - см. ДанныеПоСкладу
&НаСервере
Процедура ЗаполнитьДоступностьГруппыСкладов(ТаблицаГруппСкладов, СоответствиеДанныеСклада);
	
	МассивТекстовДоступности = СамообслуживаниеСервер.МассивТекстовДоступности();
	
	Для Каждого СтрокаТаблицыГруппыСкладов Из ТаблицаГруппСкладов Цикл
		
		ТекстДоступность = "";
		ТекстДоступностьСейчас = "";
		
		ДатаДоступности  = Неопределено;
		Для Каждого ЭлементМассива Из СтрокаТаблицыГруппыСкладов.МассивПодчиненныхСкладов Цикл
			ДанныеСклада = СоответствиеДанныеСклада.Получить(ЭлементМассива); // см. ДанныеПоСкладу
			Если ДанныеСклада <> Неопределено Тогда
				Если ДанныеСклада.Доступность = НСтр("ru = 'В наличии'")
					Или ДанныеСклада.Доступность = НСтр("ru = 'Услуга доступна'") Тогда
					ТекстДоступность = ДанныеСклада.Доступность;
					Прервать;
				Иначе
					
					Если ТекстДоступность = "" Тогда
						ТекстДоступность = ДанныеСклада.Доступность;
					Иначе
						НомерВМассивеГруппа  = МассивТекстовДоступности.Найти(ТекстДоступность);
						НомерВМассивеТекущий = МассивТекстовДоступности.Найти(ДанныеСклада.Доступность);
						Если НомерВМассивеГруппа = Неопределено Или НомерВМассивеТекущий = Неопределено Тогда
							Продолжить;
						КонецЕсли;
						Если НомерВМассивеТекущий <= НомерВМассивеГруппа Тогда
							ТекстДоступность = ДанныеСклада.Доступность;
						Иначе
							Продолжить;
						КонецЕсли;
					КонецЕсли;
					
					Если ДанныеСклада.Доступность = НСтр("ru = 'Ожидается'") + " " Тогда
						Если ДатаДоступности = Неопределено Тогда
							ДатаДоступности =ДанныеСклада.ПериодДоступности;
						ИначеЕсли ДатаДоступности > ДанныеСклада.ПериодДоступности Тогда
							ДатаДоступности = ДанныеСклада.ДатаДоступности;
						КонецЕсли;
					КонецЕсли;
					
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
		
		ДоступноСейчас = 0;
		
		Если ДоступенПросмотрОстатков Тогда
			Для Каждого ЭлементМассива Из СтрокаТаблицыГруппыСкладов.МассивПодчиненныхСкладов Цикл
				ДанныеСклада = СоответствиеДанныеСклада.Получить(ЭлементМассива);
				Если ДанныеСклада <> Неопределено Тогда
					ДоступноСейчас = ДоступноСейчас + ДанныеСклада.ДоступныйОстатокСейчас;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		
		Если ДоступноСейчас < 0 Тогда
			ДоступноСейчас = 0;
		КонецЕсли;
		
		Если ТекстДоступность = НСтр("ru = 'Ожидается'") + " " Тогда
			 ТекстДоступность = ТекстДоступность + Формат(ДатаДоступности, "ДЛФ=D");
		КонецЕсли;
		
		Если ПустаяСтрока(ТекстДоступность) Тогда
			ТекстДоступность = НСтр("ru = 'Нет в наличии'");
		КонецЕсли;
		
		Если СтрокаТаблицыГруппыСкладов.Область <> Неопределено Тогда
			Если ДоступенПросмотрОстатков Тогда
				Область = СтрокаТаблицыГруппыСкладов.Область; // ОбластьЯчеекТабличногоДокумента
				МассивИменОбластей = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Область.Имя, ":");
				ОбластьДоступность    = ТабличныйДокумент.Область(МассивИменОбластей[0]);
				ОбластьДоступноСейчас = ТабличныйДокумент.Область(МассивИменОбластей[1]);
			Иначе
				ОбластьДоступность = СтрокаТаблицыГруппыСкладов.Область;
				ОбластьДоступноСейчас = Неопределено;
			КонецЕсли;
			
			Если ОбластьДоступноСейчас <> Неопределено Тогда
				ОбластьДоступноСейчас.Текст = ДоступноСейчас;
			КонецЕсли;
			ОбластьДоступность.Текст = ТекстДоступность;
			
			Если ТекстДоступность = НСтр("ru = 'Нет в наличии'") Тогда
				ОбластьДоступность.ЦветТекста = ЦветаСтиля.ЦветОтрицательногоЧисла;
			КонецЕсли;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

// Функция-конструктор структуры "данные по складу" для вывода в отчет.
// 
// Возвращаемое значение:
//  Структура - Содержит:
//   * ДоступныйОстатокСейчас  - Строка -
//   * ПериодДоступности       - Дата -
//   * Доступность             - Строка -
//
&НаСервере
Функция ДанныеПоСкладу()
	
	Результат = Новый Структура;
	Результат.Вставить("Доступность",            Неопределено);
	Результат.Вставить("ПериодДоступности",      Неопределено);
	Результат.Вставить("ДоступныйОстатокСейчас", Неопределено);
	
	Возврат Результат;
	
КонецФункции

// Параметры:
// 	РезультатЗапроса - РезультатЗапроса, Неопределено - 
// Возвращаемое значение:
// 	ТаблицаЗначений - Содержит:
// * Склад                      - СправочникСсылка.Склады - 
// * МассивПодчиненныхСкладов   - Массив из СправочникСсылка.Склады -
// * ТекстДоступности           - Строка -
// * Область                    - Строка -
&НаСервере
Функция ТаблицаИерархииСкладов(РезультатЗапроса)

	ТаблицаСкладов = Новый ТаблицаЗначений;
	ТаблицаСкладов.Колонки.Добавить("Склад");
	ТаблицаСкладов.Колонки.Добавить("МассивПодчиненныхСкладов");
	ТаблицаСкладов.Колонки.Добавить("ТекстДоступности");
	ТаблицаСкладов.Колонки.Добавить("Область");
	
	ДеревоСкладов = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
	ДобавитьВТаблицуСкладовПоСтрокамДерева(ДеревоСкладов.Строки, Неопределено, ТаблицаСкладов, Новый Массив);
	
	Возврат ТаблицаСкладов;
	
КонецФункции

&НаСервере
Процедура ДобавитьВТаблицуСкладовПоСтрокамДерева(СтрокиДерева, Склад,  ТаблицаСкладов, МассивСкладов)

	МассивСкладовТекущий = ОбщегоНазначенияКлиентСервер.СкопироватьМассив(МассивСкладов);
	Если Склад <> Неопределено Тогда
		МассивСкладовТекущий.Добавить(Склад);
	КонецЕсли;
	
	Для Каждого СтрокаДерева Из СтрокиДерева Цикл
		
		Если СтрокаДерева.ЭтоГруппа Тогда
			Если ТаблицаСкладов.Найти(СтрокаДерева.Склад, "Склад") = Неопределено Тогда
				НоваяСтрокаТаблицы = ТаблицаСкладов.Добавить();
				НоваяСтрокаТаблицы.Склад = СтрокаДерева.Склад;
				НоваяСтрокаТаблицы.МассивПодчиненныхСкладов = Новый Массив;
				ДобавитьВТаблицуСкладовПоСтрокамДерева(СтрокаДерева.Строки, СтрокаДерева.Склад, ТаблицаСкладов, МассивСкладовТекущий);
			КонецЕсли;
		Иначе
			Для Каждого ЭлементМассива Из МассивСкладовТекущий Цикл
				СтрокаТаблицы = ТаблицаСкладов.Найти(ЭлементМассива, "Склад");
				Если СтрокаТаблицы <> Неопределено Тогда
					МассивПодчиненныхСкладов = СтрокаТаблицы.МассивПодчиненныхСкладов; // Массив
					МассивПодчиненныхСкладов.Добавить(СтрокаДерева.Склад);
				КонецЕсли;
			КонецЦикла
		КонецЕсли;
		
	КонецЦикла;

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

&НаСервере
Процедура ОчиститьЗависимыеКолонкиТаблицаСкладов(ТаблицаСкладов)

	ТаблицаСкладов.ЗаполнитьЗначения("", "ТекстДоступности");
	ТаблицаСкладов.ЗаполнитьЗначения(Неопределено, "Область");

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

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

Связанные материалы