Ввод контактной информации / Ввод адреса / Модуль формы

файл
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

// Форма параметризуется:
//
//      Заголовок     - Строка  - заголовок формы.
//      ЗначенияПолей - Строка  - сериализованное значение контактной информации или пустая строка для 
//                                ввода нового.
//      Представление - Строка  - представление адреса (используется только при работе со старыми данными).
//      ВидКонтактнойИнформации - СправочникСсылка.ВидыКонтактнойИнформации, Структура - описание того, что мы
//                                редактируем.
//      Комментарий  - Строка   - необязательный комментарий, для подстановки в поле "Комментарий".
//
//      ВозвращатьСписокЗначений - Булево - необязательный флаг того, что возвращаемое значение поля.
//                                 КонтактнаяИнформация будет иметь тип СписокЗначений (совместимость).
//
//  Результат выбора:
//      Структура - поля:
//          * КонтактнаяИнформация   - Строка - XML контактной информации.
//          * Представление          - Строка - Представление.
//          * Комментарий            - Строка - Комментарий.
//          * ВведеноВСвободнойФорме - Булево - флаг ввода.
//

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

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

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

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

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

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

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

&НаКлиенте
Процедура СтранаПриИзменении(Элемент)
	
	Если УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.addressType) Тогда
		ЧастиАдреса = СтрРазделить(НаселенныйПунктДетально.value, ",", Истина);
		СтранаДоИзменения = НаселенныйПунктДетально.country;
		Для Позиция = 0 По ЧастиАдреса.ВГраница() Цикл
			Если СтрСравнить(СокрЛП(ЧастиАдреса[Позиция]), СтранаДоИзменения) = 0 Тогда
				ПозицияНачало = СтрНайти(ВРег(ЧастиАдреса[Позиция]), ВРег(СтранаДоИзменения));
				ЧастиАдреса[Позиция] = Лев(ЧастиАдреса[Позиция], ПозицияНачало - 1) 
					+ Строка(Страна) + Сред(ЧастиАдреса[Позиция], ПозицияНачало + СтрДлина(СтранаДоИзменения));
			КонецЕсли;
		КонецЦикла;
		ПредставлениеАдреса =  СтрСоединить(ЧастиАдреса, ",");
		
		НаселенныйПунктДетально.admLevels = Новый Массив;
		НаселенныйПунктДетально.country   = СокрЛП(Страна);
		НаселенныйПунктДетально.value     = ПредставлениеАдреса;
		
	Иначе
		ОтобразитьПоляПоТипуАдреса();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура СтранаОчистка(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
КонецПроцедуры

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

&НаКлиенте
Процедура ПредставлениеИностранногоАдресаПриИзменении(Элемент)
	
	НаселенныйПунктДетально.value = ПредставлениеАдреса;
	
КонецПроцедуры

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

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

&НаСервереБезКонтекста
Функция АдресСИсторией(ЗначенияПолей)
	
	Возврат УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(ЗначенияПолей, Перечисления.ТипыКонтактнойИнформации.Адрес);
	
КонецФункции


&НаКлиенте
Процедура Адрес1ПриИзменении(Элемент)
	НаселенныйПунктДетально.street = Улица;
	ОбновитьПредставлениеАдреса();
КонецПроцедуры

&НаКлиенте
Процедура Адрес2ПриИзменении(Элемент)
	НаселенныйПунктДетально.houseNumber = ДополнительнаяИнформация;
	ОбновитьПредставлениеАдреса();
КонецПроцедуры

&НаКлиенте
Процедура ГородПриИзменении(Элемент)
	
	НаселенныйПунктДетально.city = Город;
	ОбновитьПредставлениеАдреса();

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

&НаКлиенте
Процедура РегионПриИзменении(Элемент)
	НаселенныйПунктДетально.area = Регион;
	ОбновитьПредставлениеАдреса();
КонецПроцедуры

&НаКлиенте
Процедура ИндексПриИзменении(Элемент)
	НаселенныйПунктДетально.ZIPcode = ПочтовыйИндекс;
	ОбновитьПредставлениеАдреса();
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура КомандаОтмена(Команда)
	Модифицированность = Ложь;
	Закрыть();
КонецПроцедуры

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

&НаКлиенте
Процедура СкопироватьАдресВБуферОбмена(Команда)
	УправлениеКонтактнойИнформациейКлиент.ПоместитьТекстВБуфераОбмена(ПредставлениеАдреса);
КонецПроцедуры

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

&НаКлиенте
Процедура ДобавитьКомментарий(Команда)
	Элементы.ОсновныеСтраницы.ОтображениеСтраниц = ОтображениеСтраницФормы.ЗакладкиСверху;
	Элементы.ОсновныеСтраницы.ТекущаяСтраница = Элементы.СтраницаКомментарий;
КонецПроцедуры

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

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

		КонецЦикла;
			
		НаселенныйПунктДетально.admLevels = ПорядковыйСписокПолей;
			
		НаселенныйПунктДетально.addressType = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес();
		ОтобразитьПоляАдреса(Ложь);
		ОбновитьПредставлениеАдреса();
		
	Иначе
		
		Элементы.АдресВСвободнойФорме.Пометка   = Истина;
		НаселенныйПунктДетально.addressType     = УправлениеКонтактнойИнформациейКлиентСервер.АдресВСвободнойФорме();
		РазрешитьВводАдресаВСвободнойФорме      = Истина;
		
		ОчиститьПоляНаселенногоПункта();
		Если ПустаяСтрока(НаселенныйПунктДетально.value) Тогда
			НаселенныйПунктДетально.admLevels = Новый Массив;
		КонецЕсли;
		
		ОтобразитьПоляАдреса(Истина);
		
	КонецЕсли;
	
	Улица                    = НаселенныйПунктДетально.street;
	ДополнительнаяИнформация = НаселенныйПунктДетально.houseNumber;
	Город                    = НаселенныйПунктДетально.city;
	Регион                   = НаселенныйПунктДетально.area;
	ПочтовыйИндекс           = НаселенныйПунктДетально.ZIPCode;

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


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

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

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

&НаКлиенте
Функция ПорядокПолейВАдресе(ВключатьСтрануВПредставление)

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

&НаКлиенте
Процедура ОчиститьПоляНаселенногоПункта()
	НаселенныйПунктДетально.street      = "";
	НаселенныйПунктДетально.houseNumber = "";
	НаселенныйПунктДетально.city        = "";
	НаселенныйПунктДетально.area        = "";
	НаселенныйПунктДетально.ZIPCode     = "";
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьПредставлениеАдреса()
	
	ЗаполнитьПредставлениеАдреса(НаселенныйПунктДетально, ВидКонтактнойИнформации.ВключатьСтрануВПредставление);
	ПредставлениеАдреса = НаселенныйПунктДетально.value;
		
КонецПроцедуры

&НаКлиенте
Процедура ПорядокПолейПоУмолчанию(ПорядокУровнейВАдресе, ВключатьСтрануВПредставление)
	
	Если ВключатьСтрануВПредставление Тогда
		ПорядокУровнейВАдресе.Добавить("country");
	КонецЕсли;

	ПорядокУровнейВАдресе.Добавить("zipCode");
	ПорядокУровнейВАдресе.Добавить("area");
	ПорядокУровнейВАдресе.Добавить("city");
	ПорядокУровнейВАдресе.Добавить("street");
	ПорядокУровнейВАдресе.Добавить("houseNumber");
КонецПроцедуры

&НаКлиенте
Функция ПредставлениеАдресаВСвободнойФорме(Знач Адрес, Знач ВключатьСтрануВПредставление)
	
	Если ВключатьСтрануВПредставление И Адрес.Свойство("country") И Не ПустаяСтрока(Адрес.country) Тогда
		ЧастиАдреса = СтрРазделить(Адрес.value, ",");
		Если ЗначениеЗаполнено(Адрес.value) И СтрСравнить(ЧастиАдреса[0], Адрес.country) = 0 Тогда
			ЧастиАдреса.Удалить(0);
			Адрес.Value = СтрСоединить(ЧастиАдреса, ",");
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат Адрес.Value;
	
КонецФункции

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

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

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

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

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

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

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

&НаСервереБезКонтекста
Функция СтрокаJSONВСтруктуру(Значение)
	Возврат УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(Значение, Перечисления.ТипыКонтактнойИнформации.Адрес);
КонецФункции

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

&НаКлиенте
Процедура СброситьМодифицированностьПриВыборе()
	Модифицированность = Ложь;
	КопияКомментария   = Комментарий;
КонецПроцедуры

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

	Возврат РезультатВыбора(Контекст, ВозвращатьСписокЗначений);
КонецФункции

// Параметры:
//  Контекст - Структура:
//   * ВидКонтактнойИнформации - см. УправлениеКонтактнойИнформациейСлужебный.СтруктураВидаКонтактнойИнформации
//   * НаселенныйПунктДетально - Структура
//   * ОсновнаяСтрана - СправочникСсылка.СтраныМира
//   * Страна - СправочникСсылка.СтраныМира
//  ВозвращатьСписокЗначений - Булево
//
// Возвращаемое значение:
//		см. НовыйРезультатВыбора
//
&НаСервереБезКонтекста
Функция РезультатВыбора(Контекст, ВозвращатьСписокЗначений = Ложь)

	НаселенныйПунктДетально = Контекст.НаселенныйПунктДетально;
	Представление = СокрЛП(СтрЗаменить(НаселенныйПунктДетально.Value, Символы.ПС, " "));
	
	Результат = НовыйРезультатВыбора();

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

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


&НаСервереБезКонтекста
Функция ЗаполнитьСписокКонтактнойИнформации(ВидКонтактнойИнформации, КонтактнаяИнформацияОписаниеДополнительныхРеквизитов)

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

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

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

&НаКлиенте
Процедура ОтобразитьПоляАдреса(АдресВСвободнойФорме)
	
	Элементы.ГруппаПредставлениеАдреса.Видимость = Не АдресВСвободнойФорме;
	Элементы.АдресПоПолям.Видимость              = Не АдресВСвободнойФорме;
	Элементы.ВСвободнойФорме.Видимость           = АдресВСвободнойФорме;
	Элементы.АдресВСвободнойФорме.Пометка        = АдресВСвободнойФорме;
	
КонецПроцедуры

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

	КонецЕсли;
	
	Улица         = ДанныеАдреса.street;
	ДополнительнаяИнформация         = ДанныеАдреса.houseNumber;
	Город          = ДанныеАдреса.city;
	Регион         = ДанныеАдреса.area;
	ПочтовыйИндекс = ДанныеАдреса.ZIPCode;
	
КонецПроцедуры

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

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

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

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

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

		Если Минимум = -1 Тогда
			Минимум       = Дельта + 1;
			ТекущаяСтрока = СтрокаИстория;
		КонецЕсли;
		Если Дельта > 0 И МодульЧисла(Дельта) < МодульЧисла(Минимум) Тогда
			ДействуетПо = СтрокаИстория.ДействуетС;
			Минимум     = МодульЧисла(Дельта);
		КонецЕсли;
	КонецЦикла;
	
	Результат.ДействуетПо   = ДействуетПо;
	Результат.ДействуетС    = ТекущаяСтрока.ДействуетС;
	Результат.ТекущаяСтрока = ТекущаяСтрока;
	
	Возврат Результат;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция МодульЧисла(Число)
	Возврат Макс(Число, -Число);
КонецФункции

&НаКлиенте
Процедура ОчиститьАдресКлиент()
	
	Для каждого ЭлементАдреса Из НаселенныйПунктДетально Цикл
		
		Если ЭлементАдреса.Ключ = "Type" Тогда
			Продолжить;
		Иначе
			НаселенныйПунктДетально[ЭлементАдреса.Ключ] = "";
		КонецЕсли;
		
	КонецЦикла;
	
	ОчиститьПоляАдресаНаФорме();
	
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьПоляАдресаНаФорме()
	Улица                           = "";
	ДополнительнаяИнформация        = "";
	Город                           = "";
	Регион                          = "";
	ПочтовыйИндекс                  = "";
	ПредставлениеИностранногоАдреса = "";
	ПредставлениеАдреса             = "";
КонецПроцедуры

&НаСервере
Процедура УстановитьКлючИспользованияФормы()
	КлючСохраненияПоложенияОкна = Строка(Страна);
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////////////////////////

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

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

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

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

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

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

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

// Возвращаемое значение:
//   см. УправлениеКонтактнойИнформациейСлужебный.СтруктураВидаКонтактнойИнформации
//
&НаКлиентеНаСервереБезКонтекста
Функция ОписаниеВидаКонтактнойИнформации(Форма)
	Возврат Форма.ВидКонтактнойИнформации;
КонецФункции

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

&НаКлиентеНаСервереБезКонтекста
Функция НачалоУчета()
	
	Возврат НСтр("ru = 'начало учета'");
	
КонецФункции

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

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