Skip to content

Instantly share code, notes, and snippets.

@PlugFox
Last active April 2, 2023 16:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PlugFox/9b6389fa5a2604e2bacd4f77cb1c1011 to your computer and use it in GitHub Desktop.
Save PlugFox/9b6389fa5a2604e2bacd4f77cb1c1011 to your computer and use it in GitHub Desktop.
Универсальный обмен данными JSON строкой [ПланОбмена] @PlugFox
//==============================================================================
// Планы обмена
// Отбирает изменения из узла плана обмена для последующей отправки и регистрации изменений
Функция ВыбратьИзмененныеДанные(Узел, ФильтрВыборки = Неопределено, ЭлементовВТранзакции = 0, ЭтоТест = Ложь)
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
// БЛОКИРОВКА НА ЗАПИСЬ БД +
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, Узел);
Попытка
НомерСообщения = ЗаписьСообщения.НомерСообщения;
ВыборкаДанных = ПланыОбмена.ВыбратьИзменения(Узел, НомерСообщения, ФильтрВыборки);
НаОтправку = Новый Массив;
Пока ВыборкаДанных.Следующий() Цикл
Данные = ВыборкаДанных.Получить();
ОбработатьДанные(НаОтправку, Данные);
ЭлементовВТранзакции = ЭлементовВТранзакции - 1;
Если ЭлементовВТранзакции = 0 Тогда Прервать КонецЕсли;
КонецЦикла;
ДополнитьВоВремяБлокировки(НаОтправку, ЗаписьСообщения.НомерСообщения);
Исключение
ЗаписьСообщения.ПрерватьЗапись();
ИнформацияОбОшибке = ИнформацияОбОшибке();
Если ЭтоТест Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = СтрШаблон("Ошибка во время выбора измененных данных > %1", КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
Сообщение.Сообщить();
Возврат Ложь;
КонецЕсли;
ВызватьИсключение СтрШаблон("Ошибка во время выбора измененных данных > %1", КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
КонецПопытки;
Если ЭтоТест Тогда
ЗаписьСообщения.ПрерватьЗапись();
Возврат Истина;
КонецЕсли;
ЗаписьСообщения.ЗакончитьЗапись();
// БЛОКИРОВКА НА ЗАПИСЬ БД -
ДополнитьПослеБлокировки(НаОтправку, НомерСообщения);;
Возврат НаОтправку;
КонецФункции // ВыбратьИзмененныеДанные()
//==============================================================================
// Обработка данных
// Преобразовывает Элемент из ВыборкаДанных в Массив<Структура>
// и добавляет на отправку
Процедура ОбработатьДанные(НаОтправку, Данные)
УдалениеОбъекта = ТипЗнч(Данные) = Тип("УдалениеОбъекта");
Данные = ?(УдалениеОбъекта, Данные.Ссылка, Данные);
мета = Данные.Метаданные();
Тип = мета.ПолноеИмя();
КорневойТип = Лев(Тип, СтрНайти(Тип, ".")-1);
Тип = Сред(Тип, СтрНайти(Тип, ".")+1);
Если ПустаяСтрока(КорневойТип) Тогда
ВызватьИсключение "Неизвестный корневой тип данных";
ИначеЕсли СтрНайти(КорневойТип, "Документ") Тогда
ДокументВСтруктуруJSON(НаОтправку, Данные, Тип, УдалениеОбъекта);
ИначеЕсли СтрНайти(КорневойТип, "Справочник") Тогда
СправочникВСтруктуруJSON(НаОтправку, Данные, Тип, УдалениеОбъекта);
Иначе
ВызватьИсключение "Попытка обработать неизвестный тип данных из плана обмена.";
КонецЕсли;
КонецПроцедуры // ОбработатьДанные()
// Представление элемента справочника в виде структуры, для последующей конвертации в JSON строку
Процедура СправочникВСтруктуруJSON(НаОтправку, Объект, Тип, УдалениеОбъекта)
Структура = Новый Структура;
Структура.Вставить("rootType", "Catalog");
Структура.Вставить("type", Тип);
Структура.Вставить("table", Неопределено);
Структура.Вставить("objectDeletion", УдалениеОбъекта);
Структура.Вставить("ref", ?(УдалениеОбъекта, Объект, Объект.Ссылка));
Структура.Вставить("code", Объект.Код);
Структура.Вставить("dataVersion", Объект.ВерсияДанных);
Структура.Вставить("deletionMark", Объект.ПометкаУдаления);
Структура.Вставить("description", Объект.Description);
Если Тип = "Организации" Тогда
json_ORGANIZATIONS(Структура, Объект);
НаОтправку.Добавить(Структура);
ИначеЕсли Тип = "ФизическиеЛица" Тогда
json_PERSONS(Структура, Объект);
НаОтправку.Добавить(Структура);
Иначе
ВызватьИсключение "Попытка преобразовать в структуру неизвестный тип справочника.";
КонецЕсли;
КонецПроцедуры // СправочникВСтруктуруJSON()
// Представление элемента документа в виде структуры, для последующей конвертации в JSON строку
Процедура ДокументВСтруктуруJSON(НаОтправку, Объект, Тип, УдалениеОбъекта)
Структура = Новый Структура;
Структура.Вставить("rootType", "Document");
Структура.Вставить("type", Тип);
Структура.Вставить("table", Неопределено);
Структура.Вставить("objectDeletion", УдалениеОбъекта);
Структура.Вставить("ref", ?(УдалениеОбъекта, Объект, Объект.Ссылка));
Структура.Вставить("code", Объект.Номер);
Структура.Вставить("date", Объект.Дата);
Структура.Вставить("dataVersion", Объект.ВерсияДанных);
Структура.Вставить("deletionMark", Объект.ПометкаУдаления);
Структура.Вставить("posted", Объект.Проведен);
Если СтрНайти("ПриемНаРаботу,КадровыйПеревод,Увольнение", Тип) Тогда
Структура.rootType = "Register";
Структура.table = "HR_STORY";
Структура.Вставить("lineNumber", 0);
Структура.Вставить("organization", XMLСтрока(Объект.Организация));
Структура.Вставить("organizationID", Объект.Организация.ИНН);
Структура.Вставить("contractType", ПеречислениеСтрокой(Объект.ВидДоговора));
json_HR_STORY(Структура, Объект, Тип);
НаОтправку.Добавить(Структура);
ИначеЕсли СтрНайти("ПриемНаРаботуСписком,КадровыйПереводСписком,УвольнениеСписком", Тип) Тогда
Структура.rootType = "Register";
Структура.table = "HR_STORY";
Структура.Вставить("lineNumber", 0);
Структура.Вставить("organization", XMLСтрока(Объект.Организация));
Структура.Вставить("organizationID", Объект.Организация.ИНН);
Структура.Вставить("contractType", ПеречислениеСтрокой(Объект.ВидДоговора));
Для Каждого Сотрудник Из Объект.Сотрудники Цикл
json_HR_STORY(Структура, Сотрудник, Тип);
НаОтправку.Добавить(Структура);
Структура.lineNumber = Структура.lineNumber + 1;
КонецЦикла;
Иначе
ВызватьИсключение "Попытка преобразовать в структуру неизвестный тип документа.";
КонецЕсли;
КонецПроцедуры // ДокументВСтруктуруJSON()
// Дописывает на отправку дополнительные данные (Во время блокировки на запись)
Процедура ДополнитьВоВремяБлокировки(НаОтправку, НомерСообщения = Неопределено)
// ...
КонецПроцедуры // ДополнитьВоВремяБлокировки()
// Дописывает на отправку дополнительные данные (После блокировки на запись)
Процедура ДополнитьПослеБлокировки(НаОтправку, НомерСообщения = Неопределено)
ПрефиксИБ = ПолучитьФункциональнуюОпцию("ПрефиксИнформационнойБазы");
Если ПустаяСтрока(ПрефиксИБ) Тогда
ВызватьИсключение "Префикс информационной базы не задан.";
КонецЕсли;
Для Каждого Элемент Из НаОтправку Цикл
Элемент.Вставить("msgDomain", ПрефиксИБ);
Элемент.Вставить("msgNumber", НомерСообщения);
// Сериализовать ссылки в GUID
Если Элемент.Свойство("ref") Тогда
Элемент.ref = XMLСтрока(Элемент.ref);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ДополнитьПослеБлокировки()
//==============================================================================
// Приведение объектов к структурам
Процедура json_ORGANIZATIONS(Структура, Объект)
Структура.table = "ORGANIZATIONS";
Структура.Вставить("id", Объект.ИНН);
Структура.Вставить("inn", Объект.ИНН);
Структура.Вставить("descriptionExpanded", Объект.НаименованиеПолное);
Структура.Вставить("descriptionShort", Объект.НаименованиеСокращенное);
Если ПустаяСтрока(Объект.ИНН) Тогда
ВызватьИсключение "Обмен не возможен! Не заполнен ИНН у Организации: " + Объект.Наименование;
КонецЕсли;
КонецПроцедуры // json_ORGANIZATIONS()
Процедура json_PERSONS(Структура, Объект)
Структура.table = "PERSONS";
Структура.Вставить("id", ?(ПустаяСтрока(Объект.ИНН), СтрЗаменить(ТРег(Объект.ФИО), " ", ""), Объект.ИНН));
Структура.Вставить("inn", Объект.ИНН);
Структура.Вставить("birthday", Объект.ДатаРождения);
Структура.Вставить("firstName", Объект.Имя);
Структура.Вставить("lastName", Объект.Фамилия);
Структура.Вставить("patronymic", Объект.Отчество);
Структура.Вставить("sex", XMLСтрока(Объект.Пол));
КонецПроцедуры // json_PERSONS()
Процедура json_HR_STORY(Структура, Объект, Тип)
ЭтоУвольнение = СтрНайти(Тип, "Увольнение");
Структура.Вставить("person", XMLСтрока(Объект.ФизическоеЛицо));
Структура.Вставить("personID", ?(ПустаяСтрока(Объект.ФизическоеЛицо.ИНН), СтрЗаменить(ТРег(Объект.ФизическоеЛицо.ФИО), " ", ""), Объект.ФизическоеЛицо.ИНН));
Структура.Вставить("department", ?(ЭтоУвольнение, Неопределено, Строка(Объект.Подразделение)));
Структура.Вставить("position", ?(ЭтоУвольнение, Неопределено, Строка(Объект.Должность)));
Структура.Вставить("advance", ?(ЭтоУвольнение, 0, Объект.Аванс));
Структура.Вставить("employmentType", ?(ЭтоУвольнение, Неопределено, ПеречислениеСтрокой(Объект.ВидЗанятости)));
Структура.Вставить("salary", ?(ЭтоУвольнение, 0, Объект.СовокупнаяТарифнаяСтавка));
Структура.Вставить("advanceMethod", ?(ЭтоУвольнение, Неопределено, ПеречислениеСтрокой(Объект.СпособРасчетаАванса)));
КонецПроцедуры // json_HR_STORY()
//==============================================================================
// Сериализация и десериализация
Функция ПеречислениеСтрокой(Перечисление)
Если Перечисление = Неопределено Или Перечисление.Пустая() Тогда
Возврат Неопределено;
КонецЕсли;
Возврат ОбщегоНазначения.ИмяЗначенияПеречисления(Перечисление);
КонецФункции // ПеречислениеСтрокой()
// JSON +
Функция СериализоватьJSON(Данные)
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
НастройкиСериализации = Новый НастройкиСериализацииJSON();
НастройкиСериализации.СериализовыватьМассивыКакОбъекты = Ложь;
НастройкиСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
НастройкиСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением;
ЗаписатьJSON(ЗаписьJSON, Данные, НастройкиСериализации);
Возврат ЗаписьJSON.Закрыть();
КонецФункции // СериализоватьJSON()
//******************************************************************************
Функция ДесериализоватьJSON(СтрокаJSON, ПрочитатьВСоответствие = Ложь)
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
Возврат ПрочитатьJSON(ЧтениеJSON, ПрочитатьВСоответствие);
КонецФункции // ДесериализоватьJSON()
// JSON -
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment