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



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

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

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

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

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

&НаКлиенте
Процедура ЗагрузитьИзБазыЗПЧВтораяДата()
	
	ЗагрузитьИзБазыЗапчастей(ЭтотОбъект.ВтораяРабочаяДата, ЭтотОбъект.ВтораяРабочаяДата);
	
КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьИзБазыЗПЧТретьяДата()
	
	ЗагрузитьИзБазыЗапчастей(ЭтотОбъект.ТретьяРабочаяДата, ЭтотОбъект.ТретьяРабочаяДата);
	
КонецПроцедуры

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

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

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

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

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

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

&НаСервере
Функция ЗагрузитьИзБазыЗапчастейНаСервере()
	
	ИНН = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Организация, "ИНН");
	// dev1c.koreanagroup.ru:11000/parts_dev_sz/
	HTTPСоединение = Новый HTTPСоединение("parts.koreanagroup.ru:11000/parts/hs/exchange/v1/",,"nimble_kafka","000000",,,, Ложь);
	HTTPЗапрос = Новый HTTPЗапрос("" + Организация.УникальныйИдентификатор() + "/" + ИНН + "/" + ДатаНачала + "/" + ДатаОкончания);
	Ответ = HTTPСоединение.ВызватьHTTPМетод("GET", HTTPЗапрос);
	
	Если Ответ.КодСостояния = 200 Тогда
		СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
		ЧтениеОтвета = Новый ЧтениеJSON;
		ЧтениеОтвета.УстановитьСтроку(СтрокаОтвета);
		РезультатСтруктура = ПрочитатьJSON(ЧтениеОтвета);
		ДанныеДокументов = РезультатСтруктура.result;
		СоответствиеДанныхИБ(ДанныеДокументов);
		ИнформацияОПоступленияхАдресВХранилище = ПоместитьВоВременноеХранилище(ДанныеДокументов, ЭтаФорма.УникальныйИдентификатор);
		ОбщегоНазначения.СообщитьПользователю("Проверьте соответствие основных данных и нажмите кнопку ""Создать документы""");
	КонецЕсли;
	
	Если Ответ.КодСостояния = 404 Тогда
		ОбщегоНазначения.СообщитьПользователю(Ответ.ПолучитьТелоКакСтроку());
	КонецЕсли;
		
КонецФункции

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

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

&НаСервере
Процедура СоответствиеДанныхИБ(ДанныеДокументов)
	
	Для Каждого Строка Из ДанныеДокументов Цикл
		СоответствиеСкладов(Строка);
		СоответствиеКонтрагентов(Строка);
	КонецЦикла;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

	Возврат НовыйДоговор;
	
КонецФункции

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

&НаСервереБезКонтекста
Функция ПреобразоватьНаименование(НазваниеКонтрагента)
	
	НовоеИмя = НазваниеКонтрагента;
	
	// Убираем префикс "ИП "
	Если ВРег(Лев(НовоеИмя, 3)) = "ИП " Тогда
		НовоеИмя = СокрЛП(Прав(НовоеИмя, СтрДлина(НовоеИмя) - 3));
	КонецЕсли;
	
	// Извлекаем текст в кавычках
	Если Найти(НовоеИмя, """") > 0 Тогда
		
		ПерваяКавычка = Найти(НовоеИмя, """");
		НовоеИмя = Прав(НовоеИмя, СтрДлина(НовоеИмя) - ПерваяКавычка);
		
		ВтораяКавычка = Найти(НовоеИмя, """");
		Если ВтораяКавычка > 0 Тогда
			НовоеИмя = Лев(НовоеИмя, ВтораяКавычка - 1);
		КонецЕсли;
		
	КонецЕсли;
	
	НовоеИмя = СокрЛП(НовоеИмя);
	
	Возврат НовоеИмя;
	
КонецФункции

&НаКлиенте
Процедура СоответствиеСкладовПодразделенийСкладБППриИзменении(Элемент)
	
	ТекущиеДанные = Элементы.СоответствиеСкладовПодразделений.ТекущиеДанные;
	ТекущиеДанные.Подразделение = ЗначениеРеквизитаОъекта(ТекущиеДанные.СкладБП, "ПодразделениеОрганизации");

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

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

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

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

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

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

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

&НаКлиенте
Процедура ЗагрузитьЧекиВтораяДата()
	ЗагрузитьЧекиИзБазыЗапчастей(ЭтотОбъект.ВтораяРабочаяДатаЧеки, ЭтотОбъект.ВтораяРабочаяДатаЧеки);
КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьЧекиТретьяДата()
	ЗагрузитьЧекиИзБазыЗапчастей(ЭтотОбъект.ТретьяРабочаяДатаЧеки, ЭтотОбъект.ТретьяРабочаяДатаЧеки);
КонецПроцедуры

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

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

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

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

&НаСервере
Функция ЗагрузитьЧекиИзБазыЗапчастейНаСервере()
	
	ИНН = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Организация, "ИНН");
	HTTPСоединение = Новый HTTPСоединение("parts.koreanagroup.ru",11000,"nimble_kafka","000000",,15,,Ложь);
	
	СтрокаДатаНачала    = Формат(ДатаНачалаЧеки, "ДФ=yyyyMMddHHmmss");
	СтрокаДатаОкончания = Формат(ДатаОкончанияЧеки, "ДФ=yyyyMMddHHmmss");
	
	ПутьЗапроса = СтрШаблон(
		"/parts/hs/exchange/GetChek/%1/%2/%3/%4",
		Строка(Организация.УникальныйИдентификатор()),
		ИНН,
		СтрокаДатаНачала,
		СтрокаДатаОкончания);
		
	HTTPЗапрос = Новый HTTPЗапрос(ПутьЗапроса);
	Попытка
		Ответ = HTTPСоединение.ВызватьHTTPМетод("GET", HTTPЗапрос);
	Исключение
		ОбщегоНазначения.СообщитьПользователю(
		"Ошибка подключения: " + ОписаниеОшибки());
		Возврат Неопределено;
	КонецПопытки;
	
	Если Ответ.КодСостояния = 200 Тогда
		СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
		ЧтениеОтвета = Новый ЧтениеJSON;
		ЧтениеОтвета.УстановитьСтроку(СтрокаОтвета);
		РезультатСтруктура = ПрочитатьJSON(ЧтениеОтвета);
		ДанныеДокументов = РезультатСтруктура.result;
		
		СоответствиеДанныхИБЧеки(ДанныеДокументов);
		
		ИнформацияОЧекахАдресВХранилище = ПоместитьВоВременноеХранилище(
			ДанныеДокументов, ЭтаФорма.УникальныйИдентификатор);
		ОбщегоНазначения.СообщитьПользователю(
			"Данные чеков получены. Проверьте соответствие складов и нажмите ""Создать документы""");
	ИначеЕсли Ответ.КодСостояния = 404 Тогда
		ОбщегоНазначения.СообщитьПользователю(Ответ.ПолучитьТелоКакСтроку());
	Иначе
		ОбщегоНазначения.СообщитьПользователю(
			СтрШаблон("Ошибка HTTP %1: %2", 
				Ответ.КодСостояния, Ответ.ПолучитьТелоКакСтроку()));
	КонецЕсли;
	
КонецФункции

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

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

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

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

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

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

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

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

&НаКлиенте
Процедура СоответствиеСкладовЧекиСкладБППриИзменении(Элемент)
	
	ТекущиеДанные = Элементы.СоответствиеСкладовЧеки.ТекущиеДанные;
	ТекущиеДанные.Подразделение = ЗначениеРеквизитаОъекта(ТекущиеДанные.СкладБП, "ПодразделениеОрганизации");
	
КонецПроцедуры

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

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

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

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

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