Интеграция СуперМаг Плюс и DS.
SMP: 2097
ID: 2464
SALE: 3226
Автор: Петров В.
Клиент: Ритейл Софт (Беляков Александр)
From: Беляков Александр Сергеевич <a.belyakov@retail-soft.pro> Sent: Thursday, March 19, 2026 2:36 PM To: Халдин Дмитрий Андреевич <d.haldin@retail-soft.pro>; Петров Владимир Викторович <v.petrov@retail-soft.pro>; Леонов Павел <p.leonov@retail-soft.pro>; Баринов Максим Иванович <m.barinov@retail-soft.pro>; Рамазанов Руслан Александрович <r.ramazanov@retail-soft.pro>; Куркина Лариса Сергеевна <l.kurkina@retail-soft.pro> Subject: Re: Интеграция СМ+ DS \\\ https://jira.retail-soft.pro/browse/SMP-2097
\\\ Предварительная оценка
Коллеги, интеграцию СМ+ и DS согласовываю
С уважением,
Беляков Александр
| Техническое задание v.2. |
| Техническое задание v.3.
|
| Техническое задание v.3.
|
- Бизнес процесс:
Описание: клиенты, использующие СуперМаг Плюс заинтересованы в интеграции с СуперМаг DS для использования прайс-дисплеев и esl-ценников.
В данный момент происходит интеграция УКМ5 и ДС с помощью xml-файлов на основе протокола "Импорт XML". Подробнее об этом тут Интеграция с УКМ5
Протокол специально для DS расширяется новыми полями и новыми файлами. Об этом подробнее тут Описание расширения
Для интеграции СуперМаг Плюс и DS - необходимо использовать расширенный XML-протокол, с помощью которого сейчас интегрируются УКМ5 и ДС
Интерфейс и реализация:Якорь _Toc223000651 _Toc223000651
В настоящее время УКМ5 интегрируется с СуперМаг DS по следующей схеме (рис.1.):
Рис.1.
Схема интеграции через СуперМаг Плюс претерпит следующие изменения (Рис.2.):
Рис.2.
Предполагается, что подготовкой данных будет заниматься служба Кассовый сервер СуперМаг Плюс. А публикацией сообщений для СуперМаг DS – ее отдельный модуль «СуперМаг издатель»*.
- Рабочее название.
Логика работы с ПО Kafka заключается в следующем: - Кассовый модуль СуперМаг Плюс подготавливает данные в специализированном формате XML (описан ниже).
- Полученные данные, модуль «СуперМаг издатель» должен преобразовать и отправить в топик Kafka.
Справка: Apache Kafka — распределённая система обмена сообщениями между серверными приложениями в режиме реального времени.
Описание форматов обмена:Якорь _Toc223000652 _Toc223000652
| Якорь | ||||
|---|---|---|---|---|
|
| Якорь | ||||
|---|---|---|---|---|
|
| Wiki разметка |
|---|
СуперМаг Плюс должен публиковать в Kafka файлы в следующем виде:
\{ "content_base64": "здесь содержимое в base64", "event_type": "F", "number": "1", "original_filename": "storePrices_\[262\]_\[1\]_\[F\].xml", "store_id": "262", "part": "1", "part_status": "process"
\}
\\ |
| ||
|---|---|---|
content_base64 | содержимое Xml файла в кодировке base64 (SKU и цены) | |
event_type | тип выгрузки (F/I - полная/частичная выгрузка) | |
number | порядковый номер файла (целое число) | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="07c53e20-7b79-4958-a8bc-bdb3451fa046"><ac:plain-text-body><![CDATA[ | original_filename | Имена файлов имеют формат TAGNAME_[Store][Number][P]_[Error].xml, где:
|
store_id | Id магазина во внешней системе | |
part | номер части для больших файлов | |
part_status | статус части. Варианты:
|
Формат данных для обмена:
За основу формата обмена данными взят конвертер СуперМаг XML, с некоторыми изменениями, в частности:
- Имена файлов должны быть строго такими, как они отражены в п.3.3., иначе конвертер DS их проигнорирует.
- Структура файлов расширена новыми данными.
- Файлы обмена (общий список).
Ниже представлен общий список файлов, которые требуется формировать. Часть файлов (их структура) не претерпела изменений по отношению к конвертеру СуперМаг XML, и не описывается в данном ТЗ.
№ | Имя файла | Описание назначения | Комментарий |
1. | store | магазины | Новый файл. Ранее СуперМаг плюс такой не формировал. |
2. | classif | Классификатор товаров | Без изменений. |
3. | updateItems | товары | Файл расширен новыми тегами. |
4. | storePrices | цены по месту хранения | Без изменений. |
5. | priceTagInfo | акционные цены | Новый файл. Ранее СуперМаг плюс такой не формировал. |
6. | itemInfo | QR-коды и PLU | Новый файл. Ранее СуперМаг плюс такой не формировал. |
Общее описание
Ниже описывается расширение существующего протокола обмена данными (СуперМаг XML) для создания готового "коробочного" решения, которое позволит клиентам, использующим СуперМаг Плюс, избежать отдельной интеграции с «СуперМаг DS» для использования электронных ценников (ESL) и Прайс-дисплеев.
Ранее данные из Торговой системы выгружались данные исключительно для кассовых систем и систем контроля цен. Теперь этот процесс дополняется: фактически те же самые данные будут параллельно передаваться и в DS. Это позволит системе «СуперМаг DS» получать актуальную информацию о товаре и их ценах.
Описание расширения
- Наименование файла строго как в описание. (операционная система LINUX регистрозависима)
- Формат представления информации – XML.
- Кодировка – UTF-8.
- Десятичный разделитель – точка
- Каждый тип информации передаётся с помощью отдельного файла, который имеет название, соответствующее типу передаваемой информации. В одном файле может содержаться только один тип информации.
- Расширение существующих файлов в протоколе:
Тип информации
Имя файла и головного тега
Магазины
store
Товары
updateItems
- Добавление новых файлов в протокол:
- Расширение существующих файлов в протоколе:
Тип информации | Имя файла и головного тега |
Акционные цены на товары | priceTagInfo |
QR-коды и PLU | itemInfo |
Файл store (магазины)
| Wiki разметка |
|---|
Наименование файла: {*}store* (например, store_\[1234\]_\[I\].xml).
\\
Описание изменений: Файл расширяется двумя новыми полями: |
- director — ФИО директора магазина.
- description — Произвольное текстовое описание или комментарий к магазину.
Описание файла "store":
| Примечание | Формат | Источник данных из СуперМаг Плюс |
<stores |
|
|
|
<version=""> |
| String(20) |
|
<store> |
|
|
|
<code> | Код магазина в торговой системе | String(100) | Код магазина в торговой системе |
<name> | Название магазина | String(100) | Название магазина |
<jurName> | Название юр. лица | String(100) | Собственный контрагент места хранения. Единственный из списка, или первый попавшийся. |
<address> | Адрес магазина | String(100) | Адрес магазина |
<director> | Новое поле: Директор магазина | String(100) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<description> | Новое поле: Описание магазина | String(100) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<INN> | ИНН юр. лица | String(40) | ИНН Собственного контрагента. |
<KPP> | КПП | String(40) | КПП Места хранения. |
<phone> | Телефон | String(40) | Телефон Места хранения. |
<active> | Активный/неактивный | Boolean | Фиксированное значение «true» |
<egaisIP> | IP-адрес и порт УТМ | String(255) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<CFA> | Код ЦФО – открытый идентификационный код, определяющий центр финансовой ответственности (идентификатор магазина для казначеев) | String(255) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<validatorIP> | IP-адрес и порт валидатора | String(255) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<localModuleIP> | IP-адрес локального модуля (для обращения в случае отсутствия связи с системой "Честный знак") | String (255) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<fsrarID> | Идентификатор организации в ФС РАР | String(255) | ФС РАР Собственного контрагента. |
<prismaIP> | IP-адрес и порт системы "Трассир" | String(255) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<storeIP> | IP модуля интеграции магазина | String(100) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<inputURL> | Полный URL входного каталога модуля интеграции магазина | String(255) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<outputURL> | Полный URL выходного каталога модуля интеграции магазина | String(255) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
<region> | Код региона, к которому относится магазин | Int(11) | Требуется добавить новый атрибут места хранения или использовать новую системную характеристику. |
<storeType> | Код формата магазина из справочника форматов магазинов | Int(11) | Требуется добавить новый атрибут места хранения или создать новую системную характеристику. |
</store> |
|
|
|
</stores> |
|
|
|
Файл updateItems (товары)
| Wiki разметка |
|---|
Наименование файла: *updateItems* (например: updateItems_\[1234\]_\[F\].xml).
\\
Описание изменений: Файл расширяется тремя новыми полями, которые являются необязательными для передачи: |
- producer - Страна производства
- description - Описание товара
- customType - Атрибут товара
Описание файла "updateItems":
| Примечание | Формат | Источник данных из СуперМаг Плюс |
<updateItems |
|
|
|
<version=""> |
| String(20) |
|
<item> |
|
|
|
<article> |
| String(40) |
|
<name> |
| String(255) |
|
<measure> | Сокращение (шт, кг, л) | String(40) |
|
<measprec> | Количество знаков в дробной части; точность – 1, 0.001, 0.01, 0.1 | String(one of 1; 0.1; 0.01; 0.001) |
|
<groupId> | Ссылка на узел классификатора | String(40) |
|
<producer> | Новое поле: Страна производства | String(255) | Страна |
<description> | Новое поле: Описание товара
| String(255) | Требуется создать новую системную характеристику. |
<customType> | Новое поле: Атрибут товара | Int(11) | Требуется создать новую системную характеристику. |
<egaisType> | Тип маркировки товара | Int(11) |
|
<SubExcise> | Признак подакцизности товара | Int(11) |
|
<crptNotUnique> | Признак неуникальности контрольной марки | 0 – уникальная марка |
|
<taxgroupId> | Код налоговой группы |
|
|
<propertyId> | Доп. свойство «Размер» | String(40) |
|
<addProperty> | Доп. свойства |
|
|
<id> |
| String(40) |
|
<name> |
| String(80) |
|
<value> |
| String(100) |
|
</addProperty> |
|
|
|
<barcode> | Перечень штрихкодов Один штриховой код товара. |
|
|
<id> | Непосредственно штрихкод | String(40) | Первый попавшийся, или тот, что отмечен как «Использовать при EDI обмене \ GTIN» |
<propertyValue> |
| String(100) |
|
<quantity> | «Количество» для штрихкода | Decimal(16.3) |
|
</barcode> |
|
|
|
<TNVDcode> | Идентификатор записи из справочника ТН ВЭД | String(50) |
|
<productAlcCodes> |
|
|
|
<alcCode> | Специальный идентификатор кода алкогольной продукции | String(40) |
|
</productAlcCodes> |
|
|
|
<supplierLink> |
|
|
|
<supplierINN> | ИНН поставщика | String(12) |
|
<supplierTax> | НДС поставщика из контракта с поставщиком | Возможные значения: «20%», «10%», «Не облагается» |
|
</supplierLink> |
|
|
|
</item> |
|
|
|
</updateItems> |
|
|
|
Файл priceTagInfo (акционные цены)
С помощью данного файла в DS возможно отразить следующие акционные кампании:
№ п.п. | Название компании в DS | Комментарий |
1. | Процентная скидка | Реализовано в СМ+ с помощью Маркетинговых акций. |
2. | «N по цене M» | Не реализована в СМ+, выгружаться не будет. |
3. | «Скидка от количества» | Не реализована в СМ+, выгружаться не будет. |
| Wiki разметка |
|---|
\\
\\
<span style="color: #ff0000">Источником данных для акционных ценников будут выступать документы «Маркетинговая акция».</span>
\\
Наименование файла: *priceTagInfo* (например: priceTagInfo_\[Store\]_\[Number\]_\[P\].xml)
*Описание файла "priceTagInfo":* |
|
| Примечание |
|
|
|
| Формат | Источник данных из СуперМаг Плюс | |
<priceTagInfofullness= "F/I"storeId = "" > |
| Значение может быть F или I (обязательное)Код магазина во внешней системе (обязательное) |
|
|
|
|
|
| |
<item article=""> |
| Код товара (артикул) (секция должна быть указана хотя бы один раз) |
|
|
|
| String(40) | Артикул из спецификации документа Маркетинговая акция. | |
description |
| Название акции (обязательное) |
|
|
|
| String(100) | Название акции. | |
dateFrom |
| Дата и время начала акции |
|
|
|
| DateTime() | Планируемая Дата и время начала акции | |
dateTo |
| Дата и время окончания акции |
|
|
|
| DateTime() | Панируемая \ или \ Фактическая (при наличии) Дата и время окончания акции | |
campaigntype |
| Тип компании. Один из предопределенных: (обязательное)
|
|
|
|
| String(40) | Фиксированное значение «discountbypercent» | |
<campaign> |
|
|
|
|
|
|
|
| |
|
| Внутри секции <campaign> настройки кампании, которые зависят от типа кампании (см. таблицы далее) |
|
|
|
|
| ||
</campaign> |
|
|
|
|
|
|
|
| |
</item> |
|
|
|
|
|
|
|
| |
</priceTagInfo> |
|
|
|
|
|
|
|
| |
|
|
|
| ||||||
|---|---|---|---|---|---|---|---|---|---|
<campaign> |
|
|
|
|
| Источник данных из СуперМаг Плюс |
|
|
|
price | цена (обязательное) |
|
|
| Decimal(16.2) | Цена артикула из документа Маркетинговая акция. |
|
|
|
oldPrice | старая цена |
|
|
| Decimal(16.2) | Старая цена из документа Маркетинговая акция. |
|
|
|
discount | процент скидки |
|
|
| Decimal(16.2) | Процент скидки. Требуется рассчитать и округлить до целого числа в меньшую сторону. |
|
|
|
</campaign> |
|
|
|
|
|
|
|
|
|
Пример:
<priceTagInfo fullness="I" storeId="2">
<version>1.0</version>
<item article="000177">
<description>Покупайте наших слонов</description>
<dateFrom>01.01.2025</dateFrom>
<dateTo>31.12.2025</dateTo>
<campaigntype>discountbypercent</campaigntype><campaign>
<price>45</price>
<oldPrice>50</oldPrice>
<discount>10</discount></campaign>
</item>
</priceTagInfo>
Файл itemInfo (QR-коды и PLU)
| Wiki разметка |
|---|
Наименование файла: *itemInfo* (например: itemInfo_\[Store\]_\[Number\]_\[P\].xml)
*Описание файла "itemInfo":* |
| Примечание | Формат | Источник данных из СуперМаг Плюс |
< itemInfofullness= "F/I"storeId = > | Значение может быть F или IКод магазина во внешней системе (обязательное) |
|
|
<item article=""> | Код товара (артикул) (секция должна быть указана хотя бы один раз) | String(40) |
|
<qr> | содержимое QR-кода для ценника (необязательное) | String(100) | Не заполняем |
<plu> | Код на весах (необязательное) | String(40) | PLU код из списка товаров для весов по месту хранения. |
</item> |
|
|
|
</itemInfo> |
|
|
|
- Примеры файлов:
https://manual.retail-soft.pro/x/9YT4Bw
- Правила наполнения данными для файла priceTagInfo:
Источником данных для акционных ценников будут выступать документы «Маркетинговая акция».
Следует учитывать, что у данного документа имеются следующие атрибуты, значение которых напрямую может оказывать влияние на цену товара, и как следствие цену на ценнике СуперМаг DS. К атрибутам относится:
- Планируемая дата начала акции.
- Планируемая дата окончания акции.
- Статус «Исполняется». (Статус указывает, что акция стартовала).
- Фактическая дата окончания акции.
Так же не исключены ситуации, при которых возможно пересечение артикулов в созданных маркетинговых акциях, а также досрочное завершение акции (вручную сотрудником).
Так как стоит задача, получить в DS акционные цены в строгом в соответствии в ценами в кассовой системе, то логика выгрузки определена следующая:
Маркетинговая акция запустилась (однократная выгрузка).
Задача: проинформировать DS о значении и начале действия аукционной цены.
- При формировании выгрузки storePrices (цены) - для товара участвующего в Маркетинговой акции, в качестве регулярной цены будет выгружаться текущая цена из карточки, она же на этот момент будет являться аукционной.
- При формировании выгрузки priceTagInfo (акционные цены) - для товара участвующего в действующей Маркетинговой акции, в качестве:
- «Цены» - должна выгружаться текущая цена из карточки, она же на этот момент будет являться акционной.
- «Старой цены» - должна быть выгружена цена, которая была зафиксирована как «цена до акции».
- «Название акции» - название акции, которая породила акционную цену.
- «Дата и время начала акции» - Планируемая Дата и время старта акции
- «Дата и время окончания акции» - Планируемая Дата и время окончания акции
Маркетинговая акция завершена (однократная выгрузка).
Задача: проинформировать DS о зевершения действия аукционной цены.
- При формировании выгрузки storePrices (цены) - для товара участвующего в Маркетинговой акции, в качестве регулярной цены будет выгружаться текущая цена из карточки, она же на этот момент будет являться аукционной.
- При формировании выгрузки priceTagInfo (акционные цены) - для товара участвующего в действующей Маркетинговой акции, в качестве:
- «Цены» - должна выгружаться текущая цена из карточки, она же на этот момент будет являться регулярной ценой.
- «Старой цены» - должна быть выгружена цена из карточки, она же на этот момент будет являться регулярной ценой.
- «Название акции» - название акции, которая породила акционную цену.
- «Дата и время начала акции» - Планируемая Дата и время старта акции
- «Дата и время окончания акции» - Фактическая Дата и время окончания акции
Маркетинговая акция завершена, но артикул продолжает участвовать в другой акции (однократная выгрузка).
Задача: проинформировать DS о новом значении и начале действия новой аукционной цены.
- При формировании выгрузки storePrices (цены) - для товара участвующего в Маркетинговой акции, в качестве регулярной цены будет выгружаться текущая цена из карточки, она же на этот момент будет являться акционной.
- При формировании выгрузки priceTagInfo (акционные цены) - для товара участвующего в действующей Маркетинговой акции, в качестве:
- «Цены» - должна выгружаться текущая цена из карточки, она же на этот момент будет являться акционной.
- «Старой цены» - должна быть выгружена цена, которая была зафиксирована как «цена до акции».
- «Название акции» - название акции, которая породила акционную цену.
- «Дата и время начала акции» - Планируемая Дата и время старта акции
- «Дата и время окончания акции» - Планируемая Дата и время окончания акции
- Протокол взаимодействия с Kafka:
Для публикации сообщений, рекомендуется использовать нативную библиотеку:
https://www.educative.io/courses/mastering-apache-kafka/apache-kafka-client-libraries
librdkafka — нативная библиотека для работы с Apache Kafka на C/C++. Это реализация протокола Kafka, разработанная для обеспечения высокой производительности и надёжности доставки сообщений.
- Параметры подключения к kafka:
Логин партнёра - smp-2025-producer
Пароль партнёра - 8sERmSQXtuXRKv6
id партнёра - 2025
Топики получаются вида - 2025.*
Например - 2025.store
- Web интерфейс Kafka.
http://192.168.25.118:8080
Там можно будет посмотреть, кладутся ли сообщения в очередь, сколько их и даже посмотреть (если они не очень большие).
Примечание: в интерфейсе выданы ПОЛНЫЕ права, и «легким движением» можно убить кластер. Поэтому ничего не создавать, не удалять, не изменять. Только смотреть. Очень бережно.
- Публикация файлов в kafka (топики):
Каждый клиент идентифицируется уникальным ID (partner_id). Для каждого клиента создается отдельная группа топиков в формате: partner_id.doc_type
partner_id - id партнера на сервере DS
doc_type - тип передаваемой информации
- Обработка и отправка файлов в Kafka:
- Деление файла и отправка в Kafka
- Обработка и отправка файлов в Kafka:
Разделение файла на куски поменьше и дальнейшая отправка в Kafka:
- Маленький файл:
| Wiki разметка |
|---|
Если содержимое публикуемого файла в *Kafka* *меньше{*} 1 МБ, то публиковать файл без нарезания на куски.
В этом случае в сообщении кафки {*}не должно быть полей part и part_status{*}, т.к. файл не нарезался:
\{
"content_base64": "здесь содержимое в base64",
"event_type": "F",
"number": "1",
"original_filename": "updateItems_\[1\]_\[F\].xml",
"store_id": "all",
\} |
- сontent_base64 - содержимое xml файла в кодировке base64 (информация о товарах)
- event_type - тип выгрузки (F/I - полная/частичная выгрузка)
- number - порядковый номер файла (целое число)
- original_filename - имя xml файла
- store_id - id магазина во внешней системе
В поле store_id необходимо передавать "all", т.к. файл с полным списком товаров будет передаваться через кассовый сервер.
- Большой файл:
| Wiki разметка |
|---|
Если же содержимое публикуемого файла в кафку {*}больше{*} 1 МБ, то делить его на куски перед отправкой:
Создаём новые маленькие xml-файлы (сохраняя заголовки, т.е. делаем самодостаточные файлы) и копируем туда N товаров (считать по количеству товаров или по объему - на усмотрение разработчика).
Полученные файлы должны быть меньше 1МБ
Публиковать файлы в kafka в следующем виде ({*}указывать part и part_status{*} для частей):
\{
"content_base64": "здесь содержимое в base64",
"event_type": "F",
"number": "1",
"original_filename": "updateItems_\[1\]_\[F\].xml",
"store_id": "all",
"part": "1",
"part_status": "process"
\} |
- сontent_base64 - содержимое xml файла в кодировке base64 (информация о товарах)
- event_type - тип выгрузки (F/I - полная/частичная выгрузка)
- number - порядковый номер файла (целое число)
- original_filename - имя xml файла
- store_id - id магазина во внешней системе
- part - номер части для больших файлов
- part_status - статус части. Варианты:
- process - будут еще части
- last - последняя часть
В поле store_id необходимо передавать "all", т.к. файл с полным списком товаров будет передаваться через кассовый сервер.
- Ограничение системы:
На усмотрение разработчика.
- Версия:
СуперМаг Плюс - 1.060.


