Работаем с веб-сервисом 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С, надеюсь это описание кому-нибудь поможет в работе.

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

НДФЛ

Удержание из зарплаты за питание не облагается НДФЛ и взносами

Если работник ест за свой счет, то он не должен платить за это НДФЛ.

НДФЛ

Налог на богатых принесет в бюджет 181 млрд рублей

В конце этого года Минфин ожидает, что НДФЛ по ставке 15% принесет в казну 181 млрд рублей. С 2025 года будет действовать новая прогрессия.

🔥 Директора-единственного учредителя надо будет включать в годовой отчет о стаже по форме ЕФС-1

С 2023 года ежегодные сведения о стаже сдают не на всех сотрудников, а только на тех, у кого есть особенности стажа. И таких особенностей будет больше.

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

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

Оплата перевозки внутри другой страны не облагается налогом на прибыль в РФ

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

Кадры

Две трети профессий в России оказались дефицитными

За последний год дефицит кадров в стране усилился в большинстве отраслей. Чаще всего работодатели ищут специалистов по продажам и линейный персонал. Таковы результаты обзора, проведенного ПЭК и рекрутиноговой платформой hh.ru при участии «Грузовичкоф», «ОренЗМК» (резидент «Сколково»), Major Cargo Service, «МТЭК-Логистик» и «Скиф-Карго».

Как оформить выдачу денег под отчет

Рассказываем, как выдать деньги под отчет и какими документами оформить выдачу денежных средств.

Как оформить выдачу денег под отчет
Опытом делятся эксперты-практики, без воды

В ЕФС-1 будет больше информации о договорах ГПХ

Подавая сведения о заключении договора ГПХ по форме ЕФС-1, надо будет делать пометку, есть ли в договоре условие о взносах на травматизм.

4

🎂 Сегодня последний день суперакции в честь Дня рождения школы «Клерка»! Онлайн-курсы по 3 290 рублей

Какой же праздник без подарков? 22 июля, мы отмечаем наш первый юбилей — 5 лет школе «Клерка»! Сегодня последний день, когда вы можете купить курсы по учету на маркетплейсах, финансовому анализу, ВЭД, работе на УСН и зарплате всего за 3 290 рублей. Успейте воспользоваться выгодным предложением!

🎂 Сегодня последний день суперакции в честь Дня рождения школы «Клерка»! Онлайн-курсы по 3 290 рублей

Обвиняемых по экономическим статьям не могут ограничивать в контактах с уполномоченными по правам предпринимателей

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

Маркетинг

Тенденция: растущие бренды предпочитают собственные интернет-магазины, а не маркетплейсы

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

Инвестиции

И народный, и мартышкин портфели рухнули. Итоги одиннадцатого месяца инвестиционного эксперимента

Закончился одиннадцатый из двенадцати месяц эксперимента с мартышкиным портфелем против народного портфеля. В нем смотрим, получится ли портфелю из случайных 10 акций РФ обогнать портфель из 10 самых популярных у частных инвесторов «народных» акций.

И народный, и мартышкин портфели рухнули. Итоги одиннадцатого месяца инвестиционного эксперимента

Утренний бухгалтер № 5684. Шесть рублей на человека: в 6-НДФЛ допустима погрешность при умножении дохода на налоговую ставку

Контрольные соотношения ФНС допускают погрешность при расчета налога на доходы физических лиц.

⚡ У бухгалтеров будет меньше времени на сдачу ЕФС-1

Сейчас подраздел 1.1 ЕФС-1 (бывшая СЗВ-ТД) сдают до 25 числа следующего месяца. Но есть случаи, когда сдать отчет надо на следующий день. Таких случаев будет больше.

13

Ситуация ПИ…: Бизнес, налоговая, маркетплейс

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

Налоговые новости: реформа, реформа, еще раз реформа!

Поговорим о реформах в налоговом законодательстве.

Ипотека

Начали повышать ставки тем, кто второй раз пользуется льготной ипотекой

Банки ужесточают условия для нарушителей правила «одна льготная ипотека в одни руки».

Бухгалтерский учет

Бухгалтерский учет, налогообложение и аудит в РФ

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

Практика Конституционного Суда по налогам за второе полугодие 2023

Рассматриваются ключевые решения КС по налоговым вопросам.

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

Более 600 тыс. заявлений в колледж подали абитуриенты с помощью Госуслуг. Это уже на 100 тыс. больше, чем за весь прошлый год.

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

Общество

Принят закон, упрощающий проведение общих собраний СНТ

Совет Федерации одобрил разработанный при участии Росреестра закон, по которому дачникам, садоводам и огородникам станет проще проводить общие собрания членов СНТ и ОНТ.

1