Оформление в системе Меркурий транспортной операции через XSLT-запрос


В данной статье рассматривается один из методов построения запросов к Ветис.API из учетной системы. Метод основан на применении XSLT-запроса к результатам стандартной выгрузки данных учетной системы в XML-формат. Статья продолжает цикл работ, посвященный интеграции учетных систем на базе 1С: Предприятие, с использованием методов XML/XSLT.

Введение

Напомню, мы уже обсуждали методы конвертации данных объектов информационной базы 1С:Предприятие 7.7 в XML-формат, когда говорили о выгрузке данных в другую информационную систему [ссылка] и о таком, я считаю, экзотическом ее (выгрузки) применении, как формирование движений документа по регистрам оперативного учета [ссылка].

В данной статье, мы за исходный файл, возьмем результат выгрузки в XML-формат данные узлов «ns2:stockEntry» из результата запроса «GetStockEntryList», в объединении с набором движений по партиям товара, вообще говоря, нескольких документов «РасходнаяНакладная», объединяемых в одну транспортную транзакцию (развозку). К этому файлу, мы применим XSLT-преобразование, в целях получения XML-файл в формате запроса на оформление транспортной транзакции к WEB-серверу ИС «Меркурий», реализующего Ветис.API [ссылка].

Итак,

XSLT-запрос:

        "<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" xmlns:xs=""http://www.w3.org/2001/XMLSchema""
        |xmlns:bs=""http://api.vetrf.ru/schema/cdm/base"" xmlns:apl=""http://api.vetrf.ru/schema/cdm/application"" 
        |xmlns:ws=""http://api.vetrf.ru/schema/cdm/application/ws-definitions"" xmlns:merc=""http://api.vetrf.ru/schema/cdm/mercury/applications""
        |xmlns:argc=""http://api.vetrf.ru/schema/cdm/argus/common"" xmlns:vetd=""http://api.vetrf.ru/schema/cdm/mercury/vet-document"" 
        |xmlns:ns2=""http://api.vetrf.ru/schema/cdm/mercury/vet-document""
        |xmlns:ikar=""http://api.vetrf.ru/schema/cdm/ikar"" xmlns:shp=""http://api.vetrf.ru/schema/cdm/argus/shipment""
        |xmlns:ent=""http://api.vetrf.ru/schema/cdm/cerberus/enterprise"" xmlns:prod=""http://api.vetrf.ru/schema/cdm/argus/production""
        |xmlns:env=""http://schemas.xmlsoap.org/soap/envelope/"" >
        |<xsl:key name=""delivery"" match=""Строка"" use=""Документ""/>
        |<xsl:key name=""doc"" match=""Документ.РасходнаяНакладная"" use=""Ref""/>
        |<xsl:key name=""client"" match=""Справочник.Контрагенты"" use=""Ref""/>
        |<xsl:key name=""firm"" match=""Справочник.Фирмы"" use=""Ref""/>
        |<xsl:key name=""auto"" match=""Справочник.Автомобили"" use=""Ref""/>
        |<xsl:key name=""tovar"" match=""Справочник.Номенклатура"" use=""Ref""/>
        |<xsl:key name=""stockItem"" match=""ns2:stockEntry"" use=""ns2:batch/ns2:productItem/bs:guid""/>
        |<xsl:key name=""subProduct"" match=""Справочник.схСубПродукты"" use=""Ref""/>
        |<xsl:key name=""stockSubProduct"" match=""ns2:stockEntry"" use=""ns2:batch/ns2:subProduct/bs:guid""/>
        |<xsl:template match=""/"">
        |<ROOT>
        |    <xsl:for-each select=""//Строка[(generate-id(.)=
        |        generate-id(key('delivery', Документ)[1]))]"">
        |        <xsl:sort select=""delivery""/>
        |        <xsl:for-each select=""key('delivery', Документ)"">
        |            <xsl:if test=""position() = 1"">
        |                <xsl:variable name=""doc"" select=""Документ""/>
        |                <xsl:element name=""merc:delivery"">
        |                    <xsl:for-each select=""key('doc', Документ)"">
        |                        <xsl:if test=""position() = 1"">
        |                            <xsl:variable name=""issueNumber"" select=""НомерДок""/>
        |                            <xsl:variable name=""issueDate"" select=""ДатаДок""/>
        |                            <xsl:element name=""vetd:deliveryDate"">
        |                                <xsl:value-of select=""$issueDate""/>
        |                            </xsl:element>
        |                            <xsl:for-each select=""key('firm', Фирма1)"">
        |                                <xsl:if test=""position() = 1"">
        |                                    <xsl:element name=""vetd:consignor"">
        |                                        <xsl:element name=""ent:businessEntity"">
        |                                            <xsl:element name=""bs:guid"">
        |                                                <xsl:value-of select=""схГУИдХС""/>
        |                                            </xsl:element>
        |                                        </xsl:element>
        |                                        <xsl:element name=""ent:enterprise"">
        |                                            <xsl:element name=""bs:guid"">
        |                                                <xsl:value-of select=""схГУИдПредприятия""/>
        |                                            </xsl:element>
        |                                        </xsl:element>
        |                                    </xsl:element>
        |                                </xsl:if>
        |                            </xsl:for-each>
        |                            <xsl:for-each select=""key('client', Клиент)"">
        |                                <xsl:if test=""position() = 1"">
        |                                    <xsl:element name=""vetd:consignee"">
        |                                        <xsl:element name=""ent:businessEntity"">
        |                                            <xsl:element name=""bs:guid"">
        |                                                <xsl:value-of select=""схГУИдХС""/>
        |                                            </xsl:element>
        |                                        </xsl:element>
        |                                        <xsl:element name=""ent:enterprise"">
        |                                            <xsl:element name=""bs:guid"">
        |                                                <xsl:value-of select=""схГУИдПредприятия""/>
        |                                            </xsl:element>
        |                                        </xsl:element>
        |                                    </xsl:element>
        |                                </xsl:if>
        |                            </xsl:for-each>
        |                            <xsl:for-each select=""key('delivery', $doc)"">
        |                                <xsl:element name=""vetd:consignment"">
        |                                    <xsl:attribute name=""id"">
        |                                        <xsl:value-of select=""concat('cons',НомерСтроки)""/>
        |                                    </xsl:attribute>
        |                                    <xsl:element name=""vetd:volume"">
        |                                        <xsl:value-of select=""количество""/> 
        |                                    </xsl:element>
        |                                    <xsl:for-each select=""key('tovar', товар)"">
        |                                        <xsl:if test=""position() = 1"">
        |                                            <xsl:element name=""vetd:unit"">
        |                                                <xsl:element name=""bs:uuid"">069792f0-053d-11e1-99b4-d8d385fbc9e8</xsl:element>
        |                                            </xsl:element>
        //|                                            <xsl:element name=""vetd:packingList"">
        //|                                                <xsl:element name=""argc:packingForm"">
        //|                                                    <xsl:element name=""bs:uuid""/>
        //|                                                </xsl:element>
        //|                                            </xsl:element> 
        |                                            <xsl:element name=""vetd:sourceStockEntry"">
        |                                                <xsl:element name=""bs:uuid"">
        |                                                    <xsl:choose>
        |                                                        <xsl:when test=""normalize-space(схГУИД/.)=''"">
        |                                                            <xsl:for-each select=""key('subProduct', схСубПродукт)"">
        |                                                                <xsl:if test=""position() = 1"">
        |                                                                    <xsl:for-each select=""key('stockSubProduct', ГУИД)"">
        |                                                                        <xsl:if test=""position() = 1"">
        |                                                                            <xsl:value-of select=""bs:uuid""/> 
        |                                                                        </xsl:if>
        |                                                                    </xsl:for-each>
        |                                                                </xsl:if>
        |                                                            </xsl:for-each>
        |                                                        </xsl:when>
        |                                                        <xsl:otherwise>
        |                                                            <xsl:for-each select=""key('stockItem', схГУИД)"">
        |                                                                <xsl:if test=""position() = 1"">
        |                                                                    <xsl:value-of select=""bs:uuid""/> 
        |                                                                </xsl:if>
        |                                                            </xsl:for-each>
        |                                                        </xsl:otherwise>
        |                                                    </xsl:choose>
        |                                                </xsl:element>
        |                                            </xsl:element>
        |                                        </xsl:if>
        |                                    </xsl:for-each>
        |                                </xsl:element>
        |                            </xsl:for-each>
        |                            <xsl:for-each select=""key('auto', Автомобиль)"">
          |                                <xsl:if test=""position() = 1"">
          |                                    <xsl:element name=""vetd:accompanyingForms"">
        |                                        <xsl:element name=""vetd:waybill"">
        |                                            <xsl:element name=""shp:issueNumber"">
        |                                                   <xsl:value-of select=""$issueNumber""/>
        |                                            </xsl:element>
        |                                            <xsl:element name=""shp:issueDate"">
        |                                                   <xsl:value-of select=""substring($issueDate, 1, 10)""/>
        |                                            </xsl:element>
        |                                            <xsl:element name=""shp:type"">2</xsl:element>
        //|                                            <xsl:element name=""shp:broker"">
        //|                                                <xsl:element name=""bs:guid""/>
        //|                                            </xsl:element> 
        |                                            <xsl:element name=""shp:transportInfo"">
        |                                                <xsl:element name=""shp:transportType"">1</xsl:element>
        |                                                <xsl:element name=""shp:transportNumber"">
        |                                                    <xsl:element name=""shp:vehicleNumber"">
        |                                                        <xsl:value-of select=""ГосНомер""/>
        |                                                    </xsl:element>
        |                                                </xsl:element>
        |                                            </xsl:element>
        |                                            <xsl:element name=""shp:transportStorageType"">VENTILATED</xsl:element>
        |                                        </xsl:element>
        |                                        <xsl:element name=""vetd:vetCertificate"">
        |                                            <xsl:element name=""vetd:purpose"">
        |                                                <xsl:element name=""bs:guid"">5b91af60-e089-11e1-bcf3-b499babae7ea</xsl:element>
        |                                            </xsl:element>
        |                                            <xsl:element name=""vetd:transportInfo"">
        |                                                <xsl:element name=""shp:transportType"">1</xsl:element>
        |                                                <xsl:element name=""shp:transportNumber"">
        |                                                    <xsl:element name=""shp:vehicleNumber"">
        |                                                        <xsl:value-of select=""ГосНомер""/>
        |                                                    </xsl:element>
        |                                                </xsl:element>
        |                                            </xsl:element>
        |                                            <xsl:element name=""vetd:transportStorageType"">VENTILATED</xsl:element>
        |                                            <xsl:element name=""vetd:cargoInspected"">true</xsl:element>
        |                                            <xsl:element name=""vetd:cargoExpertized"">false</xsl:element>
        |                                            <xsl:element name=""vetd:expertiseInfo"">Экспертизу провели, всё хорошо</xsl:element>
        |                                            <xsl:element name=""vetd:confirmedBy"">
        |                                                <xsl:element name=""argc:fio"">ФИО подписывающего ВСД</xsl:element>
        |                                                <xsl:element name=""argc:post"">Ветврач</xsl:element>
        |                                            </xsl:element>
        |                                            <xsl:element name=""vetd:locationProsperity"">Местность благополучна</xsl:element>
        |                                        </xsl:element>
        |                                    </xsl:element>
        |                                </xsl:if>
        |                            </xsl:for-each>
        |                        </xsl:if>
        |                    </xsl:for-each>
        |                </xsl:element>
        |            </xsl:if>
        |        </xsl:for-each>
        |    </xsl:for-each>
        |</ROOT>
        |</xsl:template>
        |</xsl:stylesheet>"

Результатом данного XSLT-преобразования будет XML-узел, который необходимо будет, в ходе формирования запроса к приложению, подчинить узлу «merc:prepareOutcomingConsignmentRequest».

Собственные комментарии

1. Данный шаблон выполняет сопоставление объектов из 1С таких, как «Клиент», «Фирма», «Автомобиль» и, что самое главное, выбор записи журнала под «Товар» с идентификаторами ИС Меркурий. Причем, для такого сопоставления с данными никаких дополнительных действий не требуется. Это просто применение шаблона к результату «стандартной» выгрузки объекта 1С в XML.

2. Для товара в «consignment» подбирается самая первая «stockEntry» в исходном файле. Поэтому, в текущем решении предполагается, что журнал «свернут» по «productItem» (SKU). В данном решении, также, предусматривается возможность подбирать записи журнала по субпродукту, то есть, до третьего уровня классификатора продукции ИС Меркурий.

3. Скорость работы шаблона вполне удовлетворительная. Гораздо больше времени занимает выгрузка набора движений по партиям товара для развозки (несколько документов продаж), что, впрочем, несколько «лечится» применением шаблона-фильтра объектов 1С на этапе выгрузки.