Создание фида ценообразования по шаблону
Фид для интеграции можно создать с помощью экспорта каталога по шаблону. Для этого небходимо создать профиль экспорта:
- Перейдите на страницу "Настройки"
- Перейдите на вкладку "Экспорт"
- Нажмите на кнопку "+"
- Укажите название профиля экспорта, выберите профиль ценообразования, по которому будет подготовлен фид, и выберите формат "Каталог по шаблону"
- Нажмите "Сохранить"
После сохранения профиля экспорта станет доступна настройка шаблона интеграции.
Редактирование существующего профиля:
- Нажмите напротив этого профиля на значок карандашика.
- Отредактируйте название или добавьте/удалите профиль ценообразования.
- Нажмите кнопку "Сохранить".
Удаление существующего профиля:
- Нажмите напротив этого профиля на значок корзинки.
- Подтвердите удаление.
Настройка шаблона интеграции:
- Перейдите на вкладку "Настройка шаблона".
- Выберите тип выгрузки параметров.
- Выберите тип валидации (при необходимости).
- Выберите шаблон (нажамите кнопку "Шаблоны") или напишите свой.
- Нажмите кнопку "Сохранить".
Для написания шаблона мы используем язык Scriban. Scriban - это быстрый, мощный, безопасный и легкий язык сценариев. Подробнее с языком можно ознакимиться здесь. Проверить корректность работы шаблона можно нажав на кнопку "Тест". После этого появится окно "Результаты", в котором, при корректнонаписаном шаблоне, появится результат (как будет выглядеть фид).
Шаблон на вход получает объект model, содержащий следующие поля:
- Currency - [строка] - валюта профиля ценообразования
- Products - [список объектов] - список товаров каталога
- AllCategories - [список объектов] - список категорий каталога
- Categories - [список объектов] - список категорий товаров из ценообразования и их родителей
- Offers - [список объектов] - список офферов (цен, сформированных по правилам профиля ценообазования)
- MaxDeliveryCost - [число] - максимальная стоимость доставки по стране среди всех офферов
- MaxDeliveryTime - [число] - максимальный срок доставки среди всех офферов
Объекты из спискаов Categories и AllCategories содержат следующие данные о категориях:
- Id - [число] - Id
- Name - [текст] - название категории
- SingularName - [текст] - название категории в единственном числе
- ParentId - [число или null] - Id родительской категории
Объекты из списка Products содержат следующие данные о товарах:
- ModelId - [число] - идентификатор модели
- Model - [текст] - название модели
- Category - [текст] - категория товара
- Vendor - [текст] - производитель
- Article - [текст] - артикул производителя
- Color - [текст] - цвет товара
- BarCodes - [список строк] - штрихкоды (EAN и др.)
- ModelExternalId - [текст или null] - внешний идентификатор модели
- CategoryId - [число] - идентификатор категории
- CategoryExternalId - [текст или null] - внешний идентификатор категории
- VendorId - [число] - идентификатор производителя
- VendorExternalId - [текст или null] - внешний идентификатор производителя
- OzonSku - [число или null] - SKU товара на Ozon
- OzonFboSku - [число или null] - SKU FBO на Ozon
- OzonFbsSku - [число или null] - SKU FBS на Ozon
- OzonProductId - [число или null] - ProductId товара на Ozon
- OzonOfferId - [текст] - OfferId товара на Ozon
- WbImtId - [число или null] - IMT ID товара на Wildberries
- WbNmId - [число или null] - NM ID товара на Wildberries
- WbSku - [текст] - SKU товара на Wildberries
- WbVendorCode - [текст] - артикул продавца на Wildberries
- Description - [текст или null] - описание товара
- Pictures - [список строк] - изображения товара
- Parameters - [список объектов] - характеристики товара
- Tags - [список объектов] - теги товара
- MinMinRetailPrice - [число] - минимальная МРЦ товара среди всех поставщиков
- MinRetailPrices - [список объектов] - список МРЦ товара
Объекты из списка Parameters содержат следующие данные о характеристиках товаров:
- Name - [текст] - название характеристики
- DefinitionId - [текст] - идентификатор характеристики
- DefinitionExternalId - [текст или null] - внешний идентификатор характеристики
- Order - [текст] - порядок сортировки характеристики
- Group - [текст или null] - группа характеристики
- GroupId - [число или null] - идентификатор группы характеристики
- GroupOrder - [число или null] - порядок сортировки группы
- Value - [текст] - значение характеристики (формат зависит от типа: Да/Нет, число, диапазон
min...max, одно значение enum, список флагов через;, список моделей через;, строка/выражение) - Unit - [текст] - единица измерения (только для числовых/диапазонных и numeric enum/flags)
Объекты из списка Tags содержат следующие данные о тегах товаров:
- Id - [число] - Id
- Name - [текст] - название тега
Объекты из списка MinRetailPrices содержат данные о минимальных розничных ценах (МРЦ), рассчитанных на основе цен поставщиков:
- ModelId - [число] - идентификатор модели товара
- ModelExternalId - [текст] - внешний идентификатор модели
- MinRetailPrice - [число] - минимальная розничная цена
- SupplierName - [текст] - название поставщика, от которого получена МРЦ
- SupplierId - [число] - идентификатор поставщика
- OriginalRecord - [объект] - оригинальная запись из прайса поставщика (необработанные данные)
Объект OriginalRecord содержит исходную (необработанную) запись строки прайса поставщика:
- [ключ: значение] - [любой тип] - поля оригинальной строки прайса поставщика, сформированные из исходного JSON без нормализации
- Param - [объект] - параметры товара из оригинального прайса в виде словаря
где:- ключ – [текст] – название параметра
- значение – [любой тип] – значение параметра из прайса поставщика
Объекты из списка Offers содержат следующие данные об офферах (предложениях):
- ModelId - [число] - идентификатор модели
- OfferId - [текст] - идентификатор оффера (формируется из ModelId в формате
d7) - Model - [текст] - название модели
- Category - [текст] - категория товара
- CategorySingularName - [текст] - категория в единственном числе
- Vendor - [текст] - производитель
- Price - [число] - итоговая цена оффера
- OriginalPrice - [число] - исходная цена до перерасчётов
- SupplierPrice - [число] - цена поставщика, используемая для расчёта
- SupplierName - [текст] - название поставщика
- Article - [текст] - артикул производителя
- DeliveryTime - [число] - срок доставки (дней)
- DeliveryTownPrice - [число] - стоимость доставки по городу
- DeliveryCountryPrice - [число] - стоимость доставки по стране
- MinHighCompetitorPrice - [число или null] - минимальная цена конкурентов (high)
- MinLowCompetitorPrice - [число или null] - минимальная цена конкурентов (low)
- Color - [текст] - цвет
- InStockAmount - [число] - количество в наличии
- BarCodes - [список строк] - штрихкоды
- ExternalId - [текст или null] - внешний идентификатор
- MinRetailPrice - [число или null] - МРЦ
- MaxRetailPrice - [число или null] - максимальная розничная цена
- CategoryId - [число] - идентификатор категории
- OzonSku - [число или null] - SKU на Ozon
- OzonFboSku - [число или null] - SKU FBO на Ozon
- OzonFbsSku - [число или null] - SKU FBS на Ozon
- OzonProductId - [число или null] - ProductId на Ozon
- OzonOfferId - [текст или null] - OfferId на Ozon
- WbImtId - [число или null] - IMT ID на Wildberries
- WbNmId - [число или null] - NM ID на Wildberries
- WbSku - [текст или null] - SKU на Wildberries
- WbVendorCode - [текст или null] - артикул продавца на Wildberries
- Description - [текст или null] - описание
- Profit - [число] - прибыль (рассчитывается как
Price - SupplierPrice) - Pictures - [список строк] - изображения товара
- Parameters - [список объектов] - характеристики товара
- Tags - [список объектов] - теги
- VendorId - [число] - идентификатор производителя
Добавление условий в шаблон
Условия помогают в выборе товаров, соответствующих определенным критериям. Для добавления условий удобно пользоваться функциями. Функции небходимо определить до шаблона и вызвать внутри шаблона. Пример:
{{-func condition(offer)
if (offer.MinHighCompetitorPrice == null && offer.MinLowCompetitorPrice == null)
ret true
else
ret false
end
end-}}
<?xml version="1.0" encoding="utf-8"?>
<yml_catalog date="{{ date.now | date.to_string '%F %R' }}">
<shop>
<categories>
{{- for category in model.Categories}}
<category id="{{category.Id}}" parentId="{{category.ParentId}}">{{category.Name}}</category>
{{- end }}
</categories>
<company>ООО "Компания"</company>
<currencies>
<currency id="{{model.Currency}}" />
</currencies>
<delivery-options>
<option cost="{{model.MaxDeliveryCost}}" days="{{model.MaxDeliveryTime}}" />
</delivery-options>
<name>Название магазина</name>
<url>https://example.ru/</url>
<offers>
{{- for offer in model.Offers}}
{{- if condition offer }}
<offer id="{{offer.OfferId}}" type="vendor.model" available="true">
<barcode>{{offer.BarCodes | array.join ", "}}</barcode>
<categoryId>{{offer.CategoryId}}</categoryId>
<currencyId>{{model.Currency}}</currencyId>
<outlets>
<outlet id="0" instock="{{offer.InStockAmount}}" />
</outlets>
<model>{{offer.Model}} {{offer.Color}}</model>
<name>{{offer.CategorySingularName}} {{offer.Vendor}} {{offer.Model}} {{offer.Color}} {{offer.Article}}</name>
{{- for parameter in offer.Parameters}}
<param name="{{parameter.Name}}" unit="{{parameter.Unit}}">{{parameter.Value}}</param>
{{- if parameter.Name == "Страна-производитель" -}}
{{- capture country_of_origin -}}
{{parameter.Value}}
{{- end -}}
{{- end -}}
{{- if parameter.Name == "Длина в упаковке" -}}
{{- capture length -}}
{{parameter.Value}}
{{- end -}}
{{- end -}}
{{- if parameter.Name == "Ширина в упаковке" -}}
{{- capture width -}}
{{parameter.Value}}
{{- end -}}
{{- end -}}
{{- if parameter.Name == "Высота в упаковке" -}}
{{- capture height -}}
{{parameter.Value}}
{{- end -}}
{{- end -}}
{{- if parameter.Name == "Вес" -}}
{{- capture weight -}}
{{parameter.Value}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- for picture in offer.Pictures}}
<picture>{{picture}}</picture>
{{- end }}
<country_of_origin>{{country_of_origin}}</country_of_origin>
<dimensions>{{length}}/{{width}}/{{height}}</dimensions>
<weight>{{weight}}</weight>
<description>{{offer.Description}}</description>
<price>{{offer.Price}}</price>
<typePrefix>{{offer.CategorySingularName}}</typePrefix>
<url>https://techshop.ru/product/?XML_ID={{offer.ExternalId}}</url>
<vendor>{{offer.Vendor}}</vendor>
<vendorCode>{{offer.Article}}</vendorCode>
<shop-sku>{{offer.OfferId}}</shop-sku>
</offer>
{{- end }}
{{- end }}
</offers>
</shop>
</yml_catalog>
Вызов функции:
<offers>
{{- for offer in model.Offers}}
{{- if condition offer }}
<offer id="{{offer.OfferId}}" type="vendor.model" available="true">
<barcode>{{offer.BarCodes | array.join ", "}}</barcode>
...
<shop-sku>{{offer.OfferId}}</shop-sku>
</offer>
{{- end }}
{{- end }}
</offers>
Примеры условий:
- Цены выше до n % от цен конкурентов 1-го уровня
{{-func condition(offer, ConditionVal)
if (offer.MinHighCompetitorPrice != null && ConditionVal != null)
if (offer.Price > offer.MinHighCompetitorPrice && (offer.Price - offer.MinHighCompetitorPrice) * 100 / offer.MinHighCompetitorPrice < ConditionVal)
ret true
else
ret false
end
end
end-}}
- Цены = ценам конкурентов 1-го уровня
{{-func condition(offer)
if (offer.MinHighCompetitorPrice != null)
if (offer.MinHighCompetitorPrice == Price)
ret true
else
ret false
end
end
end-}}
- Цена ниже, чем у 1-го, но выше более n %, чем у 2-го
{{-func condition(offer, ConditionVal)
if (offer.MinHighCompetitorPrice != null && offer.MinLowCompetitorPrice != null)
if (offer.Price < offer.MinHighCompetitorPrice && offer.Price > offer.MinLowCompetitorPrice && (offer.Price - offer.MinLowCompetitorPrice) * 100 / offer.MinLowCompetitorPrice > ConditionVal)
ret true
else
ret false
end
end
end-}}
- Цена ниже, чем у 1-го, но выше не более n %, чем у 2-го
{{-func condition(offer, ConditionVal)
if (offer.MinHighCompetitorPrice != null && offer.MinLowCompetitorPrice != null)
if (offer.Price < offer.MinHighCompetitorPrice && offer.Price > offer.MinLowCompetitorPrice && (offer.Price - offer.MinLowCompetitorPrice) * 100 / offer.MinLowCompetitorPrice <= ConditionVal)
ret true
else
ret false
end
end
end-}}
- Цена ниже, чем у 1-го и 2-го
{{-func condition(offer)
if (offer.MinHighCompetitorPrice != null && offer.MinLowCompetitorPrice != null)
if (offer.Price < offer.MinHighCompetitorPrice && offer.Price < offer.MinLowCompetitorPrice)
ret true
else
ret false
end
end
end-}}
- Нет товара у конкурентов, но есть у нас
{{-func condition(offer)
if (offer.MinHighCompetitorPrice == null && offer.MinLowCompetitorPrice == null)
ret true
else
ret false
end
end-}}
- Минимальное время доставки в диапазоне MinDeliveryTime-MaxDeliveryTime дня и маржа в диапазоне MinProfit-MaxProfit %
{{-func condition(offer, MinProfit, MaxProfit, MinDeliveryTime, MaxDeliveryTime)
if (offer.Profit >= MinProfit && offer.Profit <= MaxProfit && offer.DeliveryTime >= MinDeliveryTime && offer.DeliveryTime <= MaxDeliveryTime)
ret true
else
ret false
end
end-}}
- Функция для получения родительской категории любого уровня (положительный level для подсчета уровня с корня дерева, отрицательный - для подсчета с категории товара):
categories = {}
for category in model.Categories
categories[category.Id] = category
end
# use positive level to iterate categories from root
# use negative level to iterate categories from leaf
func getCategory(offer, level)
i = 0
path = []
current = categories[offer.CategoryId]
while current
path[i] = current
i = i + 1
current = categories[current?.ParentId ?? 0]
end
if level < 0 && path.size > -level
ret path[-level]
end
if path.size >= level
begin
ret path[path.size - level - 1]
end
ret null
end
Условий может быть несколько (при этом они должны называться по разному), несколько условий можно скомбинировать в одно, a также добавлять свои условия. Проверить корректность условий можно здесь.
Для выполнения экспорта:
- Перейдите на страницу "Задачи".
- Перейдите на вкладку "Экспорт".
- Выберите необходимый профиль экспорта.
- Нажмите кнопку "Запустить".
Статус задачи, а также историю последних выполненых экспортов можно посмотреть в списке "Последние экспорты".Результатом выполнения задачи является файл в формате .xml, который можно скачать нажав напротив нужного экспорта "Скачать". В настройках шаблона можно посмотеть ссылку на этот файл.