Подключение к Web-сервису ECOD для обмена документами в формате EDI (провайдер Корус)

06.06.13

Интеграция - WEB-интеграция

Подробное описание подключения из 1С 8.2 к Web-сервису ECOD для одностороннего обмена электронными документами в формате EDI (провайдер Корус).

Скачать файлы

Наименование Файл Версия Размер
ПодключениеКWebСервисуКорус.epf
.epf 14,63Kb
78
.epf 14,63Kb 78 Скачать

Была поставлена задача – принимать заказы от крупной сети в электронном виде. Сеть работает следующим образом – рассылает всем заказы (ORDERS) через провайдера Корус в формате EDI, а подтверждений обратно не принимает. Соответственно, обмен идет только в одну сторону. Ну, ещё желательно было сэкономить на модуле сопряжения, который Корус предлагает купить, и коннектиться к ним непосредственно из 1С.

После заполнения всех необходимых бумаг и получения GLN своей организации, наконец–то мне выдали описание формата обмена и способа подключения к Web–сервису.

Уже в процессе работы созрели 2 варианта технической реализации обмена – тот, который рекомендует Корус (по протоколу SOAP) и который позволяет платформа 8.2 (через XDTO). Опишу ОБА способа реализации.

Первый способ (рекомендованный Корусом).

Для обмена через протокол SOAP, необходимо установить Soap Toolkit 3 с сайта Майкрософт. Он может там быть доступен для скачивания в разобранном виде (файлы с расширением .msm), тогда лучше поискать дистрибутив в виде инсталлятора. Также желательно установить финишное обновление SOAPDSK3.0–KB827257–x86.exe, которое лежит на том же Майкрософте, но уже в виде инсталлятора. Для 64-битных систем всё должно тоже штатно установиться. Протокол слегка устаревший, но Корус пока другого не предлагает….

Следующий шаг – добавление сертификатов в файл Cacert.pem из каталога bin программы. На всякий случай, добавил и корневые сертификаты, выданные Thawte, и сертификаты сайта, на котором живёт Web–сервис. Способ добавления сертификатов подробно описан в литературе, не буду на нём заострять внимание.

Пример реально работающего кода:

// Необходимо установить Soap Toolkit 3 и обновление к нему
// В папку bin программы 1С 8.2 добавить отредактированный файл cacert.pem с сертификатами Web-сервиса
//
Процедура ПолучитьЗаказыПокупателяMSSOAP(ДатаНачала, ДатаКонца, Login="Ваш логин", Password="Ваш пароль", Partner_ID="GLN Партнера") Экспорт

   
ИмяСервиса = "https://www.ecod.pl/webserv2/EDIservice.asmx?WSDL";

    Попытка
       
oSOAPClient = Новый COMОбъект("MSSOAP.SoapClient30");
    Исключение
       
#Если Клиент Тогда
       
Сообщить(ОписаниеОшибки());
       
#КонецЕсли
       
Возврат;
    КонецПопытки;

    Попытка
       
Инициализация = oSOAPClient.mssoapinit(ИмяСервиса, "", "", "");
    Исключение
       
#Если Клиент Тогда
       
Сообщить(ОписаниеОшибки());
       
#КонецЕсли
       
Возврат;
    КонецПопытки;

    Попытка
       
Подключение = oSOAPClient.Relationships(Login, Password, "5000");
       
СтрокаХML = Подключение.item(1).text;
       
КодОшибкиПодключения = Подключение.item(0).text;
    Исключение
       
#Если Клиент Тогда
       
Сообщить(ОписаниеОшибки());
       
#КонецЕсли
       
Возврат;
    КонецПопытки;

    Если
КодОшибкиПодключения <> "00000000" Тогда
       
#Если Клиент Тогда
       
Сообщить("Код ошибки подключения = " + КодОшибкиПодключения);
       
#КонецЕсли
       
Возврат;
    КонецЕсли;

   
ДатаНачалаECOD = ПривестиДатуКВидуECOD(ДатаНачала);
   
ДатаКонцаECOD = ПривестиДатуКВидуECOD(ДатаКонца);

   
// Возвращает массив tracking-id документов, доставленных пользователю ECOD
   
Попытка
       
Доставка = oSOAPClient.ListMBEx(Login, Password, Partner_ID, "ORDER", "RU1", "XML", "P",
                       
ДатаНачалаECOD, ДатаКонцаECOD, "", "", "N", "5000");
       
СтрокаДоставки = Доставка.item(1).text;
       
КодОшибкиДоставки = Доставка.item(0).text;
    Исключение
       
#Если Клиент Тогда
       
Сообщить(ОписаниеОшибки());
       
#КонецЕсли
       
Возврат;
    КонецПопытки;

    Если
КодОшибкиДоставки <> "00000000" Тогда
       
#Если Клиент Тогда
       
Сообщить("Код ошибки идентификации документов = " + КодОшибкиДоставки);
       
#КонецЕсли
       
Возврат;
    КонецЕсли;

   
// Теперь соберём массив идентификаторов документов tracking-id
   
МассивИдентификаторов = ПолучитьМассивИдентификаторовДокументовECOD(СтрокаДоставки);

   
// Теперь для каждого идентификатора получим документ
   
Для Каждого Элемент Из МассивИдентификаторов Цикл
        Попытка
           
Документ = oSOAPClient.Receive(Login, Password, Partner_ID, "ORDER", Элемент, "XML", "R", "5000");
           
СтрокаДокументаXML = Документ.item(1).text;
           
КодОшибкиДокументаXML = Документ.item(0).text;
            Если
КодОшибкиДокументаXML <> "00000000" Тогда
               
#Если Клиент Тогда
               
Сообщить("Код ошибки доставки документа " + Элемент + " = " + КодОшибкиДокументаXML);
               
#КонецЕсли
               
Продолжить;
            КонецЕсли;
           
СформироватьЗаказПокупателяECODИзСтрокиXML(СтрокаДокументаXML);
        Исключение
           
#Если Клиент Тогда
           
Сообщить(ОписаниеОшибки());
           
#КонецЕсли
           
Продолжить;
        КонецПопытки;
    КонецЦикла;

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

Второй способ (использование возможностей платформы 8.2).

Известно, что 1С 8.2 тоже умеет работать с неродственными ей объектами, для этого нужно использовать объект Фабрика XDTO. В тексте процедуры показан динамический способ создания описания объектов Web–сервиса, подключения к нему и управления входящими документами.

Добавление сертификатов также обязательно и в этом случае.

 

Полный текст кода:

 

Процедура ПолучитьЗаказыПокупателяXDTO(ДатаНачала, ДатаКонца, Login="Ваш логин", Password="Ваш пароль", Partner_ID="GLN Партнера") Экспорт

   
Определение = Новый WSОпределения("https://www.ecod.pl/webserv2/EDIservice.asmx?WSDL");
   
Прокси = Новый WSПрокси(Определение, "http://www.comarch.com/", "EDIWebService", "EDIWebServiceSoap12");

   
Фабрика = Прокси.ФабрикаXDTO;

   
Запрос = Фабрика.Создать(Фабрика.Тип("http://www.comarch.com/", "Relationships"));
   
Запрос.Name = Login;
   
Запрос.Password = Password;
   
Запрос.Timeout = "5000";

   
РезультатRelationships = Прокси.Relationships(Запрос.Name, Запрос.Password, Запрос.Timeout);
   
// Возвращает документ XML, если операция выполнена успешно

   
КодОшибкиПодключения = РезультатRelationships.Res;
    Если
КодОшибкиПодключения <> "00000000" Тогда
       
#Если Клиент Тогда
       
Сообщить("Код ошибки подключения = " + КодОшибкиПодключения);
       
#КонецЕсли
       
Возврат;
    КонецЕсли;

   
Запрос = Фабрика.Создать(Фабрика.Тип("http://www.comarch.com/", "ListMBEx"));
   
Запрос.Name = Login;
   
Запрос.Password = Password;
   
Запрос.PartnerIln = Partner_ID;
   
Запрос.DocumentType = "ORDER";
   
Запрос.DocumentVersion = "RU1";
   
Запрос.DocumentStandard = "XML";
   
Запрос.DocumentTest = "P";
   
Запрос.DateFrom = ПривестиДатуКВидуECOD(ДатаНачала);
   
Запрос.DateTo = ПривестиДатуКВидуECOD(ДатаКонца);
   
Запрос.ItemFrom = "";
   
Запрос.ItemTo = "";
   
Запрос.DocumentStatus = "N";   // Читаем только новые документы
   
Запрос.Timeout = "5000";

   
РезультатListMBEx = Прокси.ListMBEx(Запрос.Name, Запрос.Password, Запрос.PartnerIln, Запрос.DocumentType, Запрос.DocumentVersion,
               
Запрос.DocumentStandard, Запрос.DocumentTest, Запрос.DateFrom, Запрос.DateTo, Запрос.ItemFrom, Запрос.ItemTo,
               
Запрос.DocumentStatus, Запрос.Timeout);

   
КодОшибкиДоставки = РезультатListMBEx.Res;
    Если
КодОшибкиДоставки <> "00000000" Тогда
       
#Если Клиент Тогда
       
Сообщить("Код ошибки идентификации документов = " + КодОшибкиДоставки);
       
#КонецЕсли
       
Возврат;
    КонецЕсли;

   
СтрокаДоставки = РезультатListMBEx.Cnt;
   
// Теперь соберём массив идентификаторов документов tracking-id
   
МассивИдентификаторов = ПолучитьМассивИдентификаторовДокументовECOD(СтрокаДоставки);

   
// Разберем полученные идентификаторы документов
   
Для Каждого Элемент Из МассивИдентификаторов Цикл
       
// А теперь получим файлы заказов из системы
       
Запрос = Фабрика.Создать(Фабрика.Тип("http://www.comarch.com/", "Receive"));
       
Запрос.Name = Login;
       
Запрос.Password = Password;
       
Запрос.PartnerIln = Partner_ID;
       
Запрос.DocumentType = "ORDER";
       
Запрос.TrackingId = Элемент;
       
Запрос.DocumentStandard = "XML";
       
Запрос.ChangeDocumentStatus = "R";   // Меняем статус на прочтённый
       
Запрос.Timeout = "5000";

       
РезультатReceive = Прокси.Receive(Запрос.Name, Запрос.Password, Запрос.PartnerIln, Запрос.DocumentType,
                   
Запрос.TrackingId, Запрос.DocumentStandard, , Запрос.Timeout);

       
КодОшибкиДокументаXML = РезультатReceive.Res;
       
СтрокаДокументаXML = РезультатReceive.Cnt;
        Если
КодОшибкиДокументаXML <> "00000000" Тогда
           
#Если Клиент Тогда
           
Сообщить("Код ошибки доставки документа " + Элемент + " = " + КодОшибкиДокументаXML);
           
#КонецЕсли
           
Продолжить;
        КонецЕсли;
       
СформироватьЗаказПокупателяECODИзСтрокиXML(СтрокаДокументаXML);

       
Запрос = Фабрика.Создать(Фабрика.Тип("http://www.comarch.com/", "ChangeDocumentStatus"));
       
Запрос.Name = Login;
       
Запрос.Password = Password;
       
Запрос.TrackingId = Элемент;
       
Запрос.Status = "R";   // Меняем статус на прочтённый

       
РезультатStatus = Прокси.ChangeDocumentStatus(Запрос.Name, Запрос.Password, Запрос.TrackingId, Запрос.Status);
       
КодОшибкиStatus = РезультатStatus.Res;
        Если
КодОшибкиStatus <> "00000000" Тогда
           
#Если Клиент Тогда
           
Сообщить("Код ошибки изменения статуса документа " + Элемент + " = " + КодОшибкиStatus);
           
#КонецЕсли
       
КонецЕсли;
    КонецЦикла;

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

Результат работы обеих процедур абсолютно одинаков - возвращаются документы ORDERS из Web-сервиса. Теперь задача существенно упрощается - необходимо правильно распарсить входной документ в формате XML и создать документы Заказ Покупателя. Для облегчения вашего читательского труда привожу код сервисных процедур чтения строки XML и парсинга. Ну а создать нужный документ в собственной базе из полученной структуры не составит особого труда.

 

// Читает полученную строку XML в формате ECOD (из Web-сервиса)
Процедура СформироватьЗаказПокупателяECODИзСтрокиXML(СтрокаXML, СсылкаНаОбъект = Неопределено) Экспорт

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

   
ДеревоЗначений.Колонки.Добавить("Элемент");
   
ДеревоЗначений.Колонки.Добавить("Текст");
   
Корень         = ДеревоЗначений.Строки.Добавить();
   
Корень.Элемент = Чтение.Имя;
   
Рекурсия(Корень, Чтение);
   
Дерево = ДеревоЗначений;

   
Чтение.Закрыть();

   
СтруктураДокумента = ПолучитьСтруктуруДокумента_ORDER_ECOD(Дерево);
    Если
ТипЗнч(СтруктураДокумента) = Тип("Структура") Тогда
       
ЗаказСсылка = ЗагрузитьСтруктуруВДокументЗаказ(СтруктураДокумента, СсылкаНаОбъект);
        Если
ЗаказСсылка <> Неопределено Тогда
           
СделатьЗаписьВСправочникеЗаказыПокупателяEDI(СтруктураДокумента, ЗаказСсылка);
        КонецЕсли;
    КонецЕсли;

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

Процедура
Рекурсия(СтрокаДерева, Чтение)

   
АтрибутыСоответствие = Новый Соответствие();
    Пока
Чтение.ПрочитатьАтрибут() Цикл
       
АтрибутыСоответствие.Вставить(Чтение.Имя, Чтение.Значение);
    КонецЦикла;
    Если
АтрибутыСоответствие.Количество() > 0 Тогда
       
СтрокаДерева.Атрибуты = АтрибутыСоответствие;
    Иначе
       
АтрибутыСоответствие = 0;
    КонецЕсли;
    Пока
Чтение.Прочитать() Цикл
        Если
Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
            Прервать;
        ИначеЕсли
Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
           
СтрокаДерева.Текст = Чтение.Значение;
        ИначеЕсли
Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
           
Дочерний         = СтрокаДерева.Строки.Добавить();
           
Дочерний.Элемент = Чтение.Имя;
           
Рекурсия(Дочерний, Чтение);
        КонецЕсли;
    КонецЦикла;

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

// Получить структуру Заказа Покупателя
Функция ПолучитьСтруктуруДокумента_ORDER_ECOD(Дерево)

   
СтруктураДокумента = Новый Структура;

   
Узел = ПолучитьУзелДерева(Дерево.Строки, "Строка", "Document-Order");
    Если НЕ
Узел = Неопределено Тогда
       
СтрокаКорня = Узел.Строки;
    Иначе
       
#Если Клиент Тогда
       
Сообщить("Файл не является Заказом покупателя!", СтатусСообщения.Важное);
       
#КонецЕсли
       
Возврат Ложь;
    КонецЕсли;

   
// I. Order-Header (из корня)

   
Узел = ПолучитьУзелДерева(СтрокаКорня, "Строка", "Order-Header");
    Если НЕ
Узел = Неопределено Тогда
       
СтрокаДерева = Узел.Строки;
    Иначе
       
#Если Клиент Тогда
       
Сообщить("Не найдена шапка документа!", СтатусСообщения.Важное);
       
#КонецЕсли
       
Возврат Ложь;
    КонецЕсли;

   
// Номер документа
   
xmlНомерДокумента = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "OrderNumber", Истина);
    Если НЕ
xmlНомерДокумента = Неопределено Тогда
       
СтруктураДокумента.Вставить("НомерДокумента", СокрЛП(xmlНомерДокумента));
    Иначе
        Возврат Ложь;
    КонецЕсли;

   
//  Дата Документа
   
xmlДатаДокумента = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "OrderDate", Истина);
    Если НЕ
xmlДатаДокумента = Неопределено Тогда
       
СтруктураДокумента.Вставить("ДатаДокумента", Дата(Прав(СокрЛП(xmlДатаДокумента),2)+"."+Сред(СокрЛП(xmlДатаДокумента),6,2)+"."+Лев(СокрЛП(xmlДатаДокумента),4)+" 0:00:00"));
    Иначе
        Возврат Ложь;
    КонецЕсли;

   
// Дата Поставки(обязательное поле)
   
xmlДатаПоставки = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "ExpectedDeliveryDate", Истина);
    Если НЕ
xmlДатапоставки = Неопределено Тогда
       
ДатаПоставки = Дата(Прав(СокрЛП(xmlДатаПоставки),2)+"."+Сред(СокрЛП(xmlДатаПоставки),6,2)+"."+Лев(СокрЛП(xmlДатаПоставки),4)+" 0:00:00");
       
СтруктураДокумента.Вставить("ДатаПоставки", ДатаПоставки);
    Иначе
        Возврат Ложь;
    КонецЕсли;

   
// Время Поставки(опциональное поле)
   
xmlВремяПоставки = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "ExpectedDeliveryTime", Ложь);
    Если НЕ
xmlВремяПоставки = Неопределено Тогда
       
СтруктураДокумента.Вставить("ВремяПоставки", xmlВремяПоставки);
    Иначе
       
СтруктураДокумента.Вставить("ВремяПоставки", "00:00");
    КонецЕсли;

   
// Валюта(UAH,RUB,USD,EUR,MDL,BYR)(опциональное поле)
   
xmlВалюта = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "Currency", Ложь);
    Если НЕ
xmlВалюта = Неопределено Тогда
       
СтруктураДокумента.Вставить("Валюта", ПолучитьВалюту(xmlВалюта));
    КонецЕсли;


   
// Обозначение Документа(опциональное поле)
   
xmlОбозначениеДокумента = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "DocumentFunctionCode", Ложь);
    Если НЕ
xmlОбозначениеДокумента = Неопределено Тогда
       
СтруктураДокумента.Вставить("ОбозначениеДокумента", СокрЛП(xmlОбозначениеДокумента));
    КонецЕсли;


   
// Свободный текст(опциональное поле)
   
xmlСвободныйТекст = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "Remarks", Ложь);
    Если НЕ
xmlСвободныйТекст = Неопределено Тогда
       
СтруктураДокумента.Вставить("СвободныйТекст", СокрЛП(xmlСвободныйТекст));
    КонецЕсли;

   
// II. Order-Summary (из корня)
   
Узел = ПолучитьУзелДерева(СтрокаКорня, "Строка", "Order-Summary");
    Если НЕ
Узел = Неопределено Тогда
       
СтрокаДерева = Узел.Строки;
    Иначе
       
#Если Клиент Тогда
       
Сообщить("Не найдены реквизиты табличной части!", СтатусСообщения.Важное);
       
#КонецЕсли
       
Возврат Ложь;
    КонецЕсли;

   
// Количество Строк(опциональное поле)
   
xmlКоличествоСтрок = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "TotalLines", Ложь);
    Если НЕ
xmlКоличествоСтрок = Неопределено Тогда
       
СтруктураДокумента.Вставить("КоличествоСтрок", СокрЛП(xmlКоличествоСтрок));
    КонецЕсли;

   
// Общая Сумма(опциональное поле)
   
xmlОбщаяСумма = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "TotalOrderedAmount", Ложь);
    Если НЕ
xmlОбщаяСумма = Неопределено Тогда
       
СтруктураДокумента.Вставить("ОбщаяСумма", СокрЛП(xmlОбщаяСумма));
    КонецЕсли;

   
// III. Order-Parties (из корня)
   
Узел = ПолучитьУзелДерева(СтрокаКорня, "Строка", "Order-Parties");
    Если НЕ
Узел = Неопределено Тогда
       
СтрокаУровня = Узел.Строки;
    Иначе
       
#Если Клиент Тогда
       
Сообщить("Не найдены реквизиты покупателя!", СтатусСообщения.Важное);
       
#КонецЕсли
       
Возврат Ложь;
    КонецЕсли;

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

   
// Поставщик(Организация)(обязательное поле)
   
xmlПоставщикGLN = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "ILN", Истина);
    Если НЕ
xmlПоставщикGLN = Неопределено Тогда
       
СтруктураДокумента.Вставить("ПоставщикGLN", СокрЛП(xmlПоставщикGLN));
    КонецЕсли;

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

   
// Покупатель(контрагент)(обязательное поле)
   
xmlКонтрагентGLN = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "ILN", Истина);
    Если НЕ
xmlКонтрагентGLN = Неопределено Тогда
       
СтруктураДокумента.Вставить("КонтрагентGLN", СокрЛП(xmlКонтрагентGLN));
    КонецЕсли;

   
xmlКонтрагентКод = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "CodeByBuyer", Истина);
    Если НЕ
xmlКонтрагентКод = Неопределено Тогда
       
СтруктураДокумента.Вставить("КонтрагентКод", СокрЛП(xmlКонтрагентКод));
    КонецЕсли;

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

   
// Точка доставки (ДоговорКонтрагента)(опциональное поле)
   
xmlТочкаДоставкиGLN = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "ILN", Ложь);
    Если НЕ
xmlТочкаДоставкиGLN = Неопределено Тогда
       
СтруктураДокумента.Вставить("ТочкаДоставкиGLN", СокрЛП(xmlТочкаДоставкиGLN));
    КонецЕсли;

   
// IV. Табличная часть
    // Order-Lines (из корня)
   
Узел = ПолучитьУзелДерева(СтрокаКорня, "Строка", "Order-Lines");
    Если НЕ
Узел = Неопределено Тогда
       
СтрокаУровня = Узел.Строки;
    Иначе
       
#Если Клиент Тогда
       
Сообщить("Не найдена табличная часть!", СтатусСообщения.Важное);
       
#КонецЕсли
       
Возврат Ложь;
    КонецЕсли;

   
// Создаем таблицуЗначений, в которую выгружаем табличную часть документа
   
ДокументТЧ = Новый ТаблицаЗначений;
   
ДокументТЧ.Колонки.Добавить("НомерСтрокиТЧ");
   
ДокументТЧ.Колонки.Добавить("ШтрихКод");
   
ДокументТЧ.Колонки.Добавить("КодПокупателя");
   
ДокументТЧ.Колонки.Добавить("НоменклатураНаименование");
   
ДокументТЧ.Колонки.Добавить("Количество");
   
ДокументТЧ.Колонки.Добавить("Цена");
   
ДокументТЧ.Колонки.Добавить("Сумма");
   
ДокументТЧ.Колонки.Добавить("Коэффициент");

   
ТабличнаяЧасть = ПолучитьУзелДерева(СтрокаУровня, "Массив", "Line");

    Для Каждого
Узел ИЗ ТабличнаяЧасть Цикл

        Если НЕ
Узел = Неопределено Тогда
           
СтрокаДерева = Узел.Строки;
        Иначе
           
#Если Клиент Тогда
           
Сообщить("Не найдены строки табличной части!", СтатусСообщения.Важное);
           
#КонецЕсли
           
Возврат Ложь;
        КонецЕсли;

       
Узел = ПолучитьУзелДерева(СтрокаДерева, "Строка", "Line-Item");

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

       
НоваяСтрокаТЧ = ДокументТЧ.Добавить();

       
//Номер строки (этот параметр при создании заказа не используется, может быть проверочным)
       
xmlНомерСтрокиТЧ = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "LineNumber", Истина);
        Если НЕ
xmlНомерСтрокиТЧ = Неопределено Тогда
           
НоваяСтрокаТЧ.НомерСтрокиТЧ = xmlНомерСтрокиТЧ;
        КонецЕсли;

       
// Определяем атрибуты номенклатуры:
        // Штрих - код номенклатуры
       
xmlШтрихКодНоменклатуры = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "EAN", Истина);
        Если НЕ
xmlШтрихКодНоменклатуры = Неопределено Тогда
           
НоваяСтрокаТЧ.ШтрихКод = СокрЛП(xmlШтрихКодНоменклатуры);
        КонецЕсли;

       
// Код поставщика(поле поиска)
       
xmlКодПокупателя = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "BuyerItemCode", Ложь);
        Если НЕ
xmlКодПокупателя = Неопределено Тогда
           
НоваяСтрокаТЧ.КодПокупателя = СокрЛП(xmlКодПокупателя);
        КонецЕсли;

       
// Наименование номенклатуры(опциональное поле)
       
xmlНоменклатураНаименование = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "ItemDescription", Ложь);
        Если НЕ
xmlНоменклатураНаименование = Неопределено Тогда
           
НоваяСтрокаТЧ.НоменклатураНаименование = СокрЛП(xmlНоменклатураНаименование);
        КонецЕсли;

       
xmlКоличество = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "OrderedQuantity", Истина);
        Если НЕ
xmlКоличество = Неопределено Тогда
            Попытка
               
НоваяСтрокаТЧ.Количество = Число(xmlКоличество);
            Исключение
               
#Если Клиент Тогда
               
Сообщить("Не определил количество!", СтатусСообщения.Важное);
               
#КонецЕсли
               
НоваяСтрокаТЧ.Количество = 0;
            КонецПопытки;
        КонецЕсли;

       
// Единицы измерения количества(опциональное поле)
       
xmlЦена = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "OrderedUnitGrossPrice", Ложь);
        Если НЕ
xmlЦена = Неопределено Тогда
           
НоваяСтрокаТЧ.Цена = Число(xmlЦена);
        КонецЕсли;

       
// Сумма
       
xmlСумма = ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, "GrossAmount", Ложь);
        Если НЕ
xmlЦена = Неопределено Тогда
           
НоваяСтрокаТЧ.Сумма = Число(xmlСумма);
        КонецЕсли;

       
НоваяСтрокаТЧ.Коэффициент = 1;

    КонецЦикла;

   
СтруктураДокумента.Вставить("ДокументТЧ", ДокументТЧ);

    Возврат
СтруктураДокумента;

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

Функция
ПолучитьУзелДерева(СтрокаДерева, ТипУзла, ИмяПоля)

    Если
ТипУзла = "Строка" Тогда
       
xmlУзел = СтрокаДерева.Найти(ИмяПоля, "Элемент", Ложь);
    ИначеЕсли
ТипУзла = "Массив" Тогда
       
xmlУзел = СтрокаДерева.НайтиСтроки(Новый Структура("Элемент", ИмяПоля), Ложь);
    Иначе
       
xmlУзел = Неопределено;
    КонецЕсли;

    Возврат
xmlУзел;

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

Функция
ПолучитьЗначениеВСтрокеДерева(СтрокаДерева, ИмяПоля, Обязательное)

   
xmlЗначение = СтрокаДерева.Найти(ИмяПоля, "Элемент", Ложь);

    Если
xmlЗначение = Неопределено Тогда

        Если
Обязательное Тогда
           
#Если Клиент Тогда
           
Сообщить("В файле не найдено обязательное поле """ + ИмяПоля + """", СтатусСообщения.ОченьВажное);
           
#КонецЕсли
       
КонецЕсли;

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

    Иначе

       
ТекстовоеЗначение = xmlЗначение.Текст;

        Если Не
ЗначениеЗаполнено(ТекстовоеЗначение) Тогда

            Если
Обязательное Тогда
               
#Если Клиент Тогда
               
Сообщить("Не заполнено обязательное поле """ + ИмяПоля + """", СтатусСообщения.Важное);
               
#КонецЕсли
           
КонецЕсли;

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

        Иначе

            Возврат
ТекстовоеЗначение;

        КонецЕсли;

    КонецЕсли;

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

Функция
ПолучитьВалюту(xmlВалюта)

    Если
xmlВалюта = "UAH" Тогда
        Возврат
Справочники.Валюты.НайтиПоКоду(980);
    ИначеЕсли
xmlВалюта = "RUB" или xmlВалюта = "0" Тогда
        Возврат
Справочники.Валюты.НайтиПоКоду(643);
    ИначеЕсли
xmlВалюта = "USD" Тогда
        Возврат
Справочники.Валюты.НайтиПоКоду(840);
    ИначеЕсли
xmlВалюта = "EUR" Тогда
        Возврат
Справочники.Валюты.НайтиПоКоду(978);
    ИначеЕсли
xmlВалюта = "MDL" Тогда
        Возврат
Справочники.Валюты.НайтиПоКоду(498);
    ИначеЕсли
xmlВалюта = "BYR" Тогда
        Возврат
Справочники.Валюты.НайтиПоКоду(974);
    ИначеЕсли
xmlВалюта = "KZT" Тогда
        Возврат
Справочники.Валюты.НайтиПоКоду(398);
    Иначе
        Возврат
Справочники.Валюты.ПустаяСсылка();
    КонецЕсли;

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

Функция ПривестиДатуКВидуECOD(ВходящаяДата) Экспорт

    Возврат
Формат(ВходящаяДата, "ДФ=""гггг-ММ-дд""");

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

Функция ПолучитьМассивИдентификаторовДокументовECOD(СтрокаХML) Экспорт

   
МассивИдентификаторов = Новый Массив;

   
Чтение = Новый ЧтениеXML;
   
Чтение.УстановитьСтроку(СтрокаХML);
    Пока
Чтение.Прочитать() Цикл
       
ИмяУзла = Чтение.Имя;
        Если
ИмяУзла <> "tracking-id" Тогда  // Пропускаем все узлы, кроме tracking-id
           
Продолжить;
        КонецЕсли;
        Если
ИмяУзла = "tracking-id" Тогда
           
Чтение.Прочитать();
            Если
Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
               
МассивИдентификаторов.Добавить(Чтение.Значение);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Возврат
МассивИдентификаторов;

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

Хочу заметить, что хотя формат EDI и является стандартом электронного документооборота, однако форматы одинаковых документов у разных провайдеров могут существенно отличаться (казалось бы должны быть одинаковы - ан нет, разные у Коруса и Эксайта например). Так что этот формат обмена тоже не универсален......

Вот, собственно, и всё...

Если буду делать двусторонний обмен с Web-сервисами, обязательно выложу работающий код.

Удачи вам и не повторяйте чужих ошибок.

 

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    15748    10    17    

11

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (8.3.18.1289). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    17551    6    15    

13

Интеграция с сервисом vetmanager

WEB-интеграция Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разрабатывалась для загрузки документов из Ветменеджер в 1С: Бухгалтерия 3.0

12000 руб.

02.02.2021    16360    42    49    

23

[Расширение] БОР-Навигатор.Культура

Зарплата Бюджетный учет WEB-интеграция Обмен с ГосИС Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Расширение конфигурации, включающее в себя объекты, необходимые для подготовки и сдачи отчета "Штатная численность" системы "БОР-Навигатор.Культура" в программе "1С:Зарплата и кадры государственного учреждения", редакция 3.1.

8400 руб.

01.02.2019    25741    9    0    

7

Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС

Обмен с ГосИС WEB-интеграция Платформа 1С v8.3 Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Обработка является альтернативой механизму, разработанному фирмой 1С и заполняющему реквизиты контрагента по ИНН или наименованию. Не требуется действующей подписки ИТС. Вызывается как внешняя дополнительная обработка, т.е. используется, непосредственно, из карточки контрагента. Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС (egrul.nalog.ru) для БП 2.0, БП 3.0, БГУ 1.0, БГУ 2.0, УТ 10.3, УТ 11.x, КА 1.1, КА 2.x, УПП 1.x, ERP 2.x, УНФ 1.5, УНФ 1.6, УНФ 3.0, ДО 2.1

2400 руб.

28.04.2016    88583    160    215    

318
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Alex_Japanese_Student 454 06.06.13 19:39 Сейчас в теме
доводилось с корусом работать, через их интерфейс и с их обработками. В целом работало все, один раз понять и настроить, а дальше все было гуд
2. aspirator23 339 16.06.13 16:39 Сейчас в теме
К сожалению сколько провайдеров столько форматов. Метро работает по другому, Гиперглобус по третьему.
Уж лучше 1с формат для обмена документами.
3. miroha 27.10.13 18:04 Сейчас в теме
Нас тоже крупный покупатель обязал перейти на EDI рекомендовал корус. Сначала был шок, зачем платить за каждый отправленный документ? ведь полно способов сделать это бесплатно. Для нас это сумма сотни тысяч рублей, причем сервера корус не всегда доступны и являлись узким местом в нашем обмене.

Купили у них пакет с внедрением, в итоге внедряли все сами и полностью переписали их программу для хранения данные в базе, а не файловой помойке, которая в их конфигурации тормозит. Техническая поддержка ужасная, специалисты плохо разбираться в конфигурации и все сводиться к пустой болтовне в почте между менеджерами, руководителями и программистами. Когда разобрались в принципах обмена перешли на другого более доступного по ценам провайдера. Дешевле всего стать самому провайдером или найти другой способ обмена.
msvd; gfoods; Dilovar9; partner1c; +4 Ответить
4. MICK77 13 20.12.13 18:29 Сейчас в теме
(3) miroha, Если не великая тайна и не в качестве рекламы на кого перешли? А то тоже выбираем сейчас из 4-х.
5. 10ra 06.05.14 15:30 Сейчас в теме
этот кусок кода лишний т.к. уже поменяли статус при получении XML (Receive...Запрос.ChangeDocumentStatus = "R";)
        
        Запрос = Фабрика.Создать(Фабрика.Тип("http://www.comarch.com/", "ChangeDocumentStatus"));
        Запрос.Name = Login;
        Запрос.Password = Password;
        Запрос.TrackingId = Элемент;
        Запрос.Status = "R";   // Меняем статус на прочтённый

        РезультатStatus = Прокси.ChangeDocumentStatus(Запрос.Name, Запрос.Password, Запрос.TrackingId, Запрос.Status);
        КодОшибкиStatus = РезультатStatus.Res;
        Если КодОшибкиStatus <> "00000000" Тогда
            #Если Клиент Тогда
            Сообщить("Код ошибки изменения статуса документа " + Элемент + " = " + КодОшибкиStatus);
            #КонецЕсли
        КонецЕсли;
Показать


+ почитать Техническая спецификация EDIservice
Прикрепленные файлы:
ws-edi.doc
6. vbelyaev 03.08.14 14:56 Сейчас в теме
Товарищи, меня чё-т в гугле забанили походу. Не могу найти как добавить сертификаты в cacert.pem.

Пните в нужном направлении пожалуйста)))
21. bobo93 06.10.16 12:56 Сейчас в теме
(6) vbelyaev,
Здравствуйте.
Вы не розобрались с вопросом?

"Товарищи, меня чё-т в гугле забанили походу. Не могу найти как добавить сертификаты в cacert.pem.

Пните в нужном направлении пожалуйста)))"
7. Ulus 288 10.09.14 06:33 Сейчас в теме
Хорошая статья.
Грамотно!

8. Ulus 288 10.09.14 06:38 Сейчас в теме
А мы взяли Адаптер 1С от коруса.
начали внедрять.
Но оказалось, что в серийном Адаптере нету документа "Приложение к уведомлению об отгрузки".
Это новый документ, для поставщиков алкогольной продукции.
И все ... Корус нас завтраками кормит. В службу поддержки, вставайте в очереь и.т.п.
Ужасный сервис у них.
Сейчас пробую стрести с них формат файла этого электронного документа.
Сделаем сами.

P.s. кому интересно рекомендую Е-Ком. Четко, быстро, качественно. Не реклама. Просто работаем с несколькими провайдерами.
10. Antonio 6 03.02.15 12:50 Сейчас в теме
(8) Ulus, позвольте спросить как организовывали обмен с несколькими провайдерами? Сейчас тоже оптимизируем затраты на провайдеров, и возникла необходимость использовать несколько провайдеров.
9. Pim 180 10.01.15 16:48 Сейчас в теме
Никто не делал обратную выгрузку (выгрузку подтверждений) на сайт?
11. itcmsch71 08.07.15 05:21 Сейчас в теме
Спасибо Вам большое - статья очень помогла
Вначале пользовались адаптером Коруса (купили пакет с внедрением) - но после некоторого времени общения с ними - нервы не выдержали - стряс с них пакет спецификаций и оттолкнувшись от статьи написал свой обмен - причем теперь работаем без участия операторов - те только оформляют первичные документы.
Если кому интересно - могу отдать.......
Да, еще - установка сертификатов не понадобилась......
Так работает
Shooroopik111; asrgroup; Oleg_Anat; Pipapalamm; gfoods; +5 Ответить
12. gfoods 11.07.15 12:28 Сейчас в теме
(11) itcmsch71,
Было бы очень любопытно посмотреть Вашу работу. Сам готовлюсь уйти от *%^#нутого Коруса, сил нет больше их поделками пользоваться.
Если готовы показать, то пришлите ссылку в личку.
Спасибо.
13. binex 277 20.07.15 18:05 Сейчас в теме
(11) itcmsch71, поясните пожалуйста, что значит "теперь работаем без участия операторов"?
Какие сообщения внедрили?
15. Pipapalamm 25.11.15 11:08 Сейчас в теме
(11) itcmsch71, Очень хотелось бы посмотреть на ваш обмен. Сам обдумываю уход от Корусовских "Адаптер+Коннектор".
Буду очень благодарен за конфигурацию.
Заранее спасибо!
16. Oleg_Anat 01.12.15 09:50 Сейчас в теме
(11) itcmsch71, очень заинтересовал сделанный вами обмен. Мы сейчас только начинаем работать с этой системой, вот обдумываю варианты передачи данных. Вариант корусовских адаптера и коннектора - теперь не рассматриваю - после прочтения отзывов в данной статье об их техподдержке и сервисе. Если можете поделится вашей разработкой - буду очень благодарен, заранее огромное спасибо!
17. serg1785 18.04.16 12:40 Сейчас в теме
(11) itcmsch71, заинтересовала ваша разработка - если есть возможность - поделитесь. Спасибо!
20. bsv69 24.08.16 14:41 Сейчас в теме
(11) itcmsch71, Добрый день. Если можно, вышлите обработку обмена. Спасибо.
23. Shooroopik111 131 20.09.17 17:37 Сейчас в теме
24. taasha25 13 06.03.18 16:04 Сейчас в теме
(11) Здравствуйте! Буду благодарна, если поделитесь разработкой. Спасибо!
25. taasha25 13 28.04.18 09:00 Сейчас в теме
(11) Здравствуйте! Можете поделиться обработкой выгрузки Приложения к уведомлению об отгрузке? Заранее спасибо!
14. АЛьФ 10.09.15 14:53 Сейчас в теме
На попытке сменить статус документа отваливается с ошибкой:

Результат = ПолучитьСОАП().ChangeDocumentStatus(
{W:\...\EDI.ERT(358)}: Client: Client:Incorrect number of parameters supplied for SOAP request HRESULT=0x80070057: Параметр задан неверно.
 - Client:Unspecified client error. HRESULT=0x80070057: Параметр задан неверно.


Кто-нибудь сталкивался? Я чего-то недопонял или проблема на их стороне?

Ой, чуть не забыл.

Вызов такой:

	Результат = ПолучитьСОАП().ChangeDocumentStatus(
								Идентификатор,
								Пароль,
								тзДокументы.идДокумента,
								НовыйСтатусДокумента);
18. katanovich 17.06.16 16:07 Сейчас в теме
Добрый день!
Выдает во втором варианте:
КодОшибкиПодключения = 000000001.
Логин/Пароль верные. Где можно посмотреть расшифровку ошибки?
19. asrgroup 20.06.16 09:47 Сейчас в теме
Неправильный пароль или логин. Логин надо брать из настроек ТТКонектора (обычно GLN + "ЕС")
22. кольщик 29.04.17 10:28 Сейчас в теме
А для 1с 7.7 есть какое-нибудь похожее описание??
26. Teut_Vlad 179 04.09.18 15:51 Сейчас в теме
Что за НайтиОбъектПоЗначениюСвойства?
Оставьте свое сообщение