Платежный календарь / Модуль менеджера

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

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

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

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

Функция СтруктураПереносаЗаявки() Экспорт
	
	Возврат Новый Структура("БанковскийСчетКасса, ДатаПлатежа, Валюта, СуммаПереноса, Коэффициент, ВалютаПереноса, ФлагЗакрыть");
	
КонецФункции

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

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

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

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

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

#КонецЕсли

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