Загрузка отчета банка по СБП / Модуль менеджера

файл
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область ПрограммныйИнтерфейс

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

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

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

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

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

Функция СоздатьДокументОтчетБанкаПоОперациямЭквайринга(ДанныеДоговора, НастройкаПодключения, ДанныеОпераций, ЗагруженныеОтчетыБанка, ПроводитьДокументыПриЗагрузке)
	
	НомерСтрокиПоТерминалу = 0;
	
	Если ПроводитьДокументыПриЗагрузке Тогда
		РежимЗаписиДок = РежимЗаписиДокумента.Проведение;
	Иначе
		РежимЗаписиДок = РежимЗаписиДокумента.Запись;
	КонецЕсли;
	
	СоответствиеДатПлатежейИДокументов = Новый Соответствие;
	СоответствиеДатПлатежейИСуммКомиссии = Новый Соответствие;
	
	Для Каждого ДанныеОперации Из ДанныеОпераций Цикл
		
		НомерСтрокиПоТерминалу = НомерСтрокиПоТерминалу + 1;
		
		ДатаПлатежа = МестноеВремя(ДанныеОперации.ДатаОперации, ЧасовойПоясСеанса());
		
		ДокументОбъект = СоответствиеДатПлатежейИДокументов.Получить(НачалоДня(ДатаПлатежа));
		Если ДокументОбъект = Неопределено Тогда
			Отбор = Новый Структура(
				"ДатаОперации, НастройкаПодключения",
				НачалоДня(ДатаПлатежа), НастройкаПодключения);
			НайденныеДокументы = ЗагруженныеОтчетыБанка.НайтиСтроки(Отбор);
			
			Если НайденныеДокументы.Количество() = 0 Тогда
				ДокументОбъект = Документы.ОтчетБанкаПоОперациямЭквайринга.СоздатьДокумент();
				ДокументОбъект.Дата                     = НачалоДня(ДатаПлатежа);
				ДокументОбъект.ДоговорЭквайринга        = ДанныеДоговора.Ссылка;
				ДокументОбъект.НастройкаПодключенияКСБП = НастройкаПодключения;
				ДокументОбъект.Организация              = ДанныеДоговора.Организация;
				ДокументОбъект.Валюта                   = ДанныеДоговора.Валюта;
			ИначеЕсли НайденныеДокументы.Количество() = 1 Тогда
				ДокументОбъект = НайденныеДокументы[0].ОтчетБанка.ПолучитьОбъект();
				ДокументОбъект.Покупки.Очистить();
				ДокументОбъект.Возвраты.Очистить();
			Иначе
				ТекстСообщения = СтрШаблон(
					НСтр("ru='Настройка подключения ""%1"", дата отчета ""%2"" - более одного документа ""Отчет банка по электронным платежным операциям""'"),
					НастройкаПодключения,
					Формат(НачалоДня(ДатаПлатежа), "ДФ=dd.MM.yyyy"));
				ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
				Возврат ТекстСообщения;
			КонецЕсли;
			
			СоответствиеДатПлатежейИДокументов.Вставить(НачалоДня(ДатаПлатежа), ДокументОбъект);
			СоответствиеДатПлатежейИСуммКомиссии.Вставить(НачалоДня(ДатаПлатежа), 0);
			
		КонецЕсли;
		
		Если Не ЗначениеЗаполнено(ДанныеОперации.ТипОперации) Тогда
			ОбщегоНазначения.СообщитьПользователю(
				СтрШаблон(
					НСтр("ru='Настройка подключения ""%1"", дата отчета ""%2"" - в данных сверки банка по операциям СБП (""Строка отчета"" №%3) не указан тип операции. ""Строка отчета"" №%3 не загружен.'"),
					НастройкаПодключения,
					Формат(НачалоДня(ДатаПлатежа), "ДФ=dd.MM.yyyy"),
					НомерСтрокиПоТерминалу));
			Продолжить;
		ИначеЕсли ВРег(СокрЛП(ДанныеОперации.ТипОперации)) = ВРег("Оплата") Тогда
			СтрТаблЧасть = ДокументОбъект.Покупки.Добавить();
		ИначеЕсли ВРег(СокрЛП(ДанныеОперации.ТипОперации)) = ВРег("Возврат") Тогда
			СтрТаблЧасть = ДокументОбъект.Возвраты.Добавить();
		Иначе
			Продолжить;
		КонецЕсли;
		
		СтрТаблЧасть.ДатаПлатежа             = ДатаПлатежа;
		СтрТаблЧасть.Сумма                   = ДанныеОперации.Сумма;
		
		ПараметрыОперации = Новый Структура;
		ПараметрыОперации.Вставить("ИдентификаторОперации", ДанныеОперации.Идентификатор);
		ПараметрыОперации.Вставить("ИдентификаторОплаты", ДанныеОперации.ИдентификаторОплаты);
		СтрТаблЧасть.ИдентификаторОплатыСБП = ПереводыСБПc2b.ИдентификаторыОперации(ПараметрыОперации);
		
		СуммаКомиссии = СоответствиеДатПлатежейИСуммКомиссии[НачалоДня(ДатаПлатежа)] + ДанныеОперации.СуммаКомиссии;
		СоответствиеДатПлатежейИСуммКомиссии.Вставить(НачалоДня(ДатаПлатежа), СуммаКомиссии);
		
	КонецЦикла;
	
	Для Каждого СтрокаСоответствия Из СоответствиеДатПлатежейИДокументов Цикл
		
		ДокументОбъект = СтрокаСоответствия.Значение;
		ДатаОтчета = СтрокаСоответствия.Ключ;
		
		Если ДокументОбъект.Покупки.Количество() + ДокументОбъект.Возвраты.Количество() = 0 Тогда
			ОбщегоНазначения.СообщитьПользователю(
				СтрШаблон(
					НСтр("ru='Настройка подключения ""%1"", дата отчета ""%2"" - при загрузке данных сверки в документе ""Отчет банка по электронным платежным операциям"" не заполнены платежи. Документ не создан.'"),
					НастройкаПодключения,
					Формат(ДатаОтчета, "ДФ=dd.MM.yyyy")));
			Продолжить;
		КонецЕсли;

		Попытка
			
			СуммаКомиссии = СоответствиеДатПлатежейИСуммКомиссии[СтрокаСоответствия.Ключ];
			Если ДанныеДоговора.ОтражатьКомиссию И СуммаКомиссии <> 0 Тогда
				ДокументОбъект.СуммаКомиссии     = СуммаКомиссии;
				ДокументОбъект.СтатьяРасходов    = ДанныеДоговора.СтатьяРасходов;
				ДокументОбъект.АналитикаРасходов = ДанныеДоговора.АналитикаРасходов;
				ДокументОбъект.Подразделение     = ДанныеДоговора.Подразделение;
			КонецЕсли;
			
			ДокументОбъект.ОтражатьКомиссию = ДанныеДоговора.ОтражатьКомиссию;
			ДокументОбъект.ДетальнаяСверкаТранзакций = ДанныеДоговора.ДетальнаяСверкаТранзакций;
			ДокументОбъект.Ответственный = Пользователи.ТекущийПользователь();
			
			Если РежимЗаписиДок = РежимЗаписиДокумента.Проведение И Не ДокументОбъект.ПроверитьЗаполнение() Тогда
				РежимЗаписиДок = РежимЗаписиДокумента.Запись;
			КонецЕсли;
			
			ДокументОбъект.Записать(РежимЗаписиДок);
			
		Исключение
			
			ТекстСообщения = СтрШаблон(
				НСтр("ru='Настройка платежа ""%1"", дата отчета ""%2"" - документ ""Отчет банка по электронным платежным операциям"" №%3 от %4 не %5. Произошли ошибки при %6.'"),
				НастройкаПодключения,
				Формат(ДатаОтчета, "ДФ=dd.MM.yyyy"),
				ДокументОбъект.Номер,
				ДокументОбъект.Дата,
				?(РежимЗаписиДок = РежимЗаписиДокумента.Запись, "записан", "проведен"),
				?(РежимЗаписиДок = РежимЗаписиДокумента.Запись, "записи", "проведении"));
			ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
			Возврат ТекстСообщения;
			
		КонецПопытки;
		
	КонецЦикла;
	
	Возврат Неопределено;
	
КонецФункции

Функция СверитьДанныеНастройкиСБанком(СтрокаТЧ, ЗагруженныеОтчетыБанка, ДанныеОпераций, ДетальныеДанныеСверки)
	
	НастройкаПодключения = СтрокаТЧ.НастройкаПодключения;
	НомерСтрокиПоТерминалу = 0;
	
	СоответствиеДатПлатежейИДокументов = Новый Соответствие;
	
	СтруктураДанныхПоДокументам = Новый Структура("СуммаПокупок, СуммаВозвратов, СуммаКомиссии", 0, 0, 0);
	СтруктураДанныхПоБанку = Новый Структура("СуммаПокупок, СуммаВозвратов, СуммаКомиссии", 0, 0, 0);
	
	Для Каждого ДанныеОперации Из ДанныеОпераций Цикл
		
		НомерСтрокиПоТерминалу = НомерСтрокиПоТерминалу + 1;
		
		ДатаПлатежа = МестноеВремя(ДанныеОперации.ДатаОперации, ЧасовойПоясСеанса());
		
		Если Не ЗначениеЗаполнено(ДанныеОперации.ТипОперации) Тогда
			Продолжить;
		КонецЕсли;
		
		Если СоответствиеДатПлатежейИДокументов.Получить(НачалоДня(ДатаПлатежа)) = Неопределено Тогда
			Отбор = Новый Структура(
				"ДатаОперации, НастройкаПодключения",
				НачалоДня(ДатаПлатежа), НастройкаПодключения);
			НайденныеДокументы = ЗагруженныеОтчетыБанка.НайтиСтроки(Отбор);
			
			Если НайденныеДокументы.Количество() = 1 Тогда
				ДанныеДокумента = НайденныеДокументы[0];
				
				СтруктураДанныхПоДокументам.СуммаПокупок = СтруктураДанныхПоДокументам.СуммаПокупок + ДанныеДокумента.СуммаПокупок;
				СтруктураДанныхПоДокументам.СуммаВозвратов = СтруктураДанныхПоДокументам.СуммаВозвратов + ДанныеДокумента.СуммаВозвратов;
				СтруктураДанныхПоДокументам.СуммаКомиссии = СтруктураДанныхПоДокументам.СуммаКомиссии + ДанныеДокумента.СуммаКомиссии;
				
			ИначеЕсли НайденныеДокументы.Количество() = 0 Тогда
				ТекстСообщения = СтрШаблон(
					НСтр("ru='Настройка подключения ""%1"", дата отчета ""%2"" - некорректные данные банка или ""Отчет банка по электронным платежным операциям"" не загружен'"),
					НастройкаПодключения,
					Формат(НачалоДня(ДатаПлатежа), "ДФ=dd.MM.yyyy"));
				ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
				
			Иначе
				ТекстСообщения = СтрШаблон(
					НСтр("ru='Настройка подключения ""%1"", дата отчета ""%2"" - более одного документа ""Отчет банка по электронным платежным операциям""'"),
					НастройкаПодключения,
					Формат(НачалоДня(ДатаПлатежа), "ДФ=dd.MM.yyyy"));
				ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
				Продолжить;
			КонецЕсли;
			
			СоответствиеДатПлатежейИДокументов.Вставить(НачалоДня(ДатаПлатежа), Истина);
			
		КонецЕсли;
		
		СуммаПокупок = 0;
		СуммаВозвратов = 0;
		СуммаКомиссии = 0;
		
		Если ВРег(СокрЛП(ДанныеОперации.ТипОперации)) = ВРег("Оплата") Тогда
			СуммаПокупок = ДанныеОперации.Сумма;
		ИначеЕсли ВРег(СокрЛП(ДанныеОперации.ТипОперации)) = ВРег("Возврат") Тогда
			СуммаВозвратов = ДанныеОперации.Сумма;
		Иначе
			Продолжить;
		КонецЕсли;
		
		СуммаКомиссии = ДанныеОперации.СуммаКомиссии;
		
		СтруктураДанныхПоБанку.СуммаПокупок = СтруктураДанныхПоБанку.СуммаПокупок + СуммаПокупок;
		СтруктураДанныхПоБанку.СуммаВозвратов = СтруктураДанныхПоБанку.СуммаВозвратов + СуммаВозвратов;
		СтруктураДанныхПоБанку.СуммаКомиссии = СтруктураДанныхПоБанку.СуммаКомиссии + СуммаКомиссии;
		
		СтрокаДанныеОпераций = ДетальныеДанныеСверки.Добавить();
		СтрокаДанныеОпераций.СуммаОплатыПоБанку   = СуммаПокупок;
		СтрокаДанныеОпераций.СуммаВозвратаПоБанку = СуммаВозвратов;
		СтрокаДанныеОпераций.СуммаКомиссииПоБанку = СуммаКомиссии;
		СтрокаДанныеОпераций.ДатаОперации         = ДатаПлатежа;
		СтрокаДанныеОпераций.НастройкаПодключения = НастройкаПодключения;
		
		ПараметрыОперации = Новый Структура;
		ПараметрыОперации.Вставить("ИдентификаторОперации", ДанныеОперации.Идентификатор);
		ПараметрыОперации.Вставить("ИдентификаторОплаты", ДанныеОперации.ИдентификаторОплаты);
		СтрокаДанныеОпераций.ИдентификаторОплатыСБП = ПереводыСБПc2b.ИдентификаторыОперации(ПараметрыОперации);
		
	КонецЦикла;
	
	СтрокаТЧ.СуммаОплатПоДокументам = СтруктураДанныхПоДокументам.СуммаПокупок;
	СтрокаТЧ.СуммаВозвратовПоДокументам = СтруктураДанныхПоДокументам.СуммаВозвратов;
	СтрокаТЧ.СуммаКомиссииПоДокументам = СтруктураДанныхПоДокументам.СуммаКомиссии;
	
	СтрокаТЧ.СуммаОплатПоБанку = СтруктураДанныхПоБанку.СуммаПокупок;
	СтрокаТЧ.СуммаВозвратовПоБанку = СтруктураДанныхПоБанку.СуммаВозвратов;
	СтрокаТЧ.СуммаКомиссииПоБанку = СтруктураДанныхПоБанку.СуммаКомиссии;
	
	СтрокаТЧ.СуммаОплатОтклонение = СтруктураДанныхПоДокументам.СуммаПокупок - СтруктураДанныхПоБанку.СуммаПокупок;
	СтрокаТЧ.СуммаВозвратовОтклонение = СтруктураДанныхПоДокументам.СуммаВозвратов - СтруктураДанныхПоБанку.СуммаВозвратов;
	СтрокаТЧ.СуммаКомиссииОтклонение = СтруктураДанныхПоДокументам.СуммаКомиссии - СтруктураДанныхПоБанку.СуммаКомиссии;
	
	СтрокаТЧ.ЕстьОтклонение = СтруктураДанныхПоДокументам.СуммаПокупок <> СтруктураДанныхПоБанку.СуммаПокупок
		ИЛИ СтруктураДанныхПоДокументам.СуммаВозвратов <> СтруктураДанныхПоБанку.СуммаВозвратов
		ИЛИ СтруктураДанныхПоДокументам.СуммаКомиссии <> СтруктураДанныхПоБанку.СуммаКомиссии;
	
	Возврат Неопределено;
	
КонецФункции

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

#КонецЕсли

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