Работаем с веб-сервисом 1С из приложения на Android

При работе над фронтом для кафе появилась задача обращаться к веб-сервису 1С из приложения, разрабатываемого на Android. Google мне дал несколько ответов на тему как вообще работать с SOAP, используя библиотеку ksoap2-android. Они помогли в передаче простых типов, но когда дело дошло до передачи массива, пришлось немного подумать.

При работе над фронтом для кафе появилась задача обращаться к веб-сервису 1С из приложения, разрабатываемого на Android. Google мне дал несколько ответов на тему как вообще работать с SOAP, используя библиотеку ksoap2-android. Они помогли в передаче простых типов, но когда дело дошло до передачи массива, пришлось немного подумать. 

Веб-сервис на стороне 1С

В конфигурации 1С создан веб-сервис с методом WriteSale. Метод принимает несколько параметров, один из которых, items, имеет тип ItemsSold (задан в пакете XDTO конфигурации). Остальные параметры имеют простые типы (string, datetime). Скрин конфигурации:

Тип ItemsSold имеет единственное свойство Items, для которого установлено свойство «Максимальное количество» в -1, указывая на то, что это массив. Тип этого свойства — ItemSold. Скрин:

У типа ItemSold все свойства простого типа. Метод WriteSale веб-сервиса имеет следующий код:

Функция WriteSale(id, date, clientCardNumber, discountRate, items, deptId, bonuses, premiumBonuses)
    Текст = "OK";
    Попытка
        Карточка = ПолучитьКартуПоНомеру(clientCardNumber);
        ПроцентСкидки = Число(discountRate);
        Подразделение = НайтиПодразделениеПоПрефиксу(deptId);
        //...
        
        Документ = НайтиДокументПоКодуДате(date, Число(id), Подразделение);
        Если Не ЗначениеЗаполнено(Документ) Тогда
            Объект = Документы.ПолныйЧек.СоздатьДокумент();
            Объект.Дата = date;
            Объект.КафеНомерДокумента = id;
        Иначе
            Объект = Документ.ПолучитьОбъект();
        КонецЕсли;
        
        Объект.ОплатаБонусами = Число(bonuses);
        //...
        Объект.Продажи.Очистить();
        // Здесь идет использование массива
        Для Каждого item Из items.Items Цикл
            Номенклатура = НайтиНоменклатуруПоКоду(item.Code);
            Строка = Объект.Продажи.Добавить();
            Строка.Количество = Число(item.Quantity);
            //...
        КонецЦикла;
        
        Объект.Записать(РежимЗаписиДокумента.Проведение);
        
    Исключение
        Текст = ОписаниеОшибки();
        ЗаписьЖурналаРегистрации("Cafe.WriteSale - исключение: " + Текст, УровеньЖурналаРегистрации.Ошибка);
        ВызватьИсключение;
    КонецПопытки;
    // Возвращаем текст ошибки или "ОК"
    Возврат Текст;
КонецФункции

Клиент на стороне Android

Для обращения к веб-сервису из приложения Android написал следующий код (в соответствии с хорошим примером простого клиента:

protected String call() throws Exception {
            result = null;
            HttpTransportSE httpTransport = new HttpTransportSE(uri);
            httpTransport.debug = true;
            String resultString;

            SoapObject request = new SoapObject(namespace, methodName);
            request.addProperty("id", sale.getId());
            SimpleDateFormat dateFormat = new SimpleDateFormat(
                    "yyyy-MM-dd'T'HH:mm:ss");
            request.addProperty("date", dateFormat.format(sale.getDate()));
            request.addProperty("clientCardNumber", sale.getCardNumber());
            request.addProperty("bonuses", Double.toString(sale.getBonuses()));
            //...

            // see - http://code.google.com/p/ksoap2-android/wiki/CodingTipsAndTricks#Adding_an_array_of_complex_objects_to_the_request
            SoapObject sales = new SoapObject(namespace, "items");
            for (SaleItemInformation item : sale.getSales()) {
                SoapObject itemSoap = new SoapObject(namespace,
                        "Items");
                itemSoap.addProperty("Code", item.getItem().getSourceCode());
                itemSoap.addProperty("Quantity",
                        Double.toString(item.getQuantity()));
                //...
                sales.addSoapObject(itemSoap);
            }
            request.addSoapObject(sales);
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                    SoapEnvelope.VER11);
            // Тоже важный элемент - не выводит типы данных в элементах xml
            envelope.implicitTypes = true;
            envelope.setOutputSoapObject(request);
            try {
                httpTransport.call(soapAction, envelope);
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
            resultString = envelope.getResponse().toString();
            return resultString;
        }

Вроде бы код выглядит правильно, формирует красивый xml-запрос:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
    <n0:WriteSale id="o0" c:root="1" xmlns:n0="http://www.xxxxx.ru">
        <date i:type="d:string">Thu May 31 16:13:08 YEKST 2012</date>
        <clientCardNumber i:type="d:string">120</clientCardNumber>
        <discountRate i:type="d:string">5.0</discountRate>
        <id i:type="d:long">11</id>
        <n0:items i:type="n0:items">
            <n0:Items i:type="n0:Items">
                <Code i:type="d:string">3000</Code>
                <Price i:type="d:string">100.0</Price>
                <Quantity i:type="d:string">2.0</Quantity>
                <Sum i:type="d:string">200.0</Sum>
            </n0:Items>
            <n0:Items i:type="n0:Items">
                <Code i:type="d:string">3001</Code>
                <Price i:type="d:string">110.0</Price>
                <Quantity i:type="d:string">1.0</Quantity>
                <Sum i:type="d:string">110.0</Sum>
            </n0:Items>
        </n0:items>
    </n0:WriteSale>
</v:Body>
</v:Envelope>

Но веб-сервис отвечает на него 500-й ошибкой. При этом, обращаясь к другому методу с параметрами простого типа на том же веб-сервисе, мы получаем корректный ответ. Более того, обращаясь из другой базы 1С через WS-ссылка к приведенному выше методу веб-сервиса, мы получаем корректный ответ и выполнение необходимых действий на стороне веб-сервиса. Поэтому пришлось перехватить запрос, формируемый другой базой 1С. Сделать это фидлером не получилось, так как он каким-то образом обрезал само тело запроса с xml и не передавал его веб-сервису. Нормально перехватить запрос удалось только с помощью WireShark.

Итак, текст запроса от 1С:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header/>
    <soap:Body> <m:WriteSale xmlns:m="http://www.xxxxx.ru">
    <m:id xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1</m:id>
    <m:date xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">2</m:date>
    <m:clientCardNumber xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">3</m:clientCardNumber>
    <m:discountRate xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">4</m:discountRate>
    <m:items xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <m:Items>
            <m:Code>123</m:Code>
            <m:Price>12.2</m:Price>
            <m:Quantity>2</m:Quantity>
            <m:Sum>2</m:Sum>
        </m:Items>
        <m:Items>
            <m:Code>2</m:Code>
            <m:Price>1</m:Price>
            <m:Quantity>2</m:Quantity>
            <m:Sum>2</m:Sum>
        </m:Items>
    </m:items>
</m:WriteSale></soap:Body>
</soap:Envelope>

Несложно заметить, что для вложенных элементов массивов (Code, Price...) библиотека ksoap2-android не проставляет префиксы с пространством имен. Для корневых элементов (id, date...) они также не проставлены, но этот факт 1С в ступор не вводит. А их отсутствие у под-элементов заставляет программу усомниться в корректности входных данных, прочитать она их не может.

Изучив код библиотеки, решил, что наиболее рациональным будет модифицировать метод SoapObject#addProperty(String, Object) следующим образом:

public static class SoapObjectCustom extends SoapObject {

        public SoapObjectCustom(String namespace, String name) {
            super(namespace, name);
        }

        @Override
        public SoapObject addProperty(String name, Object value) {
            PropertyInfo propertyInfo = new PropertyInfo();
            propertyInfo.name = name;
            propertyInfo.type = value == null ? PropertyInfo.OBJECT_CLASS
                    : value.getClass();
            propertyInfo.setValue(value);

            // Добавил эту строку
            propertyInfo.setNamespace(this.namespace);

            return addProperty(propertyInfo);
        }
    }

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

//...
SoapObjectCustom request = new SoapObjectCustom(namespace, methodName);
//...
SoapObject sales = new SoapObject(namespace, "items");
for (SaleItemInformation item : sale.getSales()) {
    SoapObjectCustom itemSoap = new SoapObjectCustom(namespace,
            "Items");
    //...
}
//...

Заключение

Скорее всего, есть смысл в том, что авторы не включали префиксы пространства имен в свойства элементов. И вполне возможно, что в работе с другими веб-сервисами такие коррективы приведут к некорректному поведению программы. Тем не менее, данный метод работает с веб-сервисами 1С, надеюсь это описание кому-нибудь поможет в работе.

Начать дискуссию

🥂 На летних верандах разрешили продавать алкогольные напитки

Госдума приняла депутатский законопроект, который разрешает продавать алкоголь на открытых сезонных верандах.

Курсы повышения
квалификации

22
Официальное удостоверение с занесением в госреестр Рособрнадзора

Борьба с киберпреступлениями выйдет на новый уровень

Замглавы Минцифры Александр Шойтов рассказал о планах в сфере информационной безопасности.

У ИП не может быть только патент, всегда за углом прячется еще одна система налогообложения. «Ночной бухгалтер» № 1686

Некоторые начинающие предприниматели, когда регистрируют ИП (особенно через посредников) и выбирают себе патентную систему, считают, что применят только ее, однако это не так. Из-за такой ошибки ИП может попасть на крупные доначисления, причем за весь год сразу.

Иллюстрация: Вера Ревина/Клерк.ру
Лучшие спикеры, новый каждый день

Брокеры начнут обмениваться информацией о расходах инвесторов

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

Власти будут компенсировать до половины затрат за переход на российское «тяжелое» ПО

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

Бесплатно с Уведомление по ЕНП

Какие налоги войдут в уведомление по ЕНП в мае 2024 года

Одно уведомление в мае бухгалтеры уже сдали по сроку 03.05.2024. Не позднее 27 мая нужно сдать еще одно.

Какие налоги войдут в уведомление по ЕНП в мае 2024 года
Опытом делятся эксперты-практики, без воды
Кадры

Всех педагогов хотят освободить от лишней бумажной работы

В России уже работает закон, который сократил бюрократическую нагрузку на учителей, но только школ.

Товарно-транспортная накладная (ТТН): форма, заполнение, образец

В составе документов на отгрузку товара присутствует несколько видов бумаг. Состав зависит от способа реализации, прописанного в договоре поставки. Товарно-транспортную накладную в 2023-2024  году заполняют компании, которые доставляют груз покупателю. Это могут быть специализированные организации, занимающиеся перевозками, продавцы и производители товара, покупатели, использующие свой или арендованный транспорт.

Иллюстрация: Вера Ревина/Клерк.ру

Наиболее распространенные ситуации налогового дробления. Как нельзя делить бизнес, с примерами из судебной практики

Приведу в данной статье наиболее типичные (а в чем-то даже одиозные) примеры подобной схемы дробления.

Почему мы теряем деньги вместо того, чтобы их приумножать

По данным НАФИ, 27% россиян младше 24 лет не ведут учет трат и не планируют свой бюджет. При этом москвичи показывают средний уровень финансовой грамотности, набирая 6,9 баллов из 10. Разбираемся, какие финансовые ошибки чаще всего совершают потребители и как этого избежать.

Иллюстрация: создано с помощью ИИ OpenAI © Вера Ревина/Клерк.ру

⚡️ Итоги дня: шенгенская виза подорожает, Lada можно купить на Wildberries, получение кешбэка стало схемой

Подготовили обзор главных событий дня — 21 мая 2024 года. Все самое интересное, что писали и обсуждали в сети, в одной подборке.

Как на УСН учитывать удержания маркетплейса из дохода за проданный товар

Сейчас многие предприниматели продают свои товары на маркетплейсах. Это электронные площадки для продажи товаров в интернете. Например, Озон, Вайлдберриз и др. ФНС разъяснила, как продавцу на УСН считать доход при удержании маркетплейсом суммы своего вознаграждения из выручки продавца.

Иллюстрация: Вера Ревина/Клерк.ру
Миникурсы, текстовые и видеоинструкции для бухгалтеров

Комплексная проверка юридического лица

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

Трафик торгового центра и торговой точки: как подсчитать, и зачем это делать

Выбирая ТЦ для открытия розничного магазина, важно оценить его трафик — сколько людей приходят за покупками, и есть ли среди них потенциальные клиенты. Стоит ли верить тем данным, которые предоставляют арендаторам ТЦ, как самостоятельно оценить трафик центра и торговой точки, проанализировать полученную информацию и использовать ее для повышения продаж.

Иллюстрация: Вера Ревина/Клерк.ру
Кадры

Цифра дня. Про трудоголиков

Почти треть россиян называют себя трудоголиками.

Цифра дня. Про трудоголиков
Реклама

Роскомнадзор сделает сдачу отчетности и получение токенов для интернет-рекламы более удобными

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

5 главных ошибок в кадровых документах работодателя

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

Банки

Формула успеха: как понимание региональной специфики и гибкие бизнес-процессы помогают бизнесу расти и процветать 

В 2024 году Агророс Банку исполняется 30 лет. За это время он превратился из скромного провинциального банка в крупную региональную организацию, отвечающую всем требованиям финансового рынка.

Иллюстрация: Вера Ревина/Клерк.ру

Кому выгодно переходить на налоговый мониторинг? Узнайте на онлайн-мероприятии 23 мая!

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

Интересные материалы

HR-тренды 2024 и их влияние на работу с кадрами

В периоды стремительных изменений важно держать руку на пульсе, отслеживать значимые тенденции и вовремя вносить в свою работу коррективы. Один из ключевых факторов, который сегодня на повестке дня у представителей российского бизнеса, — кадровый голод. Почему его нельзя игнорировать, что стоит предпринять уже сегодня, какие еще тренды наблюдаются в HR-сфере и причем тут цифровизация кадров — читайте в статье.

Иллюстрация: freepik/freepik