В начало

План обмена ПРС, транспорт HTTP-сервис

 

            Односторонний план обмена документа «Поступление на расчетный счет» (ПРС) из базы «1С Бухгалтерия предприятия» в базу «1С CRM». К слову сказать, документ переносится не в 1 в 1, а в табличную часть бизнес-процесса.

 

            В обеих базах создаем план обмена с одинаковым названием. Поскольку план обмена односторонний, то в базе «БП» добавляем в план обмена документ «ПРС». Устанавливаем права для плана обмена, чтобы документ «ПРС» могли редактировать те кому нужно.

 

Рис. План обмена в дереве метаданных

 

            В пользовательском режиме нужно заполнить элементы плана обмена для каждой базы. Далее они приведены на рисунке. Слева предопределенный элемент «Р6Т», справа – «ДЗТ».

 

Рис. Планы обмена (в базе «БП» – слева, в базе CRM» - справа)

 

            Также создаем сервис в базе «БП» для обмена, т.к. сообщения будут гоняться туда-сюда посредством HTTP-сервиса, а не файлов. В свойствах сервиса прописываем шаблон. В качестве параметра будем принимать код узла. Создаем два метода. Метод «Выгрузка» с типом «GET»  нужен для получения данных базы «БП», а метод «Загрузка» - для снятия с регистрации данных, полученных в базе «CRM».

 

 

Рис. HTTP-сервис

 

            Далее приведен листинг модуля HTTP-сервиса в базе «БП».

 

Листинг. Модуль объекта HTTP-сервиса в базе «БП»

Функция Выгрузка(Запрос)

            КодУзла = Запрос.ПараметрыURL["KodUzla"]; 

           

            ЗаписьXML = Новый ЗаписьXML;

    ЗаписьXML.УстановитьСтроку();

    ЗаписьXML.ЗаписатьОбъявлениеXML();

 

    ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения(); 

            ЗаписьСообщения.НачатьЗапись(ЗаписьXML, ПланыОбмена.ДЗФЛ_ОбменПРС.НайтиПоКоду(КодУзла));

           

    ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения);

 

            Пока ВыборкаИзменений.Следующий() Цикл

                        Выборка = ВыборкаИзменений.Получить();

                       

                        струкДок = Новый Структура;

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

                        струкДок.Вставить("НомерДокумента", Выборка.Номер);

                        струкДок.Вставить("Организация", Выборка.Организация.Наименование);

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

                        струкДок.Вставить("Проведен", Выборка.Проведен);

                       

                        струкДок.Вставить("ДатаСП", Выборка.ДЗФЛ_ДатаСП);

                        струкДок.Вставить("НомерСП", Выборка.ДЗФЛ_НомерСП);

                        струкДок.Вставить("НомерСудебногоУчастка", Выборка.ДЗФЛ_НомерСудебногоУчастка);

                       

                        СериализаторXDTO.ЗаписатьXML(ЗаписьXML, СтрукДок);

            КонецЦикла;

 

    ЗаписьСообщения.ЗакончитьЗапись();

    НаВыходе = ЗаписьXML.Закрыть();      

           

            Ответ = Новый HTTPСервисОтвет(200);   

            Ответ.Заголовки.Вставить("Content-type", "application/xml;  charset=utf-8");

            Ответ.УстановитьТелоИзСтроки(НаВыходе);

 

            Возврат Ответ;

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

 

 

Функция Загрузка(Запрос)

                       

            ЧтениеXML = Новый ЧтениеXML;

    ЧтениеXML.УстановитьСтроку(Запрос.ПолучитьТелоКакСтроку());

 

    ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения(); 

            ЧтениеСообщения.НачатьЧтение(ЧтениеXML);

           

            //Снимаем с регистрации

            ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);

           

            Пока СериализаторXDTO.ВозможностьЧтенияXML(ЧтениеXML) Цикл

                        //Обмен одностороний, поэтому здесь ничего нет

                        Данные = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);             

            КонецЦикла;

 

    ЧтениеСообщения.ЗакончитьЧтение();

           

            Ответ = Новый HTTPСервисОтвет(200);   

            Ответ.УстановитьТелоИзСтроки("Ок");

 

            Возврат Ответ;

           

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

 

            Сервис можно проверить через браузер, если ввести строку в следующем формате:

            http://[Сервер публикации сервиса]:[Порт]/[Имя базы 1С]/hs/[Корневой URL сервиса]/[Шаблон]/[Параметр шаблона]

           

Листинг. Структура XML-сообщения в браузере

This XML file does not appear to have any style information associated with it. The document tree is shown below.

<v8msg:Message xmlns:v8msg="http://v8.1c.ru/messages">

<v8msg:Header>

<v8msg:ExchangePlan>ДЗФЛ_ОбменПРС</v8msg:ExchangePlan>

<v8msg:To>ДЗТ</v8msg:To>

<v8msg:From>Р6Т</v8msg:From>

<v8msg:MessageNo>8</v8msg:MessageNo>

<v8msg:ReceivedNo>0</v8msg:ReceivedNo>

</v8msg:Header>

<v8msg:Body>

<Structure xmlns="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<Property name="ДатаДокумента">

<Value xsi:type="xs:dateTime">2024-01-26T17:00:00</Value>

</Property>

<Property name="НомерДокумента">

<Value xsi:type="xs:string">ЮЖР6-000037</Value>

</Property>

<Property name="Организация">

<Value xsi:type="xs:string">УК РЭУ №6-ЮЖНЫЙ ООО</Value>

 

            Для удобства добавим в базу-приемник «CRM» справочник с настройками подключения.

Рис. Справочник с настройками подключения в базе «CRM»

Для отправки и получения сообщений из базы «БП» создадим внешнюю обработку, которую будем запускать в базе «CRM».

 

Листинг. Модуль обработки

&НаСервере

Функция ПолучитьСсылкуНаБП(Знач НомерСП, Знач ДатаСП, Знач НомерСУ, Знач Организация)

            Запрос = Новый Запрос;

            Запрос.Текст =

                        "ВЫБРАТЬ

                        |           CRM_БизнесПроцесс.Ссылка КАК Ссылка

                        |ИЗ

                        |           БизнесПроцесс.CRM_БизнесПроцесс КАК CRM_БизнесПроцесс

                        |ГДЕ

                        |           CRM_БизнесПроцесс.НомерДелаСП = &НомерДелаСП

                        |           И CRM_БизнесПроцесс.ДатаПодачиВСудСП = &ДатаПодачиВСудСП

                        |           И CRM_БизнесПроцесс.СудебныйУчасток.Номер = &НомерСудебногоУчастка

                        |           И CRM_БизнесПроцесс.Истец.Наименование = &Истец";

           

            Запрос.УстановитьПараметр("НомерДелаСП", НомерСП);

            Запрос.УстановитьПараметр("ДатаПодачиВСудСП", ДатаСП);

            Запрос.УстановитьПараметр("НомерСудебногоУчастка", НомерСУ);

            Запрос.УстановитьПараметр("Истец", Организация);

           

            Результат = Запрос.Выполнить();  

            Выборка = Результат.Выбрать();

           

            Если Выборка.Следующий() Тогда

                        Возврат Выборка.Ссылка;

            Иначе

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

            КонецЕсли;

                       

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

 

Функция ПроверитьСтрокуТаблицы(Знач ДатаДокумента, Знач НомерДокумента, Знач СуммаДокумента)

            Запрос = Новый Запрос;

            Запрос.Текст =

                        "ВЫБРАТЬ

                        |           CRM_БизнесПроцессВзысканоПоИП.Ссылка КАК Ссылка

                        |ИЗ

                        |           БизнесПроцесс.CRM_БизнесПроцесс.ВзысканоПоИП КАК CRM_БизнесПроцессВзысканоПоИП

                        |ГДЕ

                        |           CRM_БизнесПроцессВзысканоПоИП.Период = &Период

                        |           И CRM_БизнесПроцессВзысканоПоИП.НомерДокумента = &НомерДокумента

                        |           И CRM_БизнесПроцессВзысканоПоИП.Сумма = &Сумма";

           

            Запрос.УстановитьПараметр("НомерДокумента", НомерДокумента);

            Запрос.УстановитьПараметр("Период", НачалоДня(ДатаДокумента));

            Запрос.УстановитьПараметр("Сумма", СуммаДокумента);

           

            Результат = Запрос.Выполнить();

            Выборка = Результат.Выбрать();

           

            Если Выборка.Следующий() Тогда

                        Возврат Истина;

            Иначе

                        Возврат Ложь;

            КонецЕсли;

                       

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

 

&НаСервере

Процедура ДобавитьОдинДокументВТабличнуюЧастьБП(Знач Эл)

           

 

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

                       

                        Если ЗначениеЗаполнено(СсылкаНаБП) Тогда

                                   Если НЕ ЗначениеЗаполнено(СсылкаНаБП.ВзысканоПоИП) ИЛИ

                                                НЕ ПроверитьСтрокуТаблицы(Эл.ДатаДокумента, Эл.НомерДокумента, Эл.СуммаДокумента) Тогда

                                                

                                               //Добавляем запись в таблицу БП

                                               ОбБп = СсылкаНаБП.ПолучитьОбъект();

                                              

                                               НоваяСтр = ОбБп.ВзысканоПоИП.Добавить();

                                               НоваяСтр.Период = Эл.ДатаДокумента;

                                               НоваяСтр.НомерДокумента = Эл.НомерДокумента;

                                               НоваяСтр.Сумма = Эл.СуммаДокумента;

                                              

                                               Попытка

                                                           ОбБп.Записать();

                                               Исключение  

                                                           Возврат;

                                               КонецПопытки;

                                              

                                               //Добавляем запись в РС

                                               МЗ = РегистрыСведений.РезультатОбменаЧерезСервисДЗФЛ.СоздатьМенеджерЗаписи();

                                              

                                               МЗ.НомерДокумента = Эл.НомерДокумента;

                                               МЗ.ДатаДокумента = Эл.ДатаДокумента;

                                               МЗ.Проведен = Эл.Проведен;

                                               МЗ.БизнесПроцесс = СсылкаНаБП;

                                               МЗ.Организация = Эл.Организация;

                                               МЗ.СуммаДокумента = Эл.СуммаДокумента;

                                       МЗ.ДатаСП = Эл.ДатаСП;

                                               МЗ.НомерСП = Эл.НомерСП;

                                               МЗ.НомерСудебногоУчастка = Эл.НомерСудебногоУчастка;

                                  

                                               МЗ.Записать();

                                              

                                   КонецЕсли;   

                        КонецЕсли;   

                                  

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

 

&НаСервере

Процедура ПрочитатьСообщениеЧерезСервисНаСервере()

            Выборка = Справочники.ПараметрыПодключенияКСервисуДЗФЛ.Выбрать();

            ЭтотУзел = ПланыОбмена.ДЗФЛ_ОбменПРС.ЭтотУзел();

           

            Пока Выборка.Следующий() Цикл 

                        Если Выборка.ПометкаУдаления = Ложь Тогда

                                   Соединение = Новый HTTPСоединение(Выборка.АдресПубликации, Выборка.Порт, Выборка.Логин, Выборка.Пароль,,30,,);

                                  

                                   ДатаНачала = НачалоГода(ТекущаяДата());

                                   ДатаОкончания = ТекущаяДата();

                                  

                                   Заголовки = Новый Соответствие;             

                                   Заголовки.Вставить("Content-Type", "application/xml");

                                                                      

                                   Запрос = Новый HTTPЗапрос("/" + Выборка.Наименование + "/hs/DZFL/planobmena/" + ЭтотУзел.Код, Заголовки);

                                   Результат = Соединение.ВызватьHTTPМетод("GET", Запрос);

                                  

                                   Если Результат.КодСостояния = 200 Тогда

                                              

                                               ЧтениеXML = Новый ЧтениеXML;

                                               ЧтениеXML.УстановитьСтроку(Результат.ПолучитьТелоКакСтроку());

                                              

                                               ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения(); 

                                               ЧтениеСообщения.НачатьЧтение(ЧтениеXML);

                                              

                                               //Снимаем с регистрации

                                               ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);

                                              

                                               Пока СериализаторXDTO.ВозможностьЧтенияXML(ЧтениеXML) Цикл

                                                           СтруктураДанных = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);       

                                                           ДобавитьОдинДокументВТабличнуюЧастьБП(СтруктураДанных);

                                               КонецЦикла;

                                              

                                               ЧтениеСообщения.ЗакончитьЧтение();

                                              

                                   Иначе

                                   КонецЕсли;

                                  

                        КонецЕсли;

            КонецЦикла;

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

 

 

&НаКлиенте

Процедура ПрочитатьСообщениеЧерезСервис(Команда)

            ПрочитатьСообщениеЧерезСервисНаСервере();

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

 

 

&НаСервере

Процедура ЗаписатьСообщениеЧерезСервисНаСервере()

            Выборка = Справочники.ПараметрыПодключенияКСервисуДЗФЛ.Выбрать();

            ЭтотУзел = ПланыОбмена.ДЗФЛ_ОбменПРС.ЭтотУзел();

            ТекУзел = ПланыОбмена.ДЗФЛ_ОбменПРС.НайтиПоКоду("Р6Т");

           

            Пока Выборка.Следующий() Цикл 

                        Если Выборка.ПометкаУдаления = Ложь Тогда

                                   Соединение = Новый HTTPСоединение(Выборка.АдресПубликации, Выборка.Порт, Выборка.Логин, Выборка.Пароль,,30,,);

                                  

                                    Заголовки = Новый Соответствие;             

                                   Заголовки.Вставить("Content-type", "application/xml;  charset=utf-8");

                                                                      

                                   Запрос = Новый HTTPЗапрос("/" + Выборка.Наименование + "/hs/DZFL/planobmena/" + ЭтотУзел.Код, Заголовки);

           

                                   ЗаписьXML = Новый ЗаписьXML;

                                   ЗаписьXML.УстановитьСтроку();

                                   ЗаписьXML.ЗаписатьОбъявлениеXML();

                                  

                                   ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();

                                   ЗаписьСообщения.НачатьЗапись(ЗаписьXML, ТекУзел);                                                                     

                                   ЗаписьСообщения.ЗакончитьЗапись();

                                   НаВыходе = ЗаписьXML.Закрыть();          

                                              

                                   Запрос.УстановитьТелоИзСтроки(НаВыходе);                                       

                                  

                                   Результат = Соединение.ВызватьHTTPМетод("POST", Запрос);

                                  

                                   Если Результат.КодСостояния = 200 Тогда

                                   Иначе

                                   КонецЕсли;

                                  

                        КонецЕсли;

            КонецЦикла;

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

 

 

&НаКлиенте

Процедура ЗаписатьСообщениеЧерезСервис(Команда)

            ЗаписатьСообщениеЧерезСервисНаСервере();

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

 

            Немного поэкспериментируем. Зарегистрируем на отправку 1 документ в базе-источнике. Проверить что документ отправлен можно запросом. Далее запустим обработку и проверим получение и отправку сообщений. Данные отправляются.

            Как дальнейшее продолжение можно создать регламентное задание, настроить расписание его запуска, а процедуры из обработки поместить в общий модуль и вызывать их через экспортную процедуру.