Интеграция с UDS

Наименование: Интеграция с UDS

Цель доработки (какую проблему решаем?): ИП Бойко и Тимур Фердаусович запросили интеграцию с этим сервисом. Озвученная нам цель такая: Получить альтернативный сервис облачной бонусной системы, которая работает у держателей приложения UDS, А так же новый источник заказов.  

Предлагаемый нами вариант решения:

Последний согласованный вариант решения описан подробно тут:

Оплата бонусами UDS

  • Добавляем возможность выбирать источник заказа при создании нового заказа на точке
    • В карточку торгового зала добавляем поле "Источники заказа, доступные для выбора"
    • Если это поле заполнено, то при создании нового заказа, система предложит выбрать источник заказа
      • Список доступных для выбора источников формируется пересечением множеств из торгового зала и концепции (если она определена). Т.е. в карточке ТЗ задается список вообще всех доступных на этом ТЗ  источников, а в концепции источники доступные для концепции
      • В КЦ список доступных для выбора источников формируется на основании концепции заказа и настроек ТЗ КЦ (не точки!)
    • Если пользователь откажется от выбора, то в качестве источника будет использоваться источник по умолчанию (задается в карточке ТЗ)
    • Упраздняем настройку из должности "Запрашивать источник заказа (только для заказов на доставку и на вынос)"
      • Клиентам, которые использовали данную настройку, нужно будет в ТЗ указать источники заказа, которые можно выбирать
      • Запрос источника заказа будет выводиться и для обычных заказов
  • Для кнопок раскладки добавляем новое действие  "* Бонусы UDS"
    • Проверяем, что в заказе нет каких либо скидок\подарочных товаров или бонусов
      • Если есть, то прерываем операцию и выводим сообщение, что бонусы UDS не совместимы со скидками\подарочными товарами или бонусами
      • Не проверяем скидки, за это отвечает администратор, который настраивает скидки. Во всех скидках должен стоять запрет на применение в заказах с источником UDS
    • Открываем форму ввода с одним полем, в которое пользователь вводит код клиента из приложения UDS или номер телефона клиента
      • Если в заказе уже определён клиент, то поле будет предзаполнено его номером телефона
    • Отправляем GET запрос на поиск клиента. Параметры запроса:
      • code - код, который ввёл клиент. Передается если длина введенного значения < 10
      • phone - номер телефона клиента. Передается если длина введенного значения >=10. Передается в формате +79123456789 (Юпитер автоматически приводит значение к нужному формату)
      • total - фактическая сумма заказа (с учётом всех скидок)
      • exchangeCode - всегда true
    • Если UDS не вернул клиента, то прерываем операцию и выводим сообщение, что клиент с таким телефоном\кодом не зарегистрирован в UDS
    • Если UDS вернул клиента, то ищем клиента в своей базе по UID UDS (uid из ответа UDS)
      • Если не нашли, то
        •  Ищем клиента в своей базе по номеру телефона (phone из ответа UDS)
          • Если нашли, то проверяем его UDS UID, он должен быть пустым. Если это не так, то считаем, что UDS не прислал нам номер телефона и идём дальше (т.е. в Юпитере этот номер телефона принадлежит другому клиенту, и мы не можем его использовать)
          • Если не нашли, то создаем клиента в своей базе с данными из ответа UDS
    • Когда клиент определён, сравниваем его данные и при необходимости обновляем их в нашей БД. Данные клиента обновляем только если их нет в нашей базе, т.е. данные Юпитера имеют приоритет перед данными от UDS.
        • Номер телефона - phone из ответа UDS
        • Имя - displayName из ответа UDS
        • Пол - gender из ответа UDS
        • Дата рождения и день рождения - birthDate из ответа UDS
        • Email - email из ответа UDS
    • Если в заказе уже определён клиент, то сравниваем его с найденным клиентом и если это разные клиенты, то запрашиваем у пользователя подтверждение на смену клиента в заказе
      • Если пользователь подтвердил, то заменяем клиента в заказе
      • Если пользователь отказал, то прерываем операцию
    • Открываем форму добавления оплаты бонусами UDS. Поля формы:
      • Текущее кол-во бонусов UDS у клиента (points из ответа UDS)
      • Максимальное кол-во бонусов доступное для списания (maxPoints из ответа UDS)
      • Сумма оплаты бонусами, вводит пользователь. По умолчанию подставляется максимальное кол-во бонусов доступное для списания.
        • Допустима сумма 0, считаем, что клиент не хочет тратить бонусы, а будет только копить.
    • Если пользователь подтвердил форму, то выставляем в заказ признак нужна операция UDS и сохраняем в заказе код для проведения транзакции UDS (code из ответа UDS)
    • Если пользователь ввёл сумму оплаты бонусами > 0, то добавляем в заказ скидку UDS
      • Скидка UDS является суммовой и блокирует любые изменения заказа
  • При закрытии заказа отправляем POST запрос на проведение операции
    • Отправляем только, если в заказе есть скидка UDS или в заказе стоит признак нужна операция UDS (т.е. оплачиваем\накапливаем бонусы UDS, только когда это явно определено в заказе, по умолчанию работаем с внутренней бонусной\дисконтной системой).
    • Параметры запроса:
      • code - код для проведения транзакции (если есть в заказе) или номер телефона клиента (если кода нет)
      • total - розничная сумма заказа (сумма до скидок)
      • skipLoyaltyTotal - всегда null
      • points - сумма скидки UDS
      • cash - сумма всех оплат по заказу
      • externalId и name - код и имя текущего сотрудника
      • number - код заказа в Юпитере
      • nonce - всегда null
      • tags - всегда null
    • Если UDS вернул ошибку, то показываем её и запрещаем закрыть заказ
    • Если UDS вернул успех, то сохраняем в заказе id транзакции UDS (он нужен для возврата)
  • При удалении скидки UDS , из заказа также удаляется признак нужна операция UDS и код для проведения транзакции UDS. Т.е. считаем, что клиент отказался использовать бонусы UDS.
    • Если в заказ записан id транзакции UDS, то считаем что операция проведена в UDS и нужно выполнить возрат, для этого
      • Отправляем POST запрос на операцию возврата. Параметры запроса:
        • id - id транзакции UDS из заказа
        • partialAmount - не передаем, т.к. всегда делаем полный возврат
      • Если UDS вернул ошибку, то выводим её и прерываем запрещаем удалять скидку UDS
      • Если UDS вернул успех, то удаляем из заказа id транзакции UDS, скидку UDS, признак нужна операция UDS, код для проведения транзакции UDS

    Получение заказов с сайта UDS

    • Вводим понятие Аккаунт UDS
      • Аккаунт объединяет несколько точек
        • В торговом зале добавляем параметр ID аккаунта UDS
      • Для каждого аккаунта будет свой адрес слушателя
        • Например так адрес_сервера:порт/ID_аккаунта_UDS
      • При загрузке заказа в него записывается ID аккаунта UDS

     

    • Разрабатываем HTTP сервис, который принимает POST запросы от UDS и создает заказы на доставку\на вынос.
    • Описание формата запроса. Параметры запроса:
      • id - идентификатор заказа в UDS. Сохраняем в заказе, нужно для последующей отправки в UDS и для проверки, что заказ ранее не принимался
      • dateCreated - не загружаем. Датой заказа ставит дату его попадания в Юпитер.
      • comment - комментарий к заказу
      • state - принимаем заказы только когда, STATE = NEW (иначе могут приходить предварительные заказы)
      • cash - сумма оплаты по заказу
      • points - сумма оплаты бонусами BMS. Если > 0, то добавляет скидку UDS
      • total - не загружаем. Сумма заказа определяется суммой его товаров.
      • certificatePoints - не загружаем.
      • customer 
        • id - не загружаем
        • displayName - Имя и фамилия клиента.
        • uid - UDS UID
        • membershipTier - не загружаем
      • delivery
        • receiverName - Имя клиента, который заберет заказ. Загружаем как "Другое имя для связи"
        • receiverPhone - Номер телефона клиента
          • Обязательное поле. Не формализуется и не валидируется со стороны UDS, нужно валидировать самим
          • Если клиент уже есть в базе Юпитера и у него есть номер телефона, то не обновляем номер телефона. Загружаем как "Другой номер для связи"
        • userComment - Комментарий клиента к заказу
        • branch - параметры торговой точки, только для заказов на вынос
          • id - торговая точка, для заказов на вынос
            • ID торговых точек UDS будет высылать нам вручную. Их нужно будет указать у нас
        • address - адрес доставки
          • Обязательное поле. Не формализуется и не валидируется со стороны UDS. Есть большая вераянтность, что будут проблемы с определением точки доставки
          • Если к Аккаунту UDS привязано несколько точек, то нужно определять точку доставки
            • Используем стандартный алгоритм через координаты и зоны доставки
            • Если не удалось определить точку, или точка относится к другому Аккаунту UDS, то заказ нужно оставить в КЦ в статусе Новый
              • Нужно реализовать возможность для КЦ, передать заказ на точку, но только на ту которая относится к нужному Аккаунту UDS
          • Если к Аккаунту UDS привязана одна тока, то создаем заказ не неё
        • type - вид заказа pickup - на вынос, delivery - доставка
      • onlinePayment - признак, что заказ оплачен онлайн
        • Если paymentMethod.type = CUSTOM или ONLINE, то paymentMethod = 1, иначе ошибка
      • paymentMethod - раздел с информацией об оплате
        • type - вид оплаты. Фиксированные значения (CASH - деньгами при получении, MANUAL - настраиваемы произвольный метод оплат, CUSTOM - онлайн оплата через интеграцию платежного шлюза, ONLINE - онлайн оплата через Cloudpayments).
          • Вид оплаты будем определять по коду
            • CASH - находим вид оплаты с внешним кодом 1 (доставка) или 5 (на вынос)
            • MANUAL - находим вид оплаты с внешним кодом MANUAL
            • CUSTOM - находим вид оплаты с внешним кодом CUSTOM
            • ONLINE - находим вид оплаты с внешним кодом ONLINE
        • name - название вида оплаты
      • items - раздел с товарами
        • id - не загружаем
        • externalId - не загружаем
        • name - не загружаем
        • variantName - не загружаем
        • sku - код товара в Юпитере, артикул товара в UDS. По этому полю ищем товар в своей базе. Если товар не найден, то заказ не создается
        • type -  тип товара, может быть ITEM, VARYING_ITEM обычный товар, товар с вариантами. Не загружаем
        • qty - количество
        • price - цена
        • measurement - не загружаем
    • Процедура формирования заказа работает по аналогии с процедурой загрузки заказа с сайта\приложения, за исключением:
      • В качестве источника заказа жёстко записываем "Сайт UDS" (определяется по названию)
      • В заказ записывается признак нужна операция UDS (т.е. не будут работать внутренние скидки\бонусы\промокоды\акции, вместо внутренних бонусов, будут накапливаться бонусы UDS)
      • Не выполняются автоматические действия после открытия нового заказа (добавление приборов, пакетов и т.п.)
      • Не срабатывает функций автоматического добавления товара (auto_add) по кол-ву гостей 
      • Не применяются подарочные товары
      • Не применяются автоматические скидки
      • Не применяются скидки клиента
      • Не применяется скидка - округление
      • Не добавляются обязательные модификаторы (гарниры и т.п.)
    • Заказы полученные с UDS изменять нельзя, их можно только закрыть или удалить
      • В источник заказа добавляем опцию "Запретить изменять товарную часть заказа"
        • Если опция включена, то в заказ с этим источником нельзя будет вносить изменения:
          • Добавлять, удалять, разделять, сворачивать, изменять кол-во в товарных строках
          • Добавлять, удалять, менять кол-во модификаторов
          • Добавлять, удалять скидки, бонусы
          • Изменять вид заказа
      • Данная опция не блокирует функцию полного удаления заказа
      • При закрытии заказа полученного с UDS, отправляем POST запрос на завершение заказа. Параметры запроса:
        • id - id заказа в UDS
      • При удалении заказа полученного с UDS, никакие запросы не отправляем

     

    Синхронизация меню

    Пока не реализуем. Выполняется вручную.

     

    Настройки

    • На раскладку добавить кнопку с действием "** Бонусная операция UDS"
    • В карточке торгового зала задать ключ авторизации UDS, это закодированная в Base64 строка, которая формируется по шаблону id компании:api key. id компании и api key можно получить в ЛК UDS.
    • Добавить настройку скидки с кодом UDS

    Особенности

    • Для всех запросов, таймаут ожидания ответа от UDS = 5 секунд. Если за это время UDS не возвращает ответ, то считаем, что запрос не был получен сервером UDS и выдаем ошибку
    • В карточку клиента, добавляется новое поле UID UDS - идентификатор клиента в UDS.  Поле будет использоваться для поиска клиента в базе, поэтому оно должно быть индексное. Потребуется патч структуры БД.

    Результат доработки: Интеграция с сервисом UDS. 

    Важные изменения в логике работы программы/функционале: На всех кассах подключенных к сервису всегда при создании нового заказа будет выбор источника заказов. Заказы от UDS нельзя будет редактировать, только закрывать или полностью удалять. 

    Время составления ТЗ: 7 ч. 

    Время работы программиста: 60 ч. 

    Время внедрения: 6 час. 

    Время тестирования: 20 ч. 

    Стоимость: 232 500 руб.

     

    Исполнитель
    ИП Надеждин Кирилл Дмитриевич 
    М.П. ____________________ 
    Надеждин К.Д. 

     

    Заказчик
    ООО «Суши-Сет»
    М.П. _____________________
    Глазнев А.А.


    Система JUPITER                                 www.jupiter.systems                                 (с) 2024г.