Загрузка данных


Функция ВыполнитьОбменДанными(ТекстОшибки) Экспорт
    Прокси = ПолучитьПрокси(ТекстОшибки);
    Если Прокси = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    
    КодЦБ = Константы.КодЦентральнойБазы.Получить();
    ЦентральныйУзелОбмена = ПланыОбмена.Мобильные.НайтиПоКоду(КодЦБ);
    
    Если ЦентральныйУзелОбмена.Пустая() Тогда
        ТекстОшибки = "Узел обмена с кодом """ + КодЦБ + """ не найден в плане обмена Мобильные";
        Возврат Ложь;
    КонецЕсли;
    
    Узел = ПланыОбмена.Мобильные.ЭтотУзел();
    
    НомерПринятого = ЦентральныйУзелОбмена.НомерПринятого;
    Если НомерПринятого = Неопределено Тогда
        НомерПринятого = 0;
    КонецЕсли;
    
    НомерОтправленного = ЦентральныйУзелОбмена.НомерОтправленного;
    Если НомерОтправленного = Неопределено Тогда
        НомерОтправленного = 0;
    КонецЕсли;
    
    // Инициализируем обмен с центральной базой.
    КодУзла = Прокси.НачатьОбмен(Узел.Код, НомерПринятого, НомерОтправленного);
    
    Если КодУзла = "" Тогда
        ТекстОшибки = "Узел с кодом " + Узел.Код + " не найден!" + ОписаниеОшибки();
        Возврат Ложь;
    КонецЕсли;
    
    // Отправляем данные.
    ДанныеОбмена = Обмен.СформироватьПакетОбмена(ЦентральныйУзелОбмена);
    
    // ✅ ПРОВЕРКА ДАННЫХ ПЕРЕД ОТПРАВКОЙ
    Если ДанныеОбмена = Неопределено Тогда
        ТекстОшибки = "Не удалось сформировать пакет обмена";
        Возврат Ложь;
    КонецЕсли;
    
    // ✅ ИСПРАВЛЕНО: Передаём ХранилищеЗначения как есть
    Попытка
        Прокси.ЗаписатьДанные(Узел.Код, ДанныеОбмена);
    Исключение
        ТекстОшибки = "Ошибка при отправке данных: " + ОписаниеОшибки();
        Возврат Ложь;
    КонецПопытки;
    
    // Принимаем данные.
    Попытка
        ДанныеОбмена = Прокси.ПолучитьДанные(Узел.Код);
        
        // ✅ ПРОВЕРКА ПОЛУЧЕННЫХ ДАННЫХ
        Если ДанныеОбмена = Неопределено ИЛИ ПустаяСтрока(ДанныеОбмена) Тогда
            // Нет данных для приёма - это нормальная ситуация
            Возврат Истина;
        КонецЕсли;
        
        // ✅ ИСПРАВЛЕНО: Проверяем тип полученных данных
        Если ТипЗнч(ДанныеОбмена) = Тип("Строка") Тогда
            // Если пришла строка - преобразуем в ХранилищеЗначения
            ДанныеОбмена = Новый ХранилищеЗначения(ДанныеОбмена, Новый СжатиеДанных(9));
        КонецЕсли;
        
        Обмен.ПринятьПакетОбмена(ЦентральныйУзелОбмена, ДанныеОбмена);
    Исключение
        ТекстОшибки = "Ошибка при получении данных: " + ОписаниеОшибки();
        Возврат Ложь;
    КонецПопытки;
    
    Возврат Истина;
КонецФункции

Функция ПолучитьПрокси(ТекстОшибки) Экспорт
    ТекстОшибки = "";
    Адрес = Константы.АдресЦентральнойБазы.Получить();
    
    Если ПустаяСтрока(Адрес) Тогда
        ТекстОшибки = "Не заполнен адрес центральной базы в настройках";
        Возврат Неопределено;
    КонецЕсли;
    Адрес = СокрП(Адрес);
    Если Прав(Адрес, 1) <> "/" Тогда
        Адрес = Адрес + "/";
    КонецЕсли;
    Адрес = Адрес +"/ws/wsExchange.1cws?wsdl";
    Попытка
        Определения = Новый WSОпределения(Адрес,,, 60);
    Исключение
        ТекстОшибки = "Не удалось установить соединение с сервером" + Символы.ПС
        + "Проверьте адрес и доступность сервера." + Символы.ПС + "Ошибка" + ОписаниеОшибки();
        Возврат Неопределено;
    КонецПопытки;
    URI = URIПространстваИменСервиса();
    Прокси = Новый WSПрокси(Определения, URI, "MAExchange", "MAExchangeSoap");
    Возврат Прокси;
КонецФункции

Функция URIПространстваИменСервиса()
    Возврат "http://localhost/wsExchange";
КонецФункции

Процедура ЗаписатьДанные(ЗаписьXML, Данные) Экспорт 
    Если ТипЗнч(Данные) = Тип("СправочникОбъект.Товары") Тогда 
        ЗаписатьXMLТовары(ЗаписьXML, Данные);
    ИначеЕсли ТипЗнч(Данные) = Тип("СправочникОбъект.Склады") Тогда 
        ЗаписатьXMLСклады(ЗаписьXML, Данные); 
    Иначе 
        ЗаписатьXML(ЗаписьXML, Данные); 
    КонецЕсли 
КонецПроцедуры

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

Процедура ЗаписатьXMLТовары(ЗаписьXML, Товар) Экспорт 
    ЗаписьXML.ЗаписатьНачалоЭлемента("CatalogObject.Товары.Вручную"); 
    ЗаписатьXML(ЗаписьXML, Товар.Ссылка, "Ref", НазначениеТипаXML.Явное); 
    ЗаписатьXML(ЗаписьXML, Товар.ЭтоГруппа, "IsFolder", НазначениеТипаXML.Явное); 
    ЗаписатьXML(ЗаписьXML, Товар.Родитель, "Parent", НазначениеТипаXML.Явное); 
    ЗаписатьXML(ЗаписьXML, Товар.Наименование, "Description", НазначениеТипаXML.Явное); 
    Если Не Товар.ЭтоГруппа Тогда 
        ЗаписатьXML(ЗаписьXML, Товар.Описание, "Описание", НазначениеТипаXML.Явное); 
    КонецЕсли; 
    ЗаписьXML.ЗаписатьКонецЭлемента(); 
КонецПроцедуры

Процедура ЗаписатьXMLСклады(ЗаписьXML, Склад) Экспорт
    ЗаписьXML.ЗаписатьНачалоЭлемента("CatalogObject.Склады.Вручную");
    ЗаписатьXML(ЗаписьXML, Склад.Ссылка, "Ref", НазначениеТипаXML.Явное);
    ЗаписатьXML(ЗаписьXML, Склад.Наименование, "Description", НазначениеТипаXML.Явное);
    ЗаписьXML.ЗаписатьКонецЭлемента();
КонецПроцедуры

Функция СформироватьПакетОбмена(УзелОбмена) Экспорт
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку("UTF-8");
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
    ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелОбмена);
    ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("v8", "http://v8.1c.ru/data");
    ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(УзелОбмена,
    ЗаписьСообщения.НомерСообщения);
    Пока ВыборкаИзменений.Следующий() Цикл
        Данные = ВыборкаИзменений.Получить();
        ЗаписатьДанные(ЗаписьXML, Данные);
    КонецЦикла;
    ЗаписьСообщения.ЗакончитьЗапись();
    Возврат Новый ХранилищеЗначения(ЗаписьXML.Закрыть(), Новый СжатиеДанных(9));
КонецФункции

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

Функция ВозможностьЧтенияДанных(ЧтениеXML) Экспорт
    ТипXML = ПолучитьXMLТип(ЧтениеXML);
    Если ТипXML = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    Если (ТипXML.ИмяТипа = "CatalogObject.Товары.Вручную" ИЛИ 
        ТипXML.ИмяТипа = "CatalogObject.Склады.Вручную") И ТипXML.URIПространстваИмен = "" Тогда
        Возврат Истина;
    КонецЕсли;
    Возврат ВозможностьЧтенияXML(ЧтениеXML);
КонецФункции

Функция ПрочитатьДанные(ЧтениеXML) Экспорт
    ТипXML = ПолучитьXMLТип(ЧтениеXML);
    Если ТипXML = Неопределено Тогда
        Возврат Неопределено;
    КонецЕсли;
    Если ТипXML.ИмяТипа = "CatalogObject.Склады.Вручную" И ТипXML.URIПространстваИмен = "" Тогда
        Возврат ПрочитатьXMLСклады(ЧтениеXML);
    КонецЕсли;
    Если ТипXML.ИмяТипа = "CatalogObject.Товары.Вручную" И ТипXML.URIПространстваИмен = "" Тогда
        Возврат ПрочитатьXMLТовары(ЧтениеXML);
    КонецЕсли;
    Возврат ПрочитатьXML(ЧтениеXML);
КонецФункции

Функция ПрочитатьXMLТовары(ЧтениеXML) Экспорт
    Если ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
        ВызватьИсключение "Ошибка чтения XML";
    КонецЕсли;
    ЧтениеXML.Прочитать();
    ТоварСсылка = ПрочитатьXML(ЧтениеXML);
    Если ТипЗнч(ТоварСсылка) <> Тип("СправочникСсылка.Товары") Тогда
        ВызватьИсключение "Ошибка чтения XML";
    КонецЕсли;
    Товар = ТоварСсылка.ПолучитьОбъект();
    ЭтоГруппа = ПрочитатьXML(ЧтениеXML);
    Если Товар <> Неопределено Тогда
        Если Товар.ЭтоГруппа <> ЭтоГруппа Тогда
            ВызватьИсключение "Некорректные данные";
        КонецЕсли;
    Иначе
        Если ЭтоГруппа = Истина Тогда
            Товар = Справочники.Товары.СоздатьГруппу();
        Иначе
            Товар = Справочники.Товары.СоздатьЭлемент();
        КонецЕсли;
        Товар.УстановитьСсылкуНового(ТоварСсылка);
    КонецЕсли;
    Товар.Родитель = ПрочитатьXML(ЧтениеXML);
    Товар.Наименование = ПрочитатьXML(ЧтениеXML);
    Если Не Товар.ЭтоГруппа Тогда
        Товар.Описание = ПрочитатьXML(ЧтениеXML);
        Товар.ФайлКартинки = ПрочитатьXML(ЧтениеXML);
    КонецЕсли;
    Если ЧтениеXML.ТипУзла <> ТипУзлаXML.КонецЭлемента Тогда
        ВызватьИсключение "Ошибка чтения XML";
    КонецЕсли;
    ЧтениеXML.Прочитать();
    Возврат Товар;
КонецФункции

Функция ПрочитатьXMLСклады(ЧтениеXML) Экспорт
    Если ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
        ВызватьИсключение "Ошибка чтения XML";
    КонецЕсли;
    ЧтениеXML.Прочитать();
    СкладСсылка = ПрочитатьXML(ЧтениеXML);
    Если ТипЗнч(СкладСсылка) <> Тип("СправочникСсылка.Склады") Тогда
        ВызватьИсключение "Ошибка чтения XML";
    КонецЕсли;
    Склад = СкладСсылка.ПолучитьОбъект();
    Если Склад = Неопределено Тогда
        Склад = Справочники.Склады.СоздатьЭлемент();
        Склад.УстановитьСсылкуНового(СкладСсылка);
    КонецЕсли;
    Склад.Наименование = ПрочитатьXML(ЧтениеXML);
    Если ЧтениеXML.ТипУзла <> ТипУзлаXML.КонецЭлемента Тогда
        ВызватьИсключение "Ошибка чтения XML";
    КонецЕсли;
    ЧтениеXML.Прочитать();
    Возврат Склад;
КонецФункции

Функция ПринятьИзменения(Отправитель, Данные) Экспорт
    Прием = Истина;
    Если ПланыОбмена.ИзменениеЗарегистрировано(Отправитель, Данные) Тогда
        Если ТипЗнч(Данные) = Тип("ДокументОбъект.Заказ") Тогда
            Прием = Ложь;
        КонецЕсли;
    КонецЕсли;
    Возврат Прием;
КонецФункции