// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// URL:    https://github.com/firstBitSportivnaya/PSSL/
//

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

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

// Получить записи
//
// Параметры:
//  ИдентификаторСообщения	 - Строка	 - уникальный иденотификатор сообщения обмена
//
// Возвращаемое значение:
//  ТаблицаЗначений - данные регистра ожидания асинхронных вызовов
//
Функция ПолучитьЗаписи(ИдентификаторСообщения = "") Экспорт

	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	пбп_ОжиданиеАсинхронныхВызовов.ИдентификаторСообщения КАК ИдентификаторСообщения,
	|	пбп_ОжиданиеАсинхронныхВызовов.ИсходящееСообщение КАК ИсходящееСообщение,
	|	пбп_ОжиданиеАсинхронныхВызовов.Статус КАК Статус,
	|	пбп_ОжиданиеАсинхронныхВызовов.ДатаВызова КАК ДатаВызова,
	|	пбп_ОжиданиеАсинхронныхВызовов.ОписаниеОшибки КАК ОписаниеОшибки,
	|	пбп_ОжиданиеАсинхронныхВызовов.Пользователь КАК Пользователь
	|ИЗ
	|	РегистрСведений.пбп_ОжиданиеАсинхронныхВызовов КАК пбп_ОжиданиеАсинхронныхВызовов";

	Если ЗначениеЗаполнено(ИдентификаторСообщения) Тогда
		Запрос.УстановитьПараметр("ИдентификаторСообщения", ИдентификаторСообщения);

		УсловияЗапроса = "пбп_ОжиданиеАсинхронныхВызовов.ИдентификаторСообщения = &ИдентификаторСообщения";
		Запрос = пбп_СхемыЗапросов.ДобавитьОтборВЗапрос(Запрос, УсловияЗапроса);
	КонецЕсли;

	РезультатЗапроса = Запрос.Выполнить();
	ВыгрузкаРезультатаЗапроса = РезультатЗапроса.Выгрузить();

	Возврат ВыгрузкаРезультатаЗапроса;

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

// Добавить запись.
//
// Параметры:
//  ПараметрыЗаписи - Структура - набор параметров Для записи. Ключи:
//   * ИдентификаторСообщения - Строка - уникальный идентификатор сообщения обмена
//   * ИсходящееСообщение - СправочникСсылка.пбп_ИсторияИнтеграции - история интеграции исх. сообщения
//   * Статус - ПеречислениеСсылка.пбп_СтатусыАсинхронныхВызовов - статус вызова
//   * ДатаВызова - Дата - дата вызова
//   * ОписаниеОшибки - Строка - текст ошибки асинх вызова
//
Процедура ДобавитьЗапись(ПараметрыЗаписи) Экспорт

	Если ТипЗнч(ПараметрыЗаписи) <> Тип("Структура") Тогда
		ВызватьИсключение НСтр("ru='Некорректный тип параметра'");
	КонецЕсли;

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

	Попытка
		МенеджерЗаписи = СоздатьМенеджерЗаписи();
		ЗаполнитьЗначенияСвойств(МенеджерЗаписи, ПараметрыЗаписи);

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

		ВызватьИсключение;
	КонецПопытки;

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

// Изменить запись.
//
// Параметры:
//  ПараметрыЗаписи - Структура - набор параметров Для записи. Ключи:
//   * ИдентификаторСообщения - Строка - уникальный идентификатор сообщения обмена
//   * ИсходящееСообщение - СправочникСсылка.пбп_ИсторияИнтеграции - история интеграции исх. сообщения
//   * Статус - ПеречислениеСсылка.пбп_СтатусыАсинхронныхВызовов - статус вызова
//   * ДатаВызова - Дата - дата вызова
//   * ОписаниеОшибки - Строка - текст ошибки асинх вызова
//
Процедура ИзменитьЗапись(ПараметрыЗаписи) Экспорт

	Если ТипЗнч(ПараметрыЗаписи) <> Тип("Структура") Тогда
		ВызватьИсключение НСтр("ru='Некорректный тип параметра'");
	КонецЕсли;

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

	НаборЗаписей = СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.ИдентификаторСообщения.Установить(ПараметрыЗаписи.ИдентификаторСообщения);

	НаборЗаписей.Прочитать();

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

		НаборЗаписей.Записать();
	КонецЕсли;

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

// Удалить запись.
//
// Параметры:
//  ИдентификаторСообщения - Строка - уникальный идентификатор сообщения обмена
//
Процедура УдалитьЗаписи(ИдентификаторСообщения) Экспорт

	Если Не ЗначениеЗаполнено(ИдентификаторСообщения) Тогда
		ВызватьИсключение НСтр("ru='Не указан идентификатор сообщения'");
	КонецЕсли;

	Попытка
		НаборЗаписей = СоздатьНаборЗаписей();
		НаборЗаписей.Отбор.ИдентификаторСообщения.Установить(ИдентификаторСообщения);

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

		ВызватьИсключение;
	КонецПопытки;

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

#КонецОбласти // ПрограммныйИнтерфейс

#КонецЕсли


// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// URL:    https://github.com/firstBitSportivnaya/PSSL/
//

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

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

// Добавить запись.
//
// Параметры:
//  ПараметрыЗаписи - Структура - набор параметров Для записи. Ключи:
//   * ИнтегрируемаяСистема - СправочникСсылка.пбп_ИнтегрируемыеСистемы - интегрируемая система
//   * СсылкаНаОбъект - ОпределяемыйТип.пбп_ОбъектыИнтегрируемыхСистем - ссылка на объект
//   * ИдентификаторСистемы - Строка - Идентификатор интегрируемой системы
Процедура ДобавитьЗапись(ПараметрыЗаписи) Экспорт

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

	Попытка
		МенеджерЗаписи = СоздатьМенеджерЗаписи();
		ЗаполнитьЗначенияСвойств(МенеджерЗаписи, ПараметрыЗаписи);

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

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

// Изменить запись.
//
// Параметры:
//  ПараметрыЗаписи - Структура - набор параметров Для записи. Ключи:
//   * ИнтегрируемаяСистема - СправочникСсылка.пбп_ИнтегрируемыеСистемы - интегрируемая система
//   * СсылкаНаОбъект - ОпределяемыйТип.пбп_ОбъектыИнтегрируемыхСистем - ссылка на объект
//   * ИдентификаторСистемы - Строка - Идентификатор интегрируемой системы
Процедура ИзменитьЗапись(ПараметрыЗаписи) Экспорт

	НаборЗаписей = СоздатьНаборЗаписей();

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

	Если ПараметрыЗаписи.Свойство("СсылкаНаОбъект")
		И ЗначениеЗаполнено(ПараметрыЗаписи.СсылкаНаОбъект) Тогда
		НаборЗаписей.Отбор.СсылкаНаОбъект.Установить(ПараметрыЗаписи.СсылкаНаОбъект);
	КонецЕсли;

	Если ПараметрыЗаписи.Свойство("ИдентификаторСистемы")
		И ЗначениеЗаполнено(ПараметрыЗаписи.ИдентификаторСистемы) Тогда
		НаборЗаписей.Отбор.ИдентификаторСистемы.Установить(ПараметрыЗаписи.ИдентификаторСистемы);
	КонецЕсли;

	НаборЗаписей.Прочитать();

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

		НаборЗаписей.Записать();
	КонецЕсли;

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

// Удалить запись.
//
// Параметры:
//  ПараметрыЗаписи - Структура - набор параметров Для записи. Ключи:
//   * ИнтегрируемаяСистема - СправочникСсылка.пбп_ИнтегрируемыеСистемы - интегрируемая система
//   * СсылкаНаОбъект - ОпределяемыйТип.пбп_ОбъектыИнтегрируемыхСистем - ссылка на объект
//   * ИдентификаторСистемы - Строка - Идентификатор интегрируемой системы
Процедура УдалитьЗаписи(ПараметрыЗаписи) Экспорт

	Если ТипЗнч(ПараметрыЗаписи) <> Тип("Структура") Тогда
		ВызватьИсключение НСтр("ru='Некорректный тип параметра'");
	КонецЕсли;

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

			НаборЗаписей.Отбор[КлючИЗначение.Ключ].Установить(КлючИЗначение.Значение);
		КонецЦикла;

		НаборЗаписей.Очистить();
		НаборЗаписей.Записать();

		ТекстСообщения = НСтр("ru='Удаление записей соответствия'");
		ЗаписьЖурналаРегистрации(ТекстСообщения,
			УровеньЖурналаРегистрации.Информация, , ,
			"Параметры: " + СтрСоединить(ПараметрыЗаписи));

		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;

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

#КонецОбласти // ПрограммныйИнтерфейс

#КонецЕсли


// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// URL:    https://github.com/firstBitSportivnaya/PSSL/
//

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

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

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

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

#КонецОбласти // ОбработчикиСобытийФормы

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

&НаКлиенте
Процедура ПосмотретьИспользованияВИсторииИнтеграции(Команда)

	ПараметрыОткрытия = Новый Структура;
	ПараметрыОткрытия.Вставить("ИнтегрируемаяСистема"	, Запись.ИнтегрируемаяСистема);
	ПараметрыОткрытия.Вставить("СсылкаНаОбъект"			, Запись.СсылкаНаОбъект);
	ПараметрыОткрытия.Вставить("АдресСвязанныхДанных"	, АдресДанныхСвязанныхИсторииИнтеграции);

	ОткрытьФорму("РегистрСведений.пбп_СоответствиеОбъектовИнтегрируемыхСистем.Форма.ФормаСвязанныхЗаписейИстории",
		ПараметрыОткрытия, Запись, Новый УникальныйИдентификатор);

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

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


// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// URL:    https://github.com/firstBitSportivnaya/PSSL/
//

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	ИнтегрируемаяСистема = Параметры.ИнтегрируемаяСистема;
	СсылкаНаОбъект = Параметры.СсылкаНаОбъект;

	ТаблицаДанных = ПолучитьИзВременногоХранилища(Параметры.АдресСвязанныхДанных);
	ИсторияИнтеграции.Загрузить(ТаблицаДанных);

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

#КонецОбласти // ОбработчикиСобытийФормы

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

&НаКлиенте
Процедура ЗакрытьФорму(Команда)
	ЭтотОбъект.Закрыть();
КонецПроцедуры

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


// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// URL:    https://github.com/firstBitSportivnaya/PSSL/
//

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

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

Процедура ПриЗаписи(Отказ, Замещение)

	Если ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;

	ТипыСоответствий = ЭтотОбъект.ВыгрузитьКолонку("ТипСоответствия");

	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
		|	пбп_ТипСоответствияОбъектовИБ.Ссылка КАК Ссылка
		|ИЗ
		|	Справочник.пбп_ТипСоответствияОбъектовИБ КАК пбп_ТипСоответствияОбъектовИБ
		|ГДЕ
		|	пбп_ТипСоответствияОбъектовИБ.Кэшируется
		|	И пбп_ТипСоответствияОбъектовИБ.Ссылка В(&ТипыСоответствий)";

	Запрос.УстановитьПараметр("ТипыСоответствий", ТипыСоответствий);
	РезультатЗапроса = Запрос.Выполнить();

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

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

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

#КонецЕсли


// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// URL:    https://github.com/firstBitSportivnaya/PSSL/
//

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	Если Параметры.Ключ.Пустой()									// новый
		И ЗначениеЗаполнено(Параметры.ЗначениеКопирования) Тогда	// копирование

		Элементы.ТипСоответствия.ТолькоПросмотр = Истина;
		Элементы.Объект2.ВыбиратьТип = Ложь;
		Элементы.Объект1.ВыбиратьТип = Ложь;
		ОбъектОбязателен = Параметры.ЗначенияЗаполнения.Количество() > 0 И Параметры.ЗначенияЗаполнения.Свойство("Объект1");
		Элементы.Объект1.ТолькоПросмотр = ОбъектОбязателен;

	ИначеЕсли Параметры.Ключ.Пустой()								// новый
		И Параметры.ЗначенияЗаполнения.Количество() > 0				// заполняется при переходе из объекта
		И Параметры.ЗначенияЗаполнения.Свойство("Объект1")			// есть свойство
		И НЕ ЗначениеЗаполнено(Параметры.ЗначениеКопирования) Тогда	// не копирование

		ТипОбъект1 = ТипЗнч(Параметры.ЗначенияЗаполнения.Объект1);
		ДанныеИзменены = Ложь;

		Если ДанныеИзменены Тогда

			Элементы.Объект2.ВыбиратьТип = Ложь;
			Элементы.Объект1.ВыбиратьТип = Ложь;
			Элементы.Объект1.ТолькоПросмотр = Истина;
			Элементы.ТипСоответствия.ТолькоПросмотр = Истина;

		КонецЕсли;

	КонецЕсли;

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)

	Если НЕ Параметры.Ключ.Пустой()
		И ЭтаФорма.ВладелецФормы.Родитель.Окно.Содержимое.Количество() > 1 Тогда
		// Форма открывается из Объекта1

		Элементы.Объект2.ВыбиратьТип = Ложь;
		Элементы.Объект1.ВыбиратьТип = Ложь;
		Элементы.Объект1.ТолькоПросмотр = Истина;
		Элементы.ТипСоответствия.ТолькоПросмотр = Истина;

	КонецЕсли;

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

#КонецОбласти // ОбработчикиСобытийФормы


// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// URL:    https://github.com/firstBitSportivnaya/PSSL/
//

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	Если ТипЗнч(Параметры.Отбор) = Тип("Структура")
		И Параметры.Отбор.Свойство("Объект1") Тогда
		// форма открывается из Объекта 1

		Элементы.ТипСоответствия.Видимость = Ложь;

	КонецЕсли;

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

#КонецОбласти //ОбработчикиСобытийФормы

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

&НаКлиенте
Процедура ТипСоответствияПриИзменении(Элемент)

	ТипСоответствияПриИзмененииНаСервере();

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

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

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

&НаСервере
Процедура ТипСоответствияПриИзмененииНаСервере()

	Если ЗначениеЗаполнено(ТипСоответствия) Тогда
		пбп_ОбщегоНазначенияСервер.ИзменитьЭлементОтбораСписка(Список, "ТипСоответствия", ТипСоответствия, Истина);
	Иначе
		пбп_ОбщегоНазначенияСервер.УдалитьЭлементОтбораСписка(Список, "ТипСоответствия");
	КонецЕсли;

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

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


// Библиотека проектных подсистем для упрощения разработки архитектуры на 1С: Предприятие 8,
// включая доработку типовых конфигураций.
//
// Copyright First BIT company
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
// URL:    https://github.com/firstBitSportivnaya/PSSL/
//

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

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

// Создает запись регистра с заданными параметрами.
//
// Параметры:
//  Объект		 - СправочникСсылка, ПланВидовХарактеристикСсылка	 - Ссылка на предопределенный элемент.
//  ЭтоГруппа	 - Булево - Признак того что элемент является группой.
//  КлючиХеша	 - Структура, Неопределено - Если ключи хеша не переданы, то они будут сформированы заново.
//
Процедура СоздатьЗаписьРегистра(Объект, ЭтоГруппа = Ложь, КлючиХеша = Неопределено) Экспорт

	Если КлючиХеша = Неопределено Тогда
		КлючиХеша = КлючиХешаОбъект(Объект, ЭтоГруппа);
	КонецЕсли;

	Если Не ЗначениеЗаполнено(КлючиХеша) Тогда
		Возврат;
	КонецЕсли;

	ЗаполнитьЗначенияСвойств(КлючиХеша, Объект);

	Набор = РегистрыСведений.пбп_СостоянияПредопределенныхЭлементов.СоздатьНаборЗаписей();
	Набор.Отбор.Объект.Установить(Объект);

	Запись = Набор.Добавить();
	Запись.Объект = Объект;
	Запись.ХешСумма = пбп_Переадресация.КонтрольнаяСуммаСтрокой(КлючиХеша, ХешФункция.MD5);

	Набор.Записать();

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

// Обновляет хеш элемента в регистре, устанавливая при этом ручное изменение.
//  Если хеш не был изменен по ключевым реквизитам, обновления не произойдет.
//
// Параметры:
//  Объект		 - СправочникСсылка, ПланВидовХарактеристикСсылка - Ссылка на предопределенный элемент
//  ЭтоГруппа	 - Булево										  - Признак того что элемент является группой
//  Флаг		 - Булево										  - Признак ручного изменения элемента.
//
Процедура ОбновитьХешЭлемента(Объект, ЭтоГруппа = Ложь, Флаг = Ложь) Экспорт

	КлючиХеша = КлючиХешаОбъект(Объект, ЭтоГруппа);

	Если Не ЗначениеЗаполнено(КлючиХеша) Тогда
		Возврат;
	КонецЕсли;

	ЗаполнитьЗначенияСвойств(КлючиХеша, Объект);
	НовыйХешЭлемента = пбп_Переадресация.КонтрольнаяСуммаСтрокой(КлючиХеша, ХешФункция.MD5);

	Набор = СоздатьНаборЗаписей();
	Набор.Отбор.Объект.Установить(Объект);
	Набор.Прочитать();

	Если Не ЗначениеЗаполнено(Набор) Тогда
		СообщитьОбОтсутствииЗаписи(Объект);
		Возврат;
	КонецЕсли;

	Запись = Набор[0];
	Если НовыйХешЭлемента = Запись.ХешСумма Тогда
		Возврат;
	КонецЕсли;

	Запись.ХешСумма = НовыйХешЭлемента;
	Запись.РучноеИзменение = Флаг;
	Набор.Записать();

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

// Обновляет флаг ручного изменения элемента
//
// Параметры:
//  Объект  - СправочникСсылка, ПланВидовХарактеристикСсылка - Ссылка на предопределенный элемент
//  Флаг    - Булево										 - Устанавливается если были изменены ключевые поля пользователем.
//
Процедура ОбновитьФлагРучногоИзменения(Объект, Флаг) Экспорт

	Набор = СоздатьНаборЗаписей();
	Набор.Отбор.Объект.Установить(Объект);
	Набор.Прочитать();

	Если Не ЗначениеЗаполнено(Набор) Тогда
		СообщитьОбОтсутствииЗаписи(Объект);
		Возврат;
	КонецЕсли;

	Набор[0].РучноеИзменение = Флаг;
	Набор.Записать();

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

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

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

Процедура СообщитьОбОтсутствииЗаписи(Элемент)

	ТекстСообщения = НСтр("ru = 'При обновлении не найдена запись состояния по объекту ''%1'' не найдена!';
		|en = 'No status record found during update for object ''%1'' not found!'");
	ТекстСообщения = пбп_ПереадресацияКлиентСервер.ПодставитьПараметрыВСтроку(
		ТекстСообщения,
		Элемент.Ссылка);
	пбп_Переадресация.СообщитьПользователю(ТекстСообщения, Элемент);

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

Функция КлючиХешаОбъект(Объект, ЭтоГруппа)

	МенеджерОбъекта = пбп_Переадресация.МенеджерОбъектаПоСсылке(Объект);

	КлючиХеша = пбп_ПредопределенныеЗначения.КлючиХеша(МенеджерОбъекта);

	Если ЭтоГруппа Тогда
		Возврат КлючиХеша.КлючиХешаГруппа;
	КонецЕсли;

	Возврат КлючиХеша.КлючиХешаЭлемент;

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

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

#КонецЕсли


Функция Обучение(Объект, СброситьСтарыеНастройки = Истина) Экспорт

	УстановитьПараметрыОбучения(Объект);
	МокитоСлужебный.ДобавитьНастройкуПерехватаВызововОбъекта(Объект, СброситьСтарыеНастройки);

	Возврат МокитоОбучение;

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

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

Функция Наблюдать(ИмяМетода, ПараметрыВызова = Неопределено) Экспорт

	ЗарегистрироватьПерехватВыражения(ИмяМетода, ПараметрыВызова);

	Возврат МокитоОбучение;

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

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

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

	Возврат Наблюдать(ИмяМетода, ПараметрыВызова);

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

// Указывает, что при соблюдении условий (см. Когда) метод должен вернуть указанный результат.
//
// При этом сам метод не исполняется.
//
// Параметры:
//  Результат - Произвольный - Результат, который должен вернуть метод.
//
// Возвращаемое значение:
//  ОбщийМодуль - Этот же модуль, для замыкания

Функция Вернуть(Результат) Экспорт

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

	Возврат МокитоОбучение;

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

//  Указывает, что при соблюдении условий (см. Когда) метод должен выбросить исключение.
//
//  При этом сам метод не исполняется.
//
// Параметры:
//  ТекстИсключения - Строка
//
// Возвращаемое значение:
//  ОбщийМодуль - Этот же модуль, для замыкания

Функция ВыброситьИсключение(ТекстИсключения) Экспорт

	ЗарегистрироватьРеакцию(Новый Структура("ТипДействия, Ошибка", МокитоСлужебный.ТипыДействийРеакций().ВыброситьИсключение, ТекстИсключения));

	Возврат МокитоОбучение;

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

// Указывает, что при соблюдении условий (см. Когда) метод не должен выполняться, его вызов пропускается.
//
// Если это функция, то будет возвращено `Неопределено`.
//
// Возвращаемое значение:
//  ОбщийМодуль - Этот же модуль, для замыкания

Функция Пропустить() Экспорт

	ЗарегистрироватьРеакцию(Новый Структура("ТипДействия", МокитоСлужебный.ТипыДействийРеакций().Пропустить));

	Возврат МокитоОбучение;

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

// Указывает, что при соблюдении условий (см. Когда) метод должен выполняться.
// Используется для случаев, когда необходимо задать исключения для другого правила на этом методе.
//
// TODO: Нужны примеры
//
// Возвращаемое значение:
//  ОбщийМодуль - Этот же модуль, для замыкания

Функция ВыполнитьМетод() Экспорт

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

	Возврат МокитоОбучение;

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

//  Переводит мокито в режим прогона тестов.
//
//  Вызов этого метода обязателен перед выполнением тестового прогона метода.

Процедура Прогон() Экспорт

	Мокито.Прогон();

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

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

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

Процедура ЗарегистрироватьПерехватВыражения(ИмяМетода, ПараметрыВызова)

	ПереданаСтруктураВызоваМетода = МокитоСлужебный.ЭтоСтруктураВызоваМетода(ИмяМетода);

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

	ДанныеПерехвата = МокитоСлужебный.НастройкиПерехватаОбъекта(Объект);

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

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

	Методы = ДанныеПерехвата.Методы;

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

	Реакция = СоздатьОписаниеУсловнойРеакции(СтруктураВызоваМетода);

	РеакцииМетода = Методы[СтруктураВызоваМетода.ИмяМетода].Реакции;
	РеакцииМетода.Добавить(Реакция);

	ПараметрыОбучения = ПараметрыОбучения();
	ПараметрыОбучения.РеакцияТекущегоВыражения = Реакция;
	ПараметрыОбучения.Реакции = РеакцииМетода;

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

Функция ОписаниеПараметровПерехватаМетода()

	Возврат Новый Структура("Реакции", Новый Массив);

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

#Область Реакции

Функция ОписаниеУсловнойРеакции()

	Возврат Новый Структура("УсловиеРеакции, Действие");

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

Функция СоздатьОписаниеУсловнойРеакции(СтруктураВызоваМетода)

	Условия = МокитоСлужебный.УсловиеИзПараметров(СтруктураВызоваМетода.Параметры);
	ОписаниеУсловнойРеакции = ОписаниеУсловнойРеакции();
	ОписаниеУсловнойРеакции.УсловиеРеакции = Условия;
	Возврат ОписаниеУсловнойРеакции;

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

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

#Область Параметры

Функция ОбучаемыйОбъект()

	Возврат ПараметрыОбучения().ОбучаемыйОбъект;

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

Функция ПараметрыОбучения()

	Возврат МокитоСлужебный.Настройки().ПараметрыОбучения;

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

Процедура УстановитьПараметрыОбучения(Объект)

	ПараметрыОбучения = Новый Структура("ОбучаемыйОбъект, РеакцияТекущегоВыражения, Реакции", Объект, Неопределено);
	МокитоСлужебный.Настройки().ПараметрыОбучения = ПараметрыОбучения;

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

Процедура ЗарегистрироватьРеакцию(Действие)

	Параметры = ПараметрыОбучения();

	Действие.Вставить("Обработано", Ложь);

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

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

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

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


Функция Включен() Экспорт

	ДанныеКонтекста = ЮТКонтекстСлужебный.ДанныеКонтекста();
	Настройки = Неопределено;
	Возврат ДанныеКонтекста <> Неопределено И ДанныеКонтекста.Свойство(КлючНастроек(), Настройки) И Настройки <> Неопределено;

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

Процедура УстановитьРежим(Режим) Экспорт

	Контекст = Настройки();
	Контекст.Режим = Режим;
	ОчиститьСлужебныеПараметры();

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

// Настройки.
//
// Возвращаемое значение:
//  см. НовыеНастройки

Функция Настройки() Экспорт

	Настройки = ЮТКонтекстСлужебный.ЗначениеКонтекста(КлючНастроек());

	Если Настройки = Неопределено Тогда
		ВызватьИсключение "Что-то пошло не так, настройки Мокито не инициализированы";
	КонецЕсли;

	//@skip-check constructor-function-return-section
	Возврат Настройки;

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

#Область СтруктурыДанных

Функция РежимыРаботы() Экспорт

	Режимы = Новый Структура();
	Режимы.Вставить("Обучение", "Обучение");
	Режимы.Вставить("Тестирование", "Тестирование");
	Режимы.Вставить("Проверка", "Проверка");

	Возврат Новый ФиксированнаяСтруктура(Режимы);

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

Функция ТипыДействийРеакций() Экспорт

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

	Возврат Новый ФиксированнаяСтруктура(ТипыРеакций);

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

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

Функция АнализВызова(Объект, ИмяМетода, ПараметрыМетода, ПрерватьВыполнение) Экспорт

	ПрерватьВыполнение = Ложь;

	Если НЕ Включен() Тогда
		Возврат Неопределено;
	КонецЕсли;

	Настройки = Настройки();

	Если НЕ ЗначениеЗаполнено(Настройки.Перехват) Или Настройки.ТипыПерехватываемыхОбъектов[ТипЗнч(Объект)] = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;

	ПараметрыПерехвата = ДанныеПерехвата(Объект, Настройки);

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

	РежимыРаботы = РежимыРаботы();

	СтруктураВызоваМетода = СтруктураВызоваМетода(Объект, ИмяМетода, ПараметрыМетода);

	Если Настройки.Режим = РежимыРаботы.Обучение ИЛИ Настройки.Режим = РежимыРаботы.Проверка Тогда

		ПрерватьВыполнение = Истина;
		Возврат СтруктураВызоваМетода;

	ИначеЕсли Настройки.Режим = РежимыРаботы.Тестирование Тогда

		ЗарегистрироватьВызовМетода(Настройки, ПараметрыПерехвата, СтруктураВызоваМетода);
		Возврат ПерехватитьВызовМетода(ПараметрыПерехвата, СтруктураВызоваМетода, ПрерватьВыполнение);

	КонецЕсли;

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

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

// Структура вызова метода.
//
// Параметры:
//  Объект 	- Произвольный - Объект, которому принадлежит метод
//   		- Структура - см. СтруктураВызоваМетода
//  ИмяМетода - Строка - Имя вызванного метода
//  ПараметрыМетода - Массив из Произвольный - Набор параметров, с которыми был вызван метод
//
// Возвращаемое значение:
//  Структура - Информация о вызове метода:
//   * Объект - Произвольный - Объект, которому принадлежит метод
//   * ИмяМетода - Строка - Имя вызванного метода
//   * Параметры - Массив из Произвольный - Набор параметров, с которыми был вызван метод
//   * Контекст - Строка - Контекст вызова метода

Функция СтруктураВызоваМетода(Объект, ИмяМетода, ПараметрыМетода) Экспорт

	Если ЭтоСтруктураВызоваМетода(Объект) Тогда
		Возврат Объект;
	КонецЕсли;

	СтруктураВызоваМетода = Новый Структура("Объект, ИмяМетода, Параметры", Объект, ИмяМетода, ПараметрыМетода);
	СтруктураВызоваМетода.Вставить("Контекст");

	//@skip-check constructor-function-return-section
	Возврат СтруктураВызоваМетода;

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

Функция ЭтоСтруктураВызоваМетода(Объект) Экспорт

	Возврат ТипЗнч(Объект) = Тип("Структура");

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

#Область Предикаты

Функция ТипыУсловийПараметров() Экспорт

	Типы = Новый Структура;
	Типы.Вставить("Любой", "Любой");
	Типы.Вставить("Значение", "Значение");
	Типы.Вставить("Тип", "Тип");
	Типы.Вставить("ОписаниеТипа", "ОписаниеТипа");
	Типы.Вставить("Предикат", "Предикат");

	Возврат Новый ФиксированнаяСтруктура(Типы);

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

// Описание маски параметра.
//
// Параметры:
//  ТипУсловия - Строка - см. ТипыУсловийПараметров
//  Приоритет - Число - Приоритет маски
//
// Возвращаемое значение:
//  Структура - Описание маски параметра:
// * Режим - Строка - см. ТипыУсловийПараметров
// * Приоритет - Число - Приоритет маски, используется если значение подпадает под несколько масок, чем выше приоритет, тем лучше

Функция ОписаниеМаскиПараметра(ТипУсловия, Приоритет) Экспорт

	МаскаПараметра = Новый Структура;
	ЮТОбщий.УказатьТипСтруктуры(МаскаПараметра, "МаскаПараметра");

	МаскаПараметра.Вставить("Режим", ТипУсловия);
	МаскаПараметра.Вставить("Приоритет", Приоритет);

	Возврат МаскаПараметра;

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

Функция ЭтоМаскаПарамера(Параметр) Экспорт

	Возврат ТипЗнч(Параметр) = Тип("Структура") И ЮТОбщий.ТипСтруктуры(Параметр) = "МаскаПараметра";

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

Функция ПроверитьПараметр(Параметр, Условие) Экспорт

	ТипыУсловий = ТипыУсловийПараметров();
	Совпадает = Ложь;

	Если Условие.Режим = ТипыУсловий.Любой Тогда

		Совпадает = Истина;

	ИначеЕсли Условие.Режим = ТипыУсловий.Значение Тогда

		Совпадает = ЮТСравнениеСлужебныйКлиентСервер.ЗначенияРавны(Условие.Значение, Параметр);

	ИначеЕсли Условие.Режим = ТипыУсловий.Тип Тогда

		Совпадает = Условие.Тип = ТипЗнч(Параметр);

	ИначеЕсли Условие.Режим = ТипыУсловий.ОписаниеТипа Тогда

		Совпадает = Условие.Тип.СодержитТип(ТипЗнч(Параметр));

	ИначеЕсли Условие.Режим = ТипыУсловий.Предикат Тогда

		Результат = ЮТПредикатыСлужебныйКлиентСервер.ПроверитьПредикаты(Параметр, Условие.Предикат);
		Совпадает = Результат.Успешно;

	КонецЕсли;

	Возврат Совпадает;

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

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

#Область Перехват

Функция ПараметрыПерехвата() Экспорт

	Возврат Настройки().Перехват;

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

Функция НастройкиПерехватаОбъекта(Объект) Экспорт

	ПараметрыПерехвата = ПараметрыПерехвата();
	Возврат ПараметрыПерехвата[Объект];

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

// Данные перехвата.
//
// Параметры:
//  Объект - Произвольный
//  Настройки - см. НовыеНастройки
//
// Возвращаемое значение:
//  см. ОписаниеПараметровПерехватаОбъекта

Функция ДанныеПерехвата(Объект, Настройки = Неопределено) Экспорт

	Если Настройки = Неопределено Тогда
		ПараметрыПерехвата = ПараметрыПерехвата();
	Иначе
		ПараметрыПерехвата = Настройки.Перехват;
	КонецЕсли;

	Если НЕ ЗначениеЗаполнено(ПараметрыПерехвата) Тогда
		Возврат Неопределено;
	КонецЕсли;

	Если ТипЗнч(Объект) = Тип("Структура") Тогда
		Ключ = Объект.Объект;
	Иначе
		Ключ = Объект;
	КонецЕсли;

	ПараметрыПерехватаОбъекта = ПараметрыПерехвата[Ключ];
	ТипЗначения = ТипЗнч(Ключ);

	Если ПараметрыПерехватаОбъекта = Неопределено Тогда

		Если ЮТТипыДанныхСлужебный.ЭтоТипОбъектаОбработкиОтчета(ТипЗначения) Или ЮТТипыДанныхСлужебный.ЭтоТипНабораЗаписей(ТипЗначения) Тогда

			Менеджер = ЮТОбщий.Менеджер(ТипЗначения);
			ПараметрыПерехватаОбъекта = ПараметрыПерехвата[Менеджер];

		ИначеЕсли ЮТТипыДанныхСлужебный.ЭтоТипОбъекта(ТипЗначения) Тогда

			ПараметрыПерехватаОбъекта = ПараметрыПерехвата[Ключ.Ссылка];

			Если ПараметрыПерехватаОбъекта = Неопределено Тогда

				Менеджер = ЮТОбщий.Менеджер(ТипЗначения);
				ПараметрыПерехватаОбъекта = ПараметрыПерехвата[Менеджер];

			КонецЕсли;

		КонецЕсли;

	КонецЕсли;

	//@skip-check constructor-function-return-section
	Возврат ПараметрыПерехватаОбъекта;

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


Перем мИсполнителиКоманд;

Процедура ЗарегистрироватьКоманды(Знач Парсер) Экспорт

	мИсполнителиКоманд = Новый Соответствие;

	ДобавитьКоманду("help"    ,       "КомандаСправкаПоПараметрам", Парсер);
	ДобавитьКоманду("loadcfg" ,       "КомандаЗагрузитьКонфигурацию", Парсер);
	ДобавитьКоманду("loadrepo",       "КомандаОбновитьИзХранилища", Парсер);
	ДобавитьКоманду("session" ,       "КомандаУправлениеСеансами", Парсер);
	ДобавитьКоманду("dbupdate",       "КомандаОбновитьКонфигурациюБД", Парсер);
	ДобавитьКоманду("run",            "КомандаЗапуститьВРежимеПредприятия", Парсер);
	ДобавитьКоманду("disablesupport", "КомандаСнятьСПоддержки", Парсер);
	ДобавитьКоманду("unbindrepo",     "КомандаОтключитьсяОтХранилища", Парсер);
	ДобавитьКоманду("scheduledjobs",  "КомандаУправлениеСеансами", Парсер);
	ДобавитьКоманду("info",           "КомандаУправлениеСеансами", Парсер);

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

Функция ПолучитьКоманду(Знач ИмяКоманды) Экспорт

	КлассРеализации = мИсполнителиКоманд[ИмяКоманды];
	Если КлассРеализации = Неопределено Тогда
		ВызватьИсключение "Неверная операция. Команда '"+ИмяКоманды+"' не предусмотрена";
	КонецЕсли;

	Возврат КлассРеализации;

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

Функция ВыполнитьКоманду(Знач ИмяКоманды, Знач ПараметрыКоманды) Экспорт

	Команда = ПолучитьКоманду(ИмяКоманды);

	Возврат Команда.ВыполнитьКоманду(ПараметрыКоманды);

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

Функция РезультатыКоманд() Экспорт

	РезультатыКоманд = Новый Структура;
	РезультатыКоманд.Вставить("НеРеализовано", 255);
	РезультатыКоманд.Вставить("Успех", 0);
	РезультатыКоманд.Вставить("НеверныеПараметры", 5);
	РезультатыКоманд.Вставить("ОшибкаВремениВыполнения", 1);

	Возврат РезультатыКоманд;

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

Функция КодВозвратаКоманды(Знач Команда) Экспорт
	Возврат Число(Команда);
КонецФункции

Процедура ДобавитьКоманду(Знач ИмяКоманды, Знач КлассРеализации, Знач Парсер)

	РеализацияКоманды = Новый(КлассРеализации);
	РеализацияКоманды.ЗарегистрироватьКоманду(ИмяКоманды, Парсер);
	мИсполнителиКоманд.Вставить(ИмяКоманды, РеализацияКоманды);

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

Процедура ПоказатьСправкуПоКомандам() Экспорт
	ВыполнитьКоманду("help", Новый Соответствие);
КонецПроцедуры


Функция ЗаголовкиAWS4(Знач Метод, Знач Конфигурация, Знач ДанныеАдресВХ) Экспорт
	фРезультат = Новый Массив;

	Данные = ПолучитьИзВременногоХранилища(ДанныеАдресВХ);
	УдалитьИзВременногоХранилища(ДанныеАдресВХ);

	ЗаголовокAmzContent = ХешСтрока(Данные, ХешФункция.SHA256);

	СпецификацияЗапроса = "aws4_request";
	АлгоритмШифрования = "AWS4-HMAC-SHA256";
	Аутентификация = Конфигурация.ДополнительныеПараметры.АвторизоватьсяAWS4;
	Регион = ?(ПустаяСтрока(Аутентификация.Регион), КлиентHTTPПовтИсп.РегионAWSПоУмолчанию(), Аутентификация.Регион);
	ТУД = ТекущаяУниверсальнаяДата();
	ЗаголовокAmzDate = Формат(ТУД, "ДФ=yyyyMMddTHHmmssZ");
	ДатаДействия = Формат(ТУД, "ДФ=yyyyMMdd");

	фРезультат.Добавить(Новый Структура("Ключ, Значение", "X-Amz-Date", ЗаголовокAmzDate));
	фРезультат.Добавить(Новый Структура("Ключ, Значение", "X-Amz-Content-Sha256", ЗаголовокAmzContent));

	СписокЗаголовков = СписокЗаголовковAWS4(Конфигурация.Заголовки, фРезультат);
	ПодписываемыеЗаголовки = ПодписываемыеЗаголовкиAWS4(СписокЗаголовков);

	ЧастиСтроки = Новый Массив;
	ЧастиСтроки.Добавить(Метод);
	ЧастиСтроки.Добавить(Конфигурация.ДанныеURI.Путь);
	ЧастиСтроки.Добавить(КаноническиеПараметрыAWS4(Конфигурация.Параметры));
	ЧастиСтроки.Добавить(КаноническиеЗаголовкиAWS4(СписокЗаголовков));
	ЧастиСтроки.Добавить(ПодписываемыеЗаголовки);
	ЧастиСтроки.Добавить(ЗаголовокAmzContent);
	КаноническийЗапрос = СтрСоединить(ЧастиСтроки, Символы.ПС);

	ЧастиСтроки = Новый Массив;
	ЧастиСтроки.Добавить(ДатаДействия);
	ЧастиСтроки.Добавить(Регион);
	ЧастиСтроки.Добавить(Аутентификация.Сервис);
	ЧастиСтроки.Добавить(СпецификацияЗапроса);
	ОбластьДействия = СтрСоединить(ЧастиСтроки, "/");

	ЧастиСтроки = Новый Массив;
	ЧастиСтроки.Добавить(АлгоритмШифрования);
	ЧастиСтроки.Добавить(ЗаголовокAmzDate);
	ЧастиСтроки.Добавить(ОбластьДействия);
	ЧастиСтроки.Добавить(ХешСтрока(КаноническийЗапрос, ХешФункция.SHA256));
	СтрокаДляПодписи = СтрСоединить(ЧастиСтроки, Символы.ПС);

	Подпись = HMAC256(ПолучитьДвоичныеДанныеИзСтроки("AWS4" + Аутентификация.СекретныйКлюч), ПолучитьДвоичныеДанныеИзСтроки(ДатаДействия));
	Подпись = HMAC256(Подпись, ПолучитьДвоичныеДанныеИзСтроки(Регион));
	Подпись = HMAC256(Подпись, ПолучитьДвоичныеДанныеИзСтроки(Аутентификация.Сервис));
	Подпись = HMAC256(Подпись, ПолучитьДвоичныеДанныеИзСтроки(СпецификацияЗапроса));
	Подпись = НРег(ПолучитьHexСтрокуИзДвоичныхДанных(HMAC256(Подпись, ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляПодписи))));

	фРезультат.Добавить(Новый Структура(
		"Ключ, Значение",
		КлиентHTTPПовтИсп.ЗаголовокТипАутентификации(),
		СтрШаблон(
			"%1 Credential=%2/%3, SignedHeaders=%4, Signature=%5",
			АлгоритмШифрования,
			Аутентификация.КлючДоступа,
			ОбластьДействия,
			ПодписываемыеЗаголовки,
			Подпись
		)
	));

	Возврат Новый ФиксированныйМассив(фРезультат);
КонецФункции

// Возвращает значение заголовка Hawk-аутентификации
//  Расчёт подписи содержимого тела запроса не обязателен для Hawk-аутентификации.
//
// Параметры:
//  Метод			 - Строка			 - имя HTTP-метода
//  Конфигурация	 - Структура		 - конфигурация выполнения запроса
//  ДанныеАдресВХ	 - Строка, Неопределено	 - адрес данных тела запроса во временном хранилище
//
// Возвращаемое значение:
//  Строка - значение заголовка Hawk-аутентификации
//

Функция ЗаголовокHawk(Знач Метод, Конфигурация, Знач ДанныеАдресВХ = Неопределено) Экспорт
	фРезультат = Новый Массив;

	ПодписьТела = "";
	Если ДанныеАдресВХ <> Неопределено Тогда
		Данные = ПолучитьИзВременногоХранилища(ДанныеАдресВХ);
		УдалитьИзВременногоХранилища(ДанныеАдресВХ);

		ПодписьТела = ПодписьТелаHawk(
			Данные,
			КлиентHTTPКлиентСервер.ТипMIMEИзЗаголовков(Конфигурация.Заголовки)
		);
	КонецЕсли;

	Аутентификация = Конфигурация.ДополнительныеПараметры.АвторизоватьсяHawk;
	ДополнительныеДанные = НормализованныеДополнительныеДанныеHawk(Аутентификация.Дополнение);
	РазовоеСлово = НовоеРазовоеСлово();
	ВременнаяМетка = XMLСтрока(ВременнаяМеткаUnix());

	ЧастиСтроки = Новый Массив;
	ЧастиСтроки.Добавить("hawk.1.header");
	ЧастиСтроки.Добавить(ВременнаяМетка);
	ЧастиСтроки.Добавить(РазовоеСлово);
	ЧастиСтроки.Добавить(Метод);
	ЧастиСтроки.Добавить(Конфигурация.ДанныеURI.Путь);
	ЧастиСтроки.Добавить(НРег(Конфигурация.ДанныеURI.Сервер));
	ЧастиСтроки.Добавить(XMLСтрока(Конфигурация.ДанныеURI.Порт));
	ЧастиСтроки.Добавить(ПодписьТела);
	ЧастиСтроки.Добавить(ДополнительныеДанные);

	Если НЕ ПустаяСтрока(Аутентификация.ИдентификаторПриложения) Тогда
		ЧастиСтроки.Добавить(Аутентификация.ИдентификаторПриложения);
		ЧастиСтроки.Добавить(Аутентификация.Делегирование);
	КонецЕсли;

	ЧастиСтроки.Добавить("");

	Подпись = Base64Строка(HMAC256(
		ПолучитьДвоичныеДанныеИзСтроки(Аутентификация.Ключ),
		ПолучитьДвоичныеДанныеИзСтроки(СтрСоединить(ЧастиСтроки, Символы.ПС))
	));

	фРезультат.Добавить(СтрШаблон("Hawk id=""%1"", ts=""%2"", nonce=""%3""", Аутентификация.Идентификатор, ВременнаяМетка, РазовоеСлово));
	Если ПодписьТела <> "" Тогда
		фРезультат.Добавить(СтрШаблон("hash=""%1""", ПодписьТела));
	КонецЕсли;
	Если ДополнительныеДанные <> "" Тогда
		фРезультат.Добавить(СтрШаблон("ext=""%1""", ДополнительныеДанные));
	КонецЕсли;
	фРезультат.Добавить(СтрШаблон("mac=""%1""", Подпись));
	Если НЕ ПустаяСтрока(Аутентификация.ИдентификаторПриложения) Тогда
		фРезультат.Добавить(СтрШаблон("app=""%1""", Аутентификация.ИдентификаторПриложения));
		Если НЕ ПустаяСтрока(Аутентификация.Делегирование) Тогда
			фРезультат.Добавить(СтрШаблон("dlg=""%1""", Аутентификация.Делегирование));
		КонецЕсли;
	КонецЕсли;

	Аутентификация = Новый Структура(Аутентификация);
	Аутентификация.Вставить("РазовоеСлово", РазовоеСлово);
	Аутентификация.Вставить("ВременнаяМетка", ВременнаяМетка);

	Конфигурация.ДополнительныеПараметры.АвторизоватьсяHawk = Новый ФиксированнаяСтруктура(Аутентификация);

	Возврат СтрСоединить(фРезультат, ", ");
КонецФункции

// Возвращает результат валидации ответа сервера по указанному заголовку (Hawk аутентификация)
//  Если валидация прошла успешно, вернётся Истина.
//
// Параметры:
//  ЗначениеЗаголовка	 - Строка	 - значение заголовка ответа сервера с данными Hawk аутентификации
//  КонтекстHawk		 - Структура - данные Hawk аутентификации запроса
//  ДанныеАдресВХ		 - Строка	 - адрес данных тела ответа и MIME-типа во временном хранилище
//  ОписаниеОшибки		 - Строка	 - описание ошибки валидации ответа
//
// Возвращаемое значение:
//  Булево - результат валидации
//