СтруктураОбъектаXDTOВДанныеИБ (БСП)

Автор: 1С
ОбщийМодуль.ОбменДаннымиXDTOСервер
БСП

Структура объекта xdto данные. Возвращает объект информационной базы, соответствующий полученным данным.

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

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

Рекомендации

Похожие публикации

ОбъектXDTOВСтруктуру (БСП)

Преобразование объекта в структуру

СкопироватьСтруктуру (БСП)

РазборПредставленияОбъектаXML (БСП)

ОбъектXDTOИзДанныхXDTO (БСП)

Заменить ссылки на навигационные

Реквизиты Объекта в Структуру

ФайлОбъект (БСП)

СтруктураОграниченияИзОписания (БСП)

Обновлятор-1С: групповое (пакетное) обновление и обслуживание всех баз за один раз