HTTP сервис на 1С:Шина за 1 день

30.01.25

Интеграция - Перенос данных 1C

Инструкция, как сделать на 1С:Шина http сервис, который будет принимать json и перенаправлять в 1С-ную систему, в которой есть БСП Позволит программисту создать свой http сервис за 1 день! Технические детали: 1С:Шина версия 6.1.6 (В основе 1С:Шины лежит технология 1С:Предприятие.Элемент. ) Платформа 8.3.25.1394 (все зависит от того, какие у вас требования у типовой конфигурации 1С с которой выполняется обмен).

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Выгрузка для 1С:Шина версия 6.1.6
.zip 5,47Mb ver:2.0
0
0 Скачать (5 SM) Купить за 3 050 руб.
Выгрузка для 1С:Шина версия 4
.zip 2,92Mb ver:1.4
9
9 Скачать (5 SM) Купить за 3 050 руб.

Статья написана по хроникам внедрения 1С:Шина версии 4.1 в Первом Бите на Спортивной.

Меня зовут Галац Михаил, хочу поделиться  реализацией отдельного http метода на при внедрении шины у клиента, у которого 1С-ные и не 1С-ные информационные системы.

Статья актуальная, версия на январь 2025.

 

Сокращения:

  • ИС 1С –информация система на базе 1С конфигурация с БСП.
  • Шина – 1С:Шина версии 4.1.
  • Json – текстовый файл в формате json.
  • Транслятор – объект 1С:Шина в котором выполняется преобразование сообщения.
  • Канал – объект 1С:Шина, который осуществляется доставку сообщения.
  • id – уникальный код в формате uuid.
  • РС - регистр сведений.
  • Проект - термин 1с:Шина.
  • Сообщение - сообщение интеграции.

 

Допуски:

  • У вас имеется развернутая 1С:Шина не ниже версии 4.1

или

  • второй файл для 1С:Шина версии 6.1.6

 

Источники:

  • Официальная документация по продукту 1С:Шина. Ссылка
  • Неофициальная группа в tg @esb_1C

 

Благодарности:

Отдельная благодарность, это наличие  Алексея Борисевича, моего технического архитектора по внедрению проектов 1С:Шина, за консультации и помощь в реализации, когда я был в тупике.

Моему руководителю Гейдару Габриэлянцу за корректировки в статье, моему коллеге Сергею Губареву, который участвовал редактировании кода  при переходе на 6 версию 1С:Шины

Описание задачи

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

 

Краткое описание реализации:

Шина получает json и направляет его в канал внутри шины. 

На стороне шины нужно сделать ряд проверок (проверки на заполнение, операции с датами) и  в случае обнаружения дать ответ в виде json Формат 1.

В случае отсутствия ошибок, присвоить в шине данному пакету id и сделать запись в РС «Сообщения для сторонних систем», чтобы зафиксировать заявку в виде json Формате 5. При формировании сообщения добавить ему параметры id и тип сообщения.

ИС 1С забирает из канала сообщение и записывает его во внутренний регистр сведений «Полученные сообщения» и уже на основе сформированной записи из РС «Полученные сообщения» создается документ. При изменении статус документа, выполняется формируется json и кладем в регистр сведений «Отправленные сообщения» в виде отдельной записи, а json записываем в реквизите РС «Тело сообщения».

Далее из РС «Отправленные сообщение» с использованием сервис интеграции отправляется в шину сообщение. Данное сообщение внутри шины преобразуется через транслятор и сохраняется запись в шине в регистр сведений «Сообщения для сторонних систем». На рисунке 1, представлено схематичное описание решения, которое рассматривается в данной статье:

 

 

Рисунок 1. Пример для Шины-Создание заявки

 

А теперь более подробно с примерами кода и скринами из приложений, чтобы стало более понятно и вы смогли бы воспроизвести у себя и получить профит от данной статьи.

Предполагается, что у вас уже есть проект, приложение можно создать из архива, который можно скачать в конце статьи. Или более тернистый путь и создать самостоятельно в 1С: Шина в виде отдельного  приложения на основе данной статьи. 

Процесс интеграции – http сервис – шаблон, ну и в модулях добавить код из статьи. Кстати, в дефолтовой инструкции процесс создания Процесс интеграции – http сервис – шаблон описан подробно.

Обычно для несложных проектов используется одно приложение, такой вариант предлагается, потому что сопровождать проще, выгружать / загружать данные было более удобно. Разработку с использованием git не рассматриваем (но, возможно, кто осветит данный аспект для 1С:Шина), напомню, моя задача показать практический пример, который вы сразу сможете использовать у себя на проекте. 

Вся разработка выполняется во встроенной ide шины.

А теперь создадим свой http сервис.

В навигаторе проекта, в контекстном меню создаем новый элемент проекта, см. Рисунок 2, а на рисунке 3 выбираем Элемент проекта. 

 

Рисунок 2 Создание нового элемента проекта

 

Рисунок 3 Создание Процесса Интеграции

 

  1. Права доступа пока ставим "РазрешеноВсем", если требуется ограничивать, то следующий уровень понимания.
  2. Корневой Url ставим "v1" это наша первая версия сервиса.

Примечание.

url нашего сервиса будет примерно такой http://localhost:9090/applications/<ИмяПроекта>

Внутри сервиса интеграции рисуем схему, по которой будут идти сообщения. У меня получилось так.

 

Рисунок 4 Схема Процесса Интеграции

 

 

Краткое описание по рисунку 4.

json, который присылают на http сервис мы проверим и отправим в Программный Источник и далее Сообщение Интеграции  отправляем в канал "ИзСтороннихСистем", далее сервис интеграции в ИС 1С заберет сообщения, которые там будут находиться. Взаимодействия из ИС 1С в шину в данном бизнес процессе не рассматривается.

Запустим приложение, жмем F5 и посмотрим, что получилось для нашего случая 

http://localhost:9090/applications/test

Перейдя по ссылке в браузере должно отобразиться так, см. рисунок 5.

 

Рисунок 5 Пример запущенного тестового приложения

Перечисление "ТипыЗапросов" создается вообще без каких либо сложностей. Значения: order, status, cancel

РС "СообщенияДляСтороннихСистем", создать с периодом Момент, также имеет следующую структуру:

Измерения:

  • ГуидВызова. ТипУуид
  • Пользователь. ТипНеопределено, ПользовательСсылка

Ресурсы:

  • ИсходноеСообщение. Тип Строка неограниченная
  • Обрабатано. Тип Булево
  • ТипЗапроса. Тип Перечисление.ТипыЗапросов

 

Далее создаем новый шаблон у http сервиса для рассматриваемой задачи, нужен с типом POST.

В свойствах шаблона указываем следующие действия:

Переходим в раздел Шаблоны -> Новый -> Шаблон URL, см рисунок 6.

 

Рисунок 6 Создание нового шаблона

 

И заполняем свойства шаблона:

  • Имя «Заявка»
  • КонтрольДоступа - Вызов - РазрешеноВсем
  • Шаблон /orders

Внимание. С такими настройками разрешен анонимный доступ

 

Рисунок 7 Свойства шаблона созданного http сервиса

 

Теперь добавляем, какие запросы этот шаблон должен обрабатывать, у меня это POST:

  • имя POST
  • Метод: POST
  • Обработчик: жмем на лупу или вводим свое имя метода и жмем лупу.

 

Рисунок 8.Свойства запроса

 

В дереве объектов получится так

 

Рисунок 9 Дерево объектов созданного http сервиса

 

Теперь, когда у нас созданы все объекты, то переходим в метод определенном на рисунке 8 «ОбработкаЗапроса», если в обработчике будет пусто, жмем на лупу, и название присваивается по умолчанию, как моем примере.

Ниже приведен текст метода с комментариями

// Тут описываем структуры, которые есть внутри json

1C:Шина версия 4.1

структура КонтактыКлиента
    обз пер cargos: Массив<product>
;

метод ОбработкаЗапросаЗаявка(Запрос: HttpСервисЗапрос)
    // Область переменных, корые нужно объявить заранее
    пер ПустойМассив = новый Массив<Число>()
    пер ТелоОтвета: Строка
    пер ГуидВызова = новый Ууид()
    
    /* 
    Так как поток после прочтения закрывается ,поэтому готовим его заранее, 
    чтобы передавать его в канал    
    Тело запрос сериализуем в json, далее в строку и создаем поток из строки.
    */    
    
    знч ТелоЗапросаИзПотока = Запрос.Тело.ПрочитатьКакСтроку()    
    пер ТелоЗапросаПоток = ПотокЧтения.ИзСтроки(ТелоЗапросаИзПотока)
    пер ТелоЗапроса = СериализацияJson.ПрочитатьОбъект(ТелоЗапросаПоток)
    пер ТелоЗапросаСтрокаПоток = ПотокЧтения.ИзСтроки(ТелоЗапросаИзПотока)
    
    // В канал отправляем тело запроса, коорые получилии и добавляем параметры апроса, 
    // чтобы идентифицировать и маршрутизировать данное сообщение в ИСНазначение
    пер Сообщение = новый СообщениеИнтеграции(
        {
            "id": ГуидВызова.ВСтроку(), "type" : "orders"
        }, ТелоЗапросаСтрокаПоток)

    пер Грузы = ТелоЗапроса["cargos"] // как Массив<Объект?>
    если Грузы == ПустойМассив //ORD107  
        пер КодОшибки = "ORD107"
        пер РасшифровкаТекстОшибки = "Отсутствуют грузы"
        пер ТекстОшибки =
            {
                "errorCode": КодОшибки,
                "errorMessage": РасшифровкаТекстОшибки
            }
        ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
    иначе если Грузы.ВСтроку() != ""
        для Груз из Грузы
            если Груз["places"] == ПустойМассив
                пер КодОшибки = "ORD108"
                пер РасшифровкаТекстОшибки = "Отсутствуют грузоместа"
                пер ТекстОшибки =
                    {
                        "errorCode": КодОшибки,
                        "errorMessage": РасшифровкаТекстОшибки
                    }
                ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                прервать
            иначе
                пер грузоместа = Груз["places"] // Массив грузомест
                для грузоместо из грузоместа
                    если грузоместо["weight"]["value"] < 0
                        пер КодОшибки = "ORD113"
                        пер РасшифровкаТекстОшибки = "Некорректный вес грузового места"
                        пер ТекстОшибки =
                            {
                                "errorCode": КодОшибки,
                                "errorMessage": РасшифровкаТекстОшибки
                            }
                        ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                        прервать
                    ;
                ;
            ;
            если Груз["items"] == ПустойМассив
                пер КодОшибки = "ORD109"
                пер РасшифровкаТекстОшибки = "Отсутствует номенклатура"
                пер ТекстОшибки =
                    {
                        "errorCode": КодОшибки,
                        "errorMessage": РасшифровкаТекстОшибки
                    }
                ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                прервать
            ;
            если (Груз["origin"]["dueDate"]["from"] == "") или (Груз["destination"]["dueDate"]["from"] == "")
                пер КодОшибки = "ORD104"
                пер РасшифровкаТекстОшибки = "Не указано время 'От' в точке погрузке/выгрузки"
                пер ТекстОшибки =
                    {
                        "errorCode": КодОшибки,
                        "errorMessage": РасшифровкаТекстОшибки
                    }
                ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                прервать
            иначе
                пер ДатаПогрузкиДо = новый Момент(Груз["origin"]["dueDate"]["to"])
                пер ДатаПогрузкиОт = новый Момент(Груз["origin"]["dueDate"]["from"])
                пер ДатаВыгрузкиДо = новый Момент(Груз["destination"]["dueDate"]["to"])
                пер ДатаВыгрузкиОт = новый Момент(Груз["destination"]["dueDate"]["from"])

                пер ДопустимоеВремяПогрузки = новый Длительность(4, 0, 0)
                знч ОтметкаВремениСейчас = Момент.Сейчас()

                если (ДатаПогрузкиОт >= ДатаПогрузкиДо) или (ДатаВыгрузкиОт >= ДатаВыгрузкиДо)
                    пер КодОшибки = "ORD279"
                    пер РасшифровкаТекстОшибки = "Дата 'до' ('to') раньше или равна дате 'от' ('from') той же операции"
                    пер ТекстОшибки =
                        {
                            "errorCode": КодОшибки,
                            "errorMessage": РасшифровкаТекстОшибки
                        }
                    ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                    прервать
                иначе если ДатаВыгрузкиОт <= ДатаПогрузкиОт или ДатаВыгрузкиОт <= ДатаПогрузкиДо
                    пер КодОшибки = "ORD277"
                    пер РасшифровкаТекстОшибки = "Дата-время выгрузки 'от' ('from') раньше или равна дате погрузки"
                    пер ТекстОшибки =
                        {
                            "errorCode": КодОшибки,
                            "errorMessage": РасшифровкаТекстОшибки
                        }
                    ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                    прервать
                иначе если ДатаПогрузкиОт < (ОтметкаВремениСейчас + ДопустимоеВремяПогрузки)
                    пер КодОшибки = "ORD270"
                    пер РасшифровкаТекстОшибки = "Недостаточно времени до погрузки"
                    пер ТекстОшибки =
                        {
                            "errorCode": КодОшибки,
                            "errorMessage": РасшифровкаТекстОшибки
                        }
                    ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                    прервать
                
                ;
            ;
        ;                
    ;

    // Если нет ошибок в сообщении, то отдаем guid в виде простого json
    если ТелоОтвета == ""
        пер ЗаявкаСоздана =
                {
                    "id": ГуидВызова
                } 
            ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ЗаявкаСоздана)
    ;
    //Запись в РС Сообщения из сторонних систем.
    //ГуидВызова - уид для сообщения, ДатаЗаписи - дата и время когда была сделана запись, ИсходноеСообщение - тело которое нам пришло

    
    пер Запись =
        новый СообщенияДлясторонних Систем.Запись(Период = Момент.Сейчас() , ГуидВызова = ГуидВызова, ДатаЗаписи = ДатаВремя.Сейчас(
        ЧасовойПояс {UTC+3}), ИсходноеСообщение = ТелоЗапросаИзПотока, сторонних Клиент = "Сторонний клиент", Обработано = Истина)
    СообщенияДляСтороннихСистем.Записать(Запись)

    
    // Отправляем сообщение в Узел "ПрограммныйИсточник" из него Шина отправляет в канал 
    Обмен_СторонниеСистемы.ОтправитьСообщениеВУзлы(Сообщение, Обмен_СторонниеСистемы.Схема.Узлы.ПрограммныйИсточник)
    // тут мы даем ответ на обращение в http сервис или ошибку или присвоенный guid
    
    Запрос.Ответ.УстановитьТело(ТелоОтвета, "UTF-8")
;

  Описываете все возможные значения, которые могут быть, пусть они не будут в json который вы получаете это приведет к ошибке.

1C:Шина версия 6.1.6

//====================НАЧАЛО ОБЪЯВЛЕНИЯ СТРУКТУР=====================
структура BankDetails
    пер bankName: Строка?
    пер bankCode: Строка?
    пер bankAddress: Строка?
    пер accountNumber: Строка?
    пер correspondentAccountNumber: Строка?
;
структура Phone
    пер number: Строка?
    пер extension: Строка?
;
структура Product
    пер guid: Строка?
    пер name: Строка?
    пер nsiCode: Строка?
    пер skmtrCode: Строка?
    пер nomenclatureGroup: Строка?
    пер isValuable: Булево?
;
структура Quantity
    пер value: Число?
    пер unitId: Число?
;
структура Contact
    пер name: Строка?
    пер phone: Phone?
    пер email: Строка?
;
структура Contract
    пер name: Строка?
    пер date: Строка?
    пер number: Строка?
;
структура Customer
    пер name: Строка?
    пер inn: Строка?
    пер kpp: Строка?
    пер email: Строка?
    пер phone: Строка?
    пер factAddress: Строка?
    пер legalAddress: Строка?
    пер actualAddress: Строка?
    пер taxSystem: Строка?
    пер contract: Contract?
    пер bankDetails: BankDetails?
;
структура CustomerHeadCompany
    пер name: Строка?
    пер inn: Строка?
    пер kpp: Строка?
    пер phone: Строка?
    пер factAddress: Строка? //w нет
    пер legalAddress: Строка?
    пер contract: Contract?
    пер bankDetails: BankDetails?
;
структура DangerClassDetails
    пер dangerClass: Строка?
    пер comment: Строка?
;
структура EstimatedCost
    пер currency: Строка?
    пер amount: Число?
;
структура ExternalInitiator
    пер name: Строка?
    пер phone: Строка?
    пер email: Строка?
;
структура Initiator
    пер firstName: Строка?
    пер middleName: Строка?
    пер lastName: Строка?
    пер email: Строка?
    пер phone: Строка?
;
структура Location
    пер address: Строка?
    пер name: Строка?
    пер regionId: Строка?
    пер region: Region?
    пер coords: Coords?
    пер comment: Строка?
    пер mapFileId: Строка?
;
структура Coords
    пер lat: Число?
    пер lot: Число?
;
структура Length
    пер value: Число?
    пер unit: Строка?
;
структура Width
    пер value: Число?
    пер unit: Строка?
;
структура Height
    пер value: Число?
    пер unit: Строка?
;
структура Weight
    пер value: Число?
    пер unit: Строка?
;
структура Region
    пер name: Строка?
    пер code: Строка?
;
структура MaxDimensions
    пер length: Число?
    пер width: Число?
    пер height: Число?
    пер unit: Строка?
;
структура Tariff
    //возможно будет баг, зарезервированное слово
    пер types: Строка? //должно быть пер type: Строка?
    пер minTime: Число?
;
структура TemperatureRange
    пер min: Число?
    пер max: Число?
;
структура Vehicle
    пер trailerTypeId: Число?
    пер loadingMethods: Массив<Строка>?
;
структура Volume
    пер value: Число?
    пер unit: Строка?
;
структура Origin
    пер companyId: Строка?
    пер contacts: Массив<Contact>?
    пер location: Location?
    пер dueDate: DueDate?
    пер company: Company?
    пер vehicleRestrictions: VehicleRestrictions?
;
структура Owner
    пер companyId: Строка?
    пер company: Company?
    пер legalAddress: Строка?
;
структура Item
    пер product: Product?
    пер quantity: Quantity?
    пер estimatedCost: EstimatedCost?
    пер externalCargoNumber: Строка? // нет в w
;
структура Place
    пер packagingTypeId: Число?
    пер weight: Weight?
    пер volume: Volume?
    пер dimensions: Dimensions?
    пер quantity: Число?
;
структура Seller
    пер companyId: Строка?
    пер legalAddress: Строка?
    пер company: Company?
;
структура Shipper
    пер company: Company?
    пер companyId: Строка?
    пер seller: Seller? 
    пер externalAssignmentNumber: Строка? 
    пер contacts: Массив<Contact>? 
    пер documentNumber: Строка? 
;
структура СonfirmationDocuments
    пер documents: Строка?
    пер submitDeadlineDays: Число?
;
структура Cargo
    пер items: Массив<Item>?
    пер places: Массив<Place>?
    пер isValuable: Булево?
    пер maxDimensions: MaxDimensions?
    пер origin: Origin?
    пер destination: Destination?
    пер dangerClassDetails: DangerClassDetails?
    пер shippingInstructions: Строка?
    пер loadingSchemeFileId: Строка?
    пер owner: Owner?
    пер shipper: Shipper?
    пер seller: Seller?
    пер externalAssignmentNumber: Строка?
    пер externalCargoNumber: Строка?
;
структура Company
    пер name: Строка?
    пер inn: Строка?
    пер kpp: Строка?
    пер legalAddress: Строка?
    пер actualAddress: Строка?
    пер phone: Строка?
    пер bankDetails: BankDetails?
;
структура Destination
    пер company: Company?
    пер contacts: Массив<Contact>?
    пер location: Location?
    пер dueDate: DueDate?
    пер companyId: Строка?
    пер vehicleRestrictions: VehicleRestrictions?
;
структура Dimensions
    пер length: Число?
    пер width: Число?
    пер height: Число?
    пер unit: Строка?
;
структура DueDate
    пер from: Строка? //ДатаВремя
    пер to: Строка? //ДатаВремя
;
структура VehicleRestrictions
    пер length: Length?
    пер width: Width?
    пер height: Height?
    пер weight: Weight?
;
структура Payer
    пер name: Строка?
    пер inn: Строка?
    пер kpp: Строка?
    пер legalAddress: Строка?
    пер actualAddress: Строка?
    пер factAddress: Строка?
    пер phone: Строка?
    пер contract: Contract?
    пер bankDetails: BankDetails?
;
структура Shipping
    пер dueDate: Строка? //ДатаВремя
    пер temperatureRange: TemperatureRange?
;
структура Requirements
    пер vehicle: Vehicle?
    пер specialRequirementIds: Массив<Строка>?
    пер confirmationDocuments: СonfirmationDocuments?
    пер shipping: Shipping?
    пер comment: Строка?
;
структура ЗаявкаНаТранспорт
    пер cargos: Массив<Cargo>?
    пер requirements: Requirements?
    пер externalInitiator: ExternalInitiator?
    пер comment: Строка?
    пер customerPrice: Число?
    пер isBaggage: Булево?
    пер tariff: Tariff?
    пер deliveryType: Строка?
    пер customer: Customer?
    пер payer: Payer?
    пер initiator: Initiator?
    пер isAdvancedPaymentEnabled: Булево?
    пер customerHeadCompany: CustomerHeadCompany?
    пер customerType: Строка?
;
//====================КОНЕЦ ОБЪЯВЛЕНИЯ СТРУКТУР========================

конст order = ТипыЗапросов.order
конст cancel = ТипыЗапросов.cancel
конст status = ТипыЗапросов.status


метод ОбработкаЗапросаЗаявкаНаТранспорт(Запрос: HttpСервисЗапрос)
    // Область переменных, корые нужно объявить заранее
    пер ТелоОтвета: Строка
    пер ГуидВызова = новый Ууид()
    знч Пользователь = Пользователи.ТекущийПользователь
    /* 
     * Так как поток после прочтения закрывается ,поэтому готовим его заранее, 
     * чтобы передавать его в канал    
     * Тело запрос сериализуем в json, далее в строку и создаем поток из строки.
     */
    знч ТелоЗапросаИзПотока = Запрос.Тело.ПрочитатьКакСтроку()
    /* в структуре json есть узел type, но данное слово зарезервировано, 
    поэтому заменяем types*/
    знч ТелоЗапросИзмененное = ТелоЗапросаИзПотока.Заменить("type", "types")

    пер ИзначальноеСообщение = ПотокЧтения.ИзСтроки(ТелоЗапросаИзПотока)
    пер ТелоЗапросаПоток = ПотокЧтения.ИзСтроки(ТелоЗапросИзмененное)
    пер ТелоЗапроса = СериализацияJson.ПрочитатьОбъект(ТелоЗапросаПоток, Тип<ЗаявкаНаТранспорт>)
    пер Сообщение = новый СообщениеИнтеграции(
        {
            "id": ГуидВызова.ВСтроку(),
            "type": "order"
        }, ИзначальноеСообщение)

    пер грузы = ТелоЗапроса.cargos
    если грузы.Представление() == "" //ORD107  
        пер КодОшибки = "ORD107"
        пер РасшифровкаТекстОшибки = "Отсутствуют грузы"
        пер ТекстОшибки = {
            "errorCode": КодОшибки,
            "errorMessage": РасшифровкаТекстОшибки
        }
        ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
    иначе // грузы != ПустойМассив      
        для груз из грузы
            если груз.places.Представление() == ""
                пер КодОшибки = "ORD108"
                пер РасшифровкаТекстОшибки = "Отсутствуют грузоместа"
                пер ТекстОшибки = {
                    "errorCode": КодОшибки,
                    "errorMessage": РасшифровкаТекстОшибки
                }
                ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                прервать
            иначе               
                    пер грузоместа = груз.places // Массив грузомест
                для грузоместо из грузоместа
                    если грузоместо.weight.value < 0
                        пер КодОшибки = "ORD113"
                        пер РасшифровкаТекстОшибки = "Некорректный вес грузового места"
                        пер ТекстОшибки = {
                            "errorCode": КодОшибки,
                            "errorMessage": РасшифровкаТекстОшибки
                        }
                        ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                        прервать
                    ;
                ;

                если груз.items.Представление() == ""
                    пер КодОшибки = "ORD109"
                    пер РасшифровкаТекстОшибки = "Отсутствует номенклатура"
                    пер ТекстОшибки = {
                        "errorCode": КодОшибки,
                        "errorMessage": РасшифровкаТекстОшибки
                    }
                    ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                    прервать
                ;

                если (груз.origin.dueDate.from == "") или (груз.destination.dueDate.from == "")
                    пер КодОшибки = "ORD104"
                    пер РасшифровкаТекстОшибки = "Не указано время 'От' в точке погрузке/выгрузки"
                    пер ТекстОшибки = {
                        "errorCode": КодОшибки,
                        "errorMessage": РасшифровкаТекстОшибки
                    }
                    ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                    прервать
                иначе
                    пер ДатаПогрузкиДо = новый Момент(груз.origin.dueDate.to)
                    пер ДатаПогрузкиОт = новый Момент(груз.origin.dueDate.from)
                    пер ДатаВыгрузкиДо = новый Момент(груз.destination.dueDate.to)
                    пер ДатаВыгрузкиОт = новый Момент(груз.destination.dueDate.from)

                    пер ДопустимоеВремяПогрузки = Обмен_СторонниеСистемы.Параметры.ДопустимоеВремяПогрузки
                    знч ОтметкаВремениСейчас = Момент.Сейчас()

                    если (ДатаПогрузкиОт >= ДатаПогрузкиДо) или (ДатаВыгрузкиОт >= ДатаВыгрузкиДо)
                        пер КодОшибки = "ORD279"
                        пер РасшифровкаТекстОшибки =
                            "Дата 'до' ('to') раньше или равна дате 'от' ('from') той же операции"
                        пер ТекстОшибки = {
                            "errorCode": КодОшибки,
                            "errorMessage": РасшифровкаТекстОшибки
                        }
                        ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                        прервать
                    иначе если ДатаВыгрузкиОт <= ДатаПогрузкиОт или ДатаВыгрузкиОт <= ДатаПогрузкиДо
                        пер КодОшибки = "ORD277"
                        пер РасшифровкаТекстОшибки = "Дата-время выгрузки 'от' ('from') раньше или равна дате погрузки"
                        пер ТекстОшибки = {
                            "errorCode": КодОшибки,
                            "errorMessage": РасшифровкаТекстОшибки
                        }
                        ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                        прервать
                    иначе если ДатаПогрузкиОт < (ОтметкаВремениСейчас + ДопустимоеВремяПогрузки)
                        пер КодОшибки = "ORD270"
                        пер РасшифровкаТекстОшибки = "Недостаточно времени до погрузки"
                        пер ТекстОшибки = {
                            "errorCode": КодОшибки,
                            "errorMessage": РасшифровкаТекстОшибки
                        }
                        ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ТекстОшибки)
                        прервать
                    ;
                ;
            ;

        //Запрос.Ответ.УстановитьТело(ТелоОтвета, "UTF-8")
        ;
        // Если нет ошибок в сообщении, то отдаем guid в виде простого json
        если ТелоОтвета == ""
            пер ЗаявкаСоздана = {
                "id": ГуидВызова
            }
            ТелоОтвета = СериализацияJson.ЗаписатьОбъект(ЗаявкаСоздана)
        ;
        //Запись в РС Сообщения из сторонних систем.
        //ГуидВызова - уид для сообщения, ДатаЗаписи - дата и время когда была сделана запись, ИсходноеСообщение - тело которое нам пришло
        //Пользователь - элемент справочника Пользователи, под которым подключились к шине и было отправлено  сообщение

        пер Запись = новый СообщенияДляСтороннихСистем.Запись(Период = Момент.Сейчас(), ГуидВызова = ГуидВызова,
                ДатаЗаписи = ДатаВремя.Сейчас(
				ЧасовойПояс {UTC+3}), ИсходноеСообщение = ТелоЗапросаИзПотока, Пользователь = Пользователь, ТипЗапроса = order,
                Обработано = Истина)
        СообщенияДляСтороннихСистем.Записать(Запись)


        // Отправляем сообщение в Узел "ПрограммныйИсточник" из него Шина отправляет в канал 
        Обмен_СторонниеСистемы.ОтправитьСообщениеВУзлы(Сообщение, Обмен_сторонниеСистемы.Схема.Узлы.ПрограммныйИсточник)
    ;
    // отправляем сообщение об ошибке или гуид о новой заявке, смотря что мы выше записали в переменную ТелоОтвета
    Запрос.Ответ.УстановитьТело(ТелоОтвета, "UTF-8")
;

Рекомендую через Postman или аналогичное ПО сформировать post запрос и отправить на вновь созданный http service и в отладке посмотреть какие значения присваиваются и как работает логика.

Сразу предупреждаю оптимальности кода не преследовалась, это пример который вы можете доработать и улучшить

Кстати, намеренно не описал создание РС Сообщения для Сторонних систем, создайте самостоятельно, документация по 1С:Шина позволяет это сделать без мук и испытаний, единственно отмечу, что делайте его периодическим с периодом МоментВремени.

Запускаем приложение, через Postman отправляете json в формате 1 и получаете ответ в виде ошибки или с id заявки примерно такое:

 

Рисунок 10 Заявка создана и id присвоен. Скриншот из Postman

 

Рисунок 11.Сообщение в канале для ИС1С

 

Создаем но вый Сервис Интеграции.  

Изменения теперь выполняем в ИС 1C, чтобы забрать сообщение из канала шины

версия 4.1.

Процедура Основной_Обмен_СторонниеСистемы_ИзСтороннихСистемОбработкаПолученияСообщения(Сообщение, Отказ)
	//РазмерСообщения = Сообщение.Параметры.Получить("РазмерСообщения");  
	РазмерСообщения = Сообщение.РазмерТела;
	ТипВходящегоСообщения = Сообщение.Параметры.Получить("type");  
	ID = Сообщение.Параметры.Получить("id");
	ПОпытка
		//////////////////////////////////////////
		Если РазмерСообщения <> Неопределено Тогда
			РазмерБуфера = Число(РазмерСообщения);
		Иначе
			РазмерБуфера = 1024;
		КонецЕсли;
		Тело = Новый БуферДвоичныхДанных(0);
		Буфер = Новый БуферДвоичныхДанных(РазмерБуфера);
		Поток = Сообщение.ПолучитьТелоКакПоток();
		Пока Истина Цикл
			Прочитано = Поток.Прочитать(Буфер, 0, РазмерБуфера);
			Если Прочитано > 0 Тогда
				Тело = Тело.Соединить(Буфер);
			КонецЕсли;
			Если Прочитано < РазмерБуфера Тогда
				Прервать;
			КонецЕсли;
		КонецЦикла;  
		//////////////////////////////////////    
		ТелоСтрока = ПолучитьСтрокуИзБуфераДвоичныхДанных(Тело);     
	Исключение      
		Возврат;
	КонецПопытки; 
	Если ЗначениеЗаполнено(ТипВходящегоСообщения) Тогда
		
		СтруктураРегистра = Новый Структура;
		СтруктураРегистра.Вставить("ИдентификаторСообщения", Новый УникальныйИдентификатор);
		СтруктураРегистра.Вставить("Получатель", Перечисления.битПолучателиИнформационныеСистемы.СторонниеСистемы);
		СтруктураРегистра.Вставить("ТелоСообщения", СокрП(ТелоСтрока));
		СтруктураРегистра.Вставить("ID", ID);
		СтруктураРегистра.Вставить("ДатаПолученияОтвета", ТекущаяДатаСеанса());
		СтруктураРегистра.Вставить("ДатаОтправки", ТекущаяДатаСеанса());
		СтруктураРегистра.Вставить("ТипЗапроса", ТипВходящегоСообщения);
		РегистрыСведений.БитПолученныеСообщения.ЗаписатьВРегистрПолученныеСообщения(СтруктураРегистра);
		
	Иначе 
		СтруктураРегистра = Новый Структура;
		СтруктураРегистра.Вставить("ИдентификаторСообщения", Новый УникальныйИдентификатор);
		СтруктураРегистра.Вставить("Получатель", Перечисления.битПолучателиИнформационныеСистемы.СторонниеСистемы);
		СтруктураРегистра.Вставить("ОписаниеОшибки", СокрП(ТелоСтрока));
		СтруктураРегистра.Вставить("ID", ID);
		СтруктураРегистра.Вставить("ОшибкаОбработки", Истина);
		СтруктураРегистра.Вставить("ДатаПолученияОтвета", ТекущаяДатаСеанса());
		СтруктураРегистра.Вставить("ДатаОтправки", ТекущаяДатаСеанса());
		СтруктураРегистра.Вставить("ТипЗапроса", "error");
		РегистрыСведений.БитПолученныеСообщения.ЗаписатьВРегистрПолученныеСообщения(СтруктураРегистра);
		
	КонецЕсли;
КонецПроцедуры

 

 

В данной процедуре смотрим на значение параметра сообщения “type”, если они заполнено, то забираем с канала сообщение интеграции и сохраняем его в РС «Полученные сообщения»

В отладке все вопросы должны уйти, если все же останутся вопросы, пишите в комментариях, дополню статью.

Впечатления от использования шины:

Общее впечатление по продукт у 1С:Шина положительное, а теперь подробней.

Удобным назову способ программирования - это встроенная ide, хотя она периодически подглючивает, жмешь F5, чтобы обновить страницу в браузере, а у тебя запускается приложение в отладке.

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

Вообще складывается впечатление, что синтаксис 1С Элемента позаимствован из современных web скриптовых языков.

Существуют 2 документации:

 

Рисунок 12. Виды документаций 1С:Шина

 

Документация  - это про установку, про описание объектов и примеры кода.

Синтакс-Помощник - это описание методов, которые есть в шине.

Из недостатков: 

Документация очень скудная и часто  приходится в отладке подбирать синтаксис.  А если есть примеры, то они прям очень простые или из идеальной жизни без вариаций.

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

При условии, что я не имел опыта программирования на 1С:Элемент и сам продукт 1С: Шина не щупал руками, на реализацию функционала ушла неделя.

Имея подобную статью до начала реализации, это значительно ускорило процесс разработки, чего и вам желаю.

 

14.01.2025 внес изменения и исправления ошибок

- добавлено перечисление для хранения статусов

- в Параметр выведено ранее захардкоженное значение.

- исправлена ошибка с выводом ответного json

- добавлен ресурс в РС для хранения статуса

- исправлен запрос с учетом добавленного статуса

 

28.01.2025

Добавил отдельный архив для версии шины 6, в статье дополнил, ссылка на изменения.

- Обновлена 1С:Шина до версии 6.1.6

- Выполнен рефакторинг под 6 версию шины (основное изменение)

- исправлены ошибки по сортировки сообщений в массиве по статусам

- для авторизации теперь используются токены, поэтому есть изменения в правах. Если у вас будет 403 ошибка в постмане, то после изменения прав доступа к сервису выполните "Пересчитать права доступа" .

- изменено измерение СторонниеСистемы - > Пользователь в РС "СообщенияДляСтороннихСистем"

Шина esb http сервис интеграции версия 1С:Шина

См. также

SALE! 10%

Перенос данных 1C Программист Платформа 1С v8.3 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос документов, начальных остатков и справочной информации из УПП 1.3 в ERP 2 | из УПП 1.3 в УТ 11 | из УПП в КА 2 | Правила конвертации (КД 2) | Более 360 предприятий выполнили переход с использованием этого продукта! | Сэкономьте время - используйте готовое решение для перехода! | Позволяет перенести из УПП 1.3 в ERP / УТ 11 / КА 2 всю возможную информацию | В переносе есть фильтр по организации и множество других опциональных параметров выгрузки | Есть несколько алгоритмов выгрузки остатков на выбор

55778 50200 руб.

04.08.2015    168869    350    280    

385

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

Правила в универсальном формате обмена для ERP 2.5, КА 2.5, УТ 11.5, БП 3.0, Розница, УНФ, для последних версий конфигураций. Ссылки на другие конфигурации в описании публикации. Правила совместимы со всеми другими версиями конфигураций новыми и старыми, поддерживающими обмен и синхронизацию в формате EnterpriseData. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

27660 24894 руб.

12.06.2017    143782    830    297    

430

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 Россия Управленческий учет Платные (руб)

Перенос данных из 1С:Управление торговлей 10.3 в 1С:Управление торговлей 11.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УТ 10.3 (10.3.88.x) и УТ 11.5 (11.5.20.x), также подходят для релиза 11.5 (11.5.19.x).

35000 31500 руб.

23.07.2020    53967    238    73    

194

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из ERP в ЗУП 3 | из КА 2 в ЗУП | Готовые правила конвертации данных (КД 2) для переноса остатков, документов с движениями и справочной информации 3 | Есть перенос начальной задолженности по зарплате и начальной штатной расстановки на выбранную дату | Обороты за прошлые годы (данные для расчета среднего) переносятся свернуто в документ "Перенос данных" | Есть фильтр по организациям | Документы за текущий период переносятся сразу с движениями, поэтому не потребуется делать перерасчеты | Перенос можно проверить перед покупкой, обращайтесь!

53111 47800 руб.

03.12.2020    37499    100    68    

96

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.237.x) и БП 3.0 (3.0.166.x). Правила подходят для версии ПРОФ и КОРП.

35000 31500 руб.

15.12.2021    25057    175    51    

133

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос данных из ERP в БП 3 | из КА 2 в БП 3 | из УТ 11 в БП 3 | из ЕРП в БП 3 | Сэкономьте время - используйте готовое решение для перехода! | Перенос разработан в формате КД 2 (правила конвертации данных) | Переносятся все возможные виды документов, начальных остатков и нормативно-справочная информация| Можно опционально выгружать каждую пару "номенклатура+характеристика" как отдельную номенклатуру | Есть выгрузка настроек счетов учета и зарплатных данных из ERP / КА 2 | Можно проверить на вашем сервере перед покупкой

55778 50200 руб.

15.04.2019    72976    188    152    

127

Перенос данных 1C Программист Бухгалтер Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет НДФЛ ФОМС, ЕФС Платные (руб)

Обработки для быстрого перехода с конфигураций «КАМИН:Расчет заработной платы 3.0», «КАМИН:Зарплата для бизнеса 4.0» и «КАМИН:Зарплата 5.0» на конфигурацию «Зарплата и управление персоналом» версии 3.1.

12000 руб.

25.09.2016    81833    332    253    

282

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена | Можно выполнить переход с УПП на БП 3 или запускать выгрузку данных за выбранный период времени | Переносятся документы, начальные остатки и вся справочная информация | Есть фильтр по организации и множество других параметров выгрузки | Поддерживается несколько сценариев работы: как первичный полный перенос, так и перенос только новых документов | Перенос данных возможен в "1С: Бухгалтерия 3.0" версии ПРОФ, КОРП или базовую | Переход с "1С: УПП1.3" / "1С:КА 1.1" на "1С:БП3.0" с помощью правил конвертации будет максимально комфортным! | Можно бесплатно проверить перенос на вашем сервере!

48278 43450 руб.

25.02.2015    172245    308    259    

385
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Merkalov 12 27.12.24 10:05 Сейчас в теме
Очистить очередь выгрузки из шины до сих пор нельзя? Когда занимался, приходилось удалять "группу участников" (что является просто невероятным костылем). Скорость её работы под вопросом, надежность под очень большим вопросом.
Гит (год назад) так и не заработал.
2. skillman 20 27.12.24 10:14 Сейчас в теме
(1)
Встроенного механизма очистки очереди действительно нет.
Я более скажу, загрузить дамп с приложением это тоже не прозрачно пришлось даже в архив инструкцию вложить инструкцию, как это сделать.
Но это мы с вами обсуждаем админские штуки по управлению, это не основной функционал, поэтому думаю он еще не реализован.
По поводу быстродействия на ютубе видел стрим ребят из Раруса, они разбирали пример интеграции и приводили замеры, выглядит очень даже не плохо (по скорости)
Я думаю нагрузочное тестирование для Шины это отдельный пласт с применением Apache JMeter
Но если речь о именно о транспорте то есть ощущение , сугубо личное что 10000 сообщений в час это не проблема. А вот если есть преобразование, т осами понимете что во что преобразовывать и сколько ресурсов на это будет потрачено.
скажу что 4 версия по сравнению с предыдущими шагнула по функционала вперед, это инфа от коллег, которые ранее делали проект на 1с:Шина.
Гит не щупал, ничего не могу сказать.
Merkalov; +1 Ответить
4. Mi11er 99 28.12.24 11:01 Сейчас в теме
(2) 10k сообщений в час, это очень медленно )
Пока что шина , это дорогая и не понятная игрушка. Возможно в 25м будут какие то изменения в лучшую сторону
5. skillman 20 28.12.24 11:52 Сейчас в теме
(4)
Я эту цифру где-ту слышал. не могу сказать где.
Но давайте по другому посмотрим на эту цифру.
Логично было уточнить каких сообщений. Объем, какие преобразования с ними выполняются.
Какой сервер используется?
Я думаю бессмысленно говорить про производительность.
По производительсности будет возможность получить стенд и протестировать, приду расскажу.
А по поводу цены 250 тыс за шину ну недорого это.
тот же Rabbit бесплатен, то dll денег, я про коммерческий вариант от Серебрянной пули.
Если начинаете сравнивать, то давайте более полный расклад.
Кстати да развивать есть куда продукту, интересно планы на развитие есть?
3. user1019287 27.12.24 20:23 Сейчас в теме
Писал обмен с битриксом по единой точке входа через шину. Столкнулся с проблемой разбора сообщения с последующей маршрутизацией. Т. К. Поток при первом чтении закрывался, пришлось сохранять сообщение во временный файл, а затем его несколько раз читать. Может кто сталеивался со сбросом потока чтения в начало?
6. skillman 20 28.12.24 11:55 Сейчас в теме
(3) Да я тоже с этим столкнулся.
Смысл я понял прочитал поток освободи память.
В коде у меня тоже есть вариант решения данной проблемы, даже коммент оставил, чтобы было понятно зачем мне еще один поток
7. quazare 3870 06.01.25 14:28 Сейчас в теме
Интересная конечно штука, но пока нет ни времени с ней разбираться, ни серьезных заказчиков и проектов под нее.. а под небольшие проекты, где требуется обмен - есть альтернативы "на коленке"


И что это за сервисы - где 10 тыс сообщений в час ???
8. skillman 20 06.01.25 18:07 Сейчас в теме
(7) Думаю шина имеет место когда нужна гарантированная доставка -это в моем понимание главная ценность.

Количество сообщений 10тыс, .. ну обычно не между двумя система шина используется для обмена а для многообразия и в таком.
И опять 10 тыс сообщений, а не 10 тыс пакетов в котором по 1000 сообщений.
Давай про цифры поговорим, когда будет кейс про который можно рассказать и показать.
Статья немного о другом.
9. triviumfan 98 09.01.25 12:03 Сейчас в теме
Есть ли тут люди с опытом шины "Датареон"? Насколько этот продукт хорош и конкурентноспособен с другими шинами?
10. skillman 20 09.01.25 23:22 Сейчас в теме
(9)
Насколько мне известно, Датареон организовывает обучение своих партнеров. Может в этом направлении попробовать поискать специалистов.
НА прошлом месте работы когда мы партнериться (продавать и внедрять их шину) хотели с Датареоном, мы делали 2 списка. один список людей кто учиться устанавливать то есть администрировать,а вторая уже программировать.
Оставьте свое сообщение