Почему при отправке запроса истории по справке Б в ЕГАИС возникает ошибка несоответствия формату DocType=[QueryFormB]?

Программист Управленческий учет Торговля и дистрибуция
← На главную

При самостоятельной реализации интеграции 1С с транспортным модулем ЕГАИС (УТМ) разработчики нередко сталкиваются с ситуацией, когда сформированный XML-документ полностью соответствует документации, но сервер ЕГАИС возвращает квитанцию с отказом следующего содержания:


<tc:Result>
    <tc:Conclusion>Rejected</tc:Conclusion>
    <tc:ConclusionDate>2016-11-21T08:18:50.3231738</tc:ConclusionDate>
    <tc:Comments>Документ: [...] не соответствует заявленному формату: DocType=[QueryFormB]</tc:Comments>
</tc:Result>

Разберем детально, почему возникает такое несоответствие, как правильно составить XML-пакет для получения движений по форме Б и на какие нюансы протокола УТМ следует обратить особое внимание.

Причина 1. Ошибка в адресе отправки (эндпоинте REST API)

Проанализируем текст ошибки: DocType=[QueryFormB]. Это ключевая улика. Сервер ЕГАИС сообщает, что он ожидал документ типа QueryFormB (запрос информации о самой справке Б), в то время как в теле XML был передан запрос движений QueryFormBHistory.

Такая ситуация возникает из-за специфики REST API универсального транспортного модуля. Тип документа для ЕГАИС определяется не только внутренним содержимым XML-файла, но и адресом HTTP POST-запроса, на который этот файл отправляется. В именовании методов УТМ кроется частая ловушка:

  1. Внутренний XML-тег запроса движений называется ns:QueryFormBHistory.
  2. Относительный URL для отправки POST-запроса в УТМ имеет обратный порядок слов: /opt/in/QueryHistoryFormB.
  3. Если разработчик копирует код отправки обычного запроса справки Б на адрес /opt/in/QueryFormB, УТМ автоматически присваивает исходящему пакету транспортный заголовок DocType=[QueryFormB]. В результате парсер ЕГАИС пытается валидировать тело документа по XSD-схеме для обычной справки и бракует пакет.

Для исправления проблемы необходимо проверить команду отправки HTTP-запроса и указать точный относительный путь:


// Корректный адрес для запроса истории движений по форме Б:
АдресРесурса = "/opt/in/QueryHistoryFormB";

// Ошибочный адрес (приведет к DocType=[QueryFormB]):
// АдресРесурса = "/opt/in/QueryFormB";

Причина 2. Ошибки в пространствах имен XML (Namespace)

Посмотрим на частую ошибку формирования схемы. При ручном создании XML-дерева через объекты DOM нередко путают пространства имен для параметров запроса. В частности, ошибочно объявляют несуществующее пространство http://fsrar.ru/WEGAIS/QueryHistFormB вместо стандартного http://fsrar.ru/WEGAIS/QueryParameters.

Рассмотрим эталонный пример структуры XML-документа для запроса движений по форме Б:


<?xml version="1.0" encoding="UTF-8"?>
<ns:Documents Version="1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01"
    xmlns:qp="http://fsrar.ru/WEGAIS/QueryParameters">
    <ns:Owner>
        <ns:FSRAR_ID>020000149497</ns:FSRAR_ID>
    </ns:Owner> 
    <ns:Document>
        <ns:QueryFormBHistory>
            <qp:Parameters>
                <qp:Parameter>
                    <qp:Name>RFB</qp:Name>
                    <qp:Value>FB-000000176747601</qp:Value>
                </qp:Parameter>
            </qp:Parameters>
        </ns:QueryFormBHistory>
    </ns:Document>
</ns:Documents>

Реализация формирования и отправки запроса в 1С

Выясним, как правильно реализовать этот механизм в коде 1С. Использование устаревших COM-объектов Microsoft.XMLDOM создает зависимость от операционной системы Windows. Рекомендуется использовать встроенные средства платформы 1С — объект ЗаписьXML.


Функция СформироватьXML_ЗапросИсторииФормыБ(ФСРАР_ИД, НомерСправкиБ)
    
    ЗаписьXML = Новый ЗаписьXML;
    ПараметрыЗаписи = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Ложь);
    ЗаписьXML.УстановитьСтроку(ПараметрыЗаписи);
    
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    // Корневой узел Documents с необходимыми пространствами имен
    ЗаписьXML.ЗаписатьНачалоЭлемента("ns:Documents");
    ЗаписьXML.ЗаписатьАтрибут("Version", "1.0");
    ЗаписьXML.ЗаписатьАтрибут("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    ЗаписьXML.ЗаписатьАтрибут("xmlns:ns", "http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01");
    ЗаписьXML.ЗаписатьАтрибут("xmlns:qp", "http://fsrar.ru/WEGAIS/QueryParameters");
    
    // Владелец запроса (FSRAR_ID организации)
    ЗаписьXML.ЗаписатьНачалоЭлемента("ns:Owner");
    ЗаписьXML.ЗаписатьНачалоЭлемента("ns:FSRAR_ID");
    ЗаписьXML.ЗаписатьТекст(СокрЛП(ФСРАР_ИД));
    ЗаписьXML.ЗаписатьКонецЭлемента(); // ns:FSRAR_ID
    ЗаписьXML.ЗаписатьКонецЭлемента(); // ns:Owner
    
    // Тело документа
    ЗаписьXML.ЗаписатьНачалоЭлемента("ns:Document");
    ЗаписьXML.ЗаписатьНачалоЭлемента("ns:QueryFormBHistory");
    ЗаписьXML.ЗаписатьНачалоЭлемента("qp:Parameters");
    
    // Параметр RFB
    ЗаписьXML.ЗаписатьНачалоЭлемента("qp:Parameter");
    ЗаписьXML.ЗаписатьНачалоЭлемента("qp:Name");
    ЗаписьXML.ЗаписатьТекст("RFB");
    ЗаписьXML.ЗаписатьКонецЭлемента(); // qp:Name
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("qp:Value");
    ЗаписьXML.ЗаписатьТекст(СокрЛП(НомерСправкиБ));
    ЗаписьXML.ЗаписатьКонецЭлемента(); // qp:Value
    ЗаписьXML.ЗаписатьКонецЭлемента(); // qp:Parameter
    
    ЗаписьXML.ЗаписатьКонецЭлемента(); // qp:Parameters
    ЗаписьXML.ЗаписатьКонецЭлемента(); // ns:QueryFormBHistory
    ЗаписьXML.ЗаписатьКонецЭлемента(); // ns:Document
    
    ЗаписьXML.ЗаписатьКонецЭлемента(); // ns:Documents
    
    Возврат ЗаписьXML.Закрыть();
КонецФункции

Для передачи полученного файла в транспортный модуль воспользуемся объектами HTTPСоединение и HTTPЗапрос. Важно помнить, что УТМ принимает документы через составной запрос multipart/form-data с именем поля xml_file:


Процедура ОтправитьВУТМ(СерверУТМ, ПортУТМ, ИмяФайлаXML)
    
    НТТР = Новый HTTPСоединение(СерверУТМ, ПортУТМ);
    
    // Внимание на точный URL ресурса:
    Ресурс = "/opt/in/QueryHistoryFormB";
    
    // Подготовка заголовков multipart/form-data
    Разделитель = "----" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
    
    Запрос = Новый HTTPЗапрос(Ресурс);
    Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Разделитель);
    
    // Формирование тела запроса с передачей xml_file
    // После успешной отправки УТМ вернет XML с внутренним идентификатором запроса
    Ответ = НТТР.ОтправитьДляОбработки(Запрос);
    
    Если Ответ.КодСостояния = 200 Тогда
        // Обработка успешного ответа УТМ (получение URL с docId)
    Иначе
        ВызватьИсключение "Ошибка отправки в УТМ: " + Строка(Ответ.КодСостояния);
    КонецЕсли;
    
КонецПроцедуры

Ограничения и регламенты ЕГАИС при работе с запросами движений

Разберем практические правила работы с запросами истории справок Б, чтобы избежать блокировок со стороны контролирующей системы:

  1. Интервал повторных запросов: В ЕГАИС установлено жесткое ограничение на частоту генерации информационных отчетов. Нельзя запрашивать одну и ту же справку Б подряд. Рекомендуемый таймаут между повторными запросами по одному регистрационному номеру составляет не менее 10–15 минут. При нарушении интервала сервер вернет отказ с формулировкой о превышении частоты запросов.
  2. Очередь обмена УТМ: Транспортный модуль отправляет документы в центральную базу ЕГАИС не мгновенно, а регламентными пакетами во время сеансов связи (обычно раз в несколько минут). Ответ с документом HistoryFormB также поступает не сразу, а по мере формирования выгрузки на сервере ФСРАР.
  3. Состав данных в ответе: Следует учитывать, что полученный ответ HistoryFormB отображает только ту цепочку товародвижения (ТТН, акты списания, акты постановки на баланс), в которой организация с указанным FSRAR_ID являлась прямым грузоотправителем или грузополучателем. Движения между сторонними участниками рынка до момента поставки на ваш склад будут скрыты.
← На главную