Интеграция СуперМаг Плюс и 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 и ДС
- Интерфейс и реализация:
В настоящее время УКМ5 интегрируется с СуперМаг DS по следующей схеме (рис.1.):
Рис.1.
Схема интеграции через СуперМаг Плюс претерпит следующие изменения (Рис.2.):
Рис.2.
Предполагается, что подготовкой данных будет заниматься служба Кассовый сервер СуперМаг Плюс. А публикацией сообщений для СуперМаг DS – ее отдельный модуль «СуперМаг издатель»*.
- Рабочее название.
Логика работы с ПО Kafka заключается в следующем: - Кассовый модуль СуперМаг Плюс подготавливает данные в специализированном формате XML (описан ниже).
- Полученные данные, модуль «СуперМаг издатель» должен преобразовать и отправить в топик Kafka.
Справка: Apache Kafka — распределённая система обмена сообщениями между серверными приложениями в режиме реального времени.
- Описание форматов обмена:
Формат данных для публикации.
СуперМаг Плюс должен публиковать в 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 (магазины)
Наименование файла: 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 (товары)
Наименование файла: 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. |
«Скидка от количества» |
Не реализована в СМ+, выгружаться не будет. |
<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: |
|
|
|
||||||
|---|---|---|---|---|---|---|---|---|---|
<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)
Наименование файла: 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:
-
-
-
- Маленький файл:
-
-
Если содержимое публикуемого файла в 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", т.к. файл с полным списком товаров будет передаваться через кассовый сервер.
-
-
-
- Большой файл:
-
-
Если же содержимое публикуемого файла в кафку больше 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.


