Мобильное приложение торгового представителя на 1С: офлайн-сбор заказов и обмен с Комплексной автоматизацией

Автономный АРМ на мобильной платформе 1С: сбор заказов у клиента офлайн, проверка остатков на устройстве и лёгкий HTTP-обмен с 1С:Комплексная автоматизация 2.

Заказчик: Оптовый поставщик с выездными торговыми представителями
Стек: Мобильная платформа 1С:Предприятие 8.3, iOS, Android, 1С:Комплексная автоматизация 2, HTTP-сервис 1С, планы обмена, XDTO-сериализация, сжатие данных, QR

Задача

Торговый представитель собирает заказы у клиентов, где связь нестабильна или отсутствует. Нужно на месте видеть номенклатуру, цены и остатки, оформлять заказ и проверять наличие товара на складе, а при появлении сети — выгружать заказы в учётную базу 1С:Комплексная автоматизация 2, получать их статусы и отправлять клиенту счёт. Требовалась полная автономность и компактный обмен по мобильному интернету.

Результат

Автономное приложение на мобильной платформе 1С (iOS и Android) с собственной локальной базой: заказы оформляются офлайн, остатки проверяются прямо на устройстве, а обмен с центральной базой идёт по лёгкому собственному HTTP-сервису — регистрация устройства, синхронизация справочников/цен/остатков, выгрузка заказов с разрешением конфликтов и отправка счёта на e-mail. Пакеты сериализуются в XDTO и сжимаются для экономии трафика.

Разработка мобильного приложения для торговых представителей на 1С: выездной менеджер собирает заказы прямо у клиента, в автономной базе на мобильной платформе 1С:Предприятие 8.3, а затем данные синхронизируются с учётной базой 1С:Комплексная автоматизация 2. Приложение работает офлайн, само проверяет остатки на устройстве и обменивается с центральной базой лёгкими HTTP-пакетами. Ниже — как устроен обмен и почему для этой задачи мы отказались от штатного мобильного клиента 1С.

Задача

Торговый представитель ездит по точкам, где связь нестабильна или её нет вовсе. На месте ему нужно: открыть карточку клиента, увидеть номенклатуру с ценами и актуальными остатками, оформить заказ, тут же проверить, что товар есть на складе, и не дать заказать больше, чем реально доступно. Когда появляется сеть — выгрузить собранные заказы в учётную базу, получить обратно их статусы и при необходимости отправить клиенту счёт на e-mail.

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

Почему не штатный мобильный клиент 1С

В типовой «Комплексной автоматизации» есть готовая подсистема мобильного приложения заказов. Но она тянет за собой тяжёлый обмен и заметный объём метаданных, а нам нужен был лёгкий АРМ под одну роль — сбор заказов. Поэтому обмен построен на собственной HTTP-службе и паре компактных общих модулей и в мобильной, и в центральной базе. Мобильная конфигурация содержит ровно то, что нужно представителю: справочники «Контрагенты», «Номенклатура», «Пользователи», «Упаковки», документ «Заказ клиента» и регистры цен/остатков.

Архитектура обмена

Обмен — «точка-точка» поверх обычного HTTP-сервиса 1С. Мобильное приложение вызывает методы центральной базы по адресу вида /hs/<сервис>/<метод>:

  • echo — проверка связи;
  • reg — регистрация устройства (получить узел плана обмена, пользователя, организацию, склад, вид цены, справочники);
  • sync — полная синхронизация справочников, цен и остатков;
  • update — выгрузка заказов на сервер и приём изменений обратно;
  • check — проверить, не изменился ли документ в центральной базе;
  • email — отправить клиенту счёт.

Данные упаковываются в XDTO-сериализацию и сжимаются перед отправкой — так пакет остаётся небольшим даже на медленном мобильном интернете:

// Клиент: пакет = сжатое хранилище значения, сериализованное в строку
Функция СформироватьПакетОтвета(Пакет) Экспорт
    // HTTP-сервис не умеет передавать ХранилищеЗначения напрямую —
    // сериализуем в XML, а для экономии трафика ещё и сжимаем
    СжатыйПакет = Новый ХранилищеЗначения(Сериализовать(Пакет), Новый СжатиеДанных(9));
    Возврат Сериализовать(СжатыйПакет);
КонецФункции

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

Соединение с центральной базой — обычное HTTPСоединение с логином/паролем из констант приложения. Тело запроса — сформированный пакет, ответ распаковывается тем же кодом:

Процедура DataTransferHTTP(ФункцияHTTP, СтруктураДанных, СоединениеHTTP, ПараметрыПодключения) Экспорт
    ЗапросHTTP = Новый HTTPЗапрос(ПараметрыПодключения["HTTP"] + "/hs/"
        + ПараметрыПодключения["Сервис"] + "/" + ФункцияHTTP);
    ЗапросHTTP.УстановитьТелоИзСтроки(HTTPCore.СформироватьПакетОтвета(СтруктураДанных));

    Ответ = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTP);
    СтруктураДанных.КодОтветаHTTP = Ответ.КодСостояния;

    Если СтруктураДанных.КодОтветаHTTP = 200 Тогда
        HTTPCore.ПолучитьПакетИзВходящихДанных(Ответ.ПолучитьТелоКакСтроку(), СтруктураДанных);
    КонецЕсли;
КонецПроцедуры

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

Сервер: HTTP-служба в центральной базе

На стороне «Комплексной автоматизации» опубликован HTTP-сервис. Его методы — тонкие обёртки, вся логика вынесена в общие модули, симметричные мобильным:

// Центральная база: обработчики HTTP-сервиса
Функция EchoGet(Запрос)
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.УстановитьТелоИзСтроки("Mobile HTTP service OK", КодировкаТекста.UTF8);
    Возврат Ответ;
КонецФункции

Функция SynchronizationPost(Запрос)
    Возврат nsHTTPСервер.ОбработатьHTTPЗапрос(Запрос, "Synchronization");
КонецФункции
Функция ОбработатьHTTPЗапрос(Запрос, ШаблонURL) Экспорт
    СтруктураДанных = ПолучитьДанные(Запрос);          // распаковать входящий пакет
    Если nsHTTPCore.ЕстьОшибка(СтруктураДанных) Тогда
        Возврат ОтправитьHTTPОтвет(СтруктураДанных.КодОтветаHTTP, СтруктураДанных, "1.0");
    КонецЕсли;

    nsHTTPОбмен.ОбработатьHTTPЗапрос(СтруктураДанных, ШаблонURL);  // выполнить операцию
    Возврат ОтправитьHTTPОтвет(СтруктураДанных.КодОтветаHTTP, СтруктураДанных, "1.1");
КонецФункции

Перед обработкой сервер проверяет версию конфигурации мобильного устройства — чтобы старое приложение не «сломалось» о новый формат пакета.

Проверка остатков прямо на устройстве

Главная ценность автономного режима — заказ проверяется без сети. В модуле документа «Заказ клиента» при проведении сверяем строки с локальным регистром остатков и не даём оформить дефицит:

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // остатки по складу представителя лежат в регистре на самом устройстве
    Для каждого Строка Из Товары Цикл
        Остаток = ОстаткиНоменклатуры[Строка.Номенклатура];
        Если Остаток = Неопределено Тогда
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
                "На складе " + Склад + " отсутствует: " + Строка.Номенклатура);
            Отказ = Истина;
        ИначеЕсли Остаток < Строка.КоличествоУпаковок / Числитель Тогда
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
                "Не хватает: " + Строка.Номенклатура);
            Отказ = Истина;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

Разрешение конфликтов

Один и тот же заказ может быть отредактирован и в мобильном, и в центральной базе. Обмен поддерживает явные приоритеты: ЗаменитьВЦБ (мобильная версия главнее), ЗаменитьВМобильном и ОбновлениеИзЦБ. Отдельный метод check позволяет ещё до выгрузки спросить сервер, менялся ли документ в центральной базе, и заранее предупредить представителя.

Что ещё вошло в приложение

  • Отправка счёта на e-mail клиенту прямо из карточки заказа (метод email — счёт формирует и отправляет центральная база);
  • подбор номенклатуры с учётом упаковок и кратности;
  • условия и график доставки по каждому партнёру с расчётом ближайшей возможной даты доставки;
  • чтение QR (разбор JSON из отсканированного кода);
  • журнал результатов обмена на устройстве — ошибки клиента и сервера разведены и видны представителю, что резко упрощает диагностику «в полях».

Результат

Торговый представитель оформляет заказы у клиента без интернета, видит реальные остатки и не создаёт дефицитных заказов, а при первой же связи данные уходят в «Комплексную автоматизацию» компактными сжатыми пакетами. Приложение собрано под iOS и Android на мобильной платформе 1С, обмен — на собственном лёгком HTTP-сервисе вместо тяжёлого штатного клиента.

Нужно похожее мобильное приложение на 1С — сбор заказов, приёмка, выездной АРМ с автономной базой и обменом? Мы делаем такие проекты под ключ. А если хотите разобраться в мобильной платформе 1С сами — от автономной базы до публикации и защиты клиента — посмотрите наш курс по мобильному клиенту 1С.

Частые вопросы

Нужен похожий проект?

Опишите задачу — оценю сроки и стоимость.