Проверка и подбор табачной продукции МОТП / Проверка и подбор / Модуль формы

файл
#Область ОписаниеПеременных

&НаКлиенте
Перем ИдентификаторыРодителейУдаляемыхЭлементов;

&НаКлиенте
Перем СоответствиеШтрихкодовСтрокДерева Экспорт;

&НаКлиенте
Перем КомплектующиеНаборов;

&НаКлиенте
Перем КэшированныеЗначения Экспорт;

&НаКлиенте
Перем Ссылка Экспорт;

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

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

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	ИнициализироватьПараметрыСканирования(Истина);
	
	ОповещениеПослеПрочтения = Новый ОписаниеОповещения("ПослеПрочтенияПредупрежденияОЗапретеРаботыСРазрешительнымРежимом", ЭтотОбъект);
	
	ВидыПродукции  = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(ВидМаркируемойПродукции);
	ОтменаОткрытия = ОбщегоНазначенияИСМПКлиент.ПроверитьРаботуСРазрешительнымРежимомФФД_1_05(ПараметрыСканирования, ВидыПродукции, ОповещениеПослеПрочтения);
	
	Если ОтменаОткрытия Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ВосстановленыСохраненныеРезультатыПроверки Тогда
		ЗаполнитьПараметрыПроверкиКодовМаркировки(Отказ);
		Если Отказ Тогда
			Возврат;
		ИначеЕсли Не НеобходимоОбращениеКСервисуМОТП(ПараметрыСканирования, ПараметрыПроверкиКодовМаркировки) Тогда
			// если не запрашивать данные ИС МП или требуется токен розничной продажи и не проверять упаковки 
			ТребуетсяОбновлениеКлючаСессии = Ложь;
		КонецЕсли;
		Если Не ПараметрыПроверкиКодовМаркировки.ПроверятьЗаполнениеИдентификатораГИСМТ Тогда
			ТребуетсяОбновлениеКлючаСессииРозница = Ложь;
		КонецЕсли;
	Иначе
		ЗаполнитьПараметрыПроверкиКодовМаркировки(Истина);
		Если Не ПараметрыПроверкиКодовМаркировки.ПроверятьЗаполнениеИдентификатораГИСМТ Тогда
			ТребуетсяОбновлениеКлючаСессииРозница = Ложь;
		КонецЕсли;
	КонецЕсли;
	
	// ПодключаемоеОборудование
	МенеджерОборудованияКлиент.НачатьПодключениеОборудованиеПриОткрытииФормы(Неопределено, ЭтотОбъект, ПоддерживаемыеТипыПодключаемогоОборудования);
	// Конец ПодключаемоеОборудование
	
	Если ВосстановленыСохраненныеРезультатыПроверки Тогда
		СоответствиеШтрихкодовСтрокДерева = СоответствиеШтрихкодовСтрокДерева(АдресСоответствиеШтрихкодыИдентификаторыСтрок);
		
		Если ПараметрыПроверкиКодовМаркировки.ОтсутствуетПодключениеМОТП Тогда
			Если ТребуетсяОбновлениеКлючаСессии Тогда
				ПодключитьОбработчикОжидания("ОбработкаОжиданияПовторногоЗапросаКлючаСессии", 0.5, Истина);
			Иначе
				ПриПодключенииКСервисуМОТП();
			КонецЕсли;
		КонецЕсли;
	ИначеЕсли ТребуетсяОбновлениеКлючаСессии Или ТребуетсяОбновлениеКлючаСессииРозница Тогда
		ПодключитьОбработчикОжидания("ОбработкаОжиданияЗапросаКлючаСессии", 0.5, Истина);
	Иначе
		ЗагрузитьДанныеДокумента();
	КонецЕсли;
	
	Ссылка = ПроверяемыйДокумент;
	
	УстановитьЗаголовокКомандыПроверкиПоВладельцу(ЭтотОбъект);
	УстановитьЗаголовокКомандыПроверкиСтатусовКодовМаркировки(ЭтотОбъект);
	УстановитьЗаголовокКомандыОбратноеСканирование(ЭтотОбъект);
	
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеДанныхИзНастроекНаСервере(Настройки)
	
	РежимПроверкиИзНастроек = Настройки.Получить("РежимПроверки");
	Если ЗначениеЗаполнено(РежимПроверкиИзНастроек) Тогда
		РежимПроверки = РежимПроверкиИзНастроек;
		СформироватьПредставлениеНастроек(ЭтотОбъект);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	
	Если ЗавершениеРаботы Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ВыполняетсяЗакрытие Тогда
		
		Если Модифицированность Тогда
			
			Отказ = Истина;
			
			ТекстВопроса = НСтр("ru = 'Все несохраненные результаты проверки будут потеряны. Все равно закрыть?'");
			ОписаниеОповещенияПослеВопросаПриЗакрытииФормы = Новый ОписаниеОповещения("ПослеВопросаПриЗакрытииФормы", ЭтотОбъект);
			
			ПоказатьВопрос(ОписаниеОповещенияПослеВопросаПриЗакрытииФормы, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
		
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
	
	// ПодключаемоеОборудование
	МенеджерОборудованияКлиент.НачатьОтключениеОборудованиеПриЗакрытииФормы(Неопределено, ЭтотОбъект);
	// Конец ПодключаемоеОборудование
	
КонецПроцедуры

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

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

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

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

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

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ПредставлениеСохраненногоВыбораОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	ИнтеграцияИСКлиент.ПредставлениеСохраненногоВыбораОбработкаНавигационнойСсылки(ЭтотОбъект, НавигационнаяСсылкаФорматированнойСтроки);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ДекорацияИнформацияТребуетсяПеремаркировкаОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	Если НавигационнаяСсылкаФорматированнойСтроки = "ИзменитьОтборТребуетсяПеремаркировка" Тогда
		
		УстановленОтборТребуетсяПеремаркировать = Не УстановленОтборТребуетсяПеремаркировать;
	
		Если УстановленОтборТребуетсяПеремаркировать Тогда
			УстановитьОтборПоТребующимПеремаркировки();
		Иначе
			ПроверитьПризнакУстановкиОтбораВДереве(ЭтотОбъект);
		КонецЕсли;
	
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ОтобразитьИнформациюОНеобходимостиПеремаркировки(ЭтотОбъект);
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ДекорацияНедопустимыеКодыМаркировкиОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	Если НавигационнаяСсылкаФорматированнойСтроки = "ИзменитьОтборНедопустимыеКодыМаркировки" Тогда
		
		УстановленОтборНедопустимыеКодыМаркировки = Не УстановленОтборНедопустимыеКодыМаркировки;
	
		Если УстановленОтборНедопустимыеКодыМаркировки Тогда
			УстановитьОтборНедопустимыеКодыМаркировки();
		Иначе
			ПроверитьПризнакУстановкиОтбораВДереве(ЭтотОбъект);
		КонецЕсли;
		
		ПроверкаИПодборПродукцииИСМПКлиентСервер.ОтобразитьИнформациюОНедопустимыхКодахМаркировки(ЭтотОбъект);
		
	КонецЕсли;
	
КонецПроцедуры

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

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

#Область ОбработчикиСобытийЭлементовТаблицыФормыДеревоМаркированнойПродукции

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

&НаКлиенте
Процедура ДеревоМаркированнойПродукцииПриАктивизацииСтроки(Элемент)
	
	ТекущиеДанные = Элемент.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	УправлениеДоступностьюКомандыРазобратьУпаковку();
	
	ПроверкаИПодборПродукцииИСМПКлиентСервер.ОбновитьВыводимоеПредставлениеПроверкиСодержимого(ЭтотОбъект, ТекущиеДанные);
	
КонецПроцедуры

&НаКлиенте
Процедура ДеревоМаркированнойПродукцииПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
	
	Отказ = Истина;
	
КонецПроцедуры

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

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

			Если Не ПустаяСтрока(ТекстОшибки) Тогда
				ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстОшибки,,, "ДеревоМаркированнойПродукции", Отказ);
				Возврат;
			КонецЕсли;

		КонецЕсли;
		
		УдаляемыеЭлементыДерева.Добавить(УдаляемыйЭлемент);
		ИдентификаторыУдаляемыхЭлементов.Добавить(ИдентификаторСтроки);

		Если РодительУдаляемогоЭлемента <> Неопределено Тогда
			ИдентификаторРодителя = РодительУдаляемогоЭлемента.ПолучитьИдентификатор();
			Если ИдентификаторыРодителейУдаляемыхЭлементов.Найти(ИдентификаторРодителя) = Неопределено Тогда
				ИдентификаторыРодителейУдаляемыхЭлементов.Добавить(ИдентификаторРодителя);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Для Каждого ИдентификаторУдаляемогоЭлемента Из ИдентификаторыУдаляемыхЭлементов Цикл
		ИндексУдаляемогоЭлемента = ИдентификаторыРодителейУдаляемыхЭлементов.Найти(ИдентификаторУдаляемогоЭлемента);
		Если ИндексУдаляемогоЭлемента <> Неопределено Тогда
			ИдентификаторыРодителейУдаляемыхЭлементов.Удалить(ИндексУдаляемогоЭлемента);
		КонецЕсли;
	КонецЦикла;
	
	ИндексУдаляемогоЭлемента = ИдентификаторыУдаляемыхЭлементов.Найти(ИдентификаторТекущейПроверяемойУпаковки);
	Пока ИндексУдаляемогоЭлемента <> Неопределено Цикл
		ТекущаяПроверяемаяУпаковка = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторТекущейПроверяемойУпаковки);
		
		Если ТекущаяПроверяемаяУпаковка = Неопределено Тогда
			ИдентификаторТекущейПроверяемойУпаковки = -1;
		Иначе
			ТекущаяПроверяемаяУпаковка = ТекущаяПроверяемаяУпаковка.ПолучитьРодителя();
			Если ТекущаяПроверяемаяУпаковка = Неопределено Тогда
				ИдентификаторТекущейПроверяемойУпаковки = -1;
			Иначе
				ИдентификаторТекущейПроверяемойУпаковки = ТекущаяПроверяемаяУпаковка.ПолучитьИдентификатор();
			КонецЕсли;
		КонецЕсли;
		
		ИндексУдаляемогоЭлемента = ИдентификаторыУдаляемыхЭлементов.Найти(ИдентификаторТекущейПроверяемойУпаковки);
	КонецЦикла;
	
	Если ИдентификаторТекущейПроверяемойУпаковки <> -1 Тогда
		Если ИдентификаторСтрокиПотребительскиеУпаковкиБезУпаковки <> -1 И ИдентификаторТекущейПроверяемойУпаковки = ИдентификаторСтрокиПотребительскиеУпаковкиБезУпаковки Тогда
			ИдентификаторТекущейПроверяемойУпаковки = -1;
		КонецЕсли;
		Если ИдентификаторСтрокиГрупповыеУпаковкиБезКоробки <> -1 И ИдентификаторТекущейПроверяемойУпаковки = ИдентификаторСтрокиГрупповыеУпаковкиБезКоробки Тогда
			ИдентификаторТекущейПроверяемойУпаковки = -1;
			СтрокаГрупповыеУпаковкиБезКоробки(ЭтотОбъект).ИдетПроверкаДаннойУпаковки = Ложь;
		КонецЕсли;
	КонецЕсли;
	
	КоличествоУдаляемыхТребующихПеремаркировки     = 0;
	КоличествоУдаляемыхНедопустимыхКодовМаркировки = 0;
	КоличествоКодовОбработанныхГИСМТСОшибкой       = 0;
	
	Для Каждого УдаляемыйЭлемент Из УдаляемыеЭлементыДерева Цикл
		Если УдаляемыеЭлементыДерева.Найти(УдаляемыйЭлемент.ПолучитьРодителя()) <> Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(УдаляемыйЭлемент.ТипУпаковки) Тогда
			
			Если РежимИсправленияОшибокПослеПередачиКодов Тогда
				Если Не УдаляемыйЭлемент.ОбработанСОшибкойВГИСМТ Тогда
					ОпределитьКоличествоКодовОбработанныхСОшибкойГИСМТДляКоллекции(УдаляемыйЭлемент.ПолучитьЭлементы(),КоличествоКодовОбработанныхГИСМТСОшибкой);
					Если КоличествоКодовОбработанныхГИСМТСОшибкой = 0 Тогда
						ТекстОшибки = НСтр("ru = 'Для документов, обработанных в ГИС МТ частично, можно удалять только строки и упаковки, обработанные с ошибкой'");
						ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстОшибки,,, "ДеревоМаркированнойПродукции", Отказ);
						Возврат;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
			
			КоличествоУдаляемыхТребующихПеремаркировки = КоличествоУдаляемыхТребующихПеремаркировки + ?(УдаляемыйЭлемент.ТребуетсяПеремаркировка, 1, 0);
			ОпределитьКоличествоТребующихПеремаркировкиДляКоллекции(УдаляемыйЭлемент.ПолучитьЭлементы(), КоличествоУдаляемыхТребующихПеремаркировки);
			
			Если (ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
					Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами"))
				И УдаляемыйЭлемент.ТипУпаковки = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МонотоварнаяУпаковка")
				И ЗначениеЗаполнено(УдаляемыйЭлемент.Номенклатура)
				И ЗначениеЗаполнено(УдаляемыйЭлемент.GTIN)
				И УдаляемыйЭлемент.КоличествоПодчиненныхПотребительскихУпаковок > 0
				И УдаляемыйЭлемент.ПолучитьЭлементы().Количество() = 0 Тогда
			Иначе
				РодительУдаляемогоЭлемента = УдаляемыйЭлемент.ПолучитьРодителя();
				Пока РодительУдаляемогоЭлемента <> Неопределено Цикл
					Если Не ИнтеграцияИСКлиентСервер.ЭтоУпаковка(РодительУдаляемогоЭлемента.ТипУпаковки) Тогда
						Прервать;
					КонецЕсли;
					РодительУдаляемогоЭлемента.НеПересчитыватьКоличествоПотребительскихУпаковок = Ложь;
					РодительУдаляемогоЭлемента = РодительУдаляемогоЭлемента.ПолучитьРодителя();
				КонецЦикла;
			КонецЕсли;
			
		Иначе
			
			Если РежимИсправленияОшибокПослеПередачиКодов 
				И Не (УдаляемыйЭлемент.ОбработанСОшибкойВГИСМТ
					Или УдаляемыйЭлемент.НедопустимыйКодМаркировки) Тогда
				ТекстОшибки = НСтр("ru = 'Для документов, обработанных в ГИС МТ частично, можно удалять только строки и упаковки, обработанные с ошибкой'");
				ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстОшибки,,, "ДеревоМаркированнойПродукции", Отказ);
				Возврат;
			КонецЕсли;
			
		КонецЕсли;
		
		ОбработатьПодчиненныеСтрокиДереваПриУдалении(ТаблицаИзмененийТабачнойПродукции, УдаляемыйЭлемент);
		ОбработатьСтрокуДереваПриУдалении(ТаблицаИзмененийТабачнойПродукции, УдаляемыйЭлемент);
		
		КоличествоУдаляемыхНедопустимыхКодовМаркировки = КоличествоУдаляемыхНедопустимыхКодовМаркировки + ?(УдаляемыйЭлемент.НедопустимыйКодМаркировки, 1, 0);
		ОпределитьКоличествоНедопустимыхКодовМаркировкиДляКоллекции(УдаляемыйЭлемент.ПолучитьЭлементы(), КоличествоУдаляемыхНедопустимыхКодовМаркировки);
		
	КонецЦикла;
	
	Если КоличествоУдаляемыхТребующихПеремаркировки > 0 Тогда
		КоличествоУпаковокКоторыеНеобходимоПеремаркировать = КоличествоУпаковокКоторыеНеобходимоПеремаркировать - КоличествоУдаляемыхТребующихПеремаркировки;
		ТребуетсяОбновитьИнформациюОНеобходимостиПеремаркировки = Истина;
	КонецЕсли;
	
	Если КоличествоУдаляемыхНедопустимыхКодовМаркировки > 0 Тогда
		КоличествоНедопустимыхКодовМаркировки = КоличествоНедопустимыхКодовМаркировки - КоличествоУдаляемыхНедопустимыхКодовМаркировки;
		ТребуетсяОбновитьИнформациюНедопустимыеКодыМаркировки = Истина;
	КонецЕсли;
	
КонецПроцедуры

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

&НаКлиенте
Процедура ДеревоМаркированнойПродукцииСтатусПроверкиОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	ТекущиеДанные = Элементы.ДеревоМаркированнойПродукции.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

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

&НаКлиенте
Процедура ДеревоМаркированнойПродукцииПослеУдаления(Элемент)
	
	Для Каждого ИдентификаторРодителя Из ИдентификаторыРодителейУдаляемыхЭлементов Цикл
		СтрокаДляПересчета = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторРодителя);
		Если СтрокаДляПересчета <> Неопределено Тогда
			ПроверкаИПодборПродукцииМОТПКлиентСервер.ПроверитьДопустимостьВложенияАгрегата(СтрокаДляПересчета, ПараметрыПроверкиКодовМаркировки);
			ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(СтрокаДляПересчета, Ложь);
			ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(СтрокаДляПересчета);
			ПриИзмененииМаркировкиСоставаУпаковкиНаКлиенте(ИдентификаторРодителя, Истина);
		КонецЕсли;
	КонецЦикла;
	
	ИдентификаторыРодителейУдаляемыхЭлементов.Очистить();
	
	Если ТребуетсяОбновитьИнформациюОНеобходимостиПеремаркировки
		Или ТаблицаИзмененийТабачнойПродукции.Количество() > 0 Тогда
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ОтобразитьИнформациюОНеобходимостиПеремаркировки(ЭтотОбъект);
		ОбработатьТаблицуИзмененийПодобраннойПродукции(ЭтотОбъект, КэшированныеЗначения);
	КонецЕсли;
	
	Если ТребуетсяОбновитьИнформациюНедопустимыеКодыМаркировки Тогда
		ПроверкаИПодборПродукцииИСМПКлиентСервер.ОтобразитьИнформациюОНедопустимыхКодахМаркировки(ЭтотОбъект);
	КонецЕсли;
	
КонецПроцедуры

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

#Область ОбработчикиСобытийЭлементовТаблицыФормыПодобраннаяМаркируемаяПродукция

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	ТекущиеДанные = Элемент.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если Поле = Элемент.ПодчиненныеЭлементы.ПодобраннаяМаркируемаяПродукцияНоменклатура
		И ТекущиеДанные.НоменклатураСопоставлена
		И (Не
			(ЭтоДокументПриобретения
			И (ТекущиеДанные.НоменклатураСопоставленаПоУПД
				Или Лев(ТекущиеДанные.GTIN, 3) = ИнтеграцияИСМПСлужебныйКлиентСервер.НачалоGTINМаркировкиОстатков()
				)
			)
		) Тогда
		СтандартнаяОбработка = Ложь;
		ПоказатьЗначение(, ТекущиеДанные.Номенклатура);
	ИначеЕсли Поле = Элементы.ПодобраннаяМаркируемаяПродукцияGTIN Тогда
		Если ТекущиеДанные.КодыGTIN.Количество() > 1 Тогда
			СтандартнаяОбработка = Ложь;
			ПоказатьЗначение(, ТекущиеДанные.КодыGTIN);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияПриАктивизацииСтроки(Элемент)
	
	ТекущиеДанные = Элемент.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияПередУдалением(Элемент, Отказ)
	
	ТекущиеДанные = Элементы.ПодобраннаяМаркируемаяПродукция.ТекущиеДанные;
	
	Если ТекущиеДанные.Количество > 0 ИЛИ ТекущиеДанные.КоличествоИС > 0 Тогда
		
		ТекстПредупреждения = НСтр("ru = 'Удалять можно только строки с нулевым количеством.'");
		ПоказатьПредупреждение(, ТекстПредупреждения);
		Отказ = Истина;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияПослеУдаления(Элемент)
	
	КоличествоСтрокПодобраннойТабачнойПродукции = ПодобраннаяМаркируемаяПродукция.Количество();
	
	ПроверкаИПодборПродукцииИСМПКлиентСервер.ПересчитатьНомераСтрок(ПодобраннаяМаркируемаяПродукция);
	
	Модифицированность = Истина;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
	
	Отказ = Истина;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
	
	ИмяТекущегоЭлемента = Элемент.ТекущийЭлемент.Имя;
	
	Если ИмяТекущегоЭлемента = "ПодобраннаяМаркируемаяПродукцияНоменклатура"
	 Или ИмяТекущегоЭлемента = "ПодобраннаяМаркируемаяПродукцияХарактеристика"
	 Или ИмяТекущегоЭлемента = "ПодобраннаяМаркируемаяПродукцияСерия" Тогда
		НачатьРегистрациюИзмененийНоменклатурыВСтроке();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
	
	Если ОтменаРедактирования Тогда
		ОтменитьРегистрациюИзмененийНоменклатурыВСтроке();
	Иначе
		Модифицированность = Истина;
	КонецЕсли;
	
КонецПроцедуры

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

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияНоменклатураНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	СобытияФормИСКлиентПереопределяемый.ПриНачалеВыбораНоменклатуры(Элемент, ВидМаркируемойПродукции, СтандартнаяОбработка);
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияНоменклатураСоздание(Элемент, СтандартнаяОбработка)
	
	ТекущиеДанные = Элементы.ПодобраннаяМаркируемаяПродукция.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	СобытияФормИСМПКлиентПереопределяемый.ПриСозданииНоменклатуры(ЭтотОбъект,
		ТекущиеДанные, СтандартнаяОбработка, ВидМаркируемойПродукции);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияХарактеристикаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	ТекущиеДанные = Элементы.ПодобраннаяМаркируемаяПродукция.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	СобытияФормИСМПКлиентПереопределяемый.ПриНачалеВыбораХарактеристики(ЭтотОбъект,
		ТекущиеДанные, СтандартнаяОбработка);
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобраннаяМаркируемаяПродукцияХарактеристикаСоздание(Элемент, СтандартнаяОбработка)
	
	ТекущиеДанные = Элементы.ПодобраннаяМаркируемаяПродукция.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	СобытияФормИСМПКлиентПереопределяемый.ПриСозданииХарактеристики(ЭтотОбъект,
		ТекущиеДанные, Элемент, СтандартнаяОбработка);
	
КонецПроцедуры

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

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

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

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

#Область ОбработчикиКомандФормы

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

&НаКлиенте
Процедура ПроверкаЗавершена(Команда)
	
	ПроверкаЗавершенаКлиент();
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьМаркированнуюУпаковку(Команда)
	
	ПараметрыОткрытияФормы = Новый Структура;
	ПараметрыОткрытияФормы.Вставить("АдресПредыдущихШтрихкодов", АдресПредыдущихШтрихкодов);
	ПараметрыОткрытияФормы.Вставить("ДоступныеТипыШтрихкодовСтрокой",
		ПроверкаИПодборПродукцииМОТПКлиент.ДоступныеТипыШтрихкодовСтрокой());
	ПервыйТипШтрихкодаСтрокой = ПараметрыОткрытияФормы.ДоступныеТипыШтрихкодовСтрокой.Получить(0).Значение;
	ПараметрыОткрытияФормы.Вставить("ТипШтрихкода",  ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.ТипШтрихкодаПоСтроке(ПервыйТипШтрихкодаСтрокой));
	
	ОповещениеПослеГенерацииШтрихкодаУпаковки = Новый ОписаниеОповещения("ПослеГенерацииШтрихкодаДляНовойУпаковки", ЭтотОбъект);
	
	ОткрытьФорму("Обработка.ГенерацияШтрихкодовУпаковок.Форма.Форма", ПараметрыОткрытияФормы, ЭтотОбъект,,,,
	             ОповещениеПослеГенерацииШтрихкодаУпаковки, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ЗагрузитьИзТСД(Команда)
	
	ОчиститьСообщения();
	
	МенеджерОборудованияИСКлиент.НачатьЗагрузкуДанныеИзТСД(
		Новый ОписаниеОповещения("ЗагрузитьИзТСДЗавершение", ЭтотОбъект),
		УникальныйИдентификатор);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ЗагрузитьИзВнешнегоФайла(Команда)
	
	ОчиститьСообщения();
	
	ДоступнаИерархия = (ЭтоДокументМаркировка(ЭтотОбъект) Или ЭтоДокументПриобретения);
	
	ИнтеграцияИСКлиент.ОткрытьФормуЗагрузкиКодовМаркировки(
		ЭтотОбъект,
		ДоступнаИерархия,
		ИнтеграцияИСМПКлиент.ЗаголовокФормыЗагрузкиКодовМаркировки(
			ЭтотОбъект, Истина)); // ДоступнаИерархия Истина - для упрощения заголовка
	
КонецПроцедуры

&НаКлиенте
Процедура СгенерироватьСерии(Команда)
	
	ОчиститьСообщения();
	
	Если НЕ ПроверкаИПодборПродукцииИСМПКлиентСервер.ТребуетсяУказаниеСерий(ПодобраннаяМаркируемаяПродукция) Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(
			НСтр("ru = 'Отсутствует табачная продукция, для которой требуется генерация серий.'"));
		Возврат;
	КонецЕсли;
	
	СгенерироватьСерииПодобраннойТабачнойПродукции();
	
	Модифицированность = Истина;
	
КонецПроцедуры

&НаКлиенте
Процедура ВключитьОтключитьКонтрольСтатусовКодовМаркировки(Команда)
	
	Если Не ПараметрыПроверкиКодовМаркировки.КонтролироватьСтатусыКодовМаркировки
		И Не ПараметрыПроверкиКодовМаркировки.КонтролироватьВладельцевКодовМаркировки Тогда
		// оба контроля были выключены
		
		ПроверкаСостоянияКодовМаркировки();
		
		ПараметрыПроверкиКодовМаркировки.КонтролироватьСтатусыКодовМаркировки = Не ПараметрыПроверкиКодовМаркировки.КонтролироватьСтатусыКодовМаркировки;
		УстановитьЗаголовокКомандыПроверкиСтатусовКодовМаркировки(ЭтотОбъект);
		Возврат;
		
	КонецЕсли;
	
	ПараметрыПроверкиКодовМаркировки.КонтролироватьСтатусыКодовМаркировки = Не ПараметрыПроверкиКодовМаркировки.КонтролироватьСтатусыКодовМаркировки;
	
	УстановитьЗаголовокКомандыПроверкиСтатусовКодовМаркировки(ЭтотОбъект);
	
	ПроверитьСтатусыКодовМаркировки();
	
КонецПроцедуры

&НаКлиенте
Процедура ВключитьОтключитьКонтрольПоВладельцу(Команда)
	
	Если Не ПараметрыПроверкиКодовМаркировки.КонтролироватьСтатусыКодовМаркировки
		И Не ПараметрыПроверкиКодовМаркировки.КонтролироватьВладельцевКодовМаркировки Тогда
		// оба контроля были выключены
		
		ПроверкаСостоянияКодовМаркировки();
		
		ПараметрыПроверкиКодовМаркировки.КонтролироватьВладельцевКодовМаркировки = Не ПараметрыПроверкиКодовМаркировки.КонтролироватьВладельцевКодовМаркировки;
		УстановитьЗаголовокКомандыПроверкиПоВладельцу(ЭтотОбъект);
		Возврат;
		
	КонецЕсли;
	
	ПараметрыПроверкиКодовМаркировки.КонтролироватьВладельцевКодовМаркировки = Не ПараметрыПроверкиКодовМаркировки.КонтролироватьВладельцевКодовМаркировки;
	
	УстановитьЗаголовокКомандыПроверкиПоВладельцу(ЭтотОбъект);
	
	ПроверитьСтатусыКодовМаркировки();
	
КонецПроцедуры

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

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

&НаКлиенте
Процедура СкрытьПроверенные(Команда)
	
	СкрытьПроверенные = Не СкрытьПроверенные;
	Элементы.ДеревоМаркированнойПродукцииСкрытьПроверенные.Пометка = СкрытьПроверенные;
	
	Если СкрытьПроверенные Тогда
		СкрытьПроверенныеСтрокиДерева(ЭтотОбъект);
	Иначе
		ПроверитьПризнакУстановкиОтбораВДереве(ЭтотОбъект);
	КонецЕсли;
	
	ОбновитьОтображениеДанных();
	
КонецПроцедуры

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

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

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

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

&НаКлиенте
Процедура ЗаполнитьКодыМаркировки(Команда)
	
	Если ПараметрыСканирования.Свойство("ТребоватьПолныйКодМаркировкиИСМП")
		И ПараметрыСканирования.ТребоватьПолныйКодМаркировкиИСМП
		И ПараметрыСканирования.Свойство("ПроверятьСтруктуруКодовМаркировки")
		И ПараметрыСканирования.ПроверятьСтруктуруКодовМаркировки Тогда
		ПоказатьПредупреждение(,
			НСтр("ru = 'В настройках сканирования кодов маркировки включена опция ""Проверять структуру кодов маркировки"".
			|В данном режиме необходимо осуществлять ввод полного кода маркировки путем его сканирования.'"));
		Возврат;
	КонецЕсли;
	
	ВариантыЗаполнения = Новый СписокЗначений;
	Если ПроверкаИПодборПродукцииИСМПКлиентСервер.ЭтоДокументРеализации(ПроверяемыйДокумент)
		Или ИнтеграцияИСМПКлиентСервер.ОперацииУточненияСведенийОКодахМаркировки().Найти(ПараметрыСканирования.ВидОперацииИСМП) <> Неопределено  Тогда
		Если ЕстьПравоЧтениеДокументаМаркировкаТоваров Тогда
			ВариантыЗаполнения.Добавить("ПоОтчетамОНанесении", НСтр("ru = 'По отчетам о нанесении'"));
		КонецЕсли;
	Иначе
		Если ЕстьПравоЧтениеДокументаЗаказНаЭмиссиюКодовМаркировки Тогда
			ВариантыЗаполнения.Добавить("ПоЗаказамНаЭмиссию", НСтр("ru = 'По заказам на эмиссию'"));
		КонецЕсли;
	КонецЕсли;
	
	ПроверкаИПодборПродукцииИСМПКлиентПереопределяемый.ПриОпределенииВариантовЗаполненияКодовМаркировки(
		ЭтотОбъект, ВариантыЗаполнения);
	
	Если ВариантыЗаполнения.Количество() Тогда
		
		ВариантыЗаполнения.Добавить(КодВозвратаДиалога.Отмена);
		ПоказатьВопрос(
			Новый ОписаниеОповещения(
				"Подключаемый_ПослеВопросаЗагрузкиКодовПоОснованию", ЭтотОбъект),
			НСтр("ru = 'Заполнить коды маркировки?'"), ВариантыЗаполнения);
		
	Иначе
		
		ПоказатьПредупреждение(, НСтр("ru = 'Нет доступных вариантов заполнения'"));
		
	КонецЕсли;
	
КонецПроцедуры

#Область КомандыУстановкиСтатуса

&НаКлиенте
Процедура УстановитьСтатусПроверкиВНаличии(Команда)
	
	УстановитьСтатусДляВыделенныхСтрок(Элементы.ДеревоМаркированнойПродукции.ВыделенныеСтроки,
	                                  ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.ВНаличии"),, КэшированныеЗначения);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьСтатусПроверкиНеПроверялась(Команда)
	
	УстановитьСтатусДляВыделенныхСтрок(Элементы.ДеревоМаркированнойПродукции.ВыделенныеСтроки,
	                                  ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеПроверялась"),, КэшированныеЗначения);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьСтатусПроверкиОтложена(Команда)
	
	УстановитьСтатусДляВыделенныхСтрок(Элементы.ДеревоМаркированнойПродукции.ВыделенныеСтроки,
	                                  ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.Отложена"),, КэшированныеЗначения);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьСтатусПроверкиОтсутствует(Команда)
	
	УстановитьСтатусДляВыделенныхСтрок(Элементы.ДеревоМаркированнойПродукции.ВыделенныеСтроки,
	                                  ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.Отсутствует"),, КэшированныеЗначения);
	
КонецПроцедуры

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

#Область ПодключаемыеПереопределяемыеКоманды

//@skip-warning
&НаКлиенте
Процедура Подключаемый_ВыполнитьПереопределяемуюКоманду(Команда)
	СобытияФормИСМПКлиент.ВыполнитьПереопределяемуюКоманду(ЭтотОбъект, Команда, Неопределено);
КонецПроцедуры

&НаСервере
Процедура Подключаемый_ВыполнитьПереопределяемуюКомандуНаСервере(Контекст, Результат) Экспорт
	СобытияФормИСМП.ВыполнитьПереопределяемуюКоманду(ЭтотОбъект, Контекст, Неопределено, Результат);
КонецПроцедуры

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

&НаКлиенте
Процедура УточнитьДанныеПоШтрихкоду(Команда)
	
	ТекущаяСтрокаДерева = Элементы.ДеревоМаркированнойПродукции.ТекущиеДанные;
	Если ТекущаяСтрокаДерева = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ТекущаяСтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
		ОткрытьФормуУточненияДанных(ТекущаяСтрокаДерева.ПолучитьИдентификатор(), ТекущаяСтрокаДерева, Истина);
	Иначе
		ОбщегоНазначенияКлиент.СообщитьПользователю(
			НСтр("ru = 'Операция недоступна для выбранного объекта'"));
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПропуститьОшибкуОбработкиВГИСМТ(Команда)
	
	ВыделенныеСтроки = Элементы.ДеревоМаркированнойПродукции.ВыделенныеСтроки;
	
	КоличествоКОбработке = ВыделенныеСтроки.Количество();
	КоличествоОбработанныхСтрок = 0;
	
	Если ВыделенныеСтроки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	ОбновитьИнформациюОНедопустимыхКодах = Ложь;
	Для Каждого ИдентификаторВыделеннойСтроки Из ВыделенныеСтроки Цикл
		
		ДанныеСтроки = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторВыделеннойСтроки);
		
		Если ДанныеСтроки = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если ДанныеСтроки.ОбработанСОшибкойВГИСМТ Тогда
			
			ДанныеСтроки.ОбработанСОшибкойВГИСМТ             = Ложь;
			ДанныеСтроки.ТекстОбработанСОшибкойВГИСМТ        = "";
			ДанныеСтроки.ПредставлениеПроверкиКодаМаркировки = "";
			
			Если ДанныеСтроки.НедопустимыйКодМаркировки Тогда
				ДанныеСтроки.НедопустимыйКодМаркировки = Ложь;
				КоличествоНедопустимыхКодовМаркировки = КоличествоНедопустимыхКодовМаркировки - 1;
				ОбновитьИнформациюОНедопустимыхКодах = Истина;
			КонецЕсли;
			
			ПроверкаИПодборПродукцииИСМПКлиентСервер.УстановитьИндексКартинкиСтатусаПроверки(ДанныеСтроки);
			КоличествоОбработанныхСтрок = КоличествоОбработанныхСтрок + 1;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Если ОбновитьИнформациюОНедопустимыхКодах Тогда
		ПроверкаИПодборПродукцииИСМПКлиентСервер.ОтобразитьИнформациюОНедопустимыхКодахМаркировки(ЭтотОбъект);
	КонецЕсли;
	
	ОповеститьПользователяОИзмененииСтрокиСОШибкойОбработкиГИСМТ(КоличествоОбработанныхСтрок, КоличествоКОбработке);
	
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьСопоставление(Команда)
	
	ВыделенныеСтроки = Элементы.ДеревоМаркированнойПродукции.ВыделенныеСтроки;
	
	Если ВыделенныеСтроки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ОчиститьСопоставлениеНаСервере(ВыделенныеСтроки);
	
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСостояниеКодовМаркировкиНемедленно(Команда)
	
	ПроверкаСостоянияКодовМаркировки();
	
КонецПроцедуры

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

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

#Область Серии

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

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

#Область УстановкаОтбораСкрытьПроверенные

&НаКлиентеНаСервереБезКонтекста
Процедура СкрытьПроверенныеСтрокиДерева(Форма)

	Если Форма.УстановленОтборТребуетсяПеремаркировать Тогда
		Форма.УстановленОтборТребуетсяПеремаркировать = Ложь;
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ОтобразитьИнформациюОНеобходимостиПеремаркировки(Форма);
	КонецЕсли;

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

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

&НаКлиентеНаСервереБезКонтекста
Процедура СкрытьПроверенныеВСтрокеДерева(Форма, СтрокаДерева, СоответствуетОтбору)
	
	ПодчиненныеСтроки = СтрокаДерева.ПолучитьЭлементы();

	ТекущаяСтрокаСоответствуетОтбору = Ложь;
	
	Для Каждого ПодчиненнаяСтрока Из ПодчиненныеСтроки Цикл
		
		СоответствуетОтбору = Ложь;
		
		СкрытьПроверенныеВСтрокеДерева(Форма, ПодчиненнаяСтрока, СоответствуетОтбору);
		
		Если СоответствуетОтбору Тогда
			ТекущаяСтрокаСоответствуетОтбору = Истина;
		КонецЕсли;
		
	КонецЦикла;

	Если Не ТекущаяСтрокаСоответствуетОтбору Тогда
		
		ТекущаяСтрокаСоответствуетОтбору = СтрокаДерева.СтатусПроверки <> ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.ВНаличии")
			И СтрокаДерева.СтатусПроверки <> ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась");
		
	КонецЕсли;
	
	СоответствуетОтбору = ТекущаяСтрокаСоответствуетОтбору;
	СтрокаДерева.НеСоответствуетОтбору = Не СоответствуетОтбору;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ПроверитьПризнакУстановкиОтбораВДереве(Форма)
	
	Если Форма.КоличествоУпаковокКоторыеНеобходимоПеремаркировать = 0 Тогда
		Форма.УстановленОтборТребуетсяПеремаркировать = Ложь;
	КонецЕсли;
	
	Если Форма.КоличествоНедопустимыхКодовМаркировки = 0 Тогда
		Форма.УстановленОтборНедопустимыеКодыМаркировки = Ложь;
	КонецЕсли;
	
	Форма.УстановленОтбор = (Форма.СкрытьПроверенные
		Или Форма.УстановленОтборТребуетсяПеремаркировать
		Или Форма.УстановленОтборНедопустимыеКодыМаркировки);

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

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

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

#Область ОтборНедопустимыеКодыМаркировки

&НаКлиенте
Процедура УстановитьОтборНедопустимыеКодыМаркировки()
	
	Если СкрытьПроверенные Тогда
		СкрытьПроверенные = Ложь;
		Элементы.ДеревоМаркированнойПродукцииСкрытьПроверенные.Пометка = Ложь;
	КонецЕсли;

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

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

	Если Не ТекущаяСтрокаСоответствуетОтбору Тогда
		ТекущаяСтрокаСоответствуетОтбору = СтрокаДерева.НедопустимыйКодМаркировки;
	КонецЕсли;
	
	СоответствуетОтбору = ТекущаяСтрокаСоответствуетОтбору;
	СтрокаДерева.НеСоответствуетОтбору = Не СоответствуетОтбору;
	
КонецПроцедуры

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

#Область ИзменениеСтатуса

&НаКлиенте
Процедура УстановитьСтатусДляВыделенныхСтрок(ВыделенныеСтроки, НовыйСтатус, ЭтоВосстановлениеДетализации = Ложь, КэшированныеЗначения)
	
	КоличествоКОбработке = ВыделенныеСтроки.Количество();
	КоличествоОбработанныхСтрок = 0;
	МассивУпаковокСИзменившимсяСоставом = Новый Массив;
	
	Для Каждого ИдентификаторВыделеннойСтроки Из ВыделенныеСтроки Цикл
		
		ДанныеСтроки = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторВыделеннойСтроки);
		
		Если ДанныеСтроки = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если Не ЭтоВосстановлениеДетализации Тогда

			Если ДанныеСтроки.НедопустимыйКодМаркировки Тогда
				Продолжить;
			КонецЕсли;

			Если ДанныеСтроки.СтатусПроверки = НовыйСтатус Тогда
				Продолжить;
			КонецЕсли;

			Если ДанныеСтроки.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
				Или ДанныеСтроки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
				Продолжить;
			КонецЕсли;

			Если ДанныеСтроки.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась") Тогда
				Продолжить;
			КонецЕсли;

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

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

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьСтатусОтсутствуетДляПодчиненных(Форма, СтрокаДерева)
	 
	Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.ПолучитьЭлементы() Цикл
		
		УстановитьСтатусОтсутствуетДляСтрокиДерева(Форма, ПодчиненнаяСтрока);
		
	КонецЦикла;
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(СтрокаДерева, Ложь, Форма.ЗагрузкаДанныхТСД);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(СтрокаДерева, Форма.ЗагрузкаДанныхТСД);
	
КонецПроцедуры

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

&НаКлиентеНаСервереБезКонтекста
Функция УстановкаСтатусаОтсутствуетВозможна(ТекущиеДанные)
	
	Для Каждого ПодчиненнаяСтрока Из ТекущиеДанные.ПолучитьЭлементы() Цикл
		
		Если ПодчиненнаяСтрока.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась") Тогда
			
			Возврат Ложь;
			
		КонецЕсли;
		
		Если Не УстановкаСтатусаОтсутствуетВозможна(ПодчиненнаяСтрока) Тогда
			
			Возврат Ложь;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Истина;
	
КонецФункции

&НаКлиенте
Процедура ОповеститьПользователяОИзмененииСтатусаПроверки(НовыйСтатус, КоличествоОбработанных, КоличествоВсего)

	ШаблонЗаголовкаОбработано   = НСтр("ru='Статус проверки ""%1"" установлен'");
	ШаблонСообщенияОбработано   = НСтр("ru='Для %1 из %2 выделенных в списке строк установлен статус проверки ""%3""'");
	ШаблонЗаголовкаНеОбработано = НСтр("ru='Статус проверки ""%1"" не установлен'");
	ШаблонСообщенияНеОбработано = НСтр("ru='Статус проверки ""%1"" не установлен ни для одной строки.'");
	
	Если КоличествоОбработанных > 0 Тогда
		
		ТекстЗаголовка = СтрШаблон(ШаблонЗаголовкаОбработано, НовыйСтатус);
		ТекстСообщения = СтрШаблон(ШаблонСообщенияОбработано,
		                           КоличествоОбработанных,
		                           КоличествоВсего,
		                           НовыйСтатус);
		
	Иначе
		
		ТекстЗаголовка = СтрШаблон(ШаблонЗаголовкаНеОбработано, НовыйСтатус);
		ТекстСообщения = СтрШаблон(ШаблонСообщенияНеОбработано, НовыйСтатус);
		
	КонецЕсли;
	
	ПоказатьОповещениеПользователя(ТекстЗаголовка,, ТекстСообщения, БиблиотекаКартинок.Информация32ГосИС);
	
КонецПроцедуры

&НаКлиенте
Процедура ОповеститьПользователяОИзмененииСтрокиСОШибкойОбработкиГИСМТ(КоличествоОбработанных, КоличествоВсего)

	ТекстЗаголовка   = НСтр("ru='Пропустить ошибку обработки в ГИС МТ'");
	ШаблонСообщенияОбработано   = НСтр("ru='Для %1 из %2 выделенных в списке строк снят признак обработки с ошибкой'");
	
	ТекстСообщения = СтрШаблон(ШаблонСообщенияОбработано,
	                           КоличествоОбработанных,
	                           КоличествоВсего);
	
	ПоказатьОповещениеПользователя(ТекстЗаголовка,, ТекстСообщения, БиблиотекаКартинок.Информация32ГосИС);
	
КонецПроцедуры

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

#Область ПересчетИтогов

&НаСервере
Процедура ПересчитатьВсеИтогиФормыНаСервере()
	
	ПроверкаИПодборПродукцииМОТП.ПересчитатьХешСуммыВсехУпаковок(ЭтотОбъект);
	
	ПересчитатьВсеИтогиФормы(ЭтотОбъект);
	
КонецПроцедуры

&НаКлиенте
Процедура ПересчитатьВсеИтогиФормыНаКлиенте()
	
	ПроверкаИПодборПродукцииМОТПКлиент.ПересчитатьХешСуммыВсехУпаковок(ЭтотОбъект);
	
	ПересчитатьВсеИтогиФормы(ЭтотОбъект);
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ПересчитатьВсеИтогиФормы(Форма)
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковок(Форма.ДеревоМаркированнойПродукции);
	ПроверкаИПодборПродукцииИСМПКлиентСервер.ОпределитьТипыВсехУпаковок(Форма.ДеревоМаркированнойПродукции, ПроверкаИПодборПродукцииМОТПКлиентСервер);
	
	Форма.КоличествоСтрокПодобраннойТабачнойПродукции = Форма.ПодобраннаяМаркируемаяПродукция.Количество();
	
	СформироватьПредставлениеНастроек(Форма);
	
	ШтрихкодированиеИСКлиентСервер.ОтобразитьСохраненныйВыборПоМаркируемойПродукции(Форма);
	
КонецПроцедуры

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

#Область Перемаркировка

&НаКлиенте
Процедура ПослеГенерацииШтрихкодаДляНовойУпаковки(Результат, ДополнительныеПараметры) Экспорт

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

&НаКлиенте
Процедура ПослеПеремаркировкиУпаковки(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Отказ = Ложь;
	ПроверитьКорректностьШтрихкодаПриДобавлении(Результат.Штрихкод, Отказ);
	
	Если Отказ Тогда
		Возврат;
	КонецЕсли;
	
	АдресПредыдущихШтрихкодов = Результат.АдресПредыдущихШтрихкодов;
	
	ПеремаркироватьУпаковку(Результат.Штрихкод, ДополнительныеПараметры.ИдентификаторСтроки);
	
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьКорректностьШтрихкодаПриДобавлении(Штрихкод, Отказ)
	
	Если ПустаяСтрока(Штрихкод) Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Упаковке не может быть назначен пустой Штрихкод.'"));
		Отказ = Истина;
		Возврат;
	КонецЕсли;
	
	ИдентификаторСтроки = СоответствиеШтрихкодовСтрокДерева.Получить(Штрихкод);
	
	Если ИдентификаторСтроки <> Неопределено Тогда
		
		ТекстСообщения = СтрШаблон(
			НСтр("ru = 'Штрихкодом %1 уже маркирована другая упаковка. Маркируйте данную упаковку другим штрихкодом.'"),
			ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.ПредставлениеШтрихкода(Штрихкод));
		
		ПоказатьПредупреждение(,ТекстСообщения);
		Отказ = Истина;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПеремаркироватьУпаковку(Штрихкод, ИдентификаторСтрокиУпаковки)
	
	СтрокаСУпаковкой = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторСтрокиУпаковки);
	
	Если СтрокаСУпаковкой = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ЗаменитьШтрихКодВСпискахУпаковок(ЭтотОбъект,СтрокаСУпаковкой.Штрихкод, Штрихкод);
	СоответствиеШтрихкодовСтрокДерева.Удалить(СтрокаСУпаковкой.НормализованныйШтрихкод);
	СтрокаСУпаковкой.Штрихкод = Штрихкод;
	СоответствиеШтрихкодовСтрокДерева.Вставить(СтрокаСУпаковкой.Штрихкод, ИдентификаторСтрокиУпаковки);
	
	Если СтрокаСУпаковкой.ТребуетсяПеремаркировка Тогда
		ПроверятьНеобходимостьПеремаркировки = Истина;
	КонецЕсли;
	
	ПроверкаИПодборПродукцииИСМПКлиентСервер.СформироватьПредставлениеДляСтрокиДереваМаркированнойПродукции(СтрокаСУпаковкой, ВидМаркируемойПродукции);
	
	ПриИзмененииМаркировкиСоставаУпаковкиНаКлиенте(ИдентификаторСтрокиУпаковки, Ложь);
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ЗаменитьШтрихКодВСпискахУпаковок(Форма, СтарыйШтрихкод, НовыйШтрихкод)

	ИзменитьЗначениеШтрихкодаВСписке(СтарыйШтрихкод, НовыйШтрихкод, Форма.ДобавленныеУпаковки);
	ИзменитьЗначениеШтрихкодаВСписке(СтарыйШтрихкод, НовыйШтрихкод, Форма.ДоступныеДляПроверкиУпаковки);
	ИзменитьЗначениеШтрихкодаВСписке(СтарыйШтрихкод, НовыйШтрихкод, Форма.УпаковкиДокумента);

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

&НаКлиентеНаСервереБезКонтекста
Процедура ИзменитьЗначениеШтрихкодаВСписке(СтарыйШтрихкод, НовыйШтрихкод, СписокШтрихкодов)
	
	НайденныйЭлемент = СписокШтрихкодов.НайтиПоЗначению(СтарыйШтрихкод);
	
	Если НайденныйЭлемент <> Неопределено Тогда
		
		СписокШтрихкодов.Удалить(НайденныйЭлемент);
		СписокШтрихКодов.Добавить(НовыйШтрихкод);
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПриИзмененииМаркировкиСоставаУпаковкиНаСервере(ИдентификаторСтрокиУпаковки, ПроверятьТипУпаковки, КэшированныеЗначения)

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

&НаКлиенте
Процедура ПриИзмененииМаркировкиСоставаУпаковкиНаКлиенте(ИдентификаторСтрокиУпаковки, ПроверятьТипУпаковки)

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

&НаСервере
Процедура ПриИзмененииМаркировкиСоставаУпаковкиМассиваСтрок(МассивСтрок, ПроверятьТипУпаковки, КэшированныеЗначения)

	Если ПроверятьНеобходимостьПеремаркировки Тогда
		Для Каждого СтрокаМассива Из МассивСтрок Цикл
			ПроверитьНеобходимостьМаркировкиПриИзмененииСтроки(СтрокаМассива);
		КонецЦикла
	КонецЕсли;
	
	Если ПроверятьТипУпаковки Тогда
		Для Каждого СтрокаМассива Из МассивСтрок Цикл
			ПроверкаИПодборПродукцииИСМПКлиентСервер.ОпределитьТипУпаковкиПриИзмененииСтроки(
				ДеревоМаркированнойПродукции, СтрокаМассива, ПроверкаИПодборПродукцииМОТПКлиентСервер);
		КонецЦикла;
	КонецЕсли;

	ОбработатьТаблицуИзмененийПодобраннойПродукции(ЭтотОбъект, КэшированныеЗначения);
	
КонецПроцедуры

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

&НаСервере
Процедура ПроверитьНеобходимостьМаркировкиПриИзмененииСтроки(ИдентификаторИзмененнойСтроки)

	ИзмененнаяСтрока = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторИзмененнойСтроки);
	
	Если ИзмененнаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ТаблицаХешСумм = ПроверкаИПодборПродукцииИС.ПустаяТаблицаХешСумм();
	
	Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(ИзмененнаяСтрока.ТипУпаковки) Тогда
		ПроверкаИПодборПродукцииИС.РассчитатьХешСуммыУпаковки(
			ИзмененнаяСтрока, ТаблицаХешСумм, Ложь,,,
			"КоличествоПодчиненныхПотребительскихУпаковок");
	КонецЕсли;
	
	РодительИзмененнойСтроки = ИзмененнаяСтрока.ПолучитьРодителя();
	
	Пока РодительИзмененнойСтроки <> Неопределено 
		И ИнтеграцияИСКлиентСервер.ЭтоУпаковка(РодительИзмененнойСтроки.ТипУпаковки) Цикл
		
		ПроверкаИПодборПродукцииИС.РассчитатьХешСуммыУпаковки(
			РодительИзмененнойСтроки, ТаблицаХешСумм, Ложь,,,
			"КоличествоПодчиненныхПотребительскихУпаковок");
		РодительИзмененнойСтроки = РодительИзмененнойСтроки.ПолучитьРодителя();
		
	КонецЦикла;
	
	ШтрихкодИДанныеУпаковки = Неопределено;
	ТаблицаПеремаркировки = ПроверкаИПодборПродукцииИС.ТаблицаПеремаркировки(ТаблицаХешСумм, ШтрихкодИДанныеУпаковки);
	
	// Обход ошибки расчета хеш суммы без учета поля ХешСуммыНормализации
	Для Каждого СтрокаПеремаркировки Из ТаблицаПеремаркировки Цикл
		
		Если СтрокаПеремаркировки.ТребуетсяПеремаркировка Тогда
			
			ТаблицаХешСуммБезУчетаХешСуммыНормализации = ПроверкаИПодборПродукцииИС.ПустаяТаблицаХешСумм();
			СтрокаДерева = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, СтрокаПеремаркировки.ИдентификаторВДереве);
			Если СтрокаДерева = Неопределено Тогда
				Продолжить;
			КонецЕсли;
			
			ПроверкаИПодборПродукцииИС.РассчитатьХешСуммыУпаковки(СтрокаДерева, ТаблицаХешСуммБезУчетаХешСуммыНормализации, Истина,, Ложь);
			
			Для Каждого СтрокаХешСуммы Из ТаблицаХешСуммБезУчетаХешСуммыНормализации Цикл
				
				ДанныеУпаковки = ШтрихкодИДанныеУпаковки[СтрокаХешСуммы.Штрихкод];
				Если ДанныеУпаковки = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				
				Если СтрокаХешСуммы.ХешСумма = ДанныеУпаковки.ХешСумма
					И ПустаяСтрока(СтрокаХешСуммы.ХешСумма) Тогда
					СтрокаПеремаркировки.ТребуетсяПеремаркировка = (СтрокаХешСуммы.СодержимоеОтсутствует
						И (ДанныеУпаковки.Количество <> 0 Или ДанныеУпаковки.КоличествоПотребительскихУпаковок <> 0));
				Иначе
					СтрокаПеремаркировки.ТребуетсяПеремаркировка = (СтрокаХешСуммы.ХешСумма <> ДанныеУпаковки.ХешСумма);
				КонецЕсли;
				
			КонецЦикла;
			
		КонецЕсли;
		
	КонецЦикла;
	
	ПроверкаИПодборПродукцииИС.ОбработататьТаблицуПеремаркировкиСУчетомДетализации(ЭтотОбъект, ТаблицаПеремаркировки, ШтрихкодИДанныеУпаковки);
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПроверитьНеобходимостьПеремаркировки(ЭтотОбъект, ТаблицаПеремаркировки, Истина);
	
КонецПроцедуры

&НаКлиенте
Функция СтрокаСУпаковкойДляПеремаркировки()
	
	ТекущиеДанные = Элементы.ДеревоМаркированнойПродукции.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		ПоказатьПредупреждение( , НСтр("ru = 'Спозиционируйтесь на упаковке, которую хотите перемаркировать.'"));
		Возврат Неопределено;
	КонецЕсли;
	
	Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(ТекущиеДанные.ТипУпаковки) Тогда
		
		Возврат ТекущиеДанные;
		
	Иначе
		
		РодительскаяСтрока = ТекущиеДанные.ПолучитьРодителя();
		Если РодительскаяСтрока = Неопределено Тогда
			Возврат Неопределено;
		КонецЕсли;
		
		Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(РодительскаяСтрока.ТипУпаковки) Тогда
			
			Возврат РодительскаяСтрока;
			
		Иначе
			
			Возврат Неопределено;
			
		КонецЕсли
		
	КонецЕсли;
	
КонецФункции

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

&НаКлиенте
Процедура ОпределитьКоличествоТребующихПеремаркировкиДляКоллекции(СтрокиДерева, КоличествоТребующихПеремаркировки)
	
	Для Каждого СтрокаДерева Из СтрокиДерева Цикл
		
		Если СтрокаДерева.ТребуетсяПеремаркировка Тогда
			КоличествоТребующихПеремаркировки = КоличествоТребующихПеремаркировки + 1;
		КонецЕсли;
		
		Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(СтрокаДерева.ТипУпаковки) Тогда 
			ОпределитьКоличествоТребующихПеремаркировкиДляКоллекции(СтрокаДерева.ПолучитьЭлементы(), КоличествоТребующихПеремаркировки);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ОпределитьКоличествоНедопустимыхКодовМаркировкиДляКоллекции(СтрокиДерева, КоличествоНедопустимыхКодов);
	
	Для Каждого СтрокаДерева Из СтрокиДерева Цикл
		
		Если СтрокаДерева.НедопустимыйКодМаркировки Тогда
			КоличествоНедопустимыхКодов = КоличествоНедопустимыхКодов + 1;
		КонецЕсли;
		
		ОпределитьКоличествоНедопустимыхКодовМаркировкиДляКоллекции(СтрокаДерева.ПолучитьЭлементы(), КоличествоНедопустимыхКодов);
		
	КонецЦикла;
	
КонецПроцедуры

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

&НаКлиентеНаСервереБезКонтекста
Процедура ДобавитьУпаковкуСтрокиВМассивИзмененныхУпаковок(СтрокаДерева, МассивУпаковокСИзменившимсяСоставом)
	
	СтрокаРодитель = СтрокаДерева.ПолучитьРодителя();

	Если СтрокаРодитель <> Неопределено
		И ИнтеграцияИСКлиентСервер.ЭтоУпаковка(СтрокаРодитель.ТипУпаковки) Тогда
		
		ИденитификаторСтрокиРодителя = СтрокаРодитель.ПолучитьИдентификатор();
		
		Если МассивУпаковокСИзменившимсяСоставом.Найти(ИденитификаторСтрокиРодителя) = Неопределено Тогда
			
			МассивУпаковокСИзменившимсяСоставом.Добавить(ИденитификаторСтрокиРодителя);
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

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

#Область ПроверкаСтатусаКодовМаркировки

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

&НаКлиенте
Процедура ПроверитьСтатусыКодовМаркировкиИзмененииФлагов() Экспорт
	ПроверкаСостоянияКодовМаркировки();
КонецПроцедуры

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

&НаКлиенте
Функция ОбновитьСтатусыКодовМаркировки(СообщатьОбОшибке = Истина, ПараметрыПроверки = Неопределено)
	
	Если СоответствиеШтрихкодовСтрокДерева.Количество() > 0 Тогда

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

	КонецЕсли;
	
	Для Каждого КлючИЗначение Из СоответствиеШтрихкодовСтрокДерева Цикл
		
		СтатусКодаМаркировки = РезультатЗапроса.СтатусыКодовМаркировки[КлючИЗначение.Ключ];
		
		Если СтатусКодаМаркировки = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		СтрокаДерева = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, КлючИЗначение.Значение);
		
		Если СтрокаДерева = Неопределено Тогда
			Продолжить;
		ИначеЕсли СтрокаДерева.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
			Или СтрокаДерева.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
			Продолжить;
		КонецЕсли;
		
		СтрокаДерева.СтатусКодаМаркировки             = СтатусКодаМаркировки.Статус;
		СтрокаДерева.ИННВладельца                     = СтатусКодаМаркировки.ИННВладельца;
		СтрокаДерева.РазрешительныйРежимИдентификаторЗапросаГИСМТ = СтатусКодаМаркировки.РазрешительныйРежимИдентификаторЗапросаГИСМТ;
		СтрокаДерева.РазрешительныйРежимДатаЗапросаГИСМТ          = СтатусКодаМаркировки.РазрешительныйРежимДатаЗапросаГИСМТ;
		
		Если СтатусКодаМаркировки.СписокОрганизацийБлокировкиКМ <> Неопределено Тогда
			СтрокаДерева.ОрганыБлокировкиКМ = СтрСоединить(
				ИнтерфейсИСМПОбщегоНазначенияКлиентСервер.ОрганыВластиУстанавливающиеБлокировкуНаКМПоДаннымГИСМТ(СтатусКодаМаркировки.СписокОрганизацийБлокировкиКМ));
		КонецЕсли;
		
	КонецЦикла;
	
	ПроверитьСтатусыКодовМаркировки(ПараметрыПроверки);
	
	Возврат Ложь;
	
КонецФункции

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

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

&НаКлиенте
Процедура ПроверитьСтатусыКодовМаркировкиПослеПолученияКлючаСессии(Результат, ПараметрыПроверки) Экспорт
	
	ОшибкаАвторизации  = Ложь;
	
	Если ТипЗнч(Результат) = Тип("Соответствие") Тогда
		РезультатАвторизации = Результат[Организация];
		
		Если РезультатАвторизации = Неопределено Тогда
			ОшибкаАвторизации = Истина;
			ТекстОшибки = НСтр("ru = 'Произошла ошибка при авторизации в ИС МП.'");
		ИначеЕсли РезультатАвторизации <> Истина Тогда
			ОшибкаАвторизации = Истина;
			ТекстОшибки = РезультатАвторизации;
		КонецЕсли;
	КонецЕсли;
	
	Если ОшибкаАвторизации Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстОшибки);
	Иначе
		
		ОбновитьСтатусыКодовМаркировки(Ложь, ПараметрыПроверки);
		
	КонецЕсли;
	
КонецПроцедуры

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

#Область НачальноеЗаполнение

&НаСервереБезКонтекста
Функция СоответствиеШтрихкодовСтрокДерева(АдресСоответствиеШтрихкодыИдентификаторыСтрок)
	
	Если ЭтоАдресВременногоХранилища(АдресСоответствиеШтрихкодыИдентификаторыСтрок) Тогда
		Возврат ПолучитьИзВременногоХранилища(АдресСоответствиеШтрихкодыИдентификаторыСтрок);
	Иначе
		Возврат Новый Соответствие;
	КонецЕсли;
	
КонецФункции

&НаКлиенте
Процедура ОбработкаОжиданияЗапросаКлючаСессии()
	
	ЗапроситьКлючСессииНачало();

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

&НаКлиенте
Процедура ОбработкаОжиданияПовторногоЗапросаКлючаСессии()
	
	ЗапроситьКлючСессииНачало(Истина);

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

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

&НаКлиенте
Процедура ЗапроситьКлючСессииРозницы(Результат, ДополнительныеПараметры) Экспорт
	
	ОтказОтАвторизации = Ложь;
	ОшибкаАвторизации  = Ложь;
	
	Если ТипЗнч(Результат) <> Тип("Соответствие") Тогда
		ОтказОтАвторизации = Истина;
	Иначе
		РезультатАвторизации = Результат[Организация];
		
		Если РезультатАвторизации = Неопределено Тогда
			ОшибкаАвторизации = Истина;
			ТекстОшибки = НСтр("ru = 'Произошла ошибка при авторизации в ИС МП.'");
		ИначеЕсли РезультатАвторизации <> Истина Тогда
			ОшибкаАвторизации = Истина;
			ТекстОшибки = РезультатАвторизации;
		ИначеЕсли ТребуетсяОбновлениеКлючаСессииРозница Тогда
			ТребуетсяОбновлениеКлючаСессииРозница = Ложь;
		КонецЕсли;
	КонецЕсли;
	
	ПовторныйЗапрос                = Ложь;
	ЭтоВосстановлениеДетализации   = Ложь;
	
	Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда
		ДополнительныеПараметры.Свойство("ПовторныйЗапрос",              ПовторныйЗапрос);
		ДополнительныеПараметры.Свойство("ЭтоВосстановлениеДетализации", ЭтоВосстановлениеДетализации);
	КонецЕсли;
	
	Если ПовторныйЗапрос Тогда
		Если ОтказОтАвторизации ИЛИ ОшибкаАвторизации Тогда
			ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстОшибки);
		Иначе
			ПриПодключенииКСервисуМОТП();
		КонецЕсли;
	ИначеЕсли ОтказОтАвторизации Тогда
		ЗакрытьФорму();
	ИначеЕсли ОшибкаАвторизации Тогда
		ПриОшибкеПодключенияКСервисуМОТП(ТекстОшибки, ЭтоВосстановлениеДетализации);
	Иначе
		ЗапроситьКлючСессииНачало(ПовторныйЗапрос, ДополнительныеПараметры.ПослеПолученияКлючаСессииРозницы, ЭтоВосстановлениеДетализации);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ЗапроситьКлючСессииЗавершение(Результат, ДополнительныеПараметры) Экспорт
	
	ОтказОтАвторизации = Ложь;
	ОшибкаАвторизации  = Ложь;
	
	Если ТипЗнч(Результат) <> Тип("Соответствие") Тогда
		ОтказОтАвторизации = Истина;
	Иначе
		РезультатАвторизации = Результат[Организация];
		
		Если РезультатАвторизации = Неопределено Тогда
			ОшибкаАвторизации = Истина;
			ТекстОшибки = НСтр("ru = 'Произошла ошибка при авторизации в ИС МОТП.'");
		ИначеЕсли РезультатАвторизации <> Истина Тогда
			ОшибкаАвторизации = Истина;
			ТекстОшибки = РезультатАвторизации;
		Иначе
			Если ТребуетсяОбновлениеКлючаСессии Тогда
				ТребуетсяОбновлениеКлючаСессии = Ложь;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	ПовторныйЗапрос              = Ложь;
	ЭтоВосстановлениеДетализации = Ложь;
	СозданиеАктаПриЗакрытии = Ложь;
	
	Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда
		Если ДополнительныеПараметры.Свойство("ПовторныйЗапрос") Тогда
			ПовторныйЗапрос = ДополнительныеПараметры.ПовторныйЗапрос;
		КонецЕсли;
		Если ДополнительныеПараметры.Свойство("ЭтоВосстановлениеДетализации") Тогда
			ЭтоВосстановлениеДетализации = ДополнительныеПараметры.ЭтоВосстановлениеДетализации;
		КонецЕсли;
		СозданиеАктаПриЗакрытии = ДополнительныеПараметры.Свойство("СоздаватьАктОРасхожденияхПриЗакрытии");
	КонецЕсли;
	
	Если ПовторныйЗапрос Тогда
		Если ОтказОтАвторизации Или ОшибкаАвторизации Тогда
			ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстОшибки);
		Иначе
			ПриПодключенииКСервисуМОТП();
		КонецЕсли;
	ИначеЕсли ОтказОтАвторизации Тогда
		ЗакрытьФорму();
	ИначеЕсли ОшибкаАвторизации Тогда
		ПриОшибкеПодключенияКСервисуМОТП(ТекстОшибки, ЭтоВосстановлениеДетализации);
	ИначеЕсли СозданиеАктаПриЗакрытии Тогда
		ЗавершитьПроверку(ДополнительныеПараметры.СоздаватьАктОРасхожденияхПриЗакрытии);
	Иначе
		ЗагрузитьДанныеДокумента(ЭтоВосстановлениеДетализации);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПриПодключенииКСервисуМОТП()

	ПараметрыПроверкиКодовМаркировки.ОтсутствуетПодключениеМОТП = Ложь;
	
	Если ПараметрыПроверкиКодовМаркировки.ЗапрашиватьДанныеСервиса Тогда
		ОбновитьСтатусыКодовМаркировки();
	КонецЕсли;
	
	УправлениеЭлементамиКонтроляСтатусаКодовМаркировки(ЭтотОбъект);
	
КонецПроцедуры

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

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

	КонецЕсли;
	
	ВозвращаемоеЗначение.ТребуетсяОбновлениеКлючаСессии = РезультатЗапроса.ТребуетсяОбновлениеКлючаСессии;
	ВозвращаемоеЗначение.СтатусыКодовМаркировки         = СтатусыКодовМаркировки;
	ВозвращаемоеЗначение.ТекстОшибки                    = РезультатЗапроса.ТекстОшибки;
	
	Возврат ВозвращаемоеЗначение;
	
КонецФункции

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

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

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

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

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

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

&НаСервере
Процедура ВывестиДанныеПроверкиИПодбораНаФорму(ДанныеПроверкиИПодбора)
	
	СоответствиеПараметров = Новый Соответствие;
	
	Если ДанныеПроверкиИПодбора.Свойство("ДеревоМаркированнойПродукции") Тогда
		
		ДеревоМаркированнойПродукцииОбъект = ДанныеПроверкиИПодбора.ДеревоМаркированнойПродукции;
		
		ДобавитьИЗаполнитьКолонкиПриВосстановленииДереваМаркированнойПродукции(ДеревоМаркированнойПродукцииОбъект, СоответствиеПараметров);
		
		Попытка
			ЗначениеВРеквизитФормы(ДеревоМаркированнойПродукцииОбъект, "ДеревоМаркированнойПродукции");
		Исключение
			ПроверкаИПодборПродукцииИС.ПроверитьКолонкиИсточникаИПриемникаНаСовместимость(
				ДеревоМаркированнойПродукцииОбъект, РеквизитФормыВЗначение("ДеревоМаркированнойПродукции"));
			Возврат;
		КонецПопытки;
		
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ПодобраннаяМаркируемаяПродукция") Тогда
		
		ПодобраннаяМаркируемаяПродукцияОбъект = ДанныеПроверкиИПодбора.ПодобраннаяМаркируемаяПродукция;
		
		ДобавитьИЗаполнитьКолонкиПриВосстановленииПодобраннойМаркируемойПродукции(ПодобраннаяМаркируемаяПродукцияОбъект, СоответствиеПараметров);
		
		ПодобраннаяМаркируемаяПродукция.Очистить();
		Для Каждого СтрокаТаблицы Из ПодобраннаяМаркируемаяПродукцияОбъект Цикл
			ЗаполнитьЗначенияСвойств(ПодобраннаяМаркируемаяПродукция.Добавить(), СтрокаТаблицы);
		КонецЦикла;
		
		СтрокиДереваСНулевымМРЦ = СоответствиеПараметров["СтрокиДереваСНулевымМРЦ"];
		Если СтрокиДереваСНулевымМРЦ <> Неопределено Тогда
			ЗаполнениеКолонкиВключаетМРЦПослеВосстановленииПодобраннойМаркируемойПродукцииПоСтрокамДереваСНулевымМРЦ(СтрокиДереваСНулевымМРЦ);
		КонецЕсли;
		
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ПродукцияПоДокументу") Тогда
		
		ПродукцияПоДокументуОбъект = ДанныеПроверкиИПодбора.ПродукцияПоДокументу;
		
		Попытка
			ЗначениеВРеквизитФормы(ПродукцияПоДокументуОбъект, "ПродукцияПоДокументу");
		Исключение
			ПроверкаИПодборПродукцииИС.ПроверитьКолонкиИсточникаИПриемникаНаСовместимость(
				ПродукцияПоДокументуОбъект, РеквизитФормыВЗначение("ПродукцияПоДокументу"));
			Возврат;
		КонецПопытки;
		
	КонецЕсли;
	
	ПроверкаИПодборПродукцииИСМПКлиентСервер.ПересчитатьНомераСтрок(ПодобраннаяМаркируемаяПродукция);
	ПроверкаИПодборПродукцииИСМППереопределяемый.ЗаполнитьСлужебныеРеквизитыВКоллекции(ЭтотОбъект, ПодобраннаяМаркируемаяПродукция);
	ПроверкаИПодборПродукцииИСМППереопределяемый.ЗаполнитьСтатусыУказанияСерий(ЭтотОбъект, ПараметрыУказанияСерий);
	
	СоответствиеШтрихкодовСтрокДерева = Новый Соответствие;
	ДополнитьСоответствиеШтрихкодовСтрокДереваДляКоллекции(ДеревоМаркированнойПродукции.ПолучитьЭлементы(), СоответствиеШтрихкодовСтрокДерева, ВидМаркируемойПродукции);
	
	Если ДанныеПроверкиИПодбора.Свойство("ПараметрыПроверкиКодовМаркировки") Тогда
		ЗапрашиватьДанныеСервиса = ПараметрыПроверкиКодовМаркировки.ЗапрашиватьДанныеСервиса;
		КонтролироватьСоставГрупповойУпаковкиПриИзмененииСтрокиДерева = ПараметрыПроверкиКодовМаркировки.КонтролироватьСоставГрупповойУпаковкиПриИзмененииСтрокиДерева;
		ПараметрыПроверкиКодовМаркировки = ДанныеПроверкиИПодбора.ПараметрыПроверкиКодовМаркировки;
		Если Не ЗапрашиватьДанныеСервиса И ПараметрыПроверкиКодовМаркировки.ЗапрашиватьДанныеСервиса Тогда
			ПараметрыПроверкиКодовМаркировки.ЗапрашиватьДанныеСервиса = Ложь;
		КонецЕсли;
		Если ТипЗнч(ПараметрыПроверкиКодовМаркировки) = Тип("Структура")
			И Не ПараметрыПроверкиКодовМаркировки.Свойство("ОбратноеСканирование") Тогда
			ПараметрыПроверкиКодовМаркировки.Вставить("ОбратноеСканирование", Ложь);
		КонецЕсли;
		Если КонтролироватьСоставГрупповойУпаковкиПриИзмененииСтрокиДерева Тогда
			ПараметрыПроверкиКодовМаркировки.КонтролироватьСоставГрупповойУпаковкиПриИзмененииСтрокиДерева = Истина;
			ПараметрыПроверкиКодовМаркировки.КонтролироватьСоставГрупповойУпаковки = Ложь;
		КонецЕсли;
		Если ТипЗнч(ПараметрыПроверкиКодовМаркировки) = Тип("Структура")
			И Не ПараметрыПроверкиКодовМаркировки.Свойство("РежимИсправленияОшибокПослеПередачиКодов") Тогда
			ПараметрыПроверкиКодовМаркировки.Вставить("РежимИсправленияОшибокПослеПередачиКодов", Ложь);
		КонецЕсли;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("КоличествоНедопустимыхКодовМаркировки") Тогда
		КоличествоНедопустимыхКодовМаркировки = ДанныеПроверкиИПодбора.КоличествоНедопустимыхКодовМаркировки;
		ПроверкаИПодборПродукцииИСМПКлиентСервер.ОтобразитьИнформациюОНедопустимыхКодахМаркировки(ЭтотОбъект);
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("УпаковкиДокумента") Тогда
		УпаковкиДокумента = ДанныеПроверкиИПодбора.УпаковкиДокумента;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ДобавленныеУпаковки") Тогда
		ДобавленныеУпаковки = ДанныеПроверкиИПодбора.ДобавленныеУпаковки;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ДоступныеДляПроверкиУпаковки") Тогда
		ДоступныеДляПроверкиУпаковки = ДанныеПроверкиИПодбора.ДоступныеДляПроверкиУпаковки;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("СледующийСтикерОтложено") Тогда
		СледующийСтикерОтложено = ДанныеПроверкиИПодбора.СледующийСтикерОтложено;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ДетализацияСтруктурыХранения") Тогда
		ДетализацияСтруктурыХранения = ДанныеПроверкиИПодбора.ДетализацияСтруктурыХранения;
	ИначеЕсли ДанныеПроверкиИПодбора.Свойство("ДеревоМаркированнойПродукции") Тогда
		ДетализацияСтруктурыХранения = ДетализацияСтруктурыХраненияДерева(ДанныеПроверкиИПодбора.ДеревоМаркированнойПродукции);
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("РежимПроверки") Тогда
		РежимПроверки = ДанныеПроверкиИПодбора.РежимПроверки;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("СодержимоеУпаковокНедоступно") Тогда
		СодержимоеУпаковокНедоступно = ДанныеПроверкиИПодбора.СодержимоеУпаковокНедоступно;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("СохраненВыборПоМаркируемойПродукции") Тогда
		СохраненВыборПоМаркируемойПродукции = ДанныеПроверкиИПодбора.СохраненВыборПоМаркируемойПродукции;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ДанныеВыбораПоМаркируемойПродукции") Тогда
		ДанныеВыбораПоМаркируемойПродукции = ДанныеПроверкиИПодбора.ДанныеВыбораПоМаркируемойПродукции;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ШтрихкодТекущейПроверяемойУпаковки") Тогда
		ШтрихкодТекущейПроверяемойУпаковки = ДанныеПроверкиИПодбора.ШтрихкодТекущейПроверяемойУпаковки;
		Если ЗначениеЗаполнено(ШтрихкодТекущейПроверяемойУпаковки) Тогда
			ИдентификаторСтроки = СоответствиеШтрихкодовСтрокДерева.Получить(ШтрихкодТекущейПроверяемойУпаковки);
			Если ИдентификаторСтроки = Неопределено И СтрНачинаетсяС(ШтрихкодТекущейПроверяемойУпаковки, "(") Тогда
				ШтрихкодТекущейПроверяемойУпаковки = ШтрихкодированиеМОТП.НормализованныйШтрихкод(ШтрихкодТекущейПроверяемойУпаковки, ВидМаркируемойПродукции);
				ИдентификаторСтроки                = СоответствиеШтрихкодовСтрокДерева.Получить(ШтрихкодТекущейПроверяемойУпаковки);
			КонецЕсли;
			Если ИдентификаторСтроки <> Неопределено Тогда
				ИдентификаторТекущейПроверяемойУпаковки             = ИдентификаторСтроки;
				Элементы.ДеревоМаркированнойПродукции.ТекущаяСтрока = ИдентификаторТекущейПроверяемойУпаковки;
				ДанныеТекущейСтроки = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторТекущейПроверяемойУпаковки);
				ПроверкаИПодборПродукцииИСМПКлиентСервер.ОбновитьВыводимоеПредставлениеПроверкиСодержимого(ЭтотОбъект, ДанныеТекущейСтроки);
			Иначе
				ИдентификаторТекущейПроверяемойУпаковки = -1;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ДанныеРанееСгенерированныхШтрихкодов") Тогда
		ДанныеРанееСгенерированныхШтрихкодов = ДанныеПроверкиИПодбора.ДанныеРанееСгенерированныхШтрихкодов;
		Если ДанныеРанееСгенерированныхШтрихкодов <> Неопределено Тогда
			АдресПредыдущихШтрихкодов = ПоместитьВоВременноеХранилище(ДанныеРанееСгенерированныхШтрихкодов, УникальныйИдентификатор);
		КонецЕсли;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("Контейнер") Тогда
		Контейнер = ДанныеПроверкиИПодбора.Контейнер;
	КонецЕсли;
	
	ЭлементыДерева = ДеревоМаркированнойПродукции.ПолучитьЭлементы();
	Для ИндексСтроки = 0 По Мин(1, ЭлементыДерева.Количество() - 1) Цикл
		СтрокаДереваМаркированнойПродукции = ЭлементыДерева[ИндексСтроки];
		Если СтрокаДереваМаркированнойПродукции.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки() Тогда
			ИдентификаторСтрокиПотребительскиеУпаковкиБезУпаковки = СтрокаДереваМаркированнойПродукции.ПолучитьИдентификатор();
		ИначеЕсли СтрокаДереваМаркированнойПродукции.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
			ИдентификаторСтрокиГрупповыеУпаковкиБезКоробки = СтрокаДереваМаркированнойПродукции.ПолучитьИдентификатор();
		КонецЕсли;
	КонецЦикла;
	
	Если ПустаяСтрока(АдресСоответствиеШтрихкодыИдентификаторыСтрок) Тогда
		АдресСоответствиеШтрихкодыИдентификаторыСтрок = ПоместитьВоВременноеХранилище(
			СоответствиеШтрихкодовСтрокДерева,
			УникальныйИдентификатор);
	Иначе
		АдресСоответствиеШтрихкодыИдентификаторыСтрок = ПоместитьВоВременноеХранилище(
			СоответствиеШтрихкодовСтрокДерева,
			АдресСоответствиеШтрихкодыИдентификаторыСтрок);
	КонецЕсли;
	
	Если Не ДанныеПроверкиИПодбора.Свойство("ЭтоВосстановлениеДетализации")
		Или (ДанныеПроверкиИПодбора.Свойство("ЭтоВосстановлениеДетализации") И Не ДанныеПроверкиИПодбора.ЭтоВосстановлениеДетализации) Тогда
		Если ДанныеПроверкиИПодбора.Свойство("ОшибкиПоУПД") Тогда
			ПроверкаИПодборПродукцииИСМП.ВывестиИнформациюОПроблемахУПД(ДанныеПроверкиИПодбора.ОшибкиПоУПД, ВидМаркируемойПродукции, УникальныйИдентификатор);
		КонецЕсли;
	КонецЕсли;
	
	Если ДанныеПроверкиИПодбора.Свойство("ОшибкиПроверкиСредствамиККТ") Тогда
		ЕстьОшибкиПроверкиККТ = (ДанныеПроверкиИПодбора.ОшибкиПроверкиСредствамиККТ.Количество() > 0);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ДобавитьИЗаполнитьКолонкиПриВосстановленииДереваМаркированнойПродукции(ДеревоМаркированнойПродукцииОбъект, СоответствиеПараметров)
	
	// Выполняем адаптацию старого формата
	
	ПереименоватьКолонкиПриВосстановленииДерева(ДеревоМаркированнойПродукцииОбъект);
	ДобавитьИЗаполнитьКолонкиПриВосстановленииДерева(ДеревоМаркированнойПродукцииОбъект, СоответствиеПараметров);
	
КонецПроцедуры

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

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

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

&НаСервере
Процедура ВыполнитьДействиеПриВосстановленииКоллекции(КоллекцияОбъект, Действие, СоответствиеПараметров)
	
	Если Действие = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если Действие = "ЗаполнениеКолонкиВидУпаковки" Тогда
		
		ЗаполнениеКолонкиВидУпаковкиПриВосстановленииДерева(КоллекцияОбъект.Строки);
		КоллекцияОбъект.Колонки.Удалить(КоллекцияОбъект.Колонки.ГрупповаяТоварнаяУпаковка);
		
	ИначеЕсли Действие = "ЗаполнениеКолонкиНормализованныйШтрихкод" Тогда
		
		ЗаполнениеКолонкиНормализованныйШтрихкодПриВосстановленииДерева(КоллекцияОбъект.Строки);
		
	ИначеЕсли Действие = "ЗаполнениеКолонкиВключаетМРЦ" Тогда
		
		Если ВидМаркируемойПродукции = Перечисления.ВидыПродукцииИС.Табак Тогда
			
			Если ТипЗнч(КоллекцияОбъект) = Тип("ДеревоЗначений") Тогда
				
				СтрокиДереваСНулевымМРЦ = Новый Массив;
				ЗаполнениеКолонкиВключаетМРЦПриВосстановленииДерева(КоллекцияОбъект.Строки, СтрокиДереваСНулевымМРЦ);
				
				Если СтрокиДереваСНулевымМРЦ.Количество() > 0 Тогда
					СоответствиеПараметров["СтрокиДереваСНулевымМРЦ"] = СтрокиДереваСНулевымМРЦ;
				КонецЕсли;
				
			Иначе
				ЗаполнениеКолонкиВключаетМРЦПриВосстановленииПодобраннойМаркируемойПродукции(КоллекцияОбъект);
			КонецЕсли;
			
		КонецЕсли;
		
	ИначеЕсли Действие = "ЗаполнениеКолонкиКоличество" Тогда
		
		ЗаполнениеКолонкиКоличествоПриВосстановленииДерева(КоллекцияОбъект.Строки);
		
	ИначеЕсли Действие = "ЗаполнениеКолонкиПлановоеКоличествоПотребительскихУпаковок" Тогда
		
		ЗаполнениеКолонкиПлановоеКоличествоПотребительскихУпаковокПриВосстановленииДерева(КоллекцияОбъект.Строки);
		
	ИначеЕсли Действие = "ЗаполнениеКолонкиКоличествоПотребительскихУпаковок" Тогда
		
		ЗаполнениеКолонкиКоличествоПотребительскихУпаковок(КоллекцияОбъект);
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПереименоватьКолонкиПриВосстановленииДерева(ДеревоМаркированнойПродукцииОбъект)
	
	ИменаКолонок = Новый Массив;
	ИменаКолонок.Добавить(
		Новый Структура("ИмяКолонкиСтарое, ИмяКолонкиНовое",
			"КоличествоПодчиненныхПачек", "КоличествоПодчиненныхПотребительскихУпаковок"));
	ИменаКолонок.Добавить(
		Новый Структура("ИмяКолонкиСтарое, ИмяКолонкиНовое",
			"КоличествоПодчиненныхБлоков", "КоличествоПодчиненныхГрупповыхУпаковок"));
	ИменаКолонок.Добавить(
		Новый Структура("ИмяКолонкиСтарое, ИмяКолонкиНовое",
			"НеПересчитыватьКоличествоПачек", "НеПересчитыватьКоличествоПотребительскихУпаковок"));
	ИменаКолонок.Добавить(
		Новый Структура("ИмяКолонкиСтарое, ИмяКолонкиНовое",
			"Скоропортящаяся", "СкоропортящаясяПродукция"));
	ИменаКолонок.Добавить(
		Новый Структура("ИмяКолонкиСтарое, ИмяКолонкиНовое",
			"ХэшСуммаНормализации", "ХешСуммаНормализации"));

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

	Для Каждого ДанныеКолонки Из ИменаКолонок Цикл
		Колонка = ДеревоМаркированнойПродукцииОбъект.Колонки.Найти(ДанныеКолонки.ИмяКолонкиСтарое);
		Если Колонка <> Неопределено Тогда
			Колонка.Имя = ДанныеКолонки.ИмяКолонкиНовое;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

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

&НаСервере
Процедура ЗаполнениеКолонкиВидУпаковкиПриВосстановленииДерева(КоллекцияСтрок)
	
	Для Каждого СтрокаДерева Из КоллекцияСтрок Цикл
		
		Если СтрокаДерева.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки() Тогда
			Продолжить;
		КонецЕсли;
		
		Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(СтрокаДерева.ТипУпаковки) Тогда
			Если СтрокаДерева.ГрупповаяТоварнаяУпаковка Тогда
				СтрокаДерева.ВидУпаковки = Перечисления.ВидыУпаковокИС.Групповая;
			Иначе
				СтрокаДерева.ВидУпаковки = Перечисления.ВидыУпаковокИС.Логистическая;
			КонецЕсли;
		Иначе
			СтрокаДерева.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская;
		КонецЕсли;
		
		Если СтрокаДерева.Строки.Количество() > 0 Тогда
			ЗаполнениеКолонкиВидУпаковкиПриВосстановленииДерева(СтрокаДерева.Строки);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

&НаСервере
Процедура ЗаполнениеКолонкиВключаетМРЦПриВосстановленииДерева(КоллекцияСтрок, СтрокиДереваСНулевымМРЦ)
	
	Для Каждого СтрокаДерева Из КоллекцияСтрок Цикл
		
		Если СтрокаДерева.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки() Тогда
			Продолжить;
		КонецЕсли;
		
		Если СтрокаДерева.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская
			Или СтрокаДерева.ВидУпаковки = Перечисления.ВидыУпаковокИС.Групповая Тогда
			
			Если СтрокаДерева.МРЦ = 0 И КодмаркировкиВСтрокеДереваВключаетМРЦ(СтрокаДерева) Тогда
				СтрокаДерева.ВключаетМРЦ = Истина;
				СтрокиДереваСНулевымМРЦ.Добавить(СтрокаДерева);
			Иначе
				СтрокаДерева.ВключаетМРЦ = Истина;
			КонецЕсли;
			
		КонецЕсли;
		
		Если СтрокаДерева.Строки.Количество() > 0 Тогда
			ЗаполнениеКолонкиВключаетМРЦПриВосстановленииДерева(СтрокаДерева.Строки, СтрокиДереваСНулевымМРЦ);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Функция КодМаркировкиВСтрокеДереваВключаетМРЦ(СтрокаДерева)
	
	Если СтрокаДерева.МРЦ > 0 Тогда
		Возврат Истина;
	КонецЕсли;
	
	Если СтрокаДерева.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская
		Или СтрокаДерева.ВидУпаковки = Перечисления.ВидыУпаковокИС.Групповая Тогда
		
		ПользовательскиеПараметрыРазбораКодаМаркировки = РазборКодаМаркировкиИССлужебныйКлиентСервер.ПользовательскиеПараметрыРазбораКодаМаркировки();
		ДанныеРазбора = РазобратьКодМаркировки(СтрокаДерева.Штрихкод, ВидМаркируемойПродукции, ПользовательскиеПараметрыРазбораКодаМаркировки);
		
		Если ДанныеРазбора = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;
		
		Возврат ДанныеРазбора.СоставКодаМаркировки.Свойство("ВключаетМРЦ")
			И ДанныеРазбора.СоставКодаМаркировки.ВключаетМРЦ;
		
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ДанныеШтрихкодаВключаютМРЦ(ДанныеШтрихкода)
	
	Если ДанныеШтрихкода.МРЦ > 0 Тогда
		Возврат Истина;
	КонецЕсли;
	
	Если ДанныеШтрихкода.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская")
		Или ДанныеШтрихкода.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Групповая") Тогда
		
		ДанныеРазбора = ДанныеШтрихкода.ДанныеРазбора;
		
		Если ДанныеРазбора = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;
		
		Возврат ДанныеРазбора.СоставКодаМаркировки.Свойство("ВключаетМРЦ")
			И ДанныеРазбора.СоставКодаМаркировки.ВключаетМРЦ;
		
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

&НаСервере
Процедура ЗаполнениеКолонкиВключаетМРЦПриВосстановленииПодобраннойМаркируемойПродукции(ПодобраннаяМаркируемаяПродукцияОбъект)
	
	Для Каждого СтрокаТаблицы Из ПодобраннаяМаркируемаяПродукцияОбъект Цикл
		СтрокаТаблицы.ВключаетМРЦ = (СтрокаТаблицы.МРЦ <> 0);
	КонецЦикла;
	
КонецПроцедуры

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

	Для Каждого СтрокаДерева Из СтрокиДереваСНулевымМРЦ Цикл
		
		СтрокаИзмененийДо = Новый Структура(СвойстваСтрокой);
		ЗаполнитьЗначенияСвойств(СтрокаИзмененийДо, СтрокаДерева);
		СтрокаИзмененийДо.ВключаетМРЦ = Ложь;
		
		СтрокаИзмененийПосле = Новый Структура(СвойстваСтрокой);
		ЗаполнитьЗначенияСвойств(СтрокаИзмененийПосле, СтрокаДерева);
		
		КоличествоКодовМаркировки = 1;
		
		ПроверкаИПодборПродукцииИСМПКлиентСервер.ПодобраннаяПродукцияПриУточненииСопоставления(
			ЭтотОбъект,
			СтрокаИзмененийДо,
			СтрокаИзмененийПосле,
			КоличествоКодовМаркировки,
			ОбщийМодульКонтекстаПиП(),,
			КэшированныеЗначения);
		
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнениеКолонкиКоличествоПриВосстановленииДерева(КоллекцияСтрок)
	
	Для Каждого СтрокаКоллекции Из КоллекцияСтрок Цикл
		Если ЗначениеЗаполнено(СтрокаКоллекции.ВидУпаковки) Тогда
			Если СтрокаКоллекции.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская Тогда
				СтрокаКоллекции.Количество = 1;
			Иначе
				СтрокаКоллекции.Количество = СтрокаКоллекции.КоличествоПодчиненныхПотребительскихУпаковок;
			КонецЕсли;
		КонецЕсли;
		ЗаполнениеКолонкиКоличествоПриВосстановленииДерева(СтрокаКоллекции.Строки);
	КонецЦикла;
	
КонецПроцедуры
	
&НаСервере
Процедура ЗаполнениеКолонкиКоличествоПотребительскихУпаковок(КоллекцияСтрок)
	
	Для Каждого СтрокаКоллекции Из КоллекцияСтрок Цикл
		СтрокаКоллекции.КоличествоПотребительскихУпаковок = СтрокаКоллекции.КоличествоПодобрано;
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнениеКолонкиПлановоеКоличествоПотребительскихУпаковокПриВосстановленииДерева(КоллекцияСтрок)
	
	Для Каждого СтрокаКоллекции Из КоллекцияСтрок Цикл
		СтрокаКоллекции.ПлановоеКоличествоПотребительскихУпаковок = СтрокаКоллекции.Коэффициент;
		ЗаполнениеКолонкиПлановоеКоличествоПотребительскихУпаковокПриВосстановленииДерева(СтрокаКоллекции.Строки);
	КонецЦикла;
	
КонецПроцедуры

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

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

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

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

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

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

&НаКлиенте
Процедура УточнениеКоэффициентовУпаковокБезПодключенияЗавершение(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = "УточненыКоэффициентыУпаковокИСМП" Тогда
		
		ЗагрузитьДанныеДокумента(ДополнительныеПараметры.ЭтоВосстановлениеДетализации);
		
	Иначе
		
		ЗакрытьФорму();
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Функция ЗагрузкаДанныхДокументаЗавершениеНаСервере(АдресДанныхДокумента)

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

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

&НаСервере
Процедура РассчитатьИтогиУстановитьВидимость()

	УправлениеЭлементамиФормыПриСоздании();
	ПересчитатьВсеИтогиФормыНаСервере();
	УправлениеДоступностьюКомандУпаковок(ЭтотОбъект);

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

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

	ПараметрыПроверкиКодовМаркировки.ОтсутствуетПодключениеМОТП = Ложь;

	Если ТребуетсяОбновлениеКлючаСессии Или ТребуетсяОбновлениеКлючаСессииРозница Тогда
		ЗапроситьКлючСессииНачало(,, ЭтоВосстановлениеДетализации);
	Иначе
		ЗагрузитьДанныеДокумента(ЭтоВосстановлениеДетализации);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ИнициализироватьДанныеФормы(РежимОчистки = Ложь)
	
	ИдентификаторТекущейПроверяемойУпаковки               = -1;
	ИдентификаторСтрокиПотребительскиеУпаковкиБезУпаковки = -1;
	ИдентификаторСтрокиГрупповыеУпаковкиБезКоробки        = -1;
	СледующийСтикерОтложено                               = 1;

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

	ИспользоватьСерииНоменклатуры          = ОбщегоНазначенияИС.СерииИспользуются();
	ИспользоватьХарактеристикиНоменклатуры = ОбщегоНазначенияИС.ХарактеристикиИспользуются();
	
КонецПроцедуры

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

	Элементы.ДеревоМаркированнойПродукцииИндексКартинкиТипУпаковки.КартинкаЗначений = КартинкаТипУпаковки;
	Элементы.СтраницаПодобраннаяПродукция.Заголовок = ВидМаркируемойПродукции;
	
	УправлениеЭлементамиКонтроляСтатусаКодовМаркировки(ЭтотОбъект);
	УправлениеДоступностьюПодобранногоКоличестваПродукции(ЭтотОбъект);
	
	Элементы.ОчиститьСопоставление.Видимость = ЭтоДокументПриобретения;
	
	Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПотребительскихУпаковок.Видимость          = ДопустимаПроизвольнаяЕдиницаУчета;
	Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПотребительскихУпаковокВУпаковке.Видимость = ДопустимаПроизвольнаяЕдиницаУчета;
	
	Если ЭтоДокументМаркировка(ЭтотОбъект) Тогда
		Элементы.ДеревоМаркированнойПродукцииУстановитьСтатусПроверкиОтсутствует.Видимость = Ложь;
	КонецЕсли;
	
	Элементы.ДеревоМаркированнойПродукцииТекстОшибкиПроверкиСредствамиККТ.Видимость = ЕстьОшибкиПроверкиККТ;
	
	Если Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПотребительскихУпаковокВУпаковке.Видимость Тогда
		Элементы.ГруппаПодобраннаяМаркируемаяПродукцияКоличествоИС.ОтображатьВШапке = Истина;
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоИС.Заголовок = НСтр("ru = 'Количество'");
	Иначе
		Элементы.ГруппаПодобраннаяМаркируемаяПродукцияКоличествоИС.ОтображатьВШапке = Ложь;
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоИС.Заголовок = НСтр("ru = 'В упаковках'");
	КонецЕсли;
	
	Если Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПотребительскихУпаковок.Видимость Тогда
		Элементы.ГруппаПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.ОтображатьВШапке = Истина;
		Элементы.ГруппаПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.Заголовок        = ЗаголовокКолонкиКоличествоПодобрано;
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.Заголовок              = НСтр("ru = 'Количество'");
	Иначе
		Элементы.ГруппаПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.ОтображатьВШапке = Ложь;
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.Заголовок              = ЗаголовокКолонкиКоличествоПодобрано;
	КонецЕсли;
	
	Если Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПотребительскихУпаковокВУпаковке.Видимость
		Или Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПотребительскихУпаковок.Видимость Тогда
		Элементы.ГруппаПодобраннаяМаркируемаяПродукцияКоличество.ОтображатьВШапке = Истина;
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличество.Заголовок = НСтр("ru = 'Количество'");
	Иначе
		Элементы.ГруппаПодобраннаяМаркируемаяПродукцияКоличество.ОтображатьВШапке = Ложь;
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличество.Заголовок = НСтр("ru = 'В документе'");
	КонецЕсли;
	
КонецПроцедуры

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

&НаКлиентеНаСервереБезКонтекста
Процедура УправлениеДоступностьюПодобранногоКоличестваПродукции(Форма)
	
	Элементы = Форма.Элементы;
	
	Если Форма.РежимПросмотра Тогда
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.ТолькоПросмотр = Истина;
	ИначеЕсли Форма.СодержимоеУпаковокНедоступно Тогда
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.ТолькоПросмотр = Ложь;
	Иначе
		Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.ТолькоПросмотр = Истина;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьЗаголовокКомандыПроверкиСтатусовКодовМаркировки(Форма)
	
	Элементы = Форма.Элементы;
	
	Элементы.ФормаВключитьОтключитьКонтрольСтатусовКодовМаркировки.Пометка = Форма.ПараметрыПроверкиКодовМаркировки.КонтролироватьСтатусыКодовМаркировки;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьЗаголовокКомандыПроверкиПоВладельцу(Форма)
	
	Элементы = Форма.Элементы;
	
	Элементы.ФормаВключитьОтключитьКонтрольПоВладельцу.Пометка   = Форма.ПараметрыПроверкиКодовМаркировки.КонтролироватьВладельцевКодовМаркировки;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьЗаголовокКомандыОбратноеСканирование(Форма)
	
	Элементы = Форма.Элементы;
	
	Элементы.ФормаВключитьОтключитьОбратноеСканирование.Пометка = Форма.ПараметрыПроверкиКодовМаркировки.ОбратноеСканирование;
	
КонецПроцедуры

&НаКлиенте
Процедура УправлениеДоступностьюКомандыРазобратьУпаковку()
	
	Если РежимПросмотра Тогда
		Возврат;
	КонецЕсли;
	
	Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		ДоступностьКомандыРазборкиУпаковки = Ложь;
	Иначе
		ТекущиеДанные = Элементы.ДеревоМаркированнойПродукции.ТекущиеДанные;
		
		Если ТекущиеДанные = Неопределено Тогда
			ДоступностьКомандыРазборкиУпаковки = Ложь;
		Иначе
			ДоступностьКомандыРазборкиУпаковки = ИнтеграцияИСКлиентСервер.ЭтоУпаковка(ТекущиеДанные.ТипУпаковки);
			
			Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
				Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
				ДоступностьКомандыРазборкиУпаковки = ДоступностьКомандыРазборкиУпаковки
					И Не ЭтоГрупповаяУпаковкаИлиНабор(ТекущиеДанные.ВидУпаковки);
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;

	Элементы.ДеревоМаркированнойПродукцииРазобратьУпаковку.Доступность = ДоступностьКомандыРазборкиУпаковки;

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

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

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

#Область РезультатыПроверки

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

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

&НаКлиенте
Функция ИтогиПроверкиПриЗавершении()
	
	КоличествоНепроверенных = 0;
	КоличествоОтложенных    = 0;
	КоличествоВсего         = 0;
	КоличествоОтсутствует   = 0;
	КоличествоНеЧислилось   = 0;
	
	ТипПрочиеЗоныПересчета = Тип("ПеречислениеСсылка.ПрочиеЗоныПересчетаПродукцииИСМП");
	
	Для Каждого СтрокаДерева Из ДеревоМаркированнойПродукции.ПолучитьЭлементы() Цикл
		
		КоличествоНепроверенных = КоличествоНепроверенных + СтрокаДерева.КоличествоПодчиненныхНеПроверялось;
		КоличествоОтложенных    = КоличествоОтложенных + СтрокаДерева.КоличествоПодчиненныхОтложено;
		КоличествоВсего         = КоличествоВсего + СтрокаДерева.КоличествоПодчиненныхВсего;
		КоличествоОтсутствует   = КоличествоОтсутствует + СтрокаДерева.КоличествоПодчиненныхОтсутствует;
		КоличествоНеЧислилось   = КоличествоНеЧислилось + СтрокаДерева.КоличествоПодчиненныхНеЧислилось;
		
		Если ТипЗнч(СтрокаДерева.ТипУпаковки) = ТипПрочиеЗоныПересчета Тогда
			Продолжить;
		КонецЕсли;
		
		Если СтрокаДерева.НедопустимыйКодМаркировки
			Или СтрокаДерева.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.Отсутствует") Тогда
			
			КоличествоОтсутствует = КоличествоОтсутствует + 1;
			
		ИначеЕсли СтрокаДерева.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеПроверялась") Тогда
			
			КоличествоНепроверенных = КоличествоНепроверенных + 1;
			
		ИначеЕсли СтрокаДерева.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.Отложена") Тогда
			
			КоличествоОтложенных = КоличествоОтложенных + 1;
			
		ИначеЕсли СтрокаДерева.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась") Тогда
			
			КоличествоНеЧислилось = КоличествоНеЧислилось + 1;	
			
		КонецЕсли;
		
		КоличествоВсего = КоличествоВсего + 1;
		
	КонецЦикла;
	
	Итоги = Новый Структура;
	Итоги.Вставить("КоличествоНепроверенных",КоличествоНепроверенных);
	Итоги.Вставить("КоличествоОтложенных",   КоличествоОтложенных);
	Итоги.Вставить("КоличествоВсего",        КоличествоВсего);
	Итоги.Вставить("КоличествоОтсутствует",  КоличествоОтсутствует);
	Итоги.Вставить("КоличествоНеЧислилось",  КоличествоНеЧислилось);
	
	Возврат Итоги;
	
КонецФункции

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

&НаКлиенте
Процедура ЗавершитьПроверку(СоздаватьАктОРасхождениях)
	
	ОценкаПроизводительностиКлиент.ЗамерВремени("Обработка.ПроверкаИПодборТабачнойПродукцииМОТП.Форма.ПроверкаИПодбор.ЗавершитьПроверку");

	ПараметрыОкончанияПроверки = Новый Структура;
	ПараметрыОкончанияПроверки.Вставить("СоздаватьАктОРасхождениях", Ложь);
	
	Если СоздаватьАктОРасхождениях <> Неопределено Тогда
		ПараметрыОкончанияПроверки.СоздаватьАктОРасхождениях = СоздаватьАктОРасхождениях;
	КонецЕсли;
	
	Если Не ТаблицаПодобраннойПродукцииЗаполненаКорректно() Тогда
		Возврат;
	КонецЕсли;
	
	Если ИспользоватьСерииНоменклатуры И Не РезультатГенерацииСерийПриЗавершенииПроверки() Тогда
		ТекстСообщения = НСтр("ru = 'Для завершения проверки требуется указание серий.'");
		ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстСообщения);
		Элементы.СтраницыПродукция.ТекущаяСтраница = Элементы.СтраницаПодобраннаяПродукция;
		Возврат;
	КонецЕсли;
	
	Если КоличествоНедопустимыхКодовМаркировки > 0 Тогда
		ИсключитьНедопустимыеУпаковкиИзПодобраннойПродукции(ДеревоМаркированнойПродукции.ПолучитьЭлементы());
		
		Если ТаблицаИзмененийТабачнойПродукции.Количество() > 0 Тогда
			ОбработатьТаблицуИзмененийПодобраннойПродукции(ЭтотОбъект, КэшированныеЗначения);
		КонецЕсли;
	КонецЕсли;
	
	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	ПараметрыОжидания.ТекстСообщения = НСтр("ru = 'Сохранение результатов проверки.'");

	ДлительнаяОперация = НачатьЗавершениеПроверки(ПараметрыОкончанияПроверки);
	ОповещениеОЗавершении = Новый ОписаниеОповещения("ЗавершениеПроверкиОкончание", ЭтотОбъект);

	ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОповещениеОЗавершении, ПараметрыОжидания);
	
КонецПроцедуры

&НаКлиенте
Функция РезультатИзменияСтатусаПроверкиПриЗавершении(ВыбранныйСтатусПроверки)
	
	СтруктураВозврата = Новый Структура;
	СтруктураВозврата.Вставить("ЕстьОшибки",  Ложь);
	СтруктураВозврата.Вставить("ТекстОшибки", "");
	
	Если ВыбранныйСтатусПроверки <> Неопределено Тогда
		Для Каждого СтрокаПроверяемого Из ДеревоМаркированнойПродукции.ПолучитьЭлементы() Цикл
			ИзменитьСтатусПроверкиВСтрокеДерева(СтрокаПроверяемого, ВыбранныйСтатусПроверки, Ложь);
		КонецЦикла;
	КонецЕсли;
	
	Если ТаблицаИзмененийТабачнойПродукции.Количество() > 0 Тогда
		ОбработатьТаблицуИзмененийПодобраннойПродукции(ЭтотОбъект, КэшированныеЗначения);
	КонецЕсли;
	
	ПересчитатьВсеИтогиФормыНаКлиенте();
	
	Если НеобходимаПеремаркировка() Тогда
		СтруктураВозврата.ЕстьОшибки  = Истина;
		СтруктураВозврата.ТекстОшибки = НСтр("ru = 'Есть упаковки, которые необходимо разобрать'");
	КонецЕсли;
	
	Возврат СтруктураВозврата;
	
КонецФункции

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

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

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

&НаКлиенте
Функция РезультатГенерацииСерийПриЗавершенииПроверки()
	
	Если ИнтеграцияИСКлиентСервер.ИспользоватьСерииНоменклатуры(ПараметрыУказанияСерий)
		И ПроверкаИПодборПродукцииИСМПКлиентСервер.ТребуетсяУказаниеСерий(ПодобраннаяМаркируемаяПродукция) Тогда
		
		Если ЕстьПравоДобавлениеСерий() Тогда
			
			СгенерироватьСерииПодобраннойТабачнойПродукции();
			
			Возврат Не ПроверкаИПодборПродукцииИСМПКлиентСервер.ТребуетсяУказаниеСерий(ПодобраннаяМаркируемаяПродукция);
			
		Иначе
			
			Возврат Ложь;
			
		КонецЕсли;
		
	Иначе
		
		Возврат Истина;
		
	КонецЕсли;
	
КонецФункции

&НаСервереБезКонтекста
Процедура СгенерироватьСерииНаСервере(ДанныеДляГенерацииСерий, ВидМаркируемойПродукции)
	
	ИнтеграцияИСМП.СгенерироватьСерии(ДанныеДляГенерацииСерий, ВидМаркируемойПродукции);
	
КонецПроцедуры

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

&НаСервереБезКонтекста
Процедура ДописатьВТекущийЛогДанныеИзФоновогоЗаданияПриЗавершенииПроверки(ДанныеЗаписи)
	ЛогированиеЗапросовИСМП.ДописатьВТекущийЛогДанныеИзФоновогоЗадания(ДанныеЗаписи);
КонецПроцедуры

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

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

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

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

#Область СканированиеШтрихкодаИОбработка

&НаКлиенте
Функция ИдентификаторСтрокиДереваПоШтрихкоду(Штрихкод, Нормализовать = Ложь)
	
	Если Нормализовать Тогда
		ПользовательскиеПараметрыРазбораКодаМаркировки = РазборКодаМаркировкиИССлужебныйКлиентСервер.ПользовательскиеПараметрыРазбораКодаМаркировки();
		ПользовательскиеПараметрыРазбораКодаМаркировки.ВалидироватьШтрихкодЛогистическойУпаковкиGS1128СОшибками = Не ЭтоДокументМаркировка(ЭтотОбъект);
		ШтрихкодДляПоиска = РазборКодаМаркировкиИССлужебныйКлиент.НормализованныйШтрихкод(
			Штрихкод, ВидМаркируемойПродукции,, ПользовательскиеПараметрыРазбораКодаМаркировки);
	Иначе
		ШтрихкодДляПоиска = Штрихкод;
	КонецЕсли;
	
	НайденныйИдентификаторСтроки = СоответствиеШтрихкодовСтрокДерева.Получить(ШтрихкодДляПоиска);
	
	Если НайденныйИдентификаторСтроки = Неопределено Тогда
		
		НайденныйИдентификаторСтроки = -1;
		
	КонецЕсли;
	
	Возврат НайденныйИдентификаторСтроки;
	
КонецФункции

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

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

&НаКлиенте
Процедура УдалитьСтрокуПриОбратномСканировании(УдаляемыйЭлемент);
	
	Если Не ПараметрыПроверкиКодовМаркировки.ОбратноеСканирование
		Или УдаляемыйЭлемент = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Отказ = Ложь;
	ДеревоМаркированнойПродукцииПередУдалением(Элементы.ДеревоМаркированнойПродукции, Отказ);
	
	Если Отказ Тогда
		Возврат;
	КонецЕсли;
	
	РодительУдаляемогоЭлемента = УдаляемыйЭлемент.ПолучитьРодителя();
	
	Представление = УдаляемыйЭлемент.Представление;
	
	Если РодительУдаляемогоЭлемента = Неопределено Тогда
		
		ДеревоМаркированнойПродукции.ПолучитьЭлементы().Удалить(УдаляемыйЭлемент);
		
	Иначе
		
		РодительУдаляемогоЭлемента.ПолучитьЭлементы().Удалить(УдаляемыйЭлемент);
		
	КонецЕсли;
	
	ДеревоМаркированнойПродукцииПослеУдаления(Элементы.ДеревоМаркированнойПродукции);
	
	ПоказатьОповещениеПользователя(НСтр("ru = 'Удалено из списка:'"),, Представление);
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьНайденныйВДеревеШтрихкод(НайденнаяСтрокаДерева, ТекущаяСтрокаДерева, ДанныеШтрихкода = Неопределено)
	
	РодительНайденнойСтроки = НайденнаяСтрокаДерева.ПолучитьРодителя();
	
	Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(НайденнаяСтрокаДерева.ТипУпаковки) Тогда
		
		Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
			Возврат;
		КонецЕсли;
		
		ЭтоГрупповаяУпаковка = ЭтоГрупповаяУпаковкаИлиНабор(НайденнаяСтрокаДерева.ВидУпаковки);
		
		СтрокаПроверяемойУпаковки = СтрокаТекущейПроверяемойУпаковки(ЭтотОбъект, Истина, ЭтоГрупповаяУпаковка);
		
		Если НайденнаяСтрокаДерева.ИдетПроверкаДаннойУпаковки Тогда
			
			СнятьПризнакПроверкиУРодителя = РодительНайденнойСтроки <> Неопределено
				И РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки();
			
			СнятьПризнакПроверкиУпаковки(ЭтотОбъект, НайденнаяСтрокаДерева, СнятьПризнакПроверкиУРодителя);
			СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НайденнаяСтрокаДерева);
			
		ИначеЕсли РодительНайденнойСтроки = СтрокаПроверяемойУпаковки Тогда
			
			Если НайденнаяСтрокаДерева = ТекущаяСтрокаДерева Тогда
				
				ИсходныйСтатусПроверки = НайденнаяСтрокаДерева.СтатусПроверки;
				ОтметитьСтрокуКакНайденную(НайденнаяСтрокаДерева);
				Если ИсходныйСтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.ВНаличии")
					Или ИсходныйСтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась")
					Или НайденнаяСтрокаДерева.ИдетПроверкаДаннойУпаковки Тогда
					ИзменитьСостояниеПроверкиУпаковки(ЭтотОбъект, НайденнаяСтрокаДерева);
				КонецЕсли;
				
			Иначе
				
				Если РодительНайденнойСтроки = Неопределено Тогда
					СнятьПризнакПроверкиУпаковки(ЭтотОбъект, ТекущаяСтрокаДерева);
				КонецЕсли;
				
				ОтметитьСтрокуКакНайденную(НайденнаяСтрокаДерева);
				СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НайденнаяСтрокаДерева);
				
			КонецЕсли;
			
		ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими")
			И СтрокаПроверяемойУпаковки <> Неопределено Тогда
			
			ОтметитьСтрокуКакНайденную(НайденнаяСтрокаДерева);
			СнятьПризнакПроверкиУпаковки(ЭтотОбъект, СтрокаПроверяемойУпаковки);
			СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НайденнаяСтрокаДерева);
			
		КонецЕсли;
		
		УдалитьСтрокуПриОбратномСканировании(НайденнаяСтрокаДерева);
		
	Иначе
		
		СтрокаПроверяемойУпаковки = СтрокаТекущейПроверяемойУпаковки(ЭтотОбъект, Ложь, Ложь);
		ИдентификаторУпаковки     = ИдентификаторТекущейПроверяемойУпаковки;
		
		Если (РодительНайденнойСтроки = Неопределено
				Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
				Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки())
			И ИдентификаторУпаковки = -1 Тогда
			
			ОтметитьСтрокуКакНайденную(НайденнаяСтрокаДерева);
			СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НайденнаяСтрокаДерева);
			УдалитьСтрокуПриОбратномСканировании(НайденнаяСтрокаДерева);
			
		ИначеЕсли РодительНайденнойСтроки.ПолучитьИдентификатор() = ИдентификаторУпаковки Тогда
			
			ОтметитьСтрокуКакНайденную(НайденнаяСтрокаДерева);
			СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НайденнаяСтрокаДерева);
			УдалитьСтрокуПриОбратномСканировании(НайденнаяСтрокаДерева);
			
		ИначеЕсли ЗагрузкаДанныхТСД <> Неопределено Тогда
			
			ОтметитьСтрокуКакНайденную(НайденнаяСтрокаДерева);
			ПереместитьПачку(НайденнаяСтрокаДерева, СтрокаПроверяемойУпаковки);
			
		Иначе
			
			Если (РодительНайденнойСтроки.НеСодержитсяВДанныхДокумента
					Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
					Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки())
				И (СтрокаПроверяемойУпаковки.НеСодержитсяВДанныхДокумента
					Или СтрокаПроверяемойУпаковки.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
					Или СтрокаПроверяемойУпаковки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки()) Тогда
				
				ОтметитьСтрокуКакНайденную(НайденнаяСтрокаДерева);
				ПереместитьПачку(НайденнаяСтрокаДерева, СтрокаПроверяемойУпаковки);
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьСканированиеИмеющегосяВДеревеШтрихкода(ДанныеШтрихкода, ТекущаяСтрокаДерева, ИдентификаторНайденнойСтроки)
	
	НайденнаяСтрокаДерева = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторНайденнойСтроки);
	
	Если НайденнаяСтрокаДерева = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ТипУпаковкиГдеНашли = Неопределено;
	
	Если ТребуетсяОткрытиеФормыВыбораДействия(НайденнаяСтрокаДерева, ТекущаяСтрокаДерева, ТипУпаковкиГдеНашли) Тогда
		ОткрытьФормуВыбораДействия(ДанныеШтрихкода, НайденнаяСтрокаДерева, ТипУпаковкиГдеНашли);
		Возврат;
	КонецЕсли;
	
	ЗаполнитьСтрокуДереваПоДаннымШтрихкода(ЭтотОбъект, НайденнаяСтрокаДерева, ДанныеШтрихкода, ТаблицаИзмененийТабачнойПродукции, КэшированныеЗначения);
	
	Если ТребуетсяОткрытиеФормыУточненияДанных(НайденнаяСтрокаДерева) Тогда
		ОткрытьФормуУточненияДанных(ИдентификаторНайденнойСтроки, ТекущаяСтрокаДерева);
		Возврат;
	КонецЕсли;
	
	ЗаполнитьСтрокуДереваПоДаннымВыбора(НайденнаяСтрокаДерева, ДанныеВыбораПоМаркируемойПродукции);
	ОбработатьНайденныйВДеревеШтрихкод(НайденнаяСтрокаДерева, ТекущаяСтрокаДерева, ДанныеШтрихкода);
	ШтрихкодированиеИСМПКлиент.СохранениеПолногоКодаМаркировки(ДанныеШтрихкода, ПараметрыСканирования);
	ОбработатьОчереднойШтрихкод();
	
КонецПроцедуры

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

&НаКлиенте
Функция ТребуетсяОткрытиеФормыВыбораДействия(НайденнаяСтрокаДерева, ТекущаяСтрокаДерева, ТипУпаковкиГдеНашли)
	
	РодительНайденнойСтроки = НайденнаяСтрокаДерева.ПолучитьРодителя();
	ТребуетсяОткрытиеФормыВыбораДействия = Истина;
	
	Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(НайденнаяСтрокаДерева.ТипУпаковки) Тогда
		
		Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
			Возврат ТребуетсяОткрытиеФормыВыбораДействия;
		КонецЕсли;
		
		ЭтоГрупповаяУпаковка = ЭтоГрупповаяУпаковкаИлиНабор(НайденнаяСтрокаДерева.ВидУпаковки);
		
		СтрокаПроверяемойУпаковки = СтрокаТекущейПроверяемойУпаковки(ЭтотОбъект, Истина, ЭтоГрупповаяУпаковка);
		
		Если НайденнаяСтрокаДерева.ИдетПроверкаДаннойУпаковки Тогда
			
			ТребуетсяОткрытиеФормыВыбораДействия = Ложь;
			
		ИначеЕсли РодительНайденнойСтроки = СтрокаПроверяемойУпаковки Тогда
			
			ТребуетсяОткрытиеФормыВыбораДействия = Ложь;
			
		ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими")
			И СтрокаПроверяемойУпаковки <> Неопределено Тогда
			
			ТребуетсяОткрытиеФормыВыбораДействия = Ложь;
			
		КонецЕсли;
		
	Иначе
		
		СтрокаПроверяемойУпаковки = СтрокаТекущейПроверяемойУпаковки(ЭтотОбъект, Ложь, Ложь);
		ИдентификаторУпаковки     = ИдентификаторТекущейПроверяемойУпаковки;
		
		Если (РодительНайденнойСтроки = Неопределено
				Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
				Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки())
			И ИдентификаторУпаковки = -1 Тогда
			
			ТребуетсяОткрытиеФормыВыбораДействия = Ложь;
			
		ИначеЕсли РодительНайденнойСтроки.ПолучитьИдентификатор() = ИдентификаторУпаковки Тогда
			
			ТребуетсяОткрытиеФормыВыбораДействия = Ложь;
			
		Иначе
			
			Если (РодительНайденнойСтроки.НеСодержитсяВДанныхДокумента
					Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
					Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки())
				И (СтрокаПроверяемойУпаковки.НеСодержитсяВДанныхДокумента
					Или СтрокаПроверяемойУпаковки.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
					Или СтрокаПроверяемойУпаковки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки()) Тогда
				
				ТребуетсяОткрытиеФормыВыбораДействия = Ложь;
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
	Если СтрокаПроверяемойУпаковки <> Неопределено Тогда
		ТипУпаковкиГдеНашли = СтрокаПроверяемойУпаковки.ТипУпаковки;
	КонецЕсли;
	
	Возврат ТребуетсяОткрытиеФормыВыбораДействия;
	
КонецФункции

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

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

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

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

&НаКлиенте
Процедура ПоискПоШтрихкодуЗавершение(ДанныеШтрихкода, ДополнительныеПараметры = Неопределено) Экспорт
	
	Если ДанныеШтрихкода = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ДополнительныеПараметры <> Неопределено И ДополнительныеПараметры.Свойство("ЭтоГенерацияШтрихкодовУпаковок") Тогда
		ДанныеШтрихкода.Вставить("ЭтоГенерацияШтрихкодовУпаковок", Истина);
	КонецЕсли;
	
	// Если штрихкод упаковки найден в соответствии СоответствиеШтрихкодовСтрокДерева, то детальные
	// данные по штрихкоду не собираются. В этом случае в ДанныеШтрихкода есть 2 поля: Штрихкод и Количество.
	Если ДанныеШтрихкода.Свойство("ШтрихкодУпаковки") Тогда
		
		ОбработатьОтсканированныйШтрихкод(ДанныеШтрихкода);
		
	Иначе
		
		ТекущаяСтрокаДерева = Элементы.ДеревоМаркированнойПродукции.ТекущиеДанные;
		
		ИдентификаторСтрокиДерева = ИдентификаторСтрокиДереваПоШтрихкоду(ДанныеШтрихкода.Штрихкод, Истина);
		
		ОбработатьСканированиеИмеющегосяВДеревеШтрихкода(ДанныеШтрихкода,
		                                                 ТекущаяСтрокаДерева,
		                                                 ИдентификаторСтрокиДерева);
		
		ПроверитьСоответствиеОтборуПриИзмененииСтроки(ТекущаяСтрокаДерева);
		
	КонецЕсли;
	
	Если ТаблицаИзмененийТабачнойПродукции.Количество() > 0 Тогда
		ОбработатьТаблицуИзмененийПодобраннойПродукции(ЭтотОбъект, КэшированныеЗначения);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ВыборДействияПоРезультатамВводаШтрихкодаПриЗавершении(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = Неопределено Или Результат = КодВозвратаДиалога.Отмена Тогда
		ОбработатьОчереднойШтрихкод();
		Возврат;
	КонецЕсли;
	
	Если Не ТипЗнч(Результат) = Тип("Структура") Тогда
		Возврат;
	КонецЕсли;
	
	ДанныеШтрихкода = Неопределено;
	Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура")
		И ДополнительныеПараметры.Свойство("ДанныеШтрихкода") Тогда
		ДанныеШтрихкода = ДополнительныеПараметры.ДанныеШтрихкода;
	КонецЕсли;
	
	Если Результат.ВидДействия = "ДобавлениеТабачнойнойПродукции" Тогда
		
		ДобавитьНовуюТабачнуюПродукциюВДерево(?(ДанныеШтрихкода <> Неопределено, ДанныеШтрихкода, Результат));
	
	ИначеЕсли Результат.ВидДействия = "ПереместитьУпаковкуВДругуюУпаковку" Тогда
		
		ПереместитьУпаковкуВДругуюУпаковку(ДополнительныеПараметры.ИдентификаторНайденнойСтроки, 
		                                   Результат.ШтрихкодУпаковкиНазначения,
		                                   Результат.СтатусПроверки);
		
	ИначеЕсли Результат.ВидДействия = "ПереместитьПачкуВДругуюУпаковку" Тогда
		
		ПереместитьПачкуВДругуюУпаковку(ДополнительныеПараметры.ИдентификаторНайденнойСтроки, 
		                                  Результат.ШтрихкодУпаковкиНазначения,
		                                  Результат.СтатусПроверки);
		
	ИначеЕсли Результат.ВидДействия = "ПереместитьВПачкиБезБлока" Тогда
		
		ПереместитьВПачкиБезБлока(ДополнительныеПараметры.ИдентификаторНайденнойСтроки,
		                               ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.ВНаличии"),
		                               Результат.ИзменятьКонтекстПроверки);
		
	ИначеЕсли Результат.ВидДействия = "ПереместитьВБлокиБезКоробки" Тогда
		
		ПереместитьВБлокиБезКоробки(ДополнительныеПараметры.ИдентификаторНайденнойСтроки,
		                               ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.ВНаличии"),
		                               Результат.ИзменятьКонтекстПроверки);
		
	ИначеЕсли Результат.ВидДействия = "ПоместитьНовуюВПачкиБезБлока" Тогда
		
		ПоместитьНовуюВПачкиБезБлока(Результат);
		
	ИначеЕсли Результат.ВидДействия = "ОтложитьНайденноеВДругоеМесте" Тогда
		
		ТекущиеДанныеДерева = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ДополнительныеПараметры.ИдентификаторНайденнойСтроки);
		Если ТекущиеДанныеДерева <> Неопределено Тогда
			
			ОтметитьСтрокуКакОтложенную(ТекущиеДанныеДерева);
			
		КонецЕсли;
		
	ИначеЕсли Результат.ВидДействия = "ИзменитьКонтекстПроверки" Тогда
		
		ТекущиеДанныеДерева = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ДополнительныеПараметры.ИдентификаторНайденнойСтроки);
		
		Если ТекущиеДанныеДерева <> Неопределено Тогда
			
			ОтметитьСтрокуКакНайденную(ТекущиеДанныеДерева);
			ИзменитьКонтекстПроверки(ТекущиеДанныеДерева.ПолучитьРодителя());
			
		КонецЕсли;
		
	ИначеЕсли Результат.ВидДействия = "ДобавитьНовуюУпаковку" Тогда
		
		Если ДанныеШтрихкода = Неопределено Тогда
			ПараметрДанныеШтрихкода = Результат;
			ПараметрТипУпаковки     = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МонотоварнаяУпаковка");
		Иначе
			ПараметрДанныеШтрихкода = ДанныеШтрихкода;
			ПараметрТипУпаковки     = ДанныеШтрихкода.ТипУпаковки;
		КонецЕсли;
		
		ДобавитьНовуюУпаковку(ПараметрДанныеШтрихкода, ПараметрТипУпаковки, Истина);
		
	КонецЕсли;
	
	ОбработатьОчереднойШтрихкод();

	Если ТаблицаИзмененийТабачнойПродукции.Количество() > 0 Тогда
		ОбработатьТаблицуИзмененийПодобраннойПродукции(ЭтотОбъект, КэшированныеЗначения);
	КонецЕсли;

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

&НаКлиенте
Процедура ОбработатьОтсканированныйШтрихкод(ДанныеШтрихкода)

	Если ДанныеШтрихкода = Неопределено Тогда
		Возврат;
	КонецЕсли;

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

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

&НаКлиенте
Процедура ИнформацияОНевозможностиДобавленияОтсканированногоПослеЗакрытия(Результат, ДополнительныеПараметры) Экспорт
	
	ОбработатьОчереднойШтрихкод();
	
КонецПроцедуры

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

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

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

#Область ПеремещениеДобавлениеПачекИУпаковок

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

&НаКлиенте
Процедура ПоместитьНовуюВПачкиБезБлока(ДанныеШтрихкода)
	
	СтрокаПачкиБезБлока = СтрокаПотребительскиеУпаковкиБезУпаковки(ЭтотОбъект);
	
	ДобавитьНовуюТабачнуюПродукциюВДерево(ДанныеШтрихкода, СтрокаПачкиБезБлока);
	
КонецПроцедуры

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

	НоваяСтрока.НеСодержитсяВДанныхДокумента = Истина;
	НоваяСтрока.ВидУпаковки                  = ДанныеШтрихкода.ВидУпаковки;

	Если Не РежимПодбораСуществующихУпаковок Тогда
		НоваяСтрока.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась");
	Иначе
		НоваяСтрока.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.ВНаличии");
	КонецЕсли;
	
	НоваяСтрока.КоличествоПодчиненныхПотребительскихУпаковок = ДанныеШтрихкода.КоличествоПотребительскихУпаковок;
	Если ЭтоКодМаркировкиГрупповойУпаковкиИлиНабора Тогда
		
		Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами")
			Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками") Тогда
			НоваяСтрока.НеПересчитыватьКоличествоПотребительскихУпаковок = Истина;
		КонецЕсли;
		
		НоваяСтрока.ТипУпаковки = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МонотоварнаяУпаковка");
		
	ИначеЕсли ЭтоКодЛогистическойУпаковки Тогда
		
		Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
			НоваяСтрока.НеПересчитыватьКоличествоПотребительскихУпаковок = Истина;
		КонецЕсли;
		
		НоваяСтрока.ТипУпаковки = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МонотоварнаяУпаковка");
		
	Иначе
		НоваяСтрока.ТипУпаковки = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МаркированныйТовар");
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(НоваяСтрока.Номенклатура) Тогда
		НоваяСтрока.ПредставлениеСодержимоеУпаковки = ДанныеШтрихкода.ПредставлениеНоменклатуры;
	КонецЕсли;
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПроверитьДопустимостьКодаМаркировки(НоваяСтрока, ПараметрыПроверкиКодовМаркировки);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(НоваяСтрока, Ложь, ЗагрузкаДанныхТСД);
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.УстановитьИндексКартинкиТипаУпаковки(НоваяСтрока);
	ПроверкаИПодборПродукцииИСМПКлиентСервер.УстановитьИндексКартинкиСтатусаПроверки(НоваяСтрока);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.СформироватьПредставлениеПроверкиПодчиненных(НоваяСтрока);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.СформироватьПредставлениеСодержимогоУпаковки(НоваяСтрока);
	ПроверкаИПодборПродукцииИСМПКлиентСервер.СформироватьПредставлениеДляСтрокиДереваМаркированнойПродукции(НоваяСтрока, ВидМаркируемойПродукции);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(НоваяСтрока, ЗагрузкаДанныхТСД);
	
	Если Не РежимПодбораСуществующихУпаковок Тогда
		ДополнительныеПараметры = ПроверкаИПодборПродукцииИСМПКлиентСервер.ПараметрыДобавленияСтрокиПодобраннойПродукции();
		ДополнительныеПараметры.УточнитьКоличествоИС = Истина;
		ПодобраннаяПродукцияПриДобавленииСтроки(ЭтотОбъект, НоваяСтрока, КэшированныеЗначения, ДополнительныеПараметры);
	Иначе
		ДобавитьСтрокуВТаблицуИзменений(ТаблицаИзмененийТабачнойПродукции, НоваяСтрока, 1);
	КонецЕсли;
	
	ИдентификаторСтроки = НоваяСтрока.ПолучитьИдентификатор();
	СоответствиеШтрихкодовСтрокДерева.Вставить(НоваяСтрока.НормализованныйШтрихкод, ИдентификаторСтроки);
	
	Если ЭтоКодМаркировкиГрупповойУпаковкиИлиНабора
		И ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками") Тогда
		// Контекст не меняем
	ИначеЕсли (ЭтоКодЛогистическойУпаковки Или ЭтоКодМаркировкиГрупповойУпаковкиИлиНабора)
		И ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		// Контекст не меняем
	ИначеЕсли ЭтоКодМаркировкиГрупповойУпаковкиИлиНабора Или ЭтоКодЛогистическойУпаковки Тогда
		ИзменитьКонтекстПроверки(НоваяСтрока);
	КонецЕсли;
	
	СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НоваяСтрока);
	
	Если ДетализацияСтруктурыХранения <> ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки")
		И ДетализацияСтруктурыХранения <> ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими")
		И ДобавлятьВУпаковку <> ДеревоМаркированнойПродукции
		И ДобавлятьВУпаковку.ТипУпаковки <> ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
		И ДобавлятьВУпаковку.ТипУпаковки <> ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
		ПриИзмененииМаркировкиСоставаУпаковкиНаКлиенте(ИдентификаторСтроки, ЗагрузкаДанныхТСД = Неопределено);
	КонецЕсли;
	
	ДобавленнаяПотребительскаяУпаковка(ЭтотОбъект, НоваяСтрока, "Добавить");
	
	Модифицированность = Истина;
	
КонецПроцедуры

&НаКлиенте
Процедура ПереместитьВПачкиБезБлока(ИдентификаторСтрокиПеремещаемойПачки, СтатусПроверки = Неопределено, ИзменятьКонтекстПроверки = Ложь)
	
	СтрокаНазначения   = СтрокаПотребительскиеУпаковкиБезУпаковки(ЭтотОбъект);
	ПеремещаемаяСтрока = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторСтрокиПеремещаемойПачки);
	
	ПереместитьПачку(ПеремещаемаяСтрока, СтрокаНазначения, СтатусПроверки);
	
	Если ИзменятьКонтекстПроверки Тогда
		ИзменитьКонтекстПроверки(Неопределено);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПереместитьВБлокиБезКоробки(ИдентификаторСтрокиПеремещаемойПачки, СтатусПроверки = Неопределено, ИзменятьКонтекстПроверки = Ложь)
	
	СтрокаНазначения   = СтрокаГрупповыеУпаковкиБезКоробки(ЭтотОбъект);
	ПеремещаемаяСтрока = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторСтрокиПеремещаемойПачки);
	
	ПереместитьБлок(ПеремещаемаяСтрока, СтрокаНазначения, СтатусПроверки);
	
	Если ИзменятьКонтекстПроверки Тогда
		ИзменитьКонтекстПроверки(Неопределено);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПереместитьПачкуВДругуюУпаковку(ИдентификаторСтрокиПеремещаемойПачки, ШтрихкодУпаковкиНазначения, СтатусПроверки = Неопределено)
	
	ИдентификаторСтрокиУпаковкиНазначения = ИдентификаторСтрокиДереваПоШтрихкоду(ШтрихкодУпаковкиНазначения, Истина);
	
	СтрокаНазначения   = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторСтрокиУпаковкиНазначения);
	ПеремещаемаяСтрока = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторСтрокиПеремещаемойПачки);
	
	ПереместитьПачку(ПеремещаемаяСтрока, СтрокаНазначения, СтатусПроверки);
	ИзменитьКонтекстПроверки(СтрокаНазначения);
	
КонецПроцедуры

&НаКлиенте
Процедура ПереместитьПачку(СтрокаСПачкой, НоваяУпаковка, СтатусПроверки = Неопределено)
	
	ТекущаяУпаковка = СтрокаСПачкой.ПолучитьРодителя();
	
	НоваяСтрока = НоваяУпаковка.ПолучитьЭлементы().Добавить();
	ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаСПачкой);
	
	Если СтатусПроверки <> Неопределено Тогда
		Если НеобходимоУвеличитьКоличествоПодобраннойПродукции(РежимПодбораСуществующихУпаковок, НоваяСтрока, СтатусПроверки) Тогда
			ДобавитьСтрокуВТаблицуИзменений(ТаблицаИзмененийТабачнойПродукции, НоваяСтрока, +1);
		КонецЕсли;
		
		НоваяСтрока.СтатусПроверки = СтатусПроверки;
		ПроверкаИПодборПродукцииИСМПКлиентСервер.УстановитьИндексКартинкиСтатусаПроверки(НоваяСтрока);
	КонецЕсли;
	
	ТекущаяУпаковка.ПолучитьЭлементы().Удалить(СтрокаСПачкой);
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(ТекущаяУпаковка, Ложь, ЗагрузкаДанныхТСД);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(ТекущаяУпаковка, ЗагрузкаДанныхТСД);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(НоваяСтрока, ЗагрузкаДанныхТСД);
	
	МассивСтрокИзменившихсяУпаковок = Новый Массив;
	МассивСтрокИзменившихсяУпаковок.Добавить(НоваяУпаковка.ПолучитьИдентификатор());
	МассивСтрокИзменившихсяУпаковок.Добавить(ТекущаяУпаковка.ПолучитьИдентификатор());
	
	ПриИзмененииМаркировкиСоставаУпаковкиМассиваСтрок(МассивСтрокИзменившихсяУпаковок, Истина, КэшированныеЗначения);
	
	СоответствиеШтрихкодовСтрокДерева.Вставить(НоваяСтрока.НормализованныйШтрихкод, НоваяСтрока.ПолучитьИдентификатор());
	
	СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НоваяСтрока);
	
	Модифицированность = Истина;
	
КонецПроцедуры

&НаКлиенте
Процедура ПереместитьБлок(СтрокаСБлоком, НоваяУпаковка, СтатусПроверки = Неопределено)
	
	ТекущаяУпаковка = СтрокаСБлоком.ПолучитьРодителя();
	
	НоваяСтрока = НоваяУпаковка.ПолучитьЭлементы().Добавить();
	ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаСБлоком);
	
	Если СтатусПроверки <> Неопределено Тогда
		Если (ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
			Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами"))
			И НеобходимоУвеличитьКоличествоПодобраннойПродукции(РежимПодбораСуществующихУпаковок, НоваяСтрока, СтатусПроверки) Тогда
			ДобавитьСтрокуВТаблицуИзменений(ТаблицаИзмененийТабачнойПродукции, НоваяСтрока, +1);
		КонецЕсли;
		
		НоваяСтрока.СтатусПроверки = СтатусПроверки;
		ПроверкаИПодборПродукцииИСМПКлиентСервер.УстановитьИндексКартинкиСтатусаПроверки(НоваяСтрока);
	КонецЕсли;
	
	СоответствиеШтрихкодовСтрокДерева.Вставить(НоваяСтрока.НормализованныйШтрихкод, НоваяСтрока.ПолучитьИдентификатор());
	
	Если ДетализацияСтруктурыХранения <> ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
		И ДетализацияСтруктурыХранения <> ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		Для Каждого СтрокаСПачкой Из СтрокаСБлоком.ПолучитьЭлементы() Цикл
			СтрокаНовойПачкой = НоваяСтрока.ПолучитьЭлементы().Добавить();
			ЗаполнитьЗначенияСвойств(СтрокаНовойПачкой, СтрокаСПачкой);
			СоответствиеШтрихкодовСтрокДерева.Вставить(СтрокаНовойПачкой.НормализованныйШтрихкод, СтрокаНовойПачкой.ПолучитьИдентификатор());
		КонецЦикла;
	КонецЕсли;
	
	ТекущаяУпаковка.ПолучитьЭлементы().Удалить(СтрокаСБлоком);
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(ТекущаяУпаковка, Ложь, ЗагрузкаДанныхТСД);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(ТекущаяУпаковка, ЗагрузкаДанныхТСД);
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(НоваяСтрока, ЗагрузкаДанныхТСД);
	
	МассивСтрокИзменившихсяУпаковок = Новый Массив;
	МассивСтрокИзменившихсяУпаковок.Добавить(НоваяУпаковка.ПолучитьИдентификатор());
	МассивСтрокИзменившихсяУпаковок.Добавить(ТекущаяУпаковка.ПолучитьИдентификатор());
	
	ПриИзмененииМаркировкиСоставаУпаковкиМассиваСтрок(МассивСтрокИзменившихсяУпаковок, Истина, КэшированныеЗначения);
	
	СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НоваяСтрока);
	
	Модифицированность = Истина;
	
КонецПроцедуры

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

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

&НаКлиентеНаСервереБезКонтекста
Функция ПеремещениеЭлементаДереваВозможно(СтрокаНазначение, ПеремещаемаяСтрока)
	
	Если ПеремещаемаяСтрока = СтрокаНазначение Тогда
		Возврат Ложь;
	КонецЕсли;

	Если ПеремещаемаяСтрока.ПолучитьРодителя() = СтрокаНазначение Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Для Каждого ПодчиненнаяСтрока Из ПеремещаемаяСтрока.ПолучитьЭлементы() Цикл
		
		Если ПодчиненнаяСтрока = СтрокаНазначение Тогда
			Возврат Ложь;
		КонецЕсли;
		
		РезультатПроверкиПодчиненнойСтроки = ПеремещениеЭлементаДереваВозможно(СтрокаНазначение, ПодчиненнаяСтрока);
		
		Если НЕ РезультатПроверкиПодчиненнойСтроки Тогда
			Возврат Ложь;
		КонецЕсли;
		
	КонецЦикла;
		
	Возврат Истина;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция СтрокаПотребительскиеУпаковкиБезУпаковки(Форма)
	
	Возврат НайтиПоИдентификатору(Форма.ДеревоМаркированнойПродукции, Форма.ИдентификаторСтрокиПотребительскиеУпаковкиБезУпаковки);
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция СтрокаГрупповыеУпаковкиБезКоробки(Форма)
	
	Возврат НайтиПоИдентификатору(Форма.ДеревоМаркированнойПродукции, Форма.ИдентификаторСтрокиГрупповыеУпаковкиБезКоробки);
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция СтрокаТекущейПроверяемойУпаковки(Форма, ЭтоУпаковка, ЭтоГрупповаяУпаковка)
	
	Если Форма.ИдентификаторТекущейПроверяемойУпаковки = - 1 Тогда
		
		Если Не ЭтоУпаковка Тогда
			Возврат СтрокаПотребительскиеУпаковкиБезУпаковки(Форма);
		ИначеЕсли ЭтоГрупповаяУпаковка Тогда
			Возврат СтрокаГрупповыеУпаковкиБезКоробки(Форма);
		Иначе
			Возврат Неопределено;
		КонецЕсли;
		
	Иначе
		
		Если Не ЭтоУпаковка Тогда
			Возврат НайтиПоИдентификатору(Форма.ДеревоМаркированнойПродукции, Форма.ИдентификаторТекущейПроверяемойУпаковки);
		ИначеЕсли ЭтоГрупповаяУпаковка Тогда
			Если Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
				Возврат Неопределено;
			КонецЕсли;
			Возврат НайтиПоИдентификатору(Форма.ДеревоМаркированнойПродукции, Форма.ИдентификаторТекущейПроверяемойУпаковки);
		Иначе
			Если Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими")
				Или Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
				Возврат Неопределено;
			Иначе
				Возврат НайтиПоИдентификатору(Форма.ДеревоМаркированнойПродукции, Форма.ИдентификаторТекущейПроверяемойУпаковки);
			КонецЕсли;
		КонецЕсли;
		
	КонецЕсли;
	
КонецФункции

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

#Область СканированиеСуществующихУпаковокИТабачнойПродукции

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

&НаСервере
Функция ЕстьДублиВОсканированнойУпаковке(СтрокиДерева, СоответствиеШтрихкодовСтрокДерева)
	
	ЕстьОшибки = Ложь;
	
	Если СтрокиДерева.Количество() = 0 Тогда
		Возврат ЕстьОшибки;
	КонецЕсли;
	
	ДеревоУпаковок = СтрокиДерева[0].Владелец();
	
	Если ДеревоУпаковок.Колонки.Найти("ЕстьОшибки") = Неопределено Тогда
		ДеревоУпаковок.Колонки.Добавить("ЕстьОшибки", Новый ОписаниеТипов("Булево"));
		ДеревоУпаковок.Колонки.Добавить("ТекстОшибки", ОбщегоНазначения.ОписаниеТипаСтрока(500));
	КонецЕсли;
	
	Для Каждого СтрокаДерева Из СтрокиДерева Цикл
		
		ПроверитьНаДубльВСтрокеДерева(СтрокаДерева, СоответствиеШтрихкодовСтрокДерева, ЕстьОшибки)
		
	КонецЦикла;
	
	Возврат ЕстьОшибки;
	
КонецФункции

&НаСервере
Процедура ПроверитьНаДубльВСтрокеДерева(СтрокаДерева, СоответствиеШтрихкодовСтрокДерева, ЕстьОшибки)

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

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

&НаСервере
Функция ВсеВложенныеУпаковкиЕстьВДереве(СтрокиДерева, СоответствиеШтрихкодовСтрокДерева)
	
	ЕстьОшибки = Ложь;
	
	Если СтрокиДерева.Количество() = 0 Тогда
		Возврат ЕстьОшибки;
	КонецЕсли;
	
	ДеревоУпаковок = СтрокиДерева[0].Владелец();
	Если ДеревоУпаковок.Колонки.Найти("ЕстьОшибки") = Неопределено Тогда
		ДеревоУпаковок.Колонки.Добавить("ЕстьОшибки", Новый ОписаниеТипов("Булево"));
		ДеревоУпаковок.Колонки.Добавить("ТекстОшибки", ОбщегоНазначения.ОписаниеТипаСтрока(500));
	КонецЕсли;
	
	Для Каждого СтрокаДерева Из СтрокиДерева Цикл
		
		Если СоответствиеШтрихкодовСтрокДерева.Получить(СтрокаДерева.НормализованныйШтрихкод) = Неопределено Тогда
			
			СтрокаДерева.ЕстьОшибки = Истина;
			СтрокаДерева.ТекстОшибки = НСтр("ru = 'Отсутствует в структуре упаковок'");
			
			ЕстьОшибки = Истина;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ЕстьОшибки;
	
КонецФункции

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

&НаСервере
Функция ДобавляемыйШтрихкодСоответствуетИерархии(ДанныеШтрихкода)
	
	ТекущаяПроверяемаяУпаковка = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторТекущейПроверяемойУпаковки);
	
	Если ТекущаяПроверяемаяУпаковка = Неопределено Тогда
		Возврат Истина;
	КонецЕсли;
	
	Если ТекущаяПроверяемаяУпаковка.ВидУпаковки = Перечисления.ВидыУпаковокИС.Логистическая Тогда
		
		Возврат Истина;
		
	ИначеЕсли ЭтоГрупповаяУпаковкаИлиНабор(ТекущаяПроверяемаяУпаковка.ВидУпаковки) Тогда
		
		Возврат (ДанныеШтрихкода.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская);
		
	ИначеЕсли ТекущаяПроверяемаяУпаковка.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
		
		Возврат ЭтоГрупповаяУпаковкаИлиНабор(ДанныеШтрихкода.ВидУпаковки);
		
	ИначеЕсли ТекущаяПроверяемаяУпаковка.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки() Тогда
		
		Возврат (ДанныеШтрихкода.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская);
		
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

&НаСервере
Функция ПреобразоватьСчитаннуюУпаковкуЕслиНеобходимо(КешСтрок, Штрихкод, СчитанныйКодНеСоответствуетДетализации = Неопределено)
	
	СтрокаДерева = КешСтрок[Штрихкод];
	
	Если СтрокаДерева = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Результат = Новый Массив;
	
	ДетализацияСтруктурыХраненияДерева = ДетализацияСтруктурыХраненияДерева(СтрокаДерева);
	
	Если ДетализацияСтруктурыХранения = Перечисления.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки
		// Требуется выполнить преобразование
		 И (ДетализацияСтруктурыХраненияДерева = Перечисления.ДетализацияСтруктурыХраненияИС.Полная
		Или ДетализацияСтруктурыХраненияДерева = Перечисления.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами
		Или ДетализацияСтруктурыХраненияДерева = Перечисления.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками
		Или ДетализацияСтруктурыХраненияДерева = Перечисления.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими) Тогда
		
		СчитанныйКодНеСоответствуетДетализации = Истина;
		ПреобразоватьДетализациюСчитаннойУпаковкиДоПотребительскойУпаковки(СтрокаДерева, Результат);
		
	ИначеЕсли ДетализацияСтруктурыХранения = Перечисления.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими
		// Требуется выполнить преобразование
		 И (ДетализацияСтруктурыХраненияДерева = Перечисления.ДетализацияСтруктурыХраненияИС.Полная
		Или ДетализацияСтруктурыХраненияДерева = Перечисления.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами
		Или ДетализацияСтруктурыХраненияДерева = Перечисления.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками) Тогда
		
		СчитанныйКодНеСоответствуетДетализации = Истина;
		ПреобразоватьДетализациюСчитаннойУпаковкиДоБлокаСПачками(СтрокаДерева, Результат);
		
	Иначе
		
		Результат.Добавить(СтрокаДерева);
		
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

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

#Область ОбработкаИзмененийТабачнойПродукции

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

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

&НаКлиентеНаСервереБезКонтекста
Процедура ДобавитьСтрокуВТаблицуИзменений(ТаблицаИзмененийТабачнойПродукции, СтрокаДерева, Изменение)
	
	НоваяСтрока = ТаблицаИзмененийТабачнойПродукции.Добавить();
	ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДерева);
	НоваяСтрока.ПредставлениеНоменклатуры = СтрокаДерева.ПредставлениеСодержимоеУпаковки;
	
	Если СтрокаДерева.ТипУпаковки = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МаркированныйТовар") Тогда
		НоваяСтрока.Изменение = Изменение;
	Иначе
		НоваяСтрока.Изменение = Изменение * СтрокаДерева.КоличествоПодчиненныхПотребительскихУпаковок;
	КонецЕсли;
	
КонецПроцедуры

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

&НаКлиенте
Процедура ОбработатьПодчиненныеСтрокиДереваПриУдалении(ТаблицаИзмененийПодобраннойПродукции, СтрокаДерева)
	
	Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.ПолучитьЭлементы() Цикл
		
		ОбработатьПодчиненныеСтрокиДереваПриУдалении(ТаблицаИзмененийПодобраннойПродукции, ПодчиненнаяСтрока);
		
		ОбработатьСтрокуДереваПриУдалении(ТаблицаИзмененийПодобраннойПродукции, ПодчиненнаяСтрока);
		
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьСтрокуДереваПриУдалении(ТаблицаИзмененийПодобраннойПродукции, УдаляемыйЭлемент)
	
	ДополнитьТаблицуИзменений = Истина;
	Если РежимПодбораСуществующихУпаковок Тогда
		Если УдаляемыйЭлемент.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.Отсутствует") Тогда
			ДополнитьТаблицуИзменений = Ложь;
		КонецЕсли;
	ИначеЕсли УдаляемыйЭлемент.СтатусПроверки <> ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.ВНаличии")
		И УдаляемыйЭлемент.СтатусПроверки <> ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась") Тогда
		ДополнитьТаблицуИзменений = Ложь;
	КонецЕсли;
	
	Если ДополнитьТаблицуИзменений Тогда
		Если Не РежимПодбораСуществующихУпаковок
			И УдаляемыйЭлемент.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась") Тогда
			ДополнительныеПараметры = ПроверкаИПодборПродукцииИСМПКлиентСервер.ПараметрыДобавленияСтрокиПодобраннойПродукции();
			ДополнительныеПараметры.УточнитьКоличествоИС = Истина;
			ПодобраннаяПродукцияПриУдаленииСтроки(ЭтотОбъект, УдаляемыйЭлемент, КэшированныеЗначения, ДополнительныеПараметры);
		Иначе
			ДобавитьСтрокуВТаблицуИзменений(ТаблицаИзмененийПодобраннойПродукции, УдаляемыйЭлемент, - 1);
		КонецЕсли;
	КонецЕсли;
	
	Если ИнтеграцияИСКлиентСервер.ЭтоУпаковка(УдаляемыйЭлемент.ТипУпаковки) Тогда
		ЭлементСписка = ДобавленныеУпаковки.НайтиПоЗначению(УдаляемыйЭлемент.Штрихкод);
		Если ЭлементСписка <> Неопределено Тогда
			ДобавленныеУпаковки.Удалить(ЭлементСписка);
		КонецЕсли;
	Иначе
		ДобавленнаяПотребительскаяУпаковка(ЭтотОбъект, УдаляемыйЭлемент.Штрихкод, "Удалить");
	КонецЕсли;
	
	СоответствиеШтрихкодовСтрокДерева.Удалить(УдаляемыйЭлемент.НормализованныйШтрихкод);
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ОбработатьТаблицуИзмененийПодобраннойПродукции(Форма, КэшированныеЗначения)
	
	ТаблицаИзменений = Форма.ТаблицаИзмененийТабачнойПродукции;
	
	Если ТаблицаИзменений.Количество() > 1 Тогда
		#Если Сервер Или ТолстыйКлиентУправляемоеПриложение Или ТолстыйКлиентОбычноеПриложение Тогда
		ТаблицаИзменений = ДанныеФормыВЗначение(ТаблицаИзменений, Тип("ТаблицаЗначений"));
		#Иначе
		ЗначенияСтрокТаблицыИзменений = Новый Массив;
		Для Каждого СтрокаТаблицы Из ТаблицаИзменений Цикл
			ЗначенияСтроки = Новый Структура(Форма.ЗначенияСтрокиПоУмолчаниюДляТаблицыИзмененийПодобраннойПродукции);
			ЗаполнитьЗначенияСвойств(ЗначенияСтроки, СтрокаТаблицы);
			ЗначенияСтрокТаблицыИзменений.Добавить(ЗначенияСтроки);
		КонецЦикла;
		ТаблицаИзменений = ЗначенияСтрокТаблицыИзменений;
		#КонецЕсли
		СвернутьТаблицуИзмененийПодобраннойПродукции(ТаблицаИзменений, Форма.ВидМаркируемойПродукции, Форма.ПараметрыСканирования);
	КонецЕсли;
	
	Для Каждого СтрокаТаблицы Из ТаблицаИзменений Цикл
		
		Если СтрокаТаблицы.Изменение > 0 Тогда
			
			ПодобраннаяПродукцияПриДобавленииСтроки(Форма, СтрокаТаблицы, КэшированныеЗначения);
			
		ИначеЕсли СтрокаТаблицы.Изменение < 0 Тогда
			
			ПодобраннаяПродукцияПриУдаленииСтроки(Форма, СтрокаТаблицы, КэшированныеЗначения);
			
		КонецЕсли;
		
	КонецЦикла;
	
	Форма.КоличествоСтрокПодобраннойТабачнойПродукции = Форма.ПодобраннаяМаркируемаяПродукция.Количество();
	
	Форма.ТаблицаИзмененийТабачнойПродукции.Очистить();

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

&НаСервереБезКонтекста
Процедура СвернутьТаблицуИзмененийПодобраннойПродукции(ТаблицаИзменений, ВидПродукции, ПараметрыСканирования)
	ПроверкаИПодборПродукцииИСМП.СвернутьТаблицуИзмененийПодобраннойПродукции(ТаблицаИзменений, ВидПродукции, ПараметрыСканирования);
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ТребуетсяОбработатьСтрокуИзмененийПродукции(Форма, СтрокаИзменений)
	
	// СтрокаИзменений - Строка таблицы ТаблицаИзмененийТабачнойПродукции, Строка дерева ДеревоМаркированнойПродукции
	
	Если ПустаяСтрока(СтрокаИзменений.GTIN) Тогда
		Возврат Ложь;
	ИначеЕсли СтрокаИзменений.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
		Возврат Истина;
	КонецЕсли;
	
	Если Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками") Тогда
		
		Если СтрокаИзменений.НеПересчитыватьКоличествоПотребительскихУпаковок Тогда
			Возврат ЭтоГрупповаяУпаковкаИлиНабор(СтрокаИзменений.ВидУпаковки)
				Или СтрокаИзменений.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая");
		КонецЕсли;
		
		Возврат ЭтоГрупповаяУпаковкаИлиНабор(СтрокаИзменений.ВидУпаковки);
		
	ИначеЕсли Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		
		Возврат ЭтоГрупповаяУпаковкаИлиНабор(СтрокаИзменений.ВидУпаковки)
			Или СтрокаИзменений.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая");
		
	КонецЕсли;
	
	Если СтрокаИзменений.НеПересчитыватьКоличествоПотребительскихУпаковок Тогда
		
		Возврат ЭтоГрупповаяУпаковкаИлиНабор(СтрокаИзменений.ВидУпаковки)
			Или СтрокаИзменений.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая");
		
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция НоменклатурыСтрокСовпадают(ИсходнаяСтрока, СтрокаИзменений, ПроверятьGTIN = Ложь)
	
	Если Не ПроверкаИПодборПродукцииИСМПКлиентСервер.НоменклатурыСтрокСовпадают(ИсходнаяСтрока, СтрокаИзменений) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если Не ПроверятьGTIN Тогда
		Возврат Истина;
	КонецЕсли;
	
	Возврат ПроверкаИПодборПродукцииИСМПКлиентСервер.GTINРавны(ИсходнаяСтрока.GTIN, СтрокаИзменений.GTIN);
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Процедура ПодобраннаяПродукцияПриУдаленииСтроки(Форма, СтрокаИзменений, КэшированныеЗначения, ДополнительныеПараметры = Неопределено)
	
	Если Не ТребуетсяОбработатьСтрокуИзмененийПродукции(Форма, СтрокаИзменений) Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(СтрокаИзменений) <> Тип("ДанныеФормыЭлементДерева") Тогда
		ИзменениеКоличества = СтрокаИзменений.Изменение;
	ИначеЕсли СтрокаИзменений.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская")Тогда
		ИзменениеКоличества = 1;
	ИначеЕсли Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
		Или Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		ИзменениеКоличества = СтрокаИзменений.КоличествоПодчиненныхПотребительскихУпаковок;
	ИначеЕсли ЭтоГрупповаяУпаковкаИлиНабор(СтрокаИзменений.ВидУпаковки)
		Или СтрокаИзменений.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
		ИзменениеКоличества = СтрокаИзменений.КоличествоПодчиненныхПотребительскихУпаковок;
	Иначе
		ИзменениеКоличества = 1;
	КонецЕсли;
	
	ПроверкаИПодборПродукцииИСМПКлиентСервер.ПодобраннаяПродукцияПриУдаленииСтроки(
		Форма, СтрокаИзменений, ИзменениеКоличества, ОбщийМодульКонтекстаПиП(), ДополнительныеПараметры, КэшированныеЗначения);
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ПодобраннаяПродукцияПриДобавленииСтроки(Форма, СтрокаИзменений, КэшированныеЗначения, ДополнительныеПараметры = Неопределено)
	
	Если Не ТребуетсяОбработатьСтрокуИзмененийПродукции(Форма, СтрокаИзменений) Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(СтрокаИзменений) <> Тип("ДанныеФормыЭлементДерева") Тогда
		ИзменениеКоличества = СтрокаИзменений.Изменение;
	ИначеЕсли СтрокаИзменений.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская")Тогда
		ИзменениеКоличества = 1;
	ИначеЕсли Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
		Или Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		ИзменениеКоличества = СтрокаИзменений.КоличествоПодчиненныхПотребительскихУпаковок;
	ИначеЕсли ЭтоГрупповаяУпаковкаИлиНабор(СтрокаИзменений.ВидУпаковки)
		Или СтрокаИзменений.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
		ИзменениеКоличества = СтрокаИзменений.КоличествоПодчиненныхПотребительскихУпаковок;
	Иначе
		ИзменениеКоличества = 1;
	КонецЕсли;
	
	ПроверкаИПодборПродукцииИСМПКлиентСервер.ПодобраннаяПродукцияПриДобавленииСтроки(
		Форма, СтрокаИзменений, ИзменениеКоличества, ОбщийМодульКонтекстаПиП(), ДополнительныеПараметры, КэшированныеЗначения);
	
КонецПроцедуры

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

#Область ОбработкаИзмененийНоменклатуры

&НаКлиенте
Процедура ПриВыбореНоменклатуры(ВыбранноеЗначение, ДополнительныеПараметры) Экспорт
	
	ТекущиеДанные = Элементы.ПодобраннаяМаркируемаяПродукция.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанные.Номенклатура = ВыбранноеЗначение;
	
	СобытияФормИСМПКлиентПереопределяемый.ПриИзмененииНоменклатуры(ЭтотОбъект,
		ТекущиеДанные, КэшированныеЗначения, ПараметрыУказанияСерий);
	
КонецПроцедуры

&НаКлиенте
Процедура ПриВыбореХарактеристики(ВыбранноеЗначение, ДополнительныеПараметры) Экспорт
	
	ТекущиеДанные = Элементы.ПодобраннаяМаркируемаяПродукция.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанные.Характеристика = ВыбранноеЗначение;
	
	СобытияФормИСМПКлиентПереопределяемый.ПриИзмененииХарактеристики(ЭтотОбъект,
		ТекущиеДанные, КэшированныеЗначения);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ОтменитьРегистрациюИзмененийНоменклатурыВСтроке()

	КоличествоИзменений = ТаблицаИзмененийНоменклатуры.Количество();
	
	Если КоличествоИзменений > 0 Тогда
		СтрокаИзменений = ТаблицаИзмененийНоменклатуры[КоличествоИзменений - 1];
		ТаблицаИзмененийНоменклатуры.Удалить(СтрокаИзменений);
	КонецЕсли;
	
КонецПроцедуры

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

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

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

&НаКлиентеНаСервереБезКонтекста
Процедура ОбработатьТаблицуИзмененийНоменклатуры(Форма)
	
	ИндексСтроки = 0;
	
	Пока ИндексСтроки < Форма.ТаблицаИзмененийНоменклатуры.Количество() Цикл
		СтрокаТаблицы = Форма.ТаблицаИзмененийНоменклатуры[ИндексСтроки];
		
		Если ТребуетсяОбработатьСтрокуИзмененийНоменклатуры(СтрокаТаблицы) Тогда
			ИндексСтроки = ИндексСтроки + 1;
		Иначе
			Форма.ТаблицаИзмененийНоменклатуры.Удалить(СтрокаТаблицы);
		КонецЕсли;
	КонецЦикла;
	
	Если Форма.ТаблицаИзмененийНоменклатуры.Количество() > 0 Тогда
		
		СтрокиИзмененныхУпаковок               = Новый Соответствие;
		СтрокиИзмененныхУпаковокВерхнегоУровня = Новый Соответствие;
		
		ИзменитьНоменклатуруВСтрокахДерева(Форма.ДеревоМаркированнойПродукции.ПолучитьЭлементы(),
			Форма.ТаблицаИзмененийНоменклатуры, СтрокиИзмененныхУпаковок);
		
		Для Каждого КлючИЗначение Из СтрокиИзмененныхУпаковок Цикл
			ПроверкаИПодборПродукцииИСМПКлиентСервер.ОпределитьТипУпаковкиПриИзмененииСтроки(
				Форма.ДеревоМаркированнойПродукции, КлючИЗначение.Ключ, ПроверкаИПодборПродукцииМОТПКлиентСервер, СтрокиИзмененныхУпаковокВерхнегоУровня);
		КонецЦикла;
		
		Для Каждого КлючИЗначение Из СтрокиИзмененныхУпаковокВерхнегоУровня Цикл
			ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(КлючИЗначение.Ключ, Истина);
		КонецЦикла;
		
		Форма.ТаблицаИзмененийНоменклатуры.Очистить();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ТребуетсяОбработатьСтрокуИзмененийНоменклатуры(СтрокаИзменений)
	
	Если СтрокаИзменений.Номенклатура <> СтрокаИзменений.НоваяНоменклатура
		Или СтрокаИзменений.Характеристика <> СтрокаИзменений.НоваяХарактеристика
		Или СтрокаИзменений.Серия <> СтрокаИзменений.НоваяСерия Тогда
		Возврат Истина;
	Иначе
		Возврат Ложь;
	КонецЕсли;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Процедура ИзменитьНоменклатуруВСтрокахДерева(СтрокиДерева, ТаблицаИзмененийНоменклатуры, СтрокиИзмененныхУпаковок)
	
	Для Каждого СтрокаДерева Из СтрокиДерева Цикл
		
		ПодчиненныеСтроки = СтрокаДерева.ПолучитьЭлементы();
		Если ПодчиненныеСтроки.Количество() > 0 Тогда
			ИзменитьНоменклатуруВСтрокахДерева(ПодчиненныеСтроки, ТаблицаИзмененийНоменклатуры, СтрокиИзмененныхУпаковок);
		Иначе
			
			Для Каждого СтрокаИзменений Из ТаблицаИзмененийНоменклатуры Цикл
				
				Если НоменклатурыСтрокСовпадают(СтрокаДерева, СтрокаИзменений, Истина) Тогда
					
					СтрокаДерева.Номенклатура   = СтрокаИзменений.НоваяНоменклатура;
					СтрокаДерева.Характеристика = СтрокаИзменений.НоваяХарактеристика;
					СтрокаДерева.Серия          = СтрокаИзменений.НоваяСерия;
					
					ПроверкаИПодборПродукцииМОТПКлиентСервер.СформироватьПредставлениеСодержимогоУпаковки(СтрокаДерева);
					
					РодительскаяСтрока = СтрокаДерева.ПолучитьРодителя();
					
					Если РодительскаяСтрока <> Неопределено Тогда
						ИдентификаторРодителя = РодительскаяСтрока.ПолучитьИдентификатор();
						Если СтрокиИзмененныхУпаковок.Получить(ИдентификаторРодителя) = Неопределено Тогда
							СтрокиИзмененныхУпаковок.Вставить(ИдентификаторРодителя, Истина);
						КонецЕсли;
					КонецЕсли;
					
					Прервать;
					
				КонецЕсли;
				
			КонецЦикла;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

#Область ПризнакПроверкиУпаковки

&НаКлиентеНаСервереБезКонтекста
Процедура ИзменитьСостояниеПроверкиУпаковки(Форма, СтрокаДерева)

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

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

&НаКлиентеНаСервереБезКонтекста
Процедура СнятьПризнакПроверкиУпаковки(Форма, СтрокаДерева, ВключаяРодителей = Ложь)
	
	Если СтрокаДерева = Неопределено
		Или Не ИнтеграцияИСКлиентСервер.ЭтоУпаковка(СтрокаДерева.ТипУпаковки)
		Или Не СтрокаДерева.ИдетПроверкаДаннойУпаковки Тогда
		Возврат;
	КонецЕсли;
	
	СтрокаДерева.ИдетПроверкаДаннойУпаковки = Ложь;
	#Если ТонкийКлиент ИЛИ ВебКлиент Тогда
	Форма.Элементы.ДеревоМаркированнойПродукции.Свернуть(СтрокаДерева.ПолучитьИдентификатор());
	#КонецЕсли
	ПроверкаИПодборПродукцииМОТПКлиентСервер.УстановитьИндексКартинкиТипаУпаковки(СтрокаДерева);
	
	ПодчиненныеСтроки = СтрокаДерева.ПолучитьЭлементы();
	
	Для Каждого ПодчиненнаяСтрока Из ПодчиненныеСтроки Цикл
		
		Если ПодчиненнаяСтрока.ИдетПроверкаДаннойУпаковки Тогда
			СнятьПризнакПроверкиУпаковки(Форма, ПодчиненнаяСтрока);
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Если СтрокаДерева.КоличествоПодчиненныхВсего  > 6
		И СтрокаДерева.КоличествоПодчиненныхНеПроверялось < 4 Тогда
		
		Для Каждого ПодчиненнаяСтрока Из ПодчиненныеСтроки Цикл
		
			Если ПодчиненнаяСтрока.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.НеПроверялась") Тогда
				
				ПодчиненнаяСтрока.СтатусПроверки = ПредопределенноеЗначение("Перечисление.СтатусыПроверкиНаличияПродукцииИС.Отсутствует");
				
				УстановитьСтатусОтсутствуетДляПодчиненных(Форма, ПодчиненнаяСтрока);
				
			КонецЕсли;
			
		КонецЦикла;
		
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(СтрокаДерева, Ложь, Форма.ЗагрузкаДанныхТСД);
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(СтрокаДерева, Форма.ЗагрузкаДанныхТСД);
		
	КонецЕсли;
	
	СтрокаРодитель = СтрокаДерева.ПолучитьРодителя();
	
	Если ВключаяРодителей Тогда
		
		Пока СтрокаРодитель <> Неопределено Цикл
			
			СтрокаРодитель.ИдетПроверкаДаннойУпаковки = Ложь;
			ПроверкаИПодборПродукцииМОТПКлиентСервер.УстановитьИндексКартинкиТипаУпаковки(СтрокаРодитель);
			#Если ТонкийКлиент ИЛИ ВебКлиент Тогда
			Форма.Элементы.ДеревоМаркированнойПродукции.Свернуть(СтрокаРодитель.ПолучитьИдентификатор());
			#КонецЕсли
			СтрокаРодитель = СтрокаРодитель.ПолучитьРодителя();
			
		КонецЦикла;
		
		Форма.ИдентификаторТекущейПроверяемойУпаковки = -1;
		
	Иначе
		
		Если СтрокаРодитель = Неопределено Тогда
			Форма.ИдентификаторТекущейПроверяемойУпаковки = -1;
		ИначеЕсли СтрокаРодитель = СтрокаПотребительскиеУпаковкиБезУпаковки(Форма) Тогда
			Форма.ИдентификаторТекущейПроверяемойУпаковки = -1;
		ИначеЕсли СтрокаРодитель = СтрокаГрупповыеУпаковкиБезКоробки(Форма) Тогда
			Форма.ИдентификаторТекущейПроверяемойУпаковки = -1;
		Иначе
			Форма.ИдентификаторТекущейПроверяемойУпаковки = СтрокаРодитель.ПолучитьИдентификатор();
		КонецЕсли;

	КонецЕсли;
	
	Форма.Модифицированность = Истина;
	
КонецПроцедуры

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

&НаКлиенте
Процедура ИзменитьКонтекстПроверки(НоваяПроверяемаяУпаковка)
	
	Если НоваяПроверяемаяУпаковка = Неопределено Тогда
		ИдентификаторНовойПроверяемойУпаковки = -1;
	Иначе
		ИдентификаторНовойПроверяемойУпаковки = НоваяПроверяемаяУпаковка.ПолучитьИдентификатор();
	КонецЕсли;
	
	Если ИдентификаторНовойПроверяемойУпаковки = ИдентификаторТекущейПроверяемойУпаковки Тогда
		Возврат;
	КонецЕсли;
	
	ТекущаяПроверяемаяУпаковка = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторТекущейПроверяемойУпаковки);
	Если ТекущаяПроверяемаяУпаковка <> Неопределено Тогда
		СнятьПризнакПроверкиУпаковки(ЭтотОбъект, ТекущаяПроверяемаяУпаковка, Истина);
	КонецЕсли;
	
	УстановитьПризнакПроверкиУпаковки(ЭтотОбъект, НоваяПроверяемаяУпаковка);
	
КонецПроцедуры

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

#Область Прочее

&НаКлиенте
Процедура ПослеВопросаПриЗакрытииФормы(РезультатВопроса, ДополнительныеПараметры) Экспорт

	Если РезультатВопроса = КодВозвратаДиалога.Да Тогда
		
		ЗакрытьФорму(ДополнительныеПараметры);
		
	КонецЕсли;

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

&НаКлиенте
Процедура ПослеПрочтенияПредупрежденияОЗапретеРаботыСРазрешительнымРежимом(ДополнительныеПараметры) Экспорт
	ЗакрытьФорму();
КонецПроцедуры

#Область ЗаполнениеКодовМаркировкиПоОснованию

&НаКлиенте
Процедура Подключаемый_ПослеВопросаЗагрузкиКодовПоОснованию(РезультатВопроса, ДополнительныеПараметры) Экспорт

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

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

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

	ОткрытьФорму(
		"Документ.МаркировкаТоваровИСМП.Форма.ФормаСпискаДокументов",
		ПараметрыОткрытия,
		ЭтотОбъект,
		УникальныйИдентификатор,,,
		ОповещениеОЗавершении,
		РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПослеВыбораОснованийЗаполененияКодаМаркировки(ВыбранныеЗаказы, ДополнительныеПараметры) Экспорт
	
	Если ВыбранныеЗаказы = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	КодыМаркировки = КодыМаркировкиПоЗаказамНаЭмиссию(ВыбранныеЗаказы);
	
	ЗагрузитьКодыМаркировкиПоОснованию(КодыМаркировки);
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПослеВыбораМаркировкиТоваровИСМП(ВыбранныеДокументы, ДополнительныеПараметры) Экспорт
	
	Если ВыбранныеДокументы = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	КодыМаркировки = КодыМаркировкиПоОтчетамОНанесении(ВыбранныеДокументы);
	
	ЗагрузитьКодыМаркировкиПоОснованию(КодыМаркировки);
	
КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьКодыМаркировкиПоОснованию(КодыМаркировки)
	
	Если КодыМаркировки.Количество() > 0 Тогда
		ЗагрузкаДанныхПоОснованию = Истина;
		ПараметрыОбработкиТСД = НовыеПараметрыОбработкиТСД();
		Подключаемый_ПолученыДанныеИзТСД(КодыМаркировки, ПараметрыОбработкиТСД);
	КонецЕсли;
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция КодыМаркировкиПоОснованию(Документ)
	
	Основания = ПечатьЭтикетокИСМП.МассивСвязанныхДокументовОснований(Документ);
	
	Возврат РегистрыСведений.ПулКодовМаркировкиСУЗ.КодыМаркировкиПоОснованию(Основания);
	
КонецФункции

&НаСервереБезКонтекста
Функция КодыМаркировкиПоЗаказамНаЭмиссию(ЗаказыНаЭмиссию)
	
	Возврат РегистрыСведений.ПулКодовМаркировкиСУЗ.КодыМаркировкиПоОснованию(ЗаказыНаЭмиссию);
	
КонецФункции

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

&НаСервереБезКонтекста
Функция ЗначениеРеквизитаОбъекта(Ссылка, ИмяРеквизита)
	Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, ИмяРеквизита);
КонецФункции

&НаСервереБезКонтекста
Функция ПараметрыРежимаИсправленияОшибок(Документ)
	
	ТекущееСостояние = РегистрыСведений.СтатусыДокументовИСМП.ТекущееСостояние(Документ);
	ДальнейшееДействие = ТекущееСостояние.ДальнейшееДействие1;
	
	ПараметрыРежимаИсправленияОшибок = Новый Структура;
	ПараметрыРежимаИсправленияОшибок.Вставить("ДальнейшееДействие", ДальнейшееДействие);
	ПараметрыРежимаИсправленияОшибок.Вставить("ТекущееСостояние",   ТекущееСостояние);
	
	Возврат ПараметрыРежимаИсправленияОшибок;
	
КонецФункции

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

&НаКлиенте
Процедура ЗакрытьФорму(ДополнительныеПараметры = Неопределено) Экспорт
	
	ВыполняетсяЗакрытие = Истина;

	Закрыть();
КонецПроцедуры

&НаСервере
Процедура УстановитьУсловноеОформление()
	
	УсловноеОформление.Элементы.Очистить();
	
#Область СтатусПроверки

	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СтатусПроверки");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПроверкиНаличияПродукцииИС.ВНаличии;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветУспешнойОперацииГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СтатусПроверки");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПроверкиНаличияПродукцииИС.Отсутствует;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаПроблемаГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииНомерСтикераОтложено.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СтатусПроверки");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПроверкиНаличияПродукцииИС.Отложена;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаОтложенаПриПроверкеГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
	
	НепроверяемыеТипыУпаковок = Новый СписокЗначений;
	НепроверяемыеТипыУпаковок.Добавить(ТипУпаковкиПотребительскиеУпаковкиБезУпаковки());
	НепроверяемыеТипыУпаковок.Добавить(ТипУпаковкиГрупповыеУпаковкиБезКоробки());
	
	ОтборЭлемента.ПравоеЗначение = НепроверяемыеТипыУпаковок;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru = '<не требуется>'"));
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СтатусПроверки");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПроверкиНаличияПродукцииИС.НеЧислилась;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("РежимПросмотра");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставление.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ОбработанСОшибкойВГИСМТ");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаОтложенаПриПроверкеГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ОбработанСОшибкойВГИСМТ");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ПредставлениеПроверкиКодаМаркировки"));
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаОтложенаПриПроверкеГосИС);
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.НедопустимыйКодМаркировки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ПредставлениеПроверкиКодаМаркировки"));
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаПроблемаГосИС);
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставление.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.НедопустимыйКодМаркировки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаПроблемаГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	// Режим исправления ошибок после передачи кодов
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеСодержимоеУпаковки.Имя);

	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("РежимИсправленияОшибокПослеПередачиКодов");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ОбработанСОшибкойВГИСМТ");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.НедопустимыйКодМаркировки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	ГруппаОтбораИли = ГруппаОтбора.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбораИли.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
	
	ОтборЭлемента = ГруппаОтбораИли.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.ТипыУпаковок.МаркированныйТовар;
	
	ГруппаОтбораИ = ГруппаОтбораИли.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбораИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбораИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.ВСписке;
	
	ТипыУпаковокАгрегатов = Новый СписокЗначений;
	ТипыУпаковокАгрегатов.Добавить(Перечисления.ТипыУпаковок.МонотоварнаяУпаковка);
	ТипыУпаковокАгрегатов.Добавить(Перечисления.ТипыУпаковок.МультитоварнаяУпаковка);
	
	ОтборЭлемента.ПравоеЗначение = ТипыУпаковокАгрегатов;
	
	ОтборЭлемента = ГруппаОтбораИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДальнейшееДействие");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.ВСписке;
	
	ДействияАгрегация = Новый СписокЗначений();
	ДействияАгрегация.Добавить( Перечисления.ДальнейшиеДействияПоВзаимодействиюИСМП.ВыполнитеАгрегацию);
	ДействияАгрегация.Добавить( Перечисления.ДальнейшиеДействияПоВзаимодействиюИСМП.ВыполнитеАгрегациюСИсправлениями);
	
	ОтборЭлемента.ПравоеЗначение = ДействияАгрегация;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("РежимИсправленияОшибокПослеПередачиКодов");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СтатусПроверки");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПроверкиНаличияПродукцииИС.ВНаличии;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ОбработанСОшибкойВГИСМТ");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.НедопустимыйКодМаркировки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	ГруппаОтбораИли = ГруппаОтбора.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбораИли.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
	
	ОтборЭлемента = ГруппаОтбораИли.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.ТипыУпаковок.МаркированныйТовар;
	
	ГруппаОтбораИ = ГруппаОтбораИли.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбораИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбораИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.ВСписке;
	
	ТипыУпаковокАгрегатов = Новый СписокЗначений;
	ТипыУпаковокАгрегатов.Добавить(Перечисления.ТипыУпаковок.МонотоварнаяУпаковка);
	ТипыУпаковокАгрегатов.Добавить(Перечисления.ТипыУпаковок.МультитоварнаяУпаковка);
	
	ОтборЭлемента.ПравоеЗначение = ТипыУпаковокАгрегатов;
	
	ОтборЭлемента = ГруппаОтбораИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДальнейшееДействие");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.ВСписке;
	
	ДействияАгрегация = Новый СписокЗначений();
	ДействияАгрегация.Добавить( Перечисления.ДальнейшиеДействияПоВзаимодействиюИСМП.ВыполнитеАгрегацию);
	ДействияАгрегация.Добавить( Перечисления.ДальнейшиеДействияПоВзаимодействиюИСМП.ВыполнитеАгрегациюСИсправлениями);
	
	ОтборЭлемента.ПравоеЗначение = ДействияАгрегация;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru = 'Передан'"));
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииСтатусПроверки.Имя);
	
	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("РежимИсправленияОшибокПослеПередачиКодов");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СтатусПроверки");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПроверкиНаличияПродукцииИС.ВНаличии;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ОбработанСОшибкойВГИСМТ");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.НедопустимыйКодМаркировки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.ВСписке;
	
	ТипыУпаковокАгрегатов = Новый СписокЗначений;
	ТипыУпаковокАгрегатов.Добавить(Перечисления.ТипыУпаковок.МонотоварнаяУпаковка);
	ТипыУпаковокАгрегатов.Добавить(Перечисления.ТипыУпаковок.МультитоварнаяУпаковка);
	
	ОтборЭлемента.ПравоеЗначение = ТипыУпаковокАгрегатов;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДальнейшееДействие");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.НеВСписке;
	
	ДействияАгрегация = Новый СписокЗначений();
	ДействияАгрегация.Добавить( Перечисления.ДальнейшиеДействияПоВзаимодействиюИСМП.ВыполнитеАгрегацию);
	ДействияАгрегация.Добавить( Перечисления.ДальнейшиеДействияПоВзаимодействиюИСМП.ВыполнитеАгрегациюСИсправлениями);
	
	ОтборЭлемента.ПравоеЗначение = ДействияАгрегация;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru = 'Ожидает агрегации'"));
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииТекстОшибкиПроверкиСредствамиККТ.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СостояниеТребованияПолногоКодаККТ");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 1;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаПроблемаГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииТекстОшибкиПроверкиСредствамиККТ.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СостояниеТребованияПолногоКодаККТ");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 2;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	
#КонецОбласти

#Область ПроверкаСодержимого

	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеПроверкиПодчиненных.Имя);

	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхУпаковок");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхГрупповыхУпаковок");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхПотребительскихУпаковок");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеПроверкиПодчиненных.Имя);

	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхОтложено");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Больше;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхОтсутствует");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаОтложенаПриПроверкеГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеПроверкиПодчиненных.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.ВСписке;

	НепроверяемыеТипыУпаковок = Новый СписокЗначений;
	НепроверяемыеТипыУпаковок.Добавить(Перечисления.ТипыУпаковок.МаркированныйТовар);
	НепроверяемыеТипыУпаковок.Добавить(ТипУпаковкиПотребительскиеУпаковкиБезУпаковки());
	НепроверяемыеТипыУпаковок.Добавить(ТипУпаковкиГрупповыеУпаковкиБезКоробки());

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

	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхОтсутствует");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Больше;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаПроблемаГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеПроверкиПодчиненных.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ВсяУпаковкаПроверена");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветУспешнойОперацииГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииКоличествоПодчиненныхНеПроверялось.Имя);
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииКоличествоПодчиненныхВНаличии.Имя);
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииКоличествоПодчиненныхОтсутствует.Имя);
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииКоличествоПодчиненныхНеЧислилось.Имя);
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииКоличествоПодчиненныхОтложено.Имя);
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииКоличествоПодчиненныхВсего.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.ТипыУпаковок.МаркированныйТовар;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветаСтиля.ЦветФонаНеТребуетВниманияГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииТекстОшибкиПроверкиСредствамиККТ.Имя);
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаПроблемаГосИС);
	
#КонецОбласти

#Область СодержимоеУпаковки

	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеСодержимоеУпаковки.Имя);

	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхУпаковок");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхГрупповыхУпаковок");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.КоличествоПодчиненныхПотребительскихУпаковок");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = 0;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ТипУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.НеРавно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.ТипыУпаковок.МаркированныйТовар;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ИдетПроверкаДаннойУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.НеРавно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеСодержимоеУпаковки.Имя);

	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.GTIN");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.НачинаетсяС;
	ОтборЭлемента.ПравоеЗначение = ИнтеграцияИСМПСлужебныйКлиентСервер.НачалоGTINМаркировкиОстатков();
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.Номенклатура");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеСодержимоеУпаковки.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.ИдетПроверкаДаннойУпаковки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Шрифт", Новый Шрифт(,,Истина));

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииПредставлениеСодержимоеУпаковки.Имя);

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

#Область НомерСтикераОтолжена

	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииНомерСтикераОтложено.Имя);

	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.СтатусПроверки");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.НеРавно;
	ОтборЭлемента.ПравоеЗначение = Перечисления.СтатусыПроверкиНаличияПродукцииИС.Отложена;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Отображать", Ложь);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукцииНомерСтикераОтложено.Имя);

	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ДеревоМаркированнойПродукции.НомерСтикераОтложено");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = "";
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru = '<не помечена>'"));

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

#Область Отборы

	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ДеревоМаркированнойПродукции.Имя);
	
	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;

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

#Область МРЦ
	
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента      = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПодобраннаяМаркируемаяПродукцияМРЦ.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.ВключаетМРЦ");
	ОтборЭлемента.ВидСравнения  = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст",                   НСтр("ru = '<Не загружено>'"));
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста",              ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	Элемент.Оформление.УстановитьЗначениеПараметра("ГоризонтальноеПоложение", ГоризонтальноеПоложение.Лево);
	
	
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента      = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПодобраннаяМаркируемаяПродукцияМРЦ.Имя);
	
	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.ВключаетМРЦ");
	ОтборЭлемента.ВидСравнения  = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.МРЦ");
	ОтборЭлемента.ВидСравнения  = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст",                   НСтр("ru = '0'"));
	Элемент.Оформление.УстановитьЗначениеПараметра("ГоризонтальноеПоложение", ГоризонтальноеПоложение.Право);
	
#КонецОбласти

#Область ПодобраннаяПродукция
	
	СобытияФормИСПереопределяемый.УстановитьУсловноеОформлениеХарактеристикНоменклатуры(
		ЭтотОбъект,
		"ПодобраннаяМаркируемаяПродукцияХарактеристика",
		"ПодобраннаяМаркируемаяПродукция.ХарактеристикиИспользуются");
	
	СобытияФормИСПереопределяемый.УстановитьУсловноеОформлениеСерийНоменклатуры(
		ЭтотОбъект,
		"ПодобраннаяМаркируемаяПродукцияСерия",
		"ПодобраннаяМаркируемаяПродукция.СтатусУказанияСерий",
		"ПодобраннаяМаркируемаяПродукция.ТипНоменклатуры");
	
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПодобраннаяМаркируемаяПродукцияНоменклатура.Имя);

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

	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.НоменклатураСопоставленаПоУПД");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ГруппаОтбораИЛИ = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбораИЛИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
	
	ОтборЭлемента = ГруппаОтбораИЛИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.ХарактеристикиИспользуются");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;

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

	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.НоменклатураСопоставленаПоУПД");
	ОтборЭлемента.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПодобраннаяМаркируемаяПродукцияGTIN.Имя);
	
	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.GTIN");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.ПредставлениеGTIN");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.ПредставлениеGTIN"));
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПодобраннаяМаркируемаяПродукцияGTIN.Имя);
	
	ГруппаОтбора = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.GTIN");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	ОтборЭлемента = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.ПредставлениеGTIN");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru = '<Не заполнен>'"));
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветТекстаНеТребуетВниманияГосИС);
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПодобраннаяМаркируемаяПродукцияКоличество.Имя);
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоИС.Имя);
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПодобраннаяМаркируемаяПродукцияКоличествоПодобрано.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПодобраннаяМаркируемаяПродукция.ПроизвольнаяЕдиницаУчета");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Ложь;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Формат", "ЧДЦ=0;");
	
#КонецОбласти

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

&НаКлиентеНаСервереБезКонтекста
Процедура СпозиционироватьсяНаСтрокеДерева(Форма, СтрокаДерева)
	
	Форма.Элементы.ДеревоМаркированнойПродукции.ТекущаяСтрока = СтрокаДерева.ПолучитьИдентификатор();
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УправлениеДоступностьюКомандУпаковок(Форма)
	
	КомандыДоступны = Форма.ДетализацияСтруктурыХранения <> ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки");
	
	Элементы = Форма.Элементы;
	
	Если Элементы.ДеревоМаркированнойПродукцииДобавитьПустуюКоробку.Видимость Тогда
		Элементы.ДеревоМаркированнойПродукцииДобавитьПустуюКоробку.Доступность = КомандыДоступны;
	КонецЕсли;
	
	Если Элементы.ДеревоМаркированнойПродукцииМаркироватьУпаковку.Видимость Тогда
		Элементы.ДеревоМаркированнойПродукцииМаркироватьУпаковку.Доступность = КомандыДоступны;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция УпаковкаНеСодержитсяВДанныхДокумента(ТекущаяСтрокаДерева, Детализация)
	
	Если Детализация = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		
		Возврат Ложь;
		
	ИначеЕсли ТекущаяСтрокаДерева = Неопределено Тогда
		
		Возврат Истина;
		
	ИначеЕсли ТекущаяСтрокаДерева.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
		Или ТекущаяСтрокаДерева.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
		
		Возврат Истина;
		
	ИначеЕсли ИнтеграцияИСКлиентСервер.ЭтоУпаковка(ТекущаяСтрокаДерева.ТипУпаковки) Тогда
		
		Возврат ТекущаяСтрокаДерева.НеСодержитсяВДанныхДокумента;
		
	Иначе
		
		Возврат УпаковкаНеСодержитсяВДанныхДокумента(ТекущаяСтрокаДерева.ПолучитьРодителя(), Детализация);
		
	КонецЕсли;

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

&НаСервереБезКонтекста
Функция ЕстьПравоДобавлениеСерий()
	
	Возврат ПроверкаИПодборПродукцииИСМП.ЕстьПравоДобавлениеСерий();
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ПродукцияСоответствуетДокументуОснованию(Форма, ПроверяемаяСтрока)

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

&НаСервере
Функция ШтрихкодыУпаковокДокументаСоответствуютВидуПродукции()
	
	ШтрихкодыУпаковокДокумента = Новый Массив;
	ШтрихкодированиеИСПереопределяемый.ЗаполнитьШтрихкодыУпаковокДокумента(ПроверяемыйДокумент, ШтрихкодыУпаковокДокумента);
	
	Если ШтрихкодыУпаковокДокумента.Количество() = 0 Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ПользовательскиеПараметрыРазбораКодаМаркировки = РазборКодаМаркировкиИССлужебныйКлиентСервер.ПользовательскиеПараметрыРазбораКодаМаркировки();
	ПользовательскиеПараметрыРазбораКодаМаркировки.ВалидироватьШтрихкодЛогистическойУпаковкиGS1128СОшибками = Не ЭтоДокументМаркировка(ЭтотОбъект);
	
	Для Каждого Штрихкод Из ШтрихкодыУпаковокДокумента Цикл
		ПримечаниеКРазборуШтрихкода = Неопределено;
		ДанныеРазбора = РазборКодаМаркировкиИССлужебный.РазобратьКодМаркировки(
			Штрихкод, ВидМаркируемойПродукции, ПримечаниеКРазборуШтрихкода,, ПользовательскиеПараметрыРазбораКодаМаркировки);
		Если ДанныеРазбора <> Неопределено Тогда
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Ложь;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ВидУпаковкиПоВходящимДанным(ДанныеШтрихкода, ВидМаркируемойПродукции, ЭтоДокументМаркировка)
	
	Если ДанныеШтрихкода.ТипШтрихкода = ПредопределенноеЗначение("Перечисление.ТипыШтрихкодов.SSCC") Тогда
		Возврат ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая");
	КонецЕсли;
	
	ПользовательскиеПараметрыРазбора = РазборКодаМаркировкиИССлужебныйКлиентСервер.ПользовательскиеПараметрыРазбораКодаМаркировки();
	ПользовательскиеПараметрыРазбора.ВалидироватьШтрихкодЛогистическойУпаковкиGS1128СОшибками = Не ЭтоДокументМаркировка;
	
	РезультатРазбора = РазобратьКодМаркировки(ДанныеШтрихкода.Штрихкод, ВидМаркируемойПродукции, ПользовательскиеПараметрыРазбора);
	
	Если РезультатРазбора = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Возврат РезультатРазбора.ВидУпаковки;
	
КонецФункции

&НаСервереБезКонтекста
Функция РазобратьКодМаркировки(Штрихкод, ВидМаркируемойПродукции, ПользовательскиеПараметры)
	Возврат РазборКодаМаркировкиИССлужебный.РазобратьКодМаркировки(Штрихкод, ВидМаркируемойПродукции,,, ПользовательскиеПараметры);
КонецФункции

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

#Область РаботаСТСД

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

&НаКлиенте
Процедура ЗагрузитьИзТСДПослеАвторизации(РезультатАвторизации, ДополнительныеПараметры) Экспорт
	
	РезультатАвторизацииПоОрганизации = РезультатАвторизации[Организация];
	Если РезультатАвторизацииПоОрганизации <> Истина Тогда
		Возврат;
	КонецЕсли;
	
	ПараметрыОбработкиТСД = НовыеПараметрыОбработкиТСД();
	ПараметрыОбработкиТСД.ЭтоЗавершениеАвторизации = Истина;
	ПараметрыОбработкиТСД.Состояние                = ДополнительныеПараметры.ДополнительныеПараметры;
	
	Подключаемый_ПолученыДанныеИзТСД(ДополнительныеПараметры.Штрихкоды, ПараметрыОбработкиТСД);
	
КонецПроцедуры

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

&НаКлиенте
Процедура Подключаемый_ПолученыДанныеИзТСД(Штрихкоды, ПараметрыОбработкиТСД) Экспорт
	
	Если Штрихкоды.Количество() = 0 Тогда
		
		ЗагрузкаДанныхТСД = Неопределено;
		
		ПоказатьПредупреждение(, НСтр("ru = 'В полученных данных не содержится информации о считанных штриховых кодах'"));
		
		Возврат;
		
	КонецЕсли;
	
	Если ЗагрузкаДанныхПоОснованию Тогда
		ПараметрыУведомления = Новый Структура();
		ПараметрыУведомления.Вставить("Заголовок", НСтр("ru = 'Загрузка данных по заказам'"));
		ПараметрыУведомления.Вставить("Текст",     НСтр("ru = 'Начата загрузка данных по заказам на эмиссию.'"));
	Иначе
		ПараметрыУведомления = Неопределено;
	КонецЕсли;
	
	ГрупповаяОбработкаШтрихкодовИСКлиент.ОповеститьОНачалеОбработкиДанныхТСД(ПараметрыУведомления);
	
	ШтрихкодированиеИСКлиент.ПреобразоватьШтрихкодыТСДВBase64(Штрихкоды);
	
	ИнициализироватьПараметрыСканирования();
	// Параметр сканирования ДополнительныеВариантыСопоставленияНоменклатуры будет дополнен на сервере
	
	ДанныеДляТСД = Новый Структура;
	ДанныеДляТСД.Вставить("Штрихкоды",                         Штрихкоды);
	ДанныеДляТСД.Вставить("ПараметрыСканирования",             ПараметрыСканирования);
	ДанныеДляТСД.Вставить("СоответствиеШтрихкодовСтрокДерева", СоответствиеШтрихкодовСтрокДерева);
	ДанныеДляТСД.Вставить("ДополнительныеПараметры",           ПараметрыОбработкиТСД);
	
	ОбработатьПолученныеДанныеТСДНаСервере(ДанныеДляТСД, КэшированныеЗначения);
	СоответствиеШтрихкодовСтрокДерева = ДанныеДляТСД.СоответствиеШтрихкодовСтрокДерева;
	
	Если ЗагрузкаДанныхТСД.ПредложитьЗагрузитьВУпаковке Тогда
		
		ОповещениеОЗавершении = Новый ОписаниеОповещения("ПредложитьЗагрузитьВУпаковке", ЭтотОбъект, Штрихкоды);
		
		Если ЗагрузкаДанныхТСД.ТекстПредложенияОЗагрузке = "ОдинКодБлокаИКодыМаркировки" Тогда
			
			ПоказатьВопрос(
				ОповещениеОЗавершении,
				НСтр("ru = 'Отсканирован один код блока и коды маркировки. Загрузить блок с вложенным составом?'"),
				РежимДиалогаВопрос.ДаНет);
			
			Возврат;
			
		ИначеЕсли ЗагрузкаДанныхТСД.ТекстПредложенияОЗагрузке = "ОднаУпаковкаИКодыБлоков" Тогда
			
			ПоказатьВопрос(
				ОповещениеОЗавершении,
				НСтр("ru = 'Отсканирована одна упаковка и коды табачных блоков. Загрузить упаковку с вложенным составом?'"),
				РежимДиалогаВопрос.ДаНет);
			
			Возврат;
			
		ИначеЕсли ЗагрузкаДанныхТСД.ТекстПредложенияОЗагрузке = "ОднаУпаковкаИКодыМаркировки" Тогда
			
			ПоказатьВопрос(ОповещениеОЗавершении,
				НСтр("ru = 'Отсканирована одна упаковка и коды маркировки. Загрузить упаковку с вложенным составом?'"),
				РежимДиалогаВопрос.ДаНет);
				
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;
	
	Если ЗагрузкаДанныхТСД.ПредложитьИзменитьДетализацию Тогда
		
		ОповещениеОЗавершении = Новый ОписаниеОповещения("ПредложитьИзменитьДетализациюЗавершение", ЭтотОбъект, Штрихкоды);
		
		КнопкиВопроса = Новый СписокЗначений;
		КнопкиВопроса.Добавить(Истина, СтрШаблон(НСтр("ru = 'Переключить детализацию на %1'"), ЗагрузкаДанныхТСД.РекомендуемыеДетализации[0]));
		КнопкиВопроса.Добавить(Ложь,   СтрШаблон(НСтр("ru = 'Оставить детализацию %1'"), ДетализацияСтруктурыХранения));
		
		ТекстВопроса =
			СтрШаблон(НСтр("ru = 'Отсканировано: %1 и это достаточно большой объем.
			                     |Продолжение работы с текущим уровнем детализации может привести к значительному времени обработки.
			                     |Рекомендуется переключить детализацию на %2.'"),
				ЗагрузкаДанныхТСД.ОписаниеРекомендацииСменыДетализации, ЗагрузкаДанныхТСД.РекомендуемыеДетализации[0]);
		
		ПоказатьВопрос(ОповещениеОЗавершении, ТекстВопроса, КнопкиВопроса,, Истина);
		
		Возврат;
		
	КонецЕсли;
	
	Если ЗагрузкаДанныхТСД.ТребуетсяАвторизация Тогда
		
		Если ПараметрыОбработкиТСД.ЭтоЗавершениеАвторизации Тогда
			
			ПоказатьПредупреждение(, НСтр("ru = 'Загрузка данных недоступна: авторизация в сервисе не пройдена'"));
			
			ЗагрузкаДанныхТСД = Неопределено;
			
			Возврат;
			
		КонецЕсли;
		
		ПараметрыОповещения = Новый Структура("Штрихкоды, ДополнительныеПараметры", Штрихкоды, ПараметрыОбработкиТСД.Состояние);
		ИнтерфейсАвторизацииИСМПКлиент.ЗапроситьКлючСессииСУчетомВидаТокена(
			ПараметрыСканирования, ВидМаркируемойПродукции,
			Новый ОписаниеОповещения("ЗагрузитьИзТСДПослеАвторизации", ЭтотОбъект, ПараметрыОповещения));
		
		Возврат;
		
	КонецЕсли;
	
	Если ЗагрузкаДанныхТСД.ТребуетсяАвторизацияИСМПРозница Тогда
		
		Если ПараметрыОбработкиТСД.ЭтоЗавершениеАвторизации Тогда
			
			ПоказатьПредупреждение(, НСтр("ru = 'Загрузка данных недоступна: авторизация в сервисе не пройдена'"));
			
			ЗагрузкаДанныхТСД = Неопределено;
			
			Возврат;
			
		КонецЕсли;
		
		ПараметрыОповещения = Новый Структура("Штрихкоды, ДополнительныеПараметры", Штрихкоды, ПараметрыОбработкиТСД.Состояние);
		
		ИнтерфейсАвторизацииИСМПКлиент.ЗапроситьКлючСессии(
			ИнтерфейсИСМПОбщегоНазначенияКлиентСервер.ПараметрыЗапросаКлючаСессииИСМПРозница(ПараметрыСканирования.Организация),
			Новый ОписаниеОповещения("ЗагрузитьИзТСДПослеАвторизации", ЭтотОбъект, ПараметрыОповещения));
		
		Возврат;
		
	КонецЕсли;
	
	Если ЗагрузкаДанныхТСД.ОтсутствуютCDNПлощадки Тогда
		
		Если ПараметрыОбработкиТСД.ЭтоПолучениеCDNПлощадок Тогда
			
			ПоказатьПредупреждение(, НСтр("ru = 'Загрузка CDN-площадок завершена с ошибками: получение данных невозможно.'"));
			
			ЗагрузкаДанныхТСД = Неопределено;
			
			Возврат;
			
		КонецЕсли;
		
		ПараметрыОповещения = Новый Структура("Штрихкоды, ДополнительныеПараметры", Штрихкоды, ПараметрыОбработкиТСД.Состояние);
		
		ПараметрыЗапроса                         = ИнтерфейсИСМПОбщегоНазначенияКлиент.ПараметрыЗапросаДанных();
		ПараметрыЗапроса.УникальныйИдентификатор = УникальныйИдентификатор;
		ПараметрыЗапроса.Организация             = Организация;
		ПараметрыЗапроса.Параметры               = Новый Структура("НеВыводитьОкноОжидания", Ложь);
		ПараметрыЗапроса.ОповещениеОЗавершении   = Новый ОписаниеОповещения("ЗагрузитьИзТСДПослеЗагрузкиПлощадок", ЭтотОбъект, ПараметрыОповещения);
		ИнтерфейсИСМПОбщегоНазначенияКлиент.АктуализацияСпискаCDNПлощадок(ПараметрыЗапроса);
		
		Возврат;
		
	КонецЕсли;
	
	Если ЗагрузкаДанныхТСД.ОбщаяОшибка Тогда
		
		ПараметрыОткрытияФормы = ШтрихкодированиеИСКлиент.ПараметрыОткрытияФормыНевозможностиДобавленияОтсканированного();
		
		Если ТипЗнч(ЗагрузкаДанныхТСД.ТекстОбщейОшибки) = Тип("ФорматированнаяСтрока") Тогда
			ПараметрыОткрытияФормы.ТекстОшибкиФорматированнаяСтрока = ЗагрузкаДанныхТСД.ТекстОбщейОшибки;
		Иначе
			ПараметрыОткрытияФормы.ТекстОшибки = ЗагрузкаДанныхТСД.ТекстОбщейОшибки;
		КонецЕсли;
		
		ШтрихкодированиеИСКлиент.ОткрытьФормуНевозможностиДобавленияОтсканированного(ЭтотОбъект, ПараметрыОткрытияФормы);
		
		ЗагрузкаДанныхТСД = Неопределено;
		
		Возврат;
		
	КонецЕсли;
	
	Если ЗагрузкаДанныхТСД.ШтрихкодыДляСопоставления.Количество() > 0 Тогда
		
		ДополнительныеПараметры = Новый Структура("ВсеШтрихкоды, ШтрихкодыДляСопоставления, Состояние",
			Штрихкоды, ЗагрузкаДанныхТСД.ШтрихкодыДляСопоставления, ПараметрыОбработкиТСД.Состояние);
		ОписаниеОповещения = Новый ОписаниеОповещения("СопоставлениеШтрихкодовЗавершение", ЭтотОбъект, ДополнительныеПараметры);
		ШтрихкодированиеИСКлиентПереопределяемый.ОткрытьФормуПодбораНоменклатурыПоШтрихкодам(
			ЗагрузкаДанныхТСД.ШтрихкодыДляСопоставления, ЭтотОбъект, ОписаниеОповещения);
		
		Возврат;
		
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ЗагрузкаДанныхТСД.АдресУточнениеКоэффициентовУпаковок) Тогда
		
		ДополнительныеПараметры = Новый Структура("ВсеШтрихкоды, Состояние",
			Штрихкоды, ПараметрыОбработкиТСД.Состояние);
		ОписаниеОповещения = Новый ОписаниеОповещения("УточнениеКоэффициентовУпаковокЗавершение", ЭтотОбъект, ДополнительныеПараметры);
		
		ПараметрыОткрытия = ИнтеграцияИСМПКлиент.ПараметрыОткрытияФормыУточненияУпаковокПоGTIN();
		ПараметрыОткрытия.АдресУточнениеКоэффициентовУпаковок = ЗагрузкаДанныхТСД.АдресУточнениеКоэффициентовУпаковок;
		
		ИнтеграцияИСМПКлиент.ОткрытьФормуНастройкиВидовУпаковокПоGTIN(ПараметрыОткрытия, ЭтотОбъект, ОписаниеОповещения);
		
		Возврат;
		
	КонецЕсли;
	
	Если ЗагрузкаДанныхТСД.ЕстьОшибкиВДереве
		И Не ПараметрыСканирования.ПропускатьСтрокиСОшибкамиПриЗагрузкеИзТСД Тогда
		
		ПараметрыОткрытияФормы = ШтрихкодированиеИСКлиент.ПараметрыОткрытияФормыНевозможностиДобавленияОтсканированного(
			ВидМаркируемойПродукции);
		ПараметрыОткрытияФормы.АдресДереваУпаковок = ЗагрузкаДанныхТСД.АдресДереваУпаковок;
		ШтрихкодированиеИСКлиент.ОткрытьФормуНевозможностиДобавленияОтсканированного(
			ЭтотОбъект, ПараметрыОткрытияФормы);
		
		ЗагрузкаДанныхТСД = Неопределено;
		
		Возврат;
		
	КонецЕсли;
	
	// Если требуется уточнять данные, то необходимо до вызова окон уточнения пересчитать итоги в дереве маркированной продукции
	Если ЗагрузкаДанныхТСД.Обработано < ЗагрузкаДанныхТСД.Всего Тогда
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковок(ДеревоМаркированнойПродукции);
	КонецЕсли;
	// Начиная с этого момента - разрешено пересчитывать итоги.
	ЗагрузкаДанныхТСД.ПересчитыватьИтогиВДеревеМаркированнойПродукции = Истина;
	
	ОбработатьПолученныеДанныеТСД();
	
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура ПредложитьИзменитьДетализациюЗавершение(ПереключитьДетализациюНаРекомендуемую, Штрихкоды) Экспорт
	
	Если ПереключитьДетализациюНаРекомендуемую Тогда
		ИзменитьРежимДетализации(ЗагрузкаДанныхТСД.РекомендуемыеДетализации[0]);
	КонецЕсли;
	
	ПараметрыОбработкиТСД = НовыеПараметрыОбработкиТСД();
	ПараметрыОбработкиТСД.Состояние = "ДетализацияПроверена";
	
	Подключаемый_ПолученыДанныеИзТСД(Штрихкоды, ПараметрыОбработкиТСД);
	
КонецПроцедуры

&НаСервере
Процедура ОбработатьПолученныеДанныеТСДНаСервере(ДанныеДляТСД, КэшированныеЗначения)
	
	Результат = ГрупповаяОбработкаШтрихкодовИС.РезультатЗагрузкиШтрихкодовИзТСД(ИдентификаторТекущейПроверяемойУпаковки);
	
	ЕстьИерархия = ГрупповаяОбработкаШтрихкодовИС.ДополнитьУпорядочитьДанныеТСД(ДанныеДляТСД.Штрихкоды);
	
	ПроверитьДоступнуюИерархиюШтрихкодов = (ДанныеДляТСД.ДополнительныеПараметры.Состояние <> "ИерархияПроверена")
	                                     И (ДанныеДляТСД.ДополнительныеПараметры.Состояние <> "ЗаполнениеИерархии")
	                                     И ЭтоДокументМаркировка(ЭтотОбъект)
	                                     И ДанныеДляТСД.ПараметрыСканирования.ДетализацияСтруктурыХранения <> Перечисления.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки;
	
	ПроверитьРекомендуемуюДетализацию = (ДанныеДляТСД.ДополнительныеПараметры.Состояние <> "ДетализацияПроверена");
	
	Если ДанныеДляТСД.ДополнительныеПараметры.ЭтоВосстановлениеВложенностиУпаковок Тогда
		Результат.ЭтоВосстановлениеВложенностиУпаковок = Истина;
		Результат.ДанныеДляВосстановлениеВложенности   = ДанныеДляТСД.ДополнительныеПараметры.ДополнительныеПараметры;
	КонецЕсли;
	
	Если Результат.ЭтоВосстановлениеВложенностиУпаковок Тогда
		ПроверитьДоступнуюИерархиюШтрихкодов = Ложь;
		ПроверитьРекомендуемуюДетализацию    = Ложь;
	КонецЕсли;
	
	КоличествоУпаковок                = 0;
	КоличествоПалет                   = 0;
	КоличествоКоробов                 = 0;
	КоличествоГрупповыхУпаковок       = 0;
	КоличествоПотребительскихУпаковок = 0;
	
	ЕстьУпаковка     = Ложь;
	ШтрихкодУпаковки = "";
	
	ДанныеШтрихкодов                = Новый Массив;
	МассивПропущенныхШтрихкодов     = Новый Массив;
	КешДанныхРазбора                = Новый Соответствие;
	
	ПользовательскиеПараметрыРазбораКодаМаркировки = РазборКодаМаркировкиИССлужебныйКлиентСервер.ПользовательскиеПараметрыРазбораКодаМаркировки();
	ПользовательскиеПараметрыРазбораКодаМаркировки.ПроверятьАлфавитЭлементов                                = ДанныеДляТСД.ПараметрыСканирования.ПроверятьАлфавитКодовМаркировки;
	ПользовательскиеПараметрыРазбораКодаМаркировки.РасширеннаяДетализация                                   = ДанныеДляТСД.ПараметрыСканирования.СохранятьКодыМаркировкиВПулИСМП;
	ПользовательскиеПараметрыРазбораКодаМаркировки.ВалидироватьШтрихкодЛогистическойУпаковкиGS1128СОшибками = Не ЭтоДокументМаркировка(ЭтотОбъект);
	
	НастройкиРазбораКодаМаркировки = Новый Структура;
	НастройкиРазбораКодаМаркировки.Вставить("Кеш",              РазборКодаМаркировкиИССлужебныйКлиентСервер.ИнициализироватьНастройкиИспользующиеРезультатыПредыдущихРазборов());
	НастройкиРазбораКодаМаркировки.Вставить("Общие",            РазборКодаМаркировкиИССлужебныйПовтИсп.НастройкиРазбораКодаМаркировки());
	НастройкиРазбораКодаМаркировки.Вставить("Пользовательские", ПользовательскиеПараметрыРазбораКодаМаркировки);
	
	Если ЕстьИерархия Тогда
		ДеревоУпаковок = ШтрихкодированиеИС.ИнициализироватьДеревоУпаковок(Истина);
		ДанныеПоШтрихкодам = ШтрихкодированиеОбщегоНазначенияИС.ИнициализацияДанныхПоШтрихкодам(Ложь);
		ДанныеПоШтрихкодам.ВложенныеШтрихкоды = ШтрихкодированиеИС.ИнициализацияВложенныхШтрихкодов(ДеревоУпаковок, Ложь);
		ДанныеПоШтрихкодам.ИерархическаяЗагрузкаИзТСД = Истина;
		СоответствиеСтрокДереваУпаковок = Новый Соответствие;
	КонецЕсли;
	
	ПроверкаИПодборПродукцииИСМПКлиентСервер.ПодготовитьДополнительныеВариантыСопоставленияНоменклатуры(
		ДанныеДляТСД.ПараметрыСканирования, ПодобраннаяМаркируемаяПродукция);
	
	ВидПродукцииИспользуетНаборыИлиГрупповыеУпаковки = ОбщегоНазначенияИСКлиентСерверПовтИсп.ВидПродукцииИспользуетНаборыИлиГрупповыеУпаковки(ВидМаркируемойПродукции);
	
	Если ВидПродукцииИспользуетНаборыИлиГрупповыеУпаковки Тогда
		
		GTINКОпределениюВидаУпаковки = ГрупповаяОбработкаШтрихкодовИС.ПодготовитьДанныеКОпределениюВидаУпаковки(
			ДанныеДляТСД, ВидМаркируемойПродукции, КешДанныхРазбора, НастройкиРазбораКодаМаркировки);
		
		Если GTINКОпределениюВидаУпаковки.Количество() > 0 Тогда
			
			КОпределениюВидаУпаковки = Новый Структура;
			КОпределениюВидаУпаковки.Вставить("GTIN",                  GTINКОпределениюВидаУпаковки);
			КОпределениюВидаУпаковки.Вставить("ПараметрыСканирования", ПараметрыСканирования);
			
			РезультатПодготовки = ГрупповаяОбработкаШтрихкодовИС.ОбработатьДанныеКОпределениюВидаУпаковки(КОпределениюВидаУпаковки);
			
			Если ЗначениеЗаполнено(РезультатПодготовки.ТекстОшибки) Тогда
				
				Результат.ОбщаяОшибка      = Истина;
				Результат.ТекстОбщейОшибки = РезультатПодготовки.ТекстОшибки;
				ЗагрузкаДанныхТСД = Результат;
				Возврат;
				
			ИначеЕсли РезультатПодготовки.УточнениеДанныхНеТребуется Тогда
				
				// Очистить кеш после уточнения видов упаковок.
				КешДанныхРазбора = Новый Соответствие;
				
			Иначе
				
				Если РезультатПодготовки.ТребуетсяОбновлениеКлючаСессии Тогда
					Результат.ТребуетсяАвторизация = Истина;
				КонецЕсли;
				
				Результат.АдресУточнениеКоэффициентовУпаковок = РезультатПодготовки.АдресУточнениеКоэффициентовУпаковок;
				ЗагрузкаДанныхТСД = Результат;
				
				Возврат;
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
	Для Каждого СтрокаДанныхТСД Из ДанныеДляТСД.Штрихкоды Цикл
		
		СтрокаДанныхТСД.Вставить("ШтрихкодСОшибкой", Ложь);
		
		Штрихкод = ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(СтрокаДанныхТСД.Штрихкод);
		ДанныеРазбораШтрихкода = ГрупповаяОбработкаШтрихкодовИС.ВидУпаковкиИПредставлениеШтрихкодаУпрощенныйРазбор(
			Штрихкод, ВидМаркируемойПродукции, КешДанныхРазбора,
			НастройкиРазбораКодаМаркировки);
		
		Если ДанныеРазбораШтрихкода.ВидУпаковки = Неопределено
			И Не ЗначениеЗаполнено(ДанныеРазбораШтрихкода.НормализованныйШтрихкод) Тогда
			
			Штрихкод = ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыXML(Штрихкод, "");
			
			СтрокаДанныхТСД.ШтрихкодСОшибкой = Истина;
			ОбщегоНазначенияИС.СообщитьПользователюВФорму(
				УникальныйИдентификатор,
				СтрШаблон(
					НСтр("ru = 'Код %1 не является штрихкодом потребительской, групповой или логистической 
					           |упаковки табачной продукции. Пропущен.'"),
					Штрихкод));
			
			МассивПропущенныхШтрихкодов.Добавить(СтрокаДанныхТСД);
			Продолжить;
			
		КонецЕсли;
		
		Если ДанныеРазбораШтрихкода.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская
			Или ВСтрокеНаборКакПотребительская(ДанныеРазбораШтрихкода, Ложь, ДанныеДляТСД.ПараметрыСканирования) Тогда
			КоличествоПотребительскихУпаковок = КоличествоПотребительскихУпаковок + 1;
		ИначеЕсли ДанныеРазбораШтрихкода.ВидУпаковки = Перечисления.ВидыУпаковокИС.Групповая
			Или ВСтрокеНаборКакГрупповая(ДанныеРазбораШтрихкода, Ложь, ДанныеДляТСД.ПараметрыСканирования) Тогда
			КоличествоГрупповыхУпаковок = КоличествоГрупповыхУпаковок + 1;
			Если Не ЕстьУпаковка Тогда
				ШтрихкодУпаковки = СтрокаДанныхТСД.Штрихкод;
			КонецЕсли;
		ИначеЕсли ДанныеРазбораШтрихкода.ВидУпаковки = Перечисления.ВидыУпаковокИС.Логистическая Тогда
			КоличествоУпаковок = КоличествоУпаковок + 1;
			ЕстьУпаковка       = Истина;
			ШтрихкодУпаковки   = СтрокаДанныхТСД.Штрихкод;
			
			GTIN = Неопределено;
			ДанныеРазбораИРезультат = КешДанныхРазбора[Штрихкод];
			Если ДанныеРазбораИРезультат <> Неопределено Тогда
				ДанныеРазбораИРезультат.ДанныеРазбора.СоставКодаМаркировки.Свойство("GTIN", GTIN);
			КонецЕсли;
			Если ЗначениеЗаполнено(GTIN) Тогда
				КоличествоКоробов = КоличествоКоробов + 1;
			Иначе
				КоличествоПалет = КоличествоПалет + 1;
			КонецЕсли;
		КонецЕсли;
		
		СтрокаДанныхТСД.Вставить("НормализованныйШтрихкод", ДанныеРазбораШтрихкода.НормализованныйШтрихкод);
		
		Если ЗначениеЗаполнено(СтрокаДанныхТСД.ШтрихкодУпаковки) Тогда
			
			ПроверитьДоступнуюИерархиюШтрихкодов = Ложь;
			
			ШтрихкодУпаковки = ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(СтрокаДанныхТСД.ШтрихкодУпаковки);
			ДанныеРазбораШтрихкодаУпаковки = ГрупповаяОбработкаШтрихкодовИС.ВидУпаковкиИПредставлениеШтрихкодаУпрощенныйРазбор(
				ШтрихкодУпаковки, ВидМаркируемойПродукции, КешДанныхРазбора,
				НастройкиРазбораКодаМаркировки);
			
			Если ДанныеРазбораШтрихкодаУпаковки.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская Тогда
				
				ШтрихкодУпаковки = ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыXML(ШтрихкодУпаковки, "");
				
				СтрокаДанныхТСД.ШтрихкодСОшибкой = Истина;
				ОбщегоНазначенияИС.СообщитьПользователюВФорму(
					УникальныйИдентификатор,
					СтрШаблон(
						НСтр("ru = 'Код %1 определен как потребительская упаковка. Потребительские упаковки не могут содержать вложенные упаковки. Пропущен.'"),
						ШтрихкодУпаковки));
				СтрокаДанныхТСД.Вставить("НормализованныйШтрихкодУпаковки", "");
				
			ИначеЕсли ЗначениеЗаполнено(ДанныеРазбораШтрихкодаУпаковки.ВидУпаковки)
				Или ЗначениеЗаполнено(ДанныеРазбораШтрихкодаУпаковки.НормализованныйШтрихкод) Тогда
				СтрокаДанныхТСД.Вставить("НормализованныйШтрихкодУпаковки", ДанныеРазбораШтрихкодаУпаковки.НормализованныйШтрихкод);
			Иначе
				
				ШтрихкодУпаковки = ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыXML(ШтрихкодУпаковки, "");
				
				СтрокаДанныхТСД.ШтрихкодСОшибкой = Истина;
				ОбщегоНазначенияИС.СообщитьПользователюВФорму(
					УникальныйИдентификатор,
					СтрШаблон(
						НСтр("ru = 'Код %1 не является штрихкодом групповой или логистической 
						           |упаковки табачной продукции. Пропущен.'"),
						ШтрихкодУпаковки));
				СтрокаДанныхТСД.Вставить("НормализованныйШтрихкодУпаковки", "");
			Конецесли;
			
		Иначе
			СтрокаДанныхТСД.Вставить("НормализованныйШтрихкодУпаковки", "");
		КонецЕсли;
		
		Если ЕстьИерархия
			И Не СтрокаДанныхТСД.ШтрихкодСОшибкой Тогда
			
			Если ЗначениеЗаполнено(СтрокаДанныхТСД.НормализованныйШтрихкодУпаковки) Тогда
				СтрокаДереваВерхнегоУровня = СоответствиеСтрокДереваУпаковок[СтрокаДанныхТСД.НормализованныйШтрихкодУпаковки];
				Если СтрокаДереваВерхнегоУровня = Неопределено Тогда
					СтрокаДереваВерхнегоУровня = ДеревоУпаковок;
				КонецЕсли;
			Иначе
				СтрокаДереваВерхнегоУровня = ДеревоУпаковок;
			КонецЕсли;
			
			СтрокаДерева = СтрокаДереваВерхнегоУровня.Строки.Добавить();
			
			ДанныеРазбораИПримечание = КешДанныхРазбора[Штрихкод];
			ДанныеРазбора = ДанныеРазбораИПримечание.ДанныеРазбора;
			
			// Заполнение GTIN и EAN
			Если ДанныеРазбора.СоставКодаМаркировки <> Неопределено Тогда
				ЗаполнитьЗначенияСвойств(СтрокаДерева, ДанныеРазбора.СоставКодаМаркировки);
			КонецЕсли;
			
			СтрокаДерева.ШтрихкодBase64       = СтрокаДанныхТСД.Штрихкод; // ШтрихкодBase64
			СтрокаДерева.Штрихкод             = ДанныеРазбора.НормализованныйКодМаркировки;
			СтрокаДерева.ТипШтрихкода         = ДанныеРазбора.ТипШтрихкода;
			СтрокаДерева.ВидУпаковки          = ДанныеРазбора.ВидУпаковки;
			СтрокаДерева.СоставКодаМаркировки = ДанныеРазбора.СоставКодаМаркировки;
			СтрокаДерева.ВидПродукции         = ВидМаркируемойПродукции;
			СтрокаДерева.ДанныеРазбора        = ДанныеРазбора;
			
			Если ДанныеРазбора.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская Тогда
				СтрокаДерева.ТипУпаковки = Перечисления.ТипыУпаковок.МаркированныйТовар;
			ИначеЕсли ДанныеРазбора.ВидУпаковки = Перечисления.ВидыУпаковокИС.Групповая Тогда
				СтрокаДерева.ТипУпаковки = Перечисления.ТипыУпаковок.МонотоварнаяУпаковка;
			ИначеЕсли ДанныеРазбора.ВидУпаковки = Перечисления.ВидыУпаковокИС.Логистическая
				И ЗначениеЗаполнено(СтрокаДерева.GTIN) Тогда
				СтрокаДерева.ТипУпаковки = Перечисления.ТипыУпаковок.МонотоварнаяУпаковка;
			Иначе
				СтрокаДерева.ТипУпаковки = Перечисления.ТипыУпаковок.МультитоварнаяУпаковка;
			КонецЕсли;
			
			СтрокаДерева.Входящий = Истина;
			
			ШтрихкодированиеОбщегоНазначенияИС.ПроверитьСтрокуДанныхНаВхождениеНедопустимыхСимволов(СтрокаДерева);
			
			СтрокаДерева.НормализованныйШтрихкод = ДанныеРазбора.НормализованныйКодМаркировки;
			ШтрихкодированиеОбщегоНазначенияМОТП.РассчитатьХэшСуммуНормализации(
				СтрокаДерева,
				СтрокаДерева.ДанныеРазбора);
			
			СоответствиеСтрокДереваУпаковок.Вставить(СтрокаДанныхТСД.НормализованныйШтрихкод, СтрокаДерева);
			
		КонецЕсли;
		
		ДанныеШтрихкода = Новый Структура(
			"Штрихкод, ШтрихкодBase64, Количество",
			Штрихкод, СтрокаДанныхТСД.Штрихкод, СтрокаДанныхТСД.Количество);
		
		ДанныеШтрихкодов.Добавить(ДанныеШтрихкода);
		
	КонецЦикла;
	
	Если МассивПропущенныхШтрихкодов.Количество() Тогда
		Для Каждого ЭлементМассива Из МассивПропущенныхШтрихкодов Цикл
			ПорядковыйНомер = ДанныеДляТСД.Штрихкоды.Найти(ЭлементМассива);
			Если ПорядковыйНомер <> Неопределено Тогда
				ДанныеДляТСД.Штрихкоды.Удалить(ПорядковыйНомер);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ТекущаяДетализация = Перечисления.ДетализацияСтруктурыХраненияИС.Полная;
	Если ЗначениеЗаполнено(ДанныеДляТСД.ПараметрыСканирования.ДетализацияСтруктурыХранения) Тогда
		ТекущаяДетализация = ДанныеДляТСД.ПараметрыСканирования.ДетализацияСтруктурыХранения;
	КонецЕсли;
	
	ПредложитьИзменитьДетализацию        = Ложь;
	РекомендуемыеДетализации             = Новый Массив;
	ОписаниеРекомендацииСменыДетализации = "";
	Если ПроверитьРекомендуемуюДетализацию Тогда
		Если ЭтоДокументМаркировка(ЭтотОбъект) Тогда
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.Полная);
		ИначеЕсли КоличествоПалет > 0 Или КоличествоКоробов >= 25 Тогда
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами);
		ИначеЕсли КоличествоКоробов >= 5 Или КоличествоГрупповыхУпаковок >= 250 Тогда
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками);
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами);
		Иначе
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.Полная);
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами);
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками);
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими);
			РекомендуемыеДетализации.Добавить(Перечисления.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки);
		КонецЕсли;
		ПредложитьИзменитьДетализацию = РекомендуемыеДетализации.Найти(ТекущаяДетализация) = Неопределено;
		
		СтрокиСКоличествомУпаковок = Новый Массив;
		ДобавитьПредставлениеКоличестваУпаковок(СтрокиСКоличествомУпаковок, НСтр("ru = 'палета'"), КоличествоПалет);
		ДобавитьПредставлениеКоличестваУпаковок(СтрокиСКоличествомУпаковок, НСтр("ru = 'короб'"),  КоличествоКоробов);
		ДобавитьПредставлениеКоличестваУпаковок(СтрокиСКоличествомУпаковок, НСтр("ru = 'блок'"),   КоличествоГрупповыхУпаковок);
		ДобавитьПредставлениеКоличестваУпаковок(СтрокиСКоличествомУпаковок, НСтр("ru = 'пачка'"),  КоличествоПотребительскихУпаковок);
		ОписаниеРекомендацииСменыДетализации = СтрСоединить(СтрокиСКоличествомУпаковок, ", ");
	КонецЕсли;
	
	Результат.ПредложитьИзменитьДетализацию        = ПредложитьИзменитьДетализацию;
	Результат.РекомендуемыеДетализации             = РекомендуемыеДетализации;
	Результат.ОписаниеРекомендацииСменыДетализации = ОписаниеРекомендацииСменыДетализации;
	Если ПредложитьИзменитьДетализацию Тогда
		ЗагрузкаДанныхТСД = Результат;
		Возврат;
	КонецЕсли;
	
	ПредложитьЗагрузитьВУпаковке = Ложь;
	Если ПроверитьДоступнуюИерархиюШтрихкодов Тогда
		ПредложитьЗагрузитьВУпаковке = Ложь;
		Если КоличествоУпаковок = 0 И КоличествоГрупповыхУпаковок = 1 И КоличествоПотребительскихУпаковок > 0 Тогда
			Результат.ТекстПредложенияОЗагрузке = "ОдинКодБлокаИКодыМаркировки";
			ПредложитьЗагрузитьВУпаковке = Истина;
		ИначеЕсли КоличествоУпаковок = 1 И КоличествоГрупповыхУпаковок > 0 И КоличествоПотребительскихУпаковок = 0 Тогда
			Результат.ТекстПредложенияОЗагрузке = "ОднаУпаковкаИКодыБлоков";
			ПредложитьЗагрузитьВУпаковке = Истина;
		ИначеЕсли КоличествоУпаковок = 1 И КоличествоГрупповыхУпаковок = 0 И КоличествоПотребительскихУпаковок > 0 Тогда
			Результат.ТекстПредложенияОЗагрузке = "ОднаУпаковкаИКодыМаркировки";
			ПредложитьЗагрузитьВУпаковке = Истина;
		КонецЕсли;
	КонецЕсли;
	
	Результат.ПредложитьЗагрузитьВУпаковке = ПредложитьЗагрузитьВУпаковке;
	Если ПредложитьЗагрузитьВУпаковке Тогда
		ЗагрузкаДанныхТСД = Результат;
		Возврат;
	КонецЕсли;
	
	Если ДанныеДляТСД.ДополнительныеПараметры.Состояние = "ЗаполнениеИерархии" Тогда
		
		ПредставлениеУпаковки = ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(ШтрихкодУпаковки);
		ДанныеРазбора = ГрупповаяОбработкаШтрихкодовИС.ВидУпаковкиИПредставлениеШтрихкодаУпрощенныйРазбор(
			ПредставлениеУпаковки, ВидМаркируемойПродукции, КешДанныхРазбора,
			НастройкиРазбораКодаМаркировки);
		Если ЗначениеЗаполнено(ДанныеРазбора.ВидУпаковки) Тогда
			ПредставлениеУпаковки = ДанныеРазбора.НормализованныйШтрихкод;
		Иначе
			ПредставлениеУпаковки = "";
		КонецЕсли;
		
		Для Каждого СтрокаДанныхТСД Из ДанныеДляТСД.Штрихкоды Цикл
			Если ЗначениеЗаполнено(СтрокаДанныхТСД.Штрихкод) Тогда
				Если СтрокаДанныхТСД.Штрихкод = ШтрихкодУпаковки Тогда
					СтрокаДанныхТСД.Уровень = -1;
				Иначе
					СтрокаДанныхТСД.ШтрихкодУпаковки = ШтрихкодУпаковки;
					СтрокаДанныхТСД.Вставить("НормализованныйШтрихкодУпаковки", ПредставлениеУпаковки);
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Если ЕстьИерархия Тогда
		ШтрихкодированиеМОТП.НормализоватьДанныеВложенныхШтрихкодов(
			ДанныеПоШтрихкодам.ВложенныеШтрихкоды, ДанныеДляТСД.ПараметрыСканирования);
		ШтрихкодированиеОбщегоНазначенияМОТП.ДобавитьКолонкиТаблицыДанныеКодовМаркировки(
			ДанныеПоШтрихкодам, ДанныеДляТСД.ПараметрыСканирования);
	КонецЕсли;
	
	РезультатОбработкиШтрихкодов = ШтрихкодированиеОбщегоНазначенияИС.ОбработатьШтрихкоды(
		ДанныеШтрихкодов, ДанныеДляТСД.ПараметрыСканирования,
		Неопределено, УникальныйИдентификатор, КешДанныхРазбора, ДанныеПоШтрихкодам);
	
	// 1. Авторизация
	ТребуетсяАвторизация = Ложь;
	Для Каждого КлючИЗначение Из РезультатОбработкиШтрихкодов.РезультатыОбработки Цикл
		РезультатОбработки = КлючИЗначение.Значение;
		Если РезультатОбработки.Свойство("ТребуетсяАвторизацияИСМП")
			И РезультатОбработки.ТребуетсяАвторизацияИСМП Тогда
			ТребуетсяАвторизация = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Результат.ТребуетсяАвторизация = ТребуетсяАвторизация;
	Если ТребуетсяАвторизация Тогда
		ЗагрузкаДанныхТСД = Результат;
		Возврат;
	КонецЕсли;
	
	// 2. Авторизация розничным методом
	ТребуетсяАвторизацияИСМПРозница = Ложь;
	Для Каждого КлючИЗначение Из РезультатОбработкиШтрихкодов.РезультатыОбработки Цикл
		РезультатОбработки = КлючИЗначение.Значение;
		Если РезультатОбработки.Свойство("ТребуетсяАвторизацияИСМПРозница")
			И РезультатОбработки.ТребуетсяАвторизацияИСМПРозница Тогда
			ТребуетсяАвторизацияИСМПРозница = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Результат.ТребуетсяАвторизацияИСМПРозница = ТребуетсяАвторизацияИСМПРозница;
	Если ТребуетсяАвторизацияИСМПРозница Тогда
		ЗагрузкаДанныхТСД = Результат;
		Возврат;
	КонецЕсли;
	
	// 3. Загрузка CDN-площадок
	ОтсутствуютCDNПлощадки = Ложь;
	Для Каждого КлючИЗначение Из РезультатОбработкиШтрихкодов.РезультатыОбработки Цикл
		РезультатОбработки = КлючИЗначение.Значение;
		Если РезультатОбработки.Свойство("ОтсутствуютCDNПлощадки")
			И РезультатОбработки.ОтсутствуютCDNПлощадки Тогда
			ОтсутствуютCDNПлощадки = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Результат.ОтсутствуютCDNПлощадки = ОтсутствуютCDNПлощадки;
	Если ОтсутствуютCDNПлощадки Тогда
		ЗагрузкаДанныхТСД = Результат;
		Возврат;
	КонецЕсли;
	
	// В коллекциях: ДанныеДляТСД.Штрихкоды и РезультатОбработкиШтрихкодов.РезультатыОбработки,
	// хранятся одни и теже коды маркировки с разной нормализацией.
	ДополнительныеРезультатыОбработки = Новый Соответствие;
	Для Каждого КлючЗначение Из РезультатОбработкиШтрихкодов.РезультатыОбработки Цикл
		ДополнительныеРезультатыОбработки.Вставить(КлючЗначение.Значение.ДанныеШтрихкода.НормализованныйШтрихкод, КлючЗначение.Значение);
	КонецЦикла;
	Для Каждого КлючИЗначение Из ДополнительныеРезультатыОбработки Цикл
		РезультатОбработкиШтрихкодов.РезультатыОбработки.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
	КонецЦикла;
	Для Каждого ЭлементДанных Из ДанныеДляТСД.Штрихкоды Цикл
		ЭлементДанных.НормализованныйШтрихкод = ШтрихкодированиеМОТП.НормализованныйШтрихкод(
			ЭлементДанных.НормализованныйШтрихкод, ВидМаркируемойПродукции, КешДанныхРазбора, ПользовательскиеПараметрыРазбораКодаМаркировки);
	КонецЦикла;
	
	ГрупповаяОбработкаШтрихкодовИС.УпорядочитьДанныеТСДПоРезультатамОбработкиШтрихкодов(
		ДанныеДляТСД.Штрихкоды, РезультатОбработкиШтрихкодов.РезультатыОбработки, ДанныеПоШтрихкодам.ЗаменыШтрихкодов);
	
	// 2. Ошибки
	Результат.ШтрихкодыТСД = ДанныеДляТСД.Штрихкоды;
	ГрупповаяОбработкаШтрихкодовИС.ПроверитьНаОшибкиРезультатОбработкиДанныхТСД(
		Результат, ЭтотОбъект, ДанныеДляТСД.ПараметрыСканирования);
	
	Результат.Всего = ДанныеДляТСД.Штрихкоды.Количество();
	ЗагрузкаДанныхТСД = Результат;
	
	Если Результат.ОбщаяОшибка
		Или Результат.ШтрихкодыДляСопоставления.Количество()
		Или ЗначениеЗаполнено(ЗагрузкаДанныхТСД.АдресУточнениеКоэффициентовУпаковок) Тогда
		Возврат;
	КонецЕсли;
	
	Если Результат.ЕстьОшибкиВДереве
		И Не ДанныеДляТСД.ПараметрыСканирования.ПропускатьСтрокиСОшибкамиПриЗагрузкеИзТСД Тогда
		Возврат;
	КонецЕсли;
	
	// 3. Сохранение данных по штрихкодам, уже существующим в дереве маркированной продукции
	Для Каждого ЭлементДанных Из ЗагрузкаДанныхТСД.ШтрихкодыТСД Цикл
		
		Если ЭлементДанных.РезультатОбработки = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		ДанныеШтрихкода = ЭлементДанных.РезультатОбработки.ДанныеШтрихкода;
		Если ДанныеШтрихкода = Неопределено Тогда
			// При обращении к ГИС МТ возникла ошибка
			Продолжить;
		КонецЕсли;
		
		Если ДанныеШтрихкода.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
			ИдентификаторНайденнойСтроки = ИдентификаторСтрокиДереваПоШтрихкодуНаСервере(
				ДанныеШтрихкода.Штрихкод, ДанныеДляТСД.СоответствиеШтрихкодовСтрокДерева);
			Если ИдентификаторНайденнойСтроки = -1 Тогда
				ИдентификаторНайденнойСтроки = ИдентификаторСтрокиДереваПоШтрихкодуНаСервере(
					ШтрихкодыУпаковокКлиентСервер.КодМаркировкиБезСкобок(ДанныеШтрихкода.Штрихкод),
					ДанныеДляТСД.СоответствиеШтрихкодовСтрокДерева);
			КонецЕсли;
		Иначе
			ИдентификаторНайденнойСтроки = ИдентификаторСтрокиДереваПоШтрихкодуНаСервере(
				ДанныеШтрихкода.НормализованныйШтрихкод, ДанныеДляТСД.СоответствиеШтрихкодовСтрокДерева);
		КонецЕсли;
		
		Если ИдентификаторНайденнойСтроки <> -1 Тогда
			
			СтрокаДерева = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторНайденнойСтроки);
			Если СтрокаДерева <> Неопределено Тогда
				
				Если Не ЗначениеЗаполнено(СтрокаДерева.Номенклатура)
					И ЗначениеЗаполнено(ДанныеШтрихкода.Номенклатура) Тогда // Строка уже в дереве, очистили сопоставление в форме проверки
					
					ДанныеШтрихкода.Номенклатура   = Неопределено;
					ДанныеШтрихкода.Характеристика = Неопределено;
					ДанныеШтрихкода.Серия          = Неопределено;
					
					ЭлементДанных.РезультатОбработки.ТребуетсяУточнениеДанных = Истина;
					ЭлементДанных.РезультатОбработки.ТребуетсяВыборСерии      = Ложь;
					
				ИначеЕсли СтрокаДерева.Номенклатура <> ДанныеШтрихкода.Номенклатура
					Или СтрокаДерева.Характеристика <> ДанныеШтрихкода.Характеристика
					Или СтрокаДерева.Серия <> ДанныеШтрихкода.Серия Тогда
					
					ДанныеШтрихкода.Номенклатура   = СтрокаДерева.Номенклатура;
					ДанныеШтрихкода.Характеристика = СтрокаДерева.Характеристика;
					ДанныеШтрихкода.Серия          = СтрокаДерева.Серия;
					
					ЭлементДанных.РезультатОбработки.ТребуетсяУточнениеДанных = Ложь;
					ЭлементДанных.РезультатОбработки.ТребуетсяУточнениеСоставаУпаковки = Ложь;
					ЭлементДанных.РезультатОбработки.ТребуетсяВыборСерии = Не ЗначениеЗаполнено(СтрокаДерева.Серия)
						И ИнтеграцияИС.СерияДолжнаБытьУказана(СтрокаДерева, ДанныеДляТСД.ПараметрыСканирования);
					
				КонецЕсли;
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЦикла;
	
	// 4. Обработка всех строк, не требующих вмешательства пользователя
	ЗагрузкаДанныхТСД = ОбработатьШтрихкодыНаСервере(
		ДанныеДляТСД.ПараметрыСканирования,
		ДанныеДляТСД.СоответствиеШтрихкодовСтрокДерева,
		РезультатОбработкиШтрихкодов.ДанныеПоШтрихкодам,
		КэшированныеЗначения);
	
КонецПроцедуры

&НаСервере
Функция ОбработатьШтрихкодыНаСервере(ПараметрыСканирования, СоответствиеШтрихкодовСтрокДерева, ДанныеПоШтрихкодам = Неопределено, КэшированныеЗначения)
	
	Если ЗагрузкаДанныхТСД = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	КешСтрокДереваУпаковок = Новый Соответствие;
	Пока ЗагрузкаДанныхТСД.Обработано < ЗагрузкаДанныхТСД.Всего Цикл
		Если Не ОбработатьОчереднойШтрихкодНаСервере(
				ПараметрыСканирования, СоответствиеШтрихкодовСтрокДерева, КешСтрокДереваУпаковок, ДанныеПоШтрихкодам, КэшированныеЗначения) Тогда
			Возврат ЗагрузкаДанныхТСД;
		КонецЕсли;
		ЗагрузкаДанныхТСД.Обработано = ЗагрузкаДанныхТСД.Обработано + 1;
	КонецЦикла;
	
	// Уменьшение количества данных к обработке на клиенте
	ГрупповаяОбработкаШтрихкодовИС.ОставитьНеобработанныеДанные(ЗагрузкаДанныхТСД);
	
	Возврат ЗагрузкаДанныхТСД;
	
КонецФункции

&НаСервере
Функция ОбработатьОчереднойШтрихкодНаСервере(ПараметрыСканирования, СоответствиеШтрихкодовСтрокДерева, КешСтрокДереваУпаковок, ДанныеПоШтрихкодам = Неопределено, КэшированныеЗначения)
	
	Если ЗагрузкаДанныхТСД.Обработано = ЗагрузкаДанныхТСД.Всего Тогда
		Возврат Ложь;
	КонецЕсли;
	
	СтрокаШтрихкод = ЗагрузкаДанныхТСД.ШтрихкодыТСД[ЗагрузкаДанныхТСД.Обработано];
	
	Если СтрокаШтрихкод.ШтрихкодСОшибкой Тогда
		Возврат Истина;
	КонецЕсли;
	
	Если СтрокаШтрихкод.РезультатОбработки = Неопределено
		Или СтрокаШтрихкод.РезультатОбработки.ТребуетсяУточнениеДанных
		Или СтрокаШтрихкод.РезультатОбработки.ТребуетсяУточнениеСоставаУпаковки
		Или СтрокаШтрихкод.РезультатОбработки.ТребуетсяУточнениеКоэффициентовУпаковок
		Или СтрокаШтрихкод.РезультатОбработки.ТребуетсяВыборСерии
		Или (СтрокаШтрихкод.РезультатОбработки.ТребуетсяПроверкаСредствамиККТ
			И Не СтрокаШтрихкод.РезультатОбработки.ПроверкаСредствамиККТЗавершена) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ДанныеШтрихкода = СтрокаШтрихкод.РезультатОбработки.ДанныеШтрихкода;
	
	СпозиционироватьсяНаСервере(СтрокаШтрихкод, ДанныеШтрихкода, СоответствиеШтрихкодовСтрокДерева, ДанныеПоШтрихкодам);
	
	ШтрихкодОбработан = ПоискПоШтрихкодуЗавершениеНаСервере(ДанныеШтрихкода, СоответствиеШтрихкодовСтрокДерева, КешСтрокДереваУпаковок, ПараметрыСканирования, КэшированныеЗначения);
	Если Не ШтрихкодОбработан Тогда
		СтрокаШтрихкод.Вставить("ТребуетсяОбработкаНаКлиенте");
	КонецЕсли;
	
	Возврат ШтрихкодОбработан;
	
КонецФункции

&НаКлиенте
Процедура ОбработатьПолученныеДанныеТСД() Экспорт
	
	Если ЗагрузкаДанныхТСД = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ОбработатьЗавершениеЗагрузкиИзТСД() Тогда
		Возврат;
	КонецЕсли;
	
	СтрокаШтрихкод = ЗагрузкаДанныхТСД.ШтрихкодыТСД[ЗагрузкаДанныхТСД.Обработано];
	
	Если СтрокаШтрихкод.ШтрихкодСОшибкой Тогда
		ЗагрузкаДанныхТСД.Обработано = ЗагрузкаДанныхТСД.Обработано + 1;
		ОбработатьОчереднойШтрихкод();
		Возврат;
	КонецЕсли;
	
	ДанныеШтрихкода = СтрокаШтрихкод.РезультатОбработки.ДанныеШтрихкода;
	
	Спозиционироваться(СтрокаШтрихкод, ДанныеШтрихкода);
	
	Если ЗначениеЗаполнено(СтрокаШтрихкод.Штрихкод) Тогда
		
		ИнициализироватьПараметрыСканирования();
		
		ТребуетсяУточнениеДанных = СтрокаШтрихкод.РезультатОбработки.ТребуетсяУточнениеДанных
			Или СтрокаШтрихкод.РезультатОбработки.ТребуетсяУточнениеСоставаУпаковки
			Или СтрокаШтрихкод.РезультатОбработки.ТребуетсяУточнениеКоэффициентовУпаковок
			Или СтрокаШтрихкод.РезультатОбработки.ТребуетсяВыборСерии
			Или (СтрокаШтрихкод.РезультатОбработки.ТребуетсяПроверкаСредствамиККТ
				И Не СтрокаШтрихкод.РезультатОбработки.ПроверкаСредствамиККТЗавершена);
		
		Если Не ТребуетсяУточнениеДанных
			И Не СтрокаШтрихкод.Свойство("ТребуетсяОбработкаНаКлиенте") Тогда
			
			ЗагрузкаДанныхТСД.ПересчитыватьИтогиВДеревеМаркированнойПродукции = Ложь;
			
			ЗагрузкаДанныхТСД = ОбработатьШтрихкодыНаСервере(ПараметрыСканирования, СоответствиеШтрихкодовСтрокДерева,, КэшированныеЗначения);
			
			// Если требуется уточнять данные, то необходимо до вызова окон уточнения пересчитать итоги в дереве маркированной продукции
			Если ЗагрузкаДанныхТСД.Обработано < ЗагрузкаДанныхТСД.Всего Тогда
				ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковок(ДеревоМаркированнойПродукции);
			КонецЕсли;
			// Начиная с этого момента - разрешено пересчитывать итоги.
			ЗагрузкаДанныхТСД.ПересчитыватьИтогиВДеревеМаркированнойПродукции = Истина;
			
			ОбработатьОчереднойШтрихкод();
			
			Возврат;
			
		КонецЕсли;
		
		ЗагрузкаДанныхТСД.Обработано = ЗагрузкаДанныхТСД.Обработано + 1;
		
		Если ТребуетсяУточнениеДанных Тогда
			
			ПараметрыЗавершенияОбработкиШтрихкода = ШтрихкодированиеОбщегоНазначенияИСКлиент.ПараметрыЗавершенияОбработкиШтрихкода("","","ПоискПоШтрихкодуЗавершение");
			ПараметрыЗавершенияОбработкиШтрихкода.ВызовИзФормыДокумента = Ложь;
			ПараметрыЗавершенияОбработкиШтрихкода.ДанныеШтрихкода = ДанныеШтрихкода;
			ПараметрыЗавершенияОбработкиШтрихкода.РезультатОбработкиШтрихкода = СтрокаШтрихкод.РезультатОбработки;
			ПараметрыЗавершенияОбработкиШтрихкода.КэшированныеЗначения = КэшированныеЗначения;
			ПараметрыЗавершенияОбработкиШтрихкода.ПараметрыСканирования = ПараметрыСканирования;
			ПараметрыЗавершенияОбработкиШтрихкода.Форма = ЭтотОбъект;
			
			ШтрихкодированиеОбщегоНазначенияИСКлиент.ЗавершитьОбработкуШтрихкода(ПараметрыЗавершенияОбработкиШтрихкода);
			ШтрихкодированиеОбщегоНазначенияИСКлиент.ОбработатьАсинхронноШтрихкод(ПараметрыЗавершенияОбработкиШтрихкода);
			
		Иначе
			ПоискПоШтрихкодуЗавершение(ДанныеШтрихкода);
		КонецЕсли;
		
	Иначе
		
		ОбработатьОчереднойШтрихкод();
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Функция ОбработатьЗавершениеЗагрузкиИзТСД()
	
	Если ЗагрузкаДанныхТСД.Обработано <> ЗагрузкаДанныхТСД.Всего Тогда
		Возврат Ложь;
	КонецЕсли;

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

&НаКлиенте
Процедура ОбработатьОчереднойШтрихкод()
	ПодключитьОбработчикОжидания("ОбработатьПолученныеДанныеТСД", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура Спозиционироваться(СтрокаШтрихкод, ДанныеШтрихкода)
	
	Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		Возврат;
	ИначеЕсли Не ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(СтрокаШтрихкод, "НормализованныйШтрихкодУпаковки") Тогда
		Возврат;
	КонецЕсли;
	
	Штрихкод = СтрокаШтрихкод.НормализованныйШтрихкодУпаковки;
	Если Штрихкод = "" Тогда
		Если ДанныеШтрихкода.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
			ИзменитьКонтекстПроверки(СтрокаПотребительскиеУпаковкиБезУпаковки(ЭтотОбъект));
		ИначеЕсли ЭтоГрупповаяУпаковкаИлиНабор(ДанныеШтрихкода.ВидУпаковки) Тогда
			ИзменитьКонтекстПроверки(СтрокаГрупповыеУпаковкиБезКоробки(ЭтотОбъект));
		Иначе
			ИзменитьКонтекстПроверки(Неопределено);
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	ИдентификаторСтрокиДерева = ИдентификаторСтрокиДереваПоШтрихкоду(Штрихкод, Истина);
	Если ИдентификаторСтрокиДерева <> -1 Тогда
		ИзменитьКонтекстПроверки(
			НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторСтрокиДерева));
	КонецЕсли;
	
КонецПроцедуры

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

#Область ГрупповаяОбработкаЗагруженныхСтрокТСД

//Серверные процедуры, дублирующие клиентские обработчики, связанные с вводом штрих-кода.

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

&НаСервере
Функция ОбработатьОтсканированныйШтрихкодНаСервере(ДанныеШтрихкода, СоответствиеШтрихкодов, КешСтрокДереваУпаковок, ПараметрыСканирования, КэшированныеЗначения)
	
	ШтрихкодОбработан = Истина;
	
	Если ДанныеШтрихкода.ВидУпаковки = Перечисления.ВидыУпаковокИС.Логистическая Тогда
		ИдентификаторНайденнойСтроки = ИдентификаторСтрокиДереваПоШтрихкодуНаСервере(
			ДанныеШтрихкода.Штрихкод, СоответствиеШтрихкодов);
		Если ИдентификаторНайденнойСтроки = -1 Тогда
			ИдентификаторНайденнойСтроки = ИдентификаторСтрокиДереваПоШтрихкодуНаСервере(
				ШтрихкодыУпаковокКлиентСервер.КодМаркировкиБезСкобок(ДанныеШтрихкода.Штрихкод),
				СоответствиеШтрихкодов);
		КонецЕсли;
	Иначе
		ИдентификаторНайденнойСтроки = ИдентификаторСтрокиДереваПоШтрихкодуНаСервере(
			ДанныеШтрихкода.НормализованныйШтрихкод, СоответствиеШтрихкодов);
	КонецЕсли;
	
	Если ИдентификаторНайденнойСтроки <> -1 Тогда
		
		ШтрихкодОбработан = ОбработатьСканированиеИмеющегосяВДеревеШтрихкодаНаСервере(ДанныеШтрихкода, ИдентификаторНайденнойСтроки, СоответствиеШтрихкодов, КэшированныеЗначения);
		
	ИначеЕсли ЭтоАдресВременногоХранилища(ДанныеШтрихкода.АдресДереваУпаковок)
		И (     ДанныеШтрихкода.ТипУпаковки = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МонотоварнаяУпаковка")
			Или ДанныеШтрихкода.ТипУпаковки = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МультитоварнаяУпаковка")) Тогда
		
		Результат = РезультатДобавленияСуществующейУпаковкиВДеревоМаркированнойПродукции(
			ДанныеШтрихкода, СоответствиеШтрихкодов, КешСтрокДереваУпаковок, ПараметрыСканирования, КэшированныеЗначения);
		
		Если Результат.ЕстьОшибки Тогда
			
			ШтрихкодОбработан = Ложь;
			
		ИначеЕсли Результат.ТребуетсяСбросКонтекстаПроверки Тогда
			
			ИзменитьКонтекстПроверкиНаСервере(Неопределено);
			
		КонецЕсли;
		
	Иначе
		
		ШтрихкодОбработан = ОбработатьНеНайденныйВДеревеШтрихКодНаСервере(ДанныеШтрихкода, СоответствиеШтрихкодов, КэшированныеЗначения);
		
	КонецЕсли;
	
	Если ТаблицаИзмененийТабачнойПродукции.Количество() > 0 Тогда
		ОбработатьТаблицуИзмененийПодобраннойПродукции(ЭтотОбъект, КэшированныеЗначения);
	КонецЕсли;
	
	Возврат ШтрихкодОбработан;
	
КонецФункции

&НаСервере
Функция ИдентификаторСтрокиДереваПоШтрихкодуНаСервере(Штрихкод, СоответствиеШтрихкодов, Нормализовать = Ложь)
	
	Если Нормализовать Тогда
		ПользовательскиеПараметрыРазбораКодаМаркировки = РазборКодаМаркировкиИССлужебныйКлиентСервер.ПользовательскиеПараметрыРазбораКодаМаркировки();
		ПользовательскиеПараметрыРазбораКодаМаркировки.ВалидироватьШтрихкодЛогистическойУпаковкиGS1128СОшибками = Не ЭтоДокументМаркировка(ЭтотОбъект);
		ШтрихкодДляПоиска = ШтрихкодированиеМОТП.НормализованныйШтрихкод(Штрихкод, ВидМаркируемойПродукции,, ПользовательскиеПараметрыРазбораКодаМаркировки);
	Иначе
		ШтрихкодДляПоиска = Штрихкод;
	КонецЕсли;
	
	НайденныйИдентификаторСтроки = СоответствиеШтрихкодов.Получить(ШтрихкодДляПоиска);
	
	Если НайденныйИдентификаторСтроки = Неопределено Тогда
		
		НайденныйИдентификаторСтроки = -1;
		
	КонецЕсли;
	
	Возврат НайденныйИдентификаторСтроки;

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

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

&НаСервере
Процедура ИзменитьКонтекстПроверкиНаСервере(НоваяПроверяемаяУпаковка)
	
	Если НоваяПроверяемаяУпаковка = Неопределено Тогда
		ИдентификаторНовойПроверяемойУпаковки = -1;
	Иначе
		ИдентификаторНовойПроверяемойУпаковки = НоваяПроверяемаяУпаковка.ПолучитьИдентификатор();
	КонецЕсли;
	
	Если ИдентификаторНовойПроверяемойУпаковки = ИдентификаторТекущейПроверяемойУпаковки Тогда
		Возврат;
	КонецЕсли;
	
	ТекущаяПроверяемаяУпаковка = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторТекущейПроверяемойУпаковки);
	Если ТекущаяПроверяемаяУпаковка <> Неопределено Тогда
		СнятьПризнакПроверкиУпаковки(ЭтотОбъект, ТекущаяПроверяемаяУпаковка, Истина);
	КонецЕсли;
	
	УстановитьПризнакПроверкиУпаковки(ЭтотОбъект, НоваяПроверяемаяУпаковка);
	
КонецПроцедуры

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

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

&НаСервере
Процедура ПослеУспешногоОбнаруженияОтсканированногоШтрихкодаВДеревеНаСервере(
		НайденнаяСтрокаДерева,
		РодительНайденнойСтроки,
		СоответствиеШтрихкодов,
		КэшированныеЗначения)
	
	ТекущаяСтрокаДерева = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторТекущейПроверяемойУпаковки);
	
	ЭтоУпаковка = ИнтеграцияИСКлиентСервер.ЭтоУпаковка(НайденнаяСтрокаДерева.ТипУпаковки);
	Если ЭтоУпаковка Тогда
		
		Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
			Возврат;
		КонецЕсли;
		
		ЭтоГрупповаяУпаковкаИлиНабор = ЭтоГрупповаяУпаковкаИлиНабор(НайденнаяСтрокаДерева.ВидУпаковки);
		СтрокаПроверяемойУпаковки = СтрокаТекущейПроверяемойУпаковки(ЭтотОбъект, Истина, ЭтоГрупповаяУпаковкаИлиНабор);
		
		Если НайденнаяСтрокаДерева.ИдетПроверкаДаннойУпаковки Тогда
			
			СнятьПризнакПроверкиУпаковки(ЭтотОбъект, НайденнаяСтрокаДерева);
			СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НайденнаяСтрокаДерева);
			
		ИначеЕсли РодительНайденнойСтроки = СтрокаПроверяемойУпаковки Тогда
			
			Если НайденнаяСтрокаДерева = ТекущаяСтрокаДерева Тогда
				
				ОтметитьСтрокуКакНайденнуюНаСервере(НайденнаяСтрокаДерева);
				ИзменитьСостояниеПроверкиУпаковки(ЭтотОбъект, НайденнаяСтрокаДерева);
				
			Иначе
				
				Если ТекущаяСтрокаДерева <> Неопределено Тогда
					СнятьПризнакПроверкиУпаковки(ЭтотОбъект, ТекущаяСтрокаДерева);
				КонецЕсли;
				ОтметитьСтрокуКакНайденнуюНаСервере(НайденнаяСтрокаДерева);
				
			КонецЕсли;
			
		ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими")
			И Не ЭтоГрупповаяУпаковкаИлиНабор Тогда
			Возврат;
			
		ИначеЕсли ЭтоГрупповаяУпаковкаИлиНабор Тогда
			
			ПереместитьБлокНаСервере(НайденнаяСтрокаДерева, СтрокаПроверяемойУпаковки, СоответствиеШтрихкодов, КэшированныеЗначения);
			ОтметитьСтрокуКакНайденнуюНаСервере(НайденнаяСтрокаДерева);
			
		Иначе
			
			ПереместитьУпаковкуВДругуюУпаковкуНаСервере(НайденнаяСтрокаДерева, ТекущаяСтрокаДерева, СоответствиеШтрихкодов, КэшированныеЗначения);
			ОтметитьСтрокуКакНайденнуюНаСервере(НайденнаяСтрокаДерева);
			
		КонецЕсли;
		
	Иначе
		
		ИдентификаторУпаковки = ИдентификаторТекущейПроверяемойУпаковки;
		
		Если (РодительНайденнойСтроки = Неопределено
			Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
			Или РодительНайденнойСтроки.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки())
			И ИдентификаторУпаковки = -1 Тогда
			
			ОтметитьСтрокуКакНайденнуюНаСервере(НайденнаяСтрокаДерева);
			СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НайденнаяСтрокаДерева);
		
		ИначеЕсли РодительНайденнойСтроки.ПолучитьИдентификатор() = ИдентификаторУпаковки Тогда
			
			ОтметитьСтрокуКакНайденнуюНаСервере(НайденнаяСтрокаДерева);
			СпозиционироватьсяНаСтрокеДерева(ЭтотОбъект, НайденнаяСтрокаДерева);
			
		Иначе
			
			СтрокаПроверяемойУпаковки = СтрокаТекущейПроверяемойУпаковки(ЭтотОбъект, ЭтоУпаковка, Ложь);
			ПереместитьПачкуНаСервере(НайденнаяСтрокаДерева, СтрокаПроверяемойУпаковки, СоответствиеШтрихкодов, КэшированныеЗначения);
			ОтметитьСтрокуКакНайденнуюНаСервере(НайденнаяСтрокаДерева);
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПереместитьБлокНаСервере(СтрокаСБлоком, НоваяУпаковка, СоответствиеШтрихкодов, КэшированныеЗначения)

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

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

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

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

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

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

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

&НаСервере
Процедура СпозиционироватьсяНаСервере(СтрокаШтрихкод, ДанныеШтрихкода, СоответствиеШтрихкодов, ДанныеПоШтрихкодам = Неопределено)
	
	Если ДетализацияСтруктурыХранения = Перечисления.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки Тогда
		Возврат;
	ИначеЕсли Не ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(СтрокаШтрихкод, "НормализованныйШтрихкодУпаковки") Тогда
		Возврат;
	КонецЕсли;
	
	Штрихкод = СтрокаШтрихкод.НормализованныйШтрихкодУпаковки;
	Если ПустаяСтрока(Штрихкод) Тогда
		Если ДанныеШтрихкода.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская Тогда
			ИзменитьКонтекстПроверкиНаСервере(СтрокаПотребительскиеУпаковкиБезУпаковки(ЭтотОбъект));
		ИначеЕсли ЭтоГрупповаяУпаковкаИлиНабор(ДанныеШтрихкода.ВидУпаковки) Тогда
			ИзменитьКонтекстПроверкиНаСервере(СтрокаГрупповыеУпаковкиБезКоробки(ЭтотОбъект));
		Иначе
			ИзменитьКонтекстПроверкиНаСервере(Неопределено);
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	Нормализовать = Истина;
	Если ДанныеПоШтрихкодам <> Неопределено Тогда
		НайденнаяСтрока = ДанныеПоШтрихкодам.ДанныеКодовМаркировки.Найти(Штрихкод, "Штрихкод");
		Если НайденнаяСтрока <> Неопределено Тогда
			ШтрихкодДляПоиска = НайденнаяСтрока.НормализованныйШтрихкод;
			Нормализовать = Ложь;
		Иначе
			ШтрихкодДляПоиска = Штрихкод;
		КонецЕсли;
	Иначе
		ШтрихкодДляПоиска = Штрихкод;
	КонецЕсли;
	
	ИдентификаторСтрокиДерева = ИдентификаторСтрокиДереваПоШтрихкодуНаСервере(ШтрихкодДляПоиска, СоответствиеШтрихкодов, Нормализовать);
	Если ИдентификаторСтрокиДерева <> -1 Тогда
		ИзменитьКонтекстПроверкиНаСервере(
			НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ИдентификаторСтрокиДерева));
	КонецЕсли;
	
КонецПроцедуры

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

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

#Область Выгрузка

&НаСервере
Функция СформироватьТаблицуВыгрузкиИзДерева()
	
	Результат = Новый Массив;
	ДобавитьСтрокуВВыгрузкуРекурсивно(Результат, ДеревоМаркированнойПродукции);
	Возврат Результат;
	
КонецФункции

&НаСервере
Процедура ДобавитьСтрокуВВыгрузкуРекурсивно(Результат, ДеревоИлиГруппа)
	
	Для Каждого СтрокаДерева Из ДеревоИлиГруппа.ПолучитьЭлементы() Цикл
		
		ДобавляемаяСтрока = Новый Структура;
		
		Если СтрокаДерева.ТипУпаковки = Перечисления.ТипыУпаковок.МаркированныйТовар Тогда
			ДобавляемаяСтрока.Вставить("Штрихкод", СтрокаДерева.GTIN);
			ДобавляемаяСтрока.Вставить("ШтрихкодМаркиАлкогольнойПродукции", СтрокаДерева.Штрихкод);
		Иначе
			ДобавляемаяСтрока.Вставить("Штрихкод", СтрокаДерева.Штрихкод);
		КонецЕсли;
		
		ПредставлениеНоменклатуры = Новый Массив;
		Если ТипЗнч(СтрокаДерева.ТипУпаковки) = Тип("ПеречислениеСсылка.ТипыУпаковок")
			И СтрокаДерева.ТипУпаковки<> Перечисления.ТипыУпаковок.МаркированныйТовар Тогда
			ПредставлениеНоменклатуры.Добавить("Упаковка");
		КонецЕсли;
		ПредставлениеНоменклатуры.Добавить("" + СтрокаДерева.Номенклатура);
		
		ДобавляемаяСтрока.Вставить("Номенклатура",               СтрСоединить(ПредставлениеНоменклатуры, " "));
		ДобавляемаяСтрока.Вставить("ХарактеристикаНоменклатуры", "" + СтрокаДерева.Характеристика);
		ДобавляемаяСтрока.Вставить("СерияНоменклатуры",          "" + СтрокаДерева.Серия);
		ДобавляемаяСтрока.Вставить("Количество",                 1);
		
		Если Не(СтрокаДерева.ПолучитьРодителя() = Неопределено) Тогда
			ДобавляемаяСтрока.Вставить("ШтрихкодУпаковки", СтрокаДерева.ПолучитьРодителя().Штрихкод);
		КонецЕсли;
		
		Если ДобавляемаяСтрока.Штрихкод<>"" Тогда
			Результат.Добавить(ДобавляемаяСтрока);
		КонецЕсли;
		
		ДобавитьСтрокуВВыгрузкуРекурсивно(Результат, СтрокаДерева);
		
	КонецЦикла;
	
КонецПроцедуры

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

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

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

#Область Настройки

&НаКлиентеНаСервереБезКонтекста
Процедура СформироватьПредставлениеНастроек(Форма)
	
	Форма.ПредставлениеНастроек = Новый ФорматированнаяСтрока(ПредставлениеУровняДетализации(Форма), " " , ПредставлениеРежимаПроверки(Форма));
	
КонецПроцедуры

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

&НаКлиенте
Процедура ПослеИзмененияРежимаПроверки(Результат, ДополнительныеПараметры) Экспорт
	
	Если Не ЗначениеЗаполнено(Результат)
		Или Результат = КодВозвратаДиалога.Отмена Тогда
		Возврат;
	КонецЕсли;
	
	Если Результат <> РежимПроверки Тогда
		
		Модифицированность = Истина;
		РежимПроверки = Результат;
		СформироватьПредставлениеНастроек(ЭтотОбъект);
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура СохранитьНастройкиФормы(СохраняемыеНастройки)
	
	ПроверкаИПодборПродукцииИСМП.СохранитьДетализациюСтруктурыХранения(СохраняемыеНастройки);
	
КонецПроцедуры

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

#Область ДетализацияСтруктурыХранения

&НаКлиентеНаСервереБезКонтекста
Функция ПредставлениеУровняДетализации(Форма)
	
	Если Не ЗначениеЗаполнено(Форма.ДетализацияСтруктурыХранения) Тогда
		Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная");
	КонецЕсли;
	
	ТекстВступление = НСтр("ru = 'Детализация'");
	
	СтрокаДействие  = НРег(Строка(Форма.ДетализацияСтруктурыХранения));
	Если Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		СтрокаДействие = "палеты с коробками";
	ИначеЕсли Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками") Тогда
		СтрокаДействие = "коробки с блоками";
	ИначеЕсли Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими") Тогда
		СтрокаДействие = "блоки с пачками";
	ИначеЕсли Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		СтрокаДействие = "пачки";
	ИначеЕсли Форма.ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковки") Тогда
		СтрокаДействие = "блоки, пачки";
	КонецЕсли;
	
	Если Не Форма.РежимПросмотра Тогда
		СтрокаДействие = Новый ФорматированнаяСтрока(СтрокаДействие,, Форма.ЦветГиперссылки,, "ИзменитьДетализацию");
	КонецЕсли;
	
	Возврат Новый ФорматированнаяСтрока(ТекстВступление, ": ", СтрокаДействие, ".");
	
КонецФункции

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

&НаКлиенте
Функция ЕстьУпаковкиБезКодовПотребительскихУпаковок(ЭлементыДерева)
	
	ЕстьУпаковкиБезПотребительскихУпаковок = Ложь;
	
	Для Каждого ЭлементДерева Из ЭлементыДерева Цикл
		Если ЭлементДерева.ТипУпаковки = ПредопределенноеЗначение("Перечисление.ТипыУпаковок.МаркированныйТовар") Тогда
			Продолжить;
		КонецЕсли;
		
		Если ЭлементДерева.НеПересчитыватьКоличествоПотребительскихУпаковок Тогда
			ЕстьУпаковкиБезПотребительскихУпаковок = Истина;
		ИначеЕсли ЭлементДерева.ПолучитьЭлементы().Количество() > 0 Тогда
			ЕстьУпаковкиБезПотребительскихУпаковок = ЕстьУпаковкиБезКодовПотребительскихУпаковок(ЭлементДерева.ПолучитьЭлементы());
		КонецЕсли;
		
		Если ЕстьУпаковкиБезПотребительскихУпаковок Тогда
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Возврат ЕстьУпаковкиБезПотребительскихУпаковок;
	
КонецФункции

&НаКлиенте
Процедура ПриОтветеНаВопросИзменениеРежимаДетализации(РезультатВопроса, ДополнительныеПараметры) Экспорт
	
	Если РезультатВопроса = КодВозвратаДиалога.Да Тогда
		ИзменитьРежимДетализации(ДополнительныеПараметры);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ИзменитьРежимДетализации(НовыйРежимДетализации)
	
	ТребуетсяПересчет = Ложь;
	
	Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная")
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		
		ТребуетсяПересчет = Истина;
		ПереключитьДетализациюСПолнойНаКоробки();
		
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная")
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками") Тогда
		
		ТребуетсяПересчет = Истина;
		ПовыситьУровеньДетализацииДоКоробаСГрупповымиУпаковками();
		
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная")
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими") Тогда
		
		ТребуетсяПересчет = Истина;
		ПонизитьУровеньДетализацииДоГрупповыхУпаковокСПотребительскими();
		
	ИначеЕсли (ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная")
		Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами")
		Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
		Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими"))
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		
		ТребуетсяПересчет = Истина;
		ПонизитьУровеньДетализацииДоПотребительскихУпаковок();
		ИдентификаторТекущейПроверяемойУпаковки = - 1;
		
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки")
		И НовыйРежимДетализации <> ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		
		ТребуетсяПересчет = Истина;
		УстановитьУровеньДетализацииВышеЧемПотребительскиеУпаковки(НовыйРежимДетализации);
		
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими")
		И (НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная")
		Или НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
		Или НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами")) Тогда
		
		ТребуетсяПересчет = Истина;
		УстановитьУровеньДетализацииВышеЧемГрупповыеУпаковкиСПотребительскими(НовыйРежимДетализации);
		
	ИначеЕсли (ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
			Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами"))
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная") Тогда
		
		ТребуетсяПересчет = Истина;
		ПереключитьДетализациюСКоробокИКоробокСПотребительскимиУпаковкамиНаПолную(НовыйРежимДетализации);
		
	ИначеЕсли (ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
			Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами"))
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими") Тогда
		
		ТребуетсяПересчет = Истина;
		ПонизитьУровеньДетализацииДоГрупповыхУпаковокСПотребительскими();
		
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		
		ТребуетсяПересчет = Истина;
		ПереключитьДетализациюСКоробовСПотребительскимиУпаковкамиНаКоробки();
		
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами")
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками") Тогда
		
		ТребуетсяПересчет = Истина;
		ПереключитьДетализациюСКоробкиНаКоробкиСГрупповымиУпаковками();
		
	КонецЕсли;
	
	ДетализацияСтруктурыХранения = НовыйРежимДетализации;
	
	Если ТребуетсяПересчет Тогда
		УстановитьПризнакРасчитыватьХешСуммуУпаковокПриСменеДетализации();
		СоответствиеШтрихкодовСтрокДерева = Новый Соответствие;
		ДополнитьСоответствиеШтрихкодовСтрокДереваДляКоллекции(
			ДеревоМаркированнойПродукции.ПолучитьЭлементы(),
			СоответствиеШтрихкодовСтрокДерева,
			ВидМаркируемойПродукции);
		ПересчитатьВсеИтогиФормыНаКлиенте();
	КонецЕсли;
	
	СохраняемыеНастройки = Новый Структура;
	
	Если РежимПодбораСуществующихУпаковок Тогда
		СохраняемыеНастройки.Вставить("ДетализацияСтруктурыХранения", ДетализацияСтруктурыХранения);
	Иначе
		СохраняемыеНастройки.Вставить("ДетализацияСтруктурыХраненияПриобретение", ДетализацияСтруктурыХранения);
	КонецЕсли;
	
	СохранитьНастройкиФормы(СохраняемыеНастройки);
	
	УправлениеДоступностьюКомандУпаковок(ЭтотОбъект);
	УправлениеДоступностьюКомандыРазобратьУпаковку();
	
	СформироватьПредставлениеНастроек(ЭтотОбъект);
	
	Модифицированность = Истина;
	
КонецПроцедуры

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

&НаКлиенте
Процедура ПереключитьДетализациюСПолнойНаКоробкиПродолжение(СтрокаДерева, УдаляемаяПродукция, УдаляемыеГруппы, УдаляемыеУпаковки, ГруппыДляПодобраннойПродукции, УпаковкиДляПодобраннойПродукции, РодительскаяУпаковкаСамодостаточна = Ложь, ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Ложь)
	
	Если СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
		
		Если РодительскаяУпаковкаСамодостаточна Тогда
			УдаляемаяПродукция.Добавить(СтрокаДерева);
		Иначе
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
		КонецЕсли;
		
	ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Групповая") Тогда
		
		Если РодительскаяУпаковкаСамодостаточна Или СтрокаДерева.КоличествоПодчиненныхПотребительскихУпаковок = 0 Тогда
			УдаляемыеГруппы.Добавить(СтрокаДерева);
		Иначе
			СтрокаДерева.НеПересчитыватьКоличествоПотребительскихУпаковок = Истина;
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
			ГруппыДляПодобраннойПродукции.Добавить(СтрокаДерева);
		КонецЕсли;
		
		УпаковкаСамодостаточна = Истина;
		Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.ПолучитьЭлементы() Цикл
			ПереключитьДетализациюСПолнойНаКоробкиПродолжение(
				ПодчиненнаяСтрока,
				УдаляемаяПродукция,
				Неопределено,
				Неопределено,
				Неопределено,
				Неопределено,
				УпаковкаСамодостаточна);
		КонецЦикла;
		
	ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
		
		УпаковкаСамодостаточна = Ложь;
		Если ЭтоЗаполненнаяМонотоварнаяУпаковкаСGTIN(СтрокаДерева) Тогда
			УпаковкаСамодостаточна = Истина;
		КонецЕсли;
		
		ИмеютсяПодчиненныеНеУдаляемыУпаковки = Ложь;
		
		Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.ПолучитьЭлементы() Цикл
			ПереключитьДетализациюСПолнойНаКоробкиПродолжение(
				ПодчиненнаяСтрока,
				УдаляемаяПродукция,
				УдаляемыеГруппы,
				УдаляемыеУпаковки,
				ГруппыДляПодобраннойПродукции,
				УпаковкиДляПодобраннойПродукции,
				УпаковкаСамодостаточна,
				ИмеютсяПодчиненныеНеУдаляемыУпаковки);
		КонецЦикла;
		
		Если УпаковкаСамодостаточна Тогда
			
			СтрокаДерева.НеПересчитыватьКоличествоПотребительскихУпаковок = Истина;
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
			
			УпаковкиДляПодобраннойПродукции.Добавить(СтрокаДерева);
			
		ИначеЕсли ИмеютсяПодчиненныеНеУдаляемыУпаковки Тогда
			
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
			
		Иначе
			
			УдаляемыеУпаковки.Добавить(СтрокаДерева);
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПовыситьУровеньДетализацииДоКоробаСГрупповымиУпаковками()

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

&НаКлиенте
Процедура ПовыситьУровеньДетализацииУпаковкиДоКоробаСГрупповымиУпаковками(СтрокаДерева, УдаляемыеСтроки, УдаляемыеУпаковки, ГруппыДляПодобраннойПродукции, РодительскаяУпаковкаСамодостаточна = Ложь, ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Ложь)
	
	Если СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
		
		Если РодительскаяУпаковкаСамодостаточна Тогда
			УдаляемыеСтроки.Добавить(СтрокаДерева);
		Иначе
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
		КонецЕсли;
		
	ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Групповая") Тогда
		
		СтрокаДерева.НеПересчитыватьКоличествоПотребительскихУпаковок = Истина;
		ГруппыДляПодобраннойПродукции.Добавить(СтрокаДерева);
		
		Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.ПолучитьЭлементы() Цикл
			ПовыситьУровеньДетализацииУпаковкиДоКоробаСГрупповымиУпаковками(
				ПодчиненнаяСтрока,
				УдаляемыеСтроки,
				УдаляемыеУпаковки,
				ГруппыДляПодобраннойПродукции,
				Истина);
		КонецЦикла;
		
		ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
		
	ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
		
		ИмеютсяПодчиненныеНеУдаляемыеУпаковки = Ложь;
		
		Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.ПолучитьЭлементы() Цикл
			ПовыситьУровеньДетализацииУпаковкиДоКоробаСГрупповымиУпаковками(
				ПодчиненнаяСтрока,
				УдаляемыеСтроки,
				УдаляемыеУпаковки,
				ГруппыДляПодобраннойПродукции,,
				ИмеютсяПодчиненныеНеУдаляемыеУпаковки);
		КонецЦикла;
		
		Если ИмеютсяПодчиненныеНеУдаляемыеУпаковки Тогда
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
		Иначе
			УдаляемыеУпаковки.Добавить(СтрокаДерева);
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

&НаКлиенте
Процедура ПереключитьДетализациюСКоробовСПотребительскимиУпаковкамиНаКоробки()
	
	ЭлементыДерева = ДеревоМаркированнойПродукции.ПолучитьЭлементы();
	
	УдаляемаяПродукция = Новый Массив;
	УдаляемыеГруппы    = Новый Массив;
	УдаляемыеУпаковки  = Новый Массив;
	
	УпаковкиДляПодобраннойПродукции = Новый Массив;
	
	Для Каждого СтрокаДерева Из ЭлементыДерева Цикл
		
		Если СтрокаДерева.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
			Или СтрокаДерева.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
			Продолжить;
		КонецЕсли;
		
		ПереключитьДетализациюСКоробовСПотребительскимиУпаковкамиНаКоробкиПродолжение(
			СтрокаДерева,
			УдаляемаяПродукция,
			УдаляемыеГруппы,
			УдаляемыеУпаковки,
			УпаковкиДляПодобраннойПродукции);
		
	КонецЦикла;
	
	УдалениеПодобраннойПродукцииПриСменеДетализации(УдаляемаяПродукция, ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская"));
	УдалениеПодобраннойПродукцииПриСменеДетализации(УдаляемыеГруппы, ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Групповая"));
	ДобавлениеПодобраннойПродукцииПриСменеДетализации(УпаковкиДляПодобраннойПродукции, ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая"));
	
	УдалениеСтрокИзДерева(ЭлементыДерева, УдаляемаяПродукция);
	УдалениеСтрокИзДерева(ЭлементыДерева, УдаляемыеГруппы);
	УдалениеСтрокИзДерева(ЭлементыДерева, УдаляемыеУпаковки);
	
КонецПроцедуры

&НаКлиенте
Процедура ПереключитьДетализациюСКоробовСПотребительскимиУпаковкамиНаКоробкиПродолжение(СтрокаДерева, УдаляемаяПродукция, УдаляемыеГруппы, УдаляемыеУпаковки, УпаковкиДляПодобраннойПродукции, РодительскаяУпаковкаСамодостаточна = Ложь, ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Ложь)
	
	Если СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
		
		Если РодительскаяУпаковкаСамодостаточна Тогда
			УдаляемаяПродукция.Добавить(СтрокаДерева);
		Иначе
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
		КонецЕсли;
		
	ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Групповая") Тогда
		
		Если РодительскаяУпаковкаСамодостаточна Или СтрокаДерева.КоличествоПодчиненныхПотребительскихУпаковок = 0 Тогда
			УдаляемыеГруппы.Добавить(СтрокаДерева);
		Иначе
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
		КонецЕсли;
		
	ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
		
		УпаковкаСамодостаточна = Ложь;
		Если ЭтоЗаполненнаяМонотоварнаяУпаковкаСGTIN(СтрокаДерева) Тогда
			УпаковкаСамодостаточна = Истина;
		КонецЕсли;
		
		ИмеютсяПодчиненныеНеУдаляемыУпаковк = Ложь;
		
		Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.ПолучитьЭлементы() Цикл
			ПереключитьДетализациюСКоробовСПотребительскимиУпаковкамиНаКоробкиПродолжение(
				ПодчиненнаяСтрока,
				УдаляемаяПродукция,
				УдаляемыеГруппы,
				УдаляемыеУпаковки,
				УпаковкиДляПодобраннойПродукции,
				УпаковкаСамодостаточна,
				ИмеютсяПодчиненныеНеУдаляемыУпаковк);
		КонецЦикла;
		
		Если УпаковкаСамодостаточна Тогда
			
			СтрокаДерева.НеПересчитыватьКоличествоПотребительскихУпаковок = Истина;
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
			
			УпаковкиДляПодобраннойПродукции.Добавить(СтрокаДерева);
			
		ИначеЕсли ИмеютсяПодчиненныеНеУдаляемыУпаковк Тогда
			
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
			
		Иначе
			
			УдаляемыеУпаковки.Добавить(СтрокаДерева);
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПереключитьДетализациюСКоробкиНаКоробкиСГрупповымиУпаковками()
	
	ЭлементыДерева = ДеревоМаркированнойПродукции.ПолучитьЭлементы();
	
	УдаляемыеУпаковки = Новый Массив;
	
	Для Каждого СтрокаДерева Из ЭлементыДерева Цикл
		
		Если СтрокаДерева.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
			Или СтрокаДерева.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
			Продолжить;
		КонецЕсли;
		
		ПереключитьДетализациюСКоробкиНаКоробкиСПотребительскимиУпаковкамиПродолжение(СтрокаДерева, УдаляемыеУпаковки);
		
	КонецЦикла;
	
	УдалениеПодобраннойПродукцииПриСменеДетализации(УдаляемыеУпаковки, ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая"));
	
	УдалениеСтрокИзДерева(ЭлементыДерева, УдаляемыеУпаковки);
	
КонецПроцедуры

&НаКлиенте
Процедура ПереключитьДетализациюСКоробкиНаКоробкиСПотребительскимиУпаковкамиПродолжение(СтрокаДерева, УдаляемыеУпаковки, ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Ложь)
	
	Если СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
		
		ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
		
	ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Групповая") Тогда
		
		ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
		
	ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
		
		ИмеютсяПодчиненныеНеУдаляемыУпаковк = Ложь;
		
		Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.ПолучитьЭлементы() Цикл
			ПереключитьДетализациюСКоробкиНаКоробкиСПотребительскимиУпаковкамиПродолжение(
				ПодчиненнаяСтрока, УдаляемыеУпаковки, ИмеютсяПодчиненныеНеУдаляемыУпаковк);
		КонецЦикла;
		
		Если ИмеютсяПодчиненныеНеУдаляемыУпаковк Тогда
			
			ВРодительскойУпаковкеИмеютсяНеУдаляемыеУпаковки = Истина;
			
		Иначе
			
			УдаляемыеУпаковки.Добавить(СтрокаДерева);
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Функция ДобавленнаяСтрокаПотребительскиеУпаковкиБезУпаковки()
	
	НоваяСтрока = ДеревоМаркированнойПродукции.ПолучитьЭлементы().Вставить(0);
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ЗаполнитьСтрокуПачкиБезБлока(НоваяСтрока, ВидМаркируемойПродукции);
	
	ИдентификаторСтрокиПотребительскиеУпаковкиБезУпаковки = НоваяСтрока.ПолучитьИдентификатор();
	
	Возврат НоваяСтрока;
	
КонецФункции

&НаКлиенте
Функция ДобавленнаяСтрокаГрупповыеУпаковкиБезКоробки()
	
	ЭлементыДерева = ДеревоМаркированнойПродукции.ПолучитьЭлементы();
	
	Если ЭлементыДерева.Количество() = 0 Тогда
		НоваяСтрока = ЭлементыДерева.Вставить(0);
	ИначеЕсли ЭлементыДерева[0].ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки() Тогда
		НоваяСтрока = ЭлементыДерева.Вставить(1);
	Иначе
		НоваяСтрока = ЭлементыДерева.Вставить(0);
	КонецЕсли;
	
	ПроверкаИПодборПродукцииМОТПКлиентСервер.ЗаполнитьСтрокуБлокиБезКоробки(НоваяСтрока, ВидМаркируемойПродукции);
	
	ИдентификаторСтрокиГрупповыеУпаковкиБезКоробки = НоваяСтрока.ПолучитьИдентификатор();
	
	Возврат НоваяСтрока;
	
КонецФункции

&НаСервереБезКонтекста
Функция СохраненнаяДетализацияСтруктурыХранения(РежимПодбораСуществующихУпаковок)
	
	Возврат ПроверкаИПодборПродукцииИСМП.СохраненнаяДетализацияСтруктурыХранения(РежимПодбораСуществующихУпаковок);
	
КонецФункции

&НаСервереБезКонтекста
Функция ДетализацияСтруктурыХраненияДерева(ДеревоУпаковок)
	
	Возврат Обработки.ПроверкаИПодборТабачнойПродукцииМОТП.ДетализацияСтруктурыХраненияДерева(ДеревоУпаковок);
	
КонецФункции

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

#Область ПреобразованиеДетализацииСчитанойУпаковки

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

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

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

&НаСервере
Процедура СкопироватьСтрокуДереваПриПониженииДетализацииДоБлокаСПачками(СтрокаДерева, Результат)
	
	Если СтрокаДерева.ВидУпаковки = Перечисления.ВидыУпаковокИС.Логистическая Тогда
		
		Для Каждого ПодчиненнаяСтрока Из СтрокаДерева.Строки Цикл
			
			СкопироватьСтрокуДереваПриПониженииДетализацииДоБлокаСПачками(ПодчиненнаяСтрока, Результат)
			
		КонецЦикла;
		
	Иначе
		
		Результат.Добавить(СтрокаДерева);
		
	КонецЕсли;
	
КонецПроцедуры

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

#Область РазагрегацияУпаковки

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

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

#Область РаботаСПуломИПечать

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

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

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

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

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

&НаКлиенте
Процедура РазвернутьСтрокиСОшибками(ЭлементДерева, РазвернутыеСтроки)
	
	ЭлементРодитель = ЭлементДерева.ПолучитьРодителя();
	Если ЭлементРодитель <> Неопределено Тогда
		ИдентификаторСтрокиРодителя = ЭлементРодитель.ПолучитьИдентификатор();
		Если РазвернутыеСтроки.Найти(ИдентификаторСтрокиРодителя) = Неопределено Тогда
			Если Не Элементы.ДеревоМаркированнойПродукции.Развернут(ИдентификаторСтрокиРодителя) Тогда
				Элементы.ДеревоМаркированнойПродукции.Развернуть(ИдентификаторСтрокиРодителя);
			КонецЕсли;
			РазвернутыеСтроки.Добавить(ИдентификаторСтрокиРодителя);
			РазвернутьСтрокиСОшибками(ЭлементРодитель, РазвернутыеСтроки);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

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

//@skip-warning
&НаКлиенте
Процедура Подключаемый_ОткрытьФормуУточненияДанных()
	
	ОповещениеПриЗавершении = Новый ОписаниеОповещения("РучнойВводШтрихкодаЗавершение", ЭтотОбъект);
	ШтрихкодированиеИСКлиент.Подключаемый_ОткрытьФормуУточненияДанных(ЭтотОбъект, ОповещениеПриЗавершении);
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция НайтиПоИдентификатору(ДанныеФормыДерево, Идентификатор)
	
	// Существует проблема в веб-клиенте: метод НайтиПоИдентификатору, может вернуть ДанныеФормыДерево
	
	Если Идентификатор = -1
		Или Идентификатор = Неопределено
		Или ТипЗнч(Идентификатор) <> Тип("Число") Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ДанныеФормыЭлементДерева = ДанныеФормыДерево.НайтиПоИдентификатору(Идентификатор);
	
	Если ТипЗнч(ДанныеФормыЭлементДерева) = Тип("ДанныеФормыЭлементДерева") Тогда
		Возврат ДанныеФормыЭлементДерева;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

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

&НаКлиенте
Процедура УточнитьДанныеУПользователяЗавершение(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	НайденнаяСтрокаДерева = НайтиПоИдентификатору(ДеревоМаркированнойПродукции, ДополнительныеПараметры.ИдентификаторСтрокиДерева);
	ТекущаяСтрокаДерева   = ДополнительныеПараметры.ТекущаяСтрокаДерева;
	
	ЭтоПроизвольноеРедактированиеСуществующейСтроки = ДополнительныеПараметры.Свойство("ПроизвольноеРедактированиеРеквизитов")
		И ДополнительныеПараметры.ПроизвольноеРедактированиеРеквизитов;
	
	Если ПроверкаИПодборПродукцииИСМПКлиент.ЭтоИзменениеЭлементаВГрупповойУпаковке(НайденнаяСтрокаДерева, ДополнительныеПараметры) Тогда
		Родитель = НайденнаяСтрокаДерева.ПолучитьРодителя();
		Для Каждого ПотребительскаяУпаковка Из Родитель.ПолучитьЭлементы() Цикл
			ЗаполнитьСтрокуДереваПоДаннымВыбора(ПотребительскаяУпаковка, Результат.ДанныеВыбора);
		КонецЦикла;
	Иначе 
		ЗаполнитьСтрокуДереваПоДаннымВыбора(НайденнаяСтрокаДерева, Результат.ДанныеВыбора);
	КонецЕсли;
	
	ШтрихкодированиеИСКлиентСервер.ОбработатьСохраненныйВыборДанныхПоМаркируемойПродукции(
		ЭтотОбъект, Результат.ДанныеВыбора, Результат.ЗапомнитьВыбор);
	
	Если Не ЭтоПроизвольноеРедактированиеСуществующейСтроки Тогда
		ОбработатьНайденныйВДеревеШтрихкод(НайденнаяСтрокаДерева, ТекущаяСтрокаДерева);
	КонецЕсли;
	
	Если ТаблицаИзмененийТабачнойПродукции.Количество() > 0 Тогда
		ОбработатьТаблицуИзмененийПодобраннойПродукции(ЭтотОбъект, КэшированныеЗначения);
	КонецЕсли;
	
	ОбработатьОчереднойШтрихкод();
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ЗаполнитьСтрокуДереваПоДаннымШтрихкода(Форма, СтрокаДерева, ДанныеШтрихкода, ТаблицаИзмененийПодобраннойПродукции, КэшированныеЗначения)
	
	ПроверкаИПодборПродукцииИСМПКлиентСервер.ОбработатьТребованиеПолногоКода(
		ДанныеШтрихкода,
		СтрокаДерева,
		Форма.ПараметрыСканирования);
	
	КонечнаяУпаковкаПоДетализации =
		СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская")
		Или ЭтоЗаполненнаяМонотоварнаяУпаковкаСGTIN(СтрокаДерева, "КоличествоПодчиненныхПотребительскихУпаковок")
			И СтрокаДерева.ПолучитьЭлементы().Количество() = 0;
	
	Если ДанныеШтрихкода = Неопределено
		Или Не ДанныеШтрихкода.Свойство("Номенклатура")
		Или Не КонечнаяУпаковкаПоДетализации Тогда
		Возврат;
	КонецЕсли;
	
	УчитыватьМРЦ = ПредопределенноеЗначение("Перечисление.ВидыПродукцииИС.Табак") = Форма.ВидМаркируемойПродукции
		И ОбщегоНазначенияИСМПКлиентСерверПовтИсп.УчитыватьМРЦ();
	
	ЗаполняемыеПоля = Новый Массив;
	ЗаполняемыеПоля.Добавить("Номенклатура");
	ЗаполняемыеПоля.Добавить("Характеристика");
	ЗаполняемыеПоля.Добавить("Серия");
	ЗаполняемыеПоля.Добавить("Количество");
	Если УчитыватьМРЦ Тогда
		ЗаполняемыеПоля.Добавить("МРЦ");
	КонецЕсли;
	
	ЗаполнитьИзмененияПодобраннойПродукции = Ложь;
	Для Каждого ИмяПоля Из ЗаполняемыеПоля Цикл
		ЗаполнитьИзмененияПодобраннойПродукции = ЗаполнитьИзмененияПодобраннойПродукции
			Или СтрокаДерева[ИмяПоля] <> ДанныеШтрихкода[ИмяПоля];
	КонецЦикла;
	
	Если Не ЗаполнитьИзмененияПодобраннойПродукции Тогда
		Возврат;
	КонецЕсли;
	
	ИменаСвойствСтроки = Новый Массив;
	ИменаСвойствСтроки.Добавить("GTIN");
	ИменаСвойствСтроки.Добавить("Номенклатура");
	ИменаСвойствСтроки.Добавить("Характеристика");
	ИменаСвойствСтроки.Добавить("Серия");
	ИменаСвойствСтроки.Добавить("СтатусПроверки");
	ИменаСвойствСтроки.Добавить("Количество");
	ИменаСвойствСтроки.Добавить("МРЦ");
	ИменаСвойствСтроки.Добавить("ВключаетМРЦ");
	
	СвойстваСтрокой = СтрСоединить(ИменаСвойствСтроки, ",");
	
	СтрокаИзмененийДо    = Новый Структура(СвойстваСтрокой);
	СтрокаИзмененийПосле = Новый Структура(СвойстваСтрокой);
	ЗаполнитьЗначенияСвойств(СтрокаИзмененийДо,    СтрокаДерева);
	ЗаполнитьЗначенияСвойств(СтрокаИзмененийПосле, СтрокаИзмененийДо);
	ЗаполнитьЗначенияСвойств(СтрокаИзмененийПосле, ДанныеШтрихкода);
	
	Если ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(ДанныеШтрихкода, "ВключаетМРЦ") Тогда
	ИначеЕсли ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(ДанныеШтрихкода, "МРЦ") Тогда
		СтрокаИзмененийПосле.ВключаетМРЦ = ДанныеШтрихкодаВключаютМРЦ(ДанныеШтрихкода);
	Иначе
		СтрокаИзмененийПосле.ВключаетМРЦ = Ложь;
		СтрокаИзмененийПосле.МРЦ         = 0;
	КонецЕсли;
	
	ИзменяемыеСвойства = Новый Массив;
	Для Каждого ИмяСвойства Из ИменаСвойствСтроки Цикл
		Если СтрокаИзмененийДо[ИмяСвойства] <> СтрокаИзмененийПосле[ИмяСвойства] Тогда
			ИзменяемыеСвойства.Добавить(ИмяСвойства);
		КонецЕсли;
	КонецЦикла;
	
	Если ИзменяемыеСвойства.Количество() > 0 Тогда
		
		Для Каждого ИмяСвойства Из ИзменяемыеСвойства Цикл
			СтрокаДерева[ИмяСвойства] = СтрокаИзмененийПосле[ИмяСвойства];
		КонецЦикла;
		
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(СтрокаДерева, Ложь);
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(СтрокаДерева);
		ПроверкаИПодборПродукцииМОТПКлиентСервер.СформироватьПредставлениеСодержимогоУпаковки(СтрокаДерева);
		
		ДополнительныеПараметры = Новый Структура;
		ДополнительныеПараметры.Вставить("СтатусПроверки", СтрокаДерева.СтатусПроверки);
		
		КоличествоКодовМаркировки = 1;
		
		ПроверкаИПодборПродукцииИСМПКлиентСервер.ПодобраннаяПродукцияПриУточненииСопоставления(
			Форма,
			СтрокаИзмененийДо,
			СтрокаИзмененийПосле,
			КоличествоКодовМаркировки,
			ОбщийМодульКонтекстаПиП(),
			ДополнительныеПараметры,
			КэшированныеЗначения);
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьСтрокуДереваПоДаннымВыбора(СтрокаДерева, ДанныеВыбора)
	
	Если ДанныеВыбора = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ДанныеВыбора.GTIN <> СтрокаДерева.GTIN Тогда
		Возврат;
	КонецЕсли;
	
	ИменаСвойствСтроки = Новый Массив;
	ИменаСвойствСтроки.Добавить("GTIN");
	ИменаСвойствСтроки.Добавить("Номенклатура");
	ИменаСвойствСтроки.Добавить("Характеристика");
	ИменаСвойствСтроки.Добавить("Серия");
	ИменаСвойствСтроки.Добавить("СтатусПроверки");
	ИменаСвойствСтроки.Добавить("Количество");
	ИменаСвойствСтроки.Добавить("ПроизвольнаяЕдиницаУчета");
	ИменаСвойствСтроки.Добавить("МРЦ");
	ИменаСвойствСтроки.Добавить("ВключаетМРЦ");
	
	Если ПараметрыСканирования.ТребуетсяЧастичноеВыбытие
		И ОбщегоНазначенияИСКлиентСерверПовтИсп.ПоддерживаетсяЧастичноеВыбытие(
		ВидМаркируемойПродукции,
		ПараметрыСканирования.ВидОперацииИСМП) Тогда
		ИменаСвойствСтроки.Добавить("ЧастичноеВыбытие");
	КонецЕсли;
	
	СвойстваСтрокой = СтрСоединить(ИменаСвойствСтроки, ",");
	
	СтрокаИзмененийДо    = Новый Структура(СвойстваСтрокой);
	СтрокаИзмененийПосле = Новый Структура(СвойстваСтрокой);
	ЗаполнитьЗначенияСвойств(СтрокаИзмененийДо,    СтрокаДерева);
	ЗаполнитьЗначенияСвойств(СтрокаИзмененийПосле, СтрокаИзмененийДо);
	ЗаполнитьЗначенияСвойств(СтрокаИзмененийПосле, ДанныеВыбора);
	
	ИзменяемыеСвойства = Новый Массив;
	Для Каждого ИмяСвойства Из ИменаСвойствСтроки Цикл
		Если СтрокаИзмененийДо[ИмяСвойства] <> СтрокаИзмененийПосле[ИмяСвойства] Тогда
			ИзменяемыеСвойства.Добавить(ИмяСвойства);
		КонецЕсли;
	КонецЦикла;
	
	Если ИзменяемыеСвойства.Количество() > 0 Тогда
		
		Для Каждого ИмяСвойства Из ИзменяемыеСвойства Цикл
			СтрокаДерева[ИмяСвойства] = СтрокаИзмененийПосле[ИмяСвойства];
		КонецЦикла;
		
		ДополнительныеПараметры = Новый Структура;
		ДополнительныеПараметры.Вставить("СтатусПроверки", СтрокаДерева.СтатусПроверки);
		
		СтрокаДерева.Номенклатура   = ДанныеВыбора.Номенклатура;
		СтрокаДерева.Характеристика = ДанныеВыбора.Характеристика;
		СтрокаДерева.Серия          = ДанныеВыбора.Серия;
		
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковки(СтрокаДерева, Ложь);
		ПроверкаИПодборПродукцииМОТПКлиентСервер.ПересчитатьИтогиПоПроверкеСодержимогоУпаковкиПриИзмененииСтроки(СтрокаДерева);
		ПроверкаИПодборПродукцииМОТПКлиентСервер.СформироватьПредставлениеСодержимогоУпаковки(СтрокаДерева);
		
		КоличествоКодовМаркировки = 1;
		
		ПроверкаИПодборПродукцииИСМПКлиентСервер.ПодобраннаяПродукцияПриУточненииСопоставления(
			ЭтотОбъект,
			СтрокаИзмененийДо,
			СтрокаИзмененийПосле,
			КоличествоКодовМаркировки,
			ОбщийМодульКонтекстаПиП(),
			ДополнительныеПараметры,
			КэшированныеЗначения);
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ДобавленнаяПотребительскаяУпаковка(Форма, Данные, Действие)
	
	КодМаркировки = Неопределено;
	Если ТипЗнч(Данные) = Тип("Строка") Тогда
		КодМаркировки = Данные;
	ИначеЕсли ТипЗнч(Данные) = Тип("ДанныеФормыЭлементДерева") Тогда
		Если Данные.ВидУпаковки <> ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
			Возврат Ложь;
		КонецЕсли;
		КодМаркировки = Данные.Штрихкод;
	КонецЕсли;
	
	ИмяСвойстваКонтейнера = "ДобавленнаяПотребительскаяУпаковка";
	
	Возврат УпаковкиВКонтейнере(Форма, ИмяСвойстваКонтейнера, Действие, КодМаркировки);
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция УпаковкиВКонтейнере(Форма, ИмяСвойстваКонтейнера, Действие, КодМаркировки)
	
	Контейнер = Форма.Контейнер;
	
	Если Контейнер = Неопределено Тогда
		Контейнер = Новый Структура;
		Форма.Контейнер = Контейнер;
	КонецЕсли;
	
	Если Не Контейнер.Свойство(ИмяСвойстваКонтейнера) Тогда
		Контейнер.Вставить(ИмяСвойстваКонтейнера, Новый Массив);
	КонецЕсли;
	
	Упаковки = Контейнер[ИмяСвойстваКонтейнера];
	
	Если Действие = "Очистить" Тогда
		Упаковки.Очистить();
		Возврат Истина;
	ИначеЕсли Действие = "Упаковки" Тогда
		Возврат Упаковки;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(КодМаркировки) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ИндексЭлемента = Упаковки.Найти(КодМаркировки);
	
	КодМаркировкиДобавлен = (ИндексЭлемента <> Неопределено);
	
	Если Действие = "Добавить" Тогда
		
		Если КодМаркировкиДобавлен Тогда
			Возврат Истина;
		КонецЕсли;
		
		Упаковки.Добавить(КодМаркировки);
		
		Возврат Истина;
		
	ИначеЕсли Действие = "Удалить" Тогда
		
		Если Не КодМаркировкиДобавлен Тогда
			 Возврат Истина;
		КонецЕсли;
		
		Упаковки.Удалить(ИндексЭлемента);
		
		Возврат Истина;
		
	ИначеЕсли Действие = "Содержит" Тогда
		
		Возврат КодМаркировкиДобавлен;
		
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

&НаСервере
Процедура ОчиститьСопоставлениеНаСервере(ВыделенныеСтроки)
	
	КэшированныеЗначения = Неопределено;
	ПроверкаИПодборПродукцииИСМП.ПриОчисткеСопоставленияМаркированнойПродукции(ЭтотОбъект, ВыделенныеСтроки, КэшированныеЗначения);
	
КонецПроцедуры

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

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

&НаКлиентеНаСервереБезКонтекста
Функция ЭтоЗаполненнаяМонотоварнаяУпаковкаСGTIN(СтрокаДерева, ИмяКолонкиКоличествоПотребительскихУпаковок = "КоличествоПодчиненныхПотребительскихУпаковок")
	
	Возврат ЗначениеЗаполнено(СтрокаДерева.Номенклатура)
		И СтрокаДерева[ИмяКолонкиКоличествоПотребительскихУпаковок] > 0
		И ЗначениеЗаполнено(СтрокаДерева.GTIN);
	
КонецФункции

&НаКлиенте
Процедура УдалениеСтрокИзДерева(ЭлементыДерева, УдаляемыеСтроки)
	
	Для Каждого СтрокаДерева Из УдаляемыеСтроки Цикл
		
		Родитель = СтрокаДерева.ПолучитьРодителя();
		
		Если СтрокаДерева.ИдетПроверкаДаннойУпаковки
			И СтрокаДерева.ПолучитьИдентификатор() = ИдентификаторТекущейПроверяемойУпаковки Тогда
			
			Если Родитель = Неопределено
				Или Не ИнтеграцияИСКлиентСервер.ЭтоУпаковка(Родитель.ТипУпаковки) Тогда
				ИдентификаторТекущейПроверяемойУпаковки = -1;
			Иначе
				ИдентификаторТекущейПроверяемойУпаковки = Родитель.ПолучитьИдентификатор();
			КонецЕсли;
			
		КонецЕсли;
		
		Если Родитель = Неопределено Тогда
			ЭлементыДерева.Удалить(СтрокаДерева);
		Иначе
			Родитель.ПолучитьЭлементы().Удалить(СтрокаДерева);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьПризнакРасчитыватьХешСуммуУпаковокПриСменеДетализации()
	
	Если РежимПросмотра Тогда
		Возврат;
	КонецЕсли;
	
	Если ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
		Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами")
		Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковки") Тогда
		РасчитыватьХешСуммуУпаковок = Ложь;
	Иначе
		РасчитыватьХешСуммуУпаковок = Истина;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Функция ШтрихкодыВерхнегоУровня(ДеревоУпаковок = Неопределено, Штрихкоды = Неопределено)
	Если Штрихкоды = Неопределено Тогда
		Штрихкоды = Новый Массив;
	КонецЕсли;
	Если ДеревоУпаковок = Неопределено Тогда
		ДеревоУпаковок = ДеревоМаркированнойПродукции;
	КонецЕсли;
	Для Каждого СтрокаДерева Из ДеревоУпаковок.ПолучитьЭлементы() Цикл
		Если ЗначениеЗаполнено(СтрокаДерева.ВидУпаковки) Тогда
			Штрихкод                = СтрокаДерева.Штрихкод;
			НормализованныйШтрихкод = СтрокаДерева.Штрихкод;
			Если СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
				НормализованныйШтрихкод = РазборКодаМаркировкиИССлужебныйКлиент.НормализованныйШтрихкод(Штрихкод, ВидМаркируемойПродукции, Неопределено);
			КонецЕсли;
			
			Штрихкоды.Добавить(
				Новый Структура("Штрихкод, НормализованныйШтрихкод, Количество, ШтрихкодУпаковки",
					Штрихкод, НормализованныйШтрихкод, 1, ""));
		Иначе
			ШтрихкодыВерхнегоУровня(СтрокаДерева, Штрихкоды);
		КонецЕсли;
	КонецЦикла;
	Возврат Штрихкоды;
КонецФункции

&НаКлиенте
Процедура ЗаполнитьШтрихкодыИСтатусыПроверки(ДеревоУпаковок, ШтрихкодыИСтатусыПроверки)
	Для Каждого СтрокаДерева Из ДеревоУпаковок.ПолучитьЭлементы() Цикл
		Если ЗначениеЗаполнено(СтрокаДерева.ВидУпаковки) Тогда
			Штрихкод                = СтрокаДерева.Штрихкод;
			НормализованныйШтрихкод = СтрокаДерева.Штрихкод;
			Если СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
				НормализованныйШтрихкод = РазборКодаМаркировкиИССлужебныйКлиент.НормализованныйШтрихкод(Штрихкод, ВидМаркируемойПродукции, Неопределено);
			КонецЕсли;
			
			ШтрихкодыИСтатусыПроверки.Добавить(
				Новый Структура("Штрихкод, НормализованныйШтрихкод, СтатусПроверки",
					Штрихкод, НормализованныйШтрихкод, СтрокаДерева.СтатусПроверки));
		КонецЕсли;
		ЗаполнитьШтрихкодыИСтатусыПроверки(СтрокаДерева, ШтрихкодыИСтатусыПроверки);
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура УдалитьУпаковкиВерхнегоУровня(СтрокиДереваУпаковок)
	ТекущийИндекс = СтрокиДереваУпаковок.Количество() - 1;
	Пока ТекущийИндекс >= 0 Цикл
		СтрокаДерева = СтрокиДереваУпаковок[ТекущийИндекс];
		Если ЗначениеЗаполнено(СтрокаДерева.ВидУпаковки) Тогда
			ОбработатьПодчиненныеСтрокиДереваПриУдалении(ТаблицаИзмененийТабачнойПродукции, СтрокаДерева);
			ОбработатьСтрокуДереваПриУдалении(ТаблицаИзмененийТабачнойПродукции, СтрокаДерева);
			СтрокиДереваУпаковок.Удалить(СтрокаДерева);
		Иначе
			УдалитьУпаковкиВерхнегоУровня(СтрокаДерева.ПолучитьЭлементы());
		КонецЕсли;
		ТекущийИндекс = ТекущийИндекс - 1;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Функция ИспользоватьЗагрузкуИзТСДПриСменеДетализации(НовыйРежимДетализации)
	
	Если ЭтоДокументМаркировка(ЭтотОбъект) Тогда
		Возврат Ложь;
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная")
			Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими")
			Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		Возврат Ложь;
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками")
		И НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами") Тогда
		Возврат Ложь;
	ИначеЕсли НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.Полная")
		Или НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими")
		Или НовыйРежимДетализации = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		Возврат ТребуетсяВосстановитьДетализацию(ДеревоМаркированнойПродукции, Ложь);
	КонецЕсли;
	
	// Коробки -> КоробкиСБлоками
	Возврат ТребуетсяВосстановитьДетализацию(ДеревоМаркированнойПродукции, Истина);
	
КонецФункции

&НаКлиенте
Функция ТребуетсяВосстановитьДетализацию(ДеревоУпаковок, ДопустимБлокБезПачек, ТребуетсяВосстановитьДетализацию = Ложь)
	
	Если ТребуетсяВосстановитьДетализацию Тогда
		Возврат ТребуетсяВосстановитьДетализацию;
	КонецЕсли;
	
	Для Каждого СтрокаДерева Из ДеревоУпаковок.ПолучитьЭлементы() Цикл
		Если СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Потребительская") Тогда
		ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Групповая") Тогда
			Если СтрокаДерева.ПолучитьЭлементы().Количество() = 0
				И СтрокаДерева.КоличествоПодчиненныхПотребительскихУпаковок > 0
				И Не ДопустимБлокБезПачек Тогда
				ТребуетсяВосстановитьДетализацию = Истина;
			КонецЕсли;
		ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Набор") Тогда
			Если СтрокаДерева.ПолучитьЭлементы().Количество() = 0
				И СтрокаДерева.КоличествоПодчиненныхПотребительскихУпаковок > 0
				И Не ДопустимБлокБезПачек
				И ВСтрокеНаборКакГрупповая(СтрокаДерева, Истина, ПараметрыСканирования) Тогда
				ТребуетсяВосстановитьДетализацию = Истина;
			КонецЕсли;
		ИначеЕсли СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
			Если СтрокаДерева.ПолучитьЭлементы().Количество() = 0 И СтрокаДерева.КоличествоПодчиненныхПотребительскихУпаковок > 0 Тогда
				ТребуетсяВосстановитьДетализацию = Истина;
			Иначе
				ТребуетсяВосстановитьДетализацию(СтрокаДерева, ДопустимБлокБезПачек, ТребуетсяВосстановитьДетализацию);
			КонецЕсли
		Иначе
			ТребуетсяВосстановитьДетализацию(СтрокаДерева, ДопустимБлокБезПачек, ТребуетсяВосстановитьДетализацию);
		КонецЕсли;
		Если ТребуетсяВосстановитьДетализацию Тогда
			Возврат ТребуетсяВосстановитьДетализацию;
		КонецЕсли;
	КонецЦикла;
	
	Возврат ТребуетсяВосстановитьДетализацию;
	
КонецФункции

&НаКлиенте
Функция РекомендуемаяДетализацияНаОснованииСтатистикиПоШтрихкодамПриПереключенииДетализации()

	Если ЭтоДокументМаркировка(ЭтотОбъект)
		Или ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПотребительскиеУпаковки") Тогда
		Возврат Неопределено;
	ИначеЕсли ДетализацияСтруктурыХранения = ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ГрупповыеУпаковкиСПотребительскими") Тогда
		Если ДеревоМаркированнойПродукции.ПолучитьЭлементы().Количество() - 1 < 250 Тогда
			Возврат Неопределено;
		КонецЕсли;
		Возврат ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками");
	КонецЕсли;

	КоличествоПалет             = 0;
	КоличествоКоробов           = 0;
	КоличествоГрупповыхУпаковок = 0;

	Для Каждого СтрокаДерева Из ДеревоМаркированнойПродукции.ПолучитьЭлементы() Цикл

		Если СтрокаДерева.ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Логистическая") Тогда
			КоличествоГрупповыхУпаковок = КоличествоГрупповыхУпаковок + СтрокаДерева.КоличествоПодчиненныхГрупповыхУпаковок;
			Если ЭтоЗаполненнаяМонотоварнаяУпаковкаСGTIN(СтрокаДерева) Тогда
				КоличествоКоробов = КоличествоКоробов + 1;
			Иначе
				КоличествоПалет = КоличествоПалет + 1;
			КонецЕсли;
		ИначеЕсли СтрокаДерева.ТипУпаковки = ТипУпаковкиПотребительскиеУпаковкиБезУпаковки() Тогда
			Продолжить;
		ИначеЕсли СтрокаДерева.ТипУпаковки = ТипУпаковкиГрупповыеУпаковкиБезКоробки() Тогда
			КоличествоГрупповыхУпаковок = КоличествоГрупповыхУпаковок + СтрокаДерева.КоличествоПодчиненныхГрупповыхУпаковок;
		КонецЕсли;

		Если КоличествоПалет > 0 Или КоличествоКоробов >= 25 Тогда
			Возврат ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.ПалетыСМонотоварнымиКоробами");
		КонецЕсли;

	КонецЦикла;

	Если КоличествоКоробов >= 5 Или КоличествоГрупповыхУпаковок >= 250 Тогда
		Возврат ПредопределенноеЗначение("Перечисление.ДетализацияСтруктурыХраненияИС.КоробаСГрупповымиУпаковками");
	КонецЕсли;

	Возврат Неопределено;

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

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

&НаСервере
Процедура ДобавитьПредставлениеКоличестваУпаковок(СтрокиСКоличествомУпаковок, ПредставлениеУпаковки, Количество)
	Если Количество = 0 Тогда
		Возврат;
	КонецЕсли;
	СтрокаСКоличеством = ПолучитьСклоненияСтрокиПоЧислу(ПредставлениеУпаковки, Количество,, "ЧС=Количественное;Л=ru_RU", "ПД=Именительный")[0];
	СтрокиСКоличествомУпаковок.Добавить(СтрокаСКоличеством);
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ОбщийМодульКонтекстаПиП()
	#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
	Возврат ПроверкаИПодборПродукцииИСМП;
	#Иначе
	Возврат ПроверкаИПодборПродукцииИСМПКлиент;
	#КонецЕсли
КонецФункции

&НаКлиенте
Функция НеобходимаПеремаркировка()
	// При завершении подбора будет создаваться новая упаковка
	Если КоличествоУпаковокКоторыеНеобходимоПеремаркировать > 0 Тогда
		Если ЭтоДокументМаркировка(ЭтотОбъект) Тогда
			Возврат Ложь;
		КонецЕсли;
		Возврат Истина;
	КонецЕсли;
	Возврат Ложь;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ТипУпаковкиПотребительскиеУпаковкиБезУпаковки()
	Возврат ПроверкаИПодборПродукцииИСМПКлиентСервер.ТипУпаковкиПотребительскиеУпаковкиБезУпаковки();
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ТипУпаковкиГрупповыеУпаковкиБезКоробки()
	Возврат ПроверкаИПодборПродукцииИСМПКлиентСервер.ТипУпаковкиГрупповыеУпаковкиБезКоробки();
КонецФункции

&НаКлиенте
Процедура ОбработатьСопоставлениеНоменклатурыШтрихкодам(ТоварныеПозицииGTIN)
	
	Для Каждого ИсходныеДанные Из ТоварныеПозицииGTIN Цикл
		
		ПроверкаИПодборПродукцииИСМПКлиентСервер.ПодобраннаяПродукцияПриСопоставлениеНоменклатурыШтрихкодам(
			ЭтотОбъект, ИсходныеДанные, ПроверкаИПодборПродукцииИСМПКлиент,, КэшированныеЗначения);
		
	КонецЦикла;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ВСтрокеНаборКакПотребительская(Строка, ПроверятьТипУпаковки, ПараметрыСканирования)
	Возврат ПроверкаИПодборПродукцииИСМПКлиентСервер.ВСтрокеНаборКакПотребительская(Строка, ПроверятьТипУпаковки, ПараметрыСканирования);
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ВСтрокеНаборКакГрупповая(Строка, ПроверятьТипУпаковки, ПараметрыСканирования)
	Возврат ПроверкаИПодборПродукцииИСМПКлиентСервер.ВСтрокеНаборКакГрупповая(Строка, ПроверятьТипУпаковки, ПараметрыСканирования);
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ЭтоДокументМаркировка(Форма)
	Возврат Не Форма.ПроверкаНеПоДокументу
		И ТипЗнч(Форма.ПроверяемыйДокумент) = Тип("ДокументСсылка.МаркировкаТоваровИСМП");
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ЭтоГрупповаяУпаковкаИлиНабор(ВидУпаковки)
	
	Возврат ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Групповая")
		Или ВидУпаковки = ПредопределенноеЗначение("Перечисление.ВидыУпаковокИС.Набор")
	
КонецФункции

&НаКлиенте
Процедура ВключитьОтключитьОбратноеСканированиеКлиент()
		
	ПараметрыПроверкиКодовМаркировки.ОбратноеСканирование = НЕ ПараметрыПроверкиКодовМаркировки.ОбратноеСканирование;
	
	УстановитьЗаголовокКомандыОбратноеСканирование(ЭтотОбъект);
	
КонецПроцедуры

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

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

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

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