Настройка шаблонов парсинга цен поставщика

Настройка шаблонов парсинга цен поставщика производится на вкладке "Настройки шаблона" соотвествующих настроек поставщика.

Для распознавания файла на вкладке нужно указать уникальную подстроку в названии файла и задать шаблон.

Для написания шаблона мы используем язык Scriban. Scriban - это быстрый, мощный, безопасный и легкий язык сценариев. Подробнее с языком можно ознакимиться здесь.

Шаблон на вход получает объект сформированный из xml-файла, а возращать должен объект PriceRecord. Объект PriceRecord состоит из следующих полей:

  • Name - название товара
  • Category - категория товара
  • Vendor - бренд товара
  • Article - артикул бренда
  • Ean - EAN
  • SellerCode - внешний Id
  • Price - цена товара (можно передавать как строку и в качестве разделитля дробной части использовать '.' или ',')
  • PriceCurrency - валюта цены (поддерживаются значения "BYN", "RUB", "USD", "EUR", "UAH", "KZT", регистр не учитывается)
  • MinRetailPrice - МРЦ товара (можно передавать как строку и в качестве разделитля дробной части использовать '.' или ',')
  • MinRetailPriceCurrency - валюта МРЦ (поддерживаются значения "BYN", "RUB", "USD", "EUR", "UAH", "KZT", регистр не учитывается)
  • InStockAmount - количество товаров на складе
  • DeliveryTime - время доставки, дней (если не указано, то значение по умолчанию возьмется из настроек поставщика)
  • DeliveryCountryPrice - цена доставки по стране (можно передавать как строку и в качестве разделитля дробной части использовать '.' или ',')
  • DeliveryTownPrice - цена доставки по городу (можно передавать как строку и в качестве разделитля дробной части использовать '.' или ',')
  • Source - внешняя ссылка (URL) на товар

Исходный xml-файл будет предбразован в scriban-объект согласно вложенности файла. Более подробно разберем на примере.

Пример xml-файла:

<?xml version="1.0" encoding="UTF-8"?>
<supplier_catalog date="2022-05-23 13:44" version="1.2">
	<supplier>
		<company>catalog.app</company>
		<post_address>109428, Москва г</post_address>
		<legal_address>109428, Москва г</legal_address>
		<address>109428, Москва г</address>
		<website>https://catalog.app</website>
		<phone>(123)456-78-90</phone>
		<platform>1C</platform>
		<platform_version>8.2</platform_version>
		<email>example@catalog.app</email>
		<currencies>
			<currency id="RUR" rate="1"/>
		</currencies>
		<categories>
			<category id="28255779">09.01.02 Бассейны, игровые центры BESTWAY</category>
			<category id="28274064">18.01 Кухня</category>
			<category id="28266257">313.18.12 Разное</category>
			<category id="28266266">313.18.13 Пластиковые горшки</category>
		</categories>
		<offers>
			<offer id="28263223">
				<currencyId>RUR</currencyId>
				<categoryId>28266257</categoryId>
				<Article>44695</Article>
				<name>Антилед Гуд Хим Стронг 4л, арт. 44695</name>
				<description/>
				<url/>
				<stock1>0</stock1>
				<stock2>2</stock2>
				<price_rrc>172</price_rrc>
				<price_opt>125.06</price_opt>
				<price_opt1>121.43</price_opt1>
				<price_opt2>117.91</price_opt2>
				<price_opt3>114.48</price_opt3>
				<VAT>20</VAT>
				<multi>120</multi>
				<unit>шт.</unit>
				<brand>ГудХим</brand>
				<SHK>4623721344695</SHK>
			</offer>
			<offer id="28266353">
				<currencyId>RUR</currencyId>
				<categoryId>28274064</categoryId>
				<Article/>
				<name>Ручка для стеклянной банки d-82, 5шт.</name>
				<description/>
				<url/>
				<stock1>0</stock1>
				<stock2>&gt;50</stock2>
				<price_rrc>48</price_rrc>
				<price_opt>34.96</price_opt>
				<price_opt1>33.94</price_opt1>
				<price_opt2>32.96</price_opt2>
				<price_opt3>32</price_opt3>
				<VAT>20</VAT>
				<multi>40</multi>
				<unit>шт.</unit>
				<brand>Нет бренда</brand>
				<SHK>4665299490220</SHK>
			</offer>
			<offer id="28261987">
				<currencyId>RUR</currencyId>
				<categoryId>28266266</categoryId>
				<Article>П-12TX</Article>
				<name>Корона для орхидей МИНИ с поддоном</name>
				<description/>
				<url/>
				<stock1>>50</stock1>
				<stock2>32</stock2>
				<price_rrc>230</price_rrc>
				<price_opt>167.14</price_opt>
				<price_opt1>162.29</price_opt1>
				<price_opt2>157.59</price_opt2>
				<price_opt3>153</price_opt3>
				<VAT>20</VAT>
				<multi>24</multi>
				<unit>шт.</unit>
				<brand>Нет бренда</brand>
				<SHK>4607021018777</SHK>
			</offer>
			<offer id="28271213">
				<currencyId>RUR</currencyId>
				<categoryId>28255779</categoryId>
				<Article>57273</Article>
				<name>57273 Бассейн с надувным бортом 366х76см</name>
				<picture>https://example.com/shop/products/52/74/17452/images/8944/8944.970.jpg</picture>
				<description/>
				<url>https://example.com/57273-basseyn-366-kh-76-sm/</url>
				<stock1>6</stock1>
				<stock2>32</stock2>
				<price_rrc>7865</price_rrc>
				<price_opt>5727.45</price_opt>
				<price_opt1>5561.25</price_opt1>
				<price_opt2>5400.29</price_opt2>
				<price_opt3>5243</price_opt3>
				<VAT>20</VAT>
				<multi>1</multi>
				<unit>шт.</unit>
				<brand>Bestway</brand>
				<SHK>6942138951356</SHK>
			</offer>
		</offers>
	</supplier>
</supplier_catalog>

Данный xml-файл будет преобразован в следующий объект (для понятности используем JSON):

{
    "?xml": {
        "version": "1.0",
        "encoding": "UTF-8"
    },
    "supplier_catalog": {
        "date": "2022-05-23 13:44",
        "version": "1.2",
        "supplier": {
            "company": "catalog.app",
            "post_address": "109428, Москва г",
            "legal_address": "109428, Москва г",
            "address": "109428, Москва г",
            "website": "https://catalog.app",
            "phone": "(123)456-78-90",
            "platform": "1C",
            "platform_version": "8.2",
            "email": "example@catalog.app",
            "currencies": {
                "currency": {
                    "id": "RUR",
                    "rate": "1"
                }
            },
            "categories": {
                "category": [
                    {
                        "id": "28255779",
                        "text": "09.01.02 Бассейны, игровые центры BESTWAY"
                    },
                    {
                        "id": "28274064",
                        "text": "18.01 Кухня"
                    },
                    {
                        "id": "28266257",
                        "text": "313.18.12 Разное"
                    },
                    {
                        "id": "28266266",
                        "text": "313.18.13 Пластиковые горшки"
                    }
                ]
            },
            "offers": {
                "offer": [
                    {
                        "id": "28263223",
                        "currencyId": "RUR",
                        "categoryId": "28266257",
                        "Article": "44695",
                        "name": "Антилед Гуд Хим Стронг 4л, арт. 44695",
                        "description": null,
                        "url": null,
                        "stock1": "0",
                        "stock2": "2",
                        "price_rrc": "172",
                        "price_opt": "125.06",
                        "price_opt1": "121.43",
                        "price_opt2": "117.91",
                        "price_opt3": "114.48",
                        "VAT": "20",
                        "multi": "120",
                        "unit": "шт.",
                        "brand": "ГудХим",
                        "SHK": "4623721344695"
                    },
                    {
                        "id": "28266353",
                        "currencyId": "RUR",
                        "categoryId": "28274064",
                        "Article": null,
                        "name": "Ручка для стеклянной банки d-82, 5шт.",
                        "description": null,
                        "url": null,
                        "stock1": "0",
                        "stock2": ">50",
                        "price_rrc": "48",
                        "price_opt": "34.96",
                        "price_opt1": "33.94",
                        "price_opt2": "32.96",
                        "price_opt3": "32",
                        "VAT": "20",
                        "multi": "40",
                        "unit": "шт.",
                        "brand": "Нет бренда",
                        "SHK": "4665299490220"
                    },
                    {
                        "id": "28261987",
                        "currencyId": "RUR",
                        "categoryId": "28266266",
                        "Article": "П-12TX",
                        "name": "Корона для орхидей МИНИ с поддоном",
                        "description": null,
                        "url": null,
                        "stock1": ">50",
                        "stock2": "32",
                        "price_rrc": "230",
                        "price_opt": "167.14",
                        "price_opt1": "162.29",
                        "price_opt2": "157.59",
                        "price_opt3": "153",
                        "VAT": "20",
                        "multi": "24",
                        "unit": "шт.",
                        "brand": "Нет бренда",
                        "SHK": "4607021018777"
                    },
                    {
                        "id": "28271213",
                        "currencyId": "RUR",
                        "categoryId": "28255779",
                        "Article": "57273",
                        "name": "57273 Бассейн с надувным бортом 366х76см",
                        "picture": "https://example.com/shop/products/52/74/17452/images/8944/8944.970.jpg",
                        "description": null,
                        "url": "https://example.com/57273-basseyn-366-kh-76-sm/",
                        "stock1": "6",
                        "stock2": "32",
                        "price_rrc": "7865",
                        "price_opt": "5727.45",
                        "price_opt1": "5561.25",
                        "price_opt2": "5400.29",
                        "price_opt3": "5243",
                        "VAT": "20",
                        "multi": "1",
                        "unit": "шт.",
                        "brand": "Bestway",
                        "SHK": "6942138951356"
                    }
                ]
            }
        }
    }
}

Особое внимание стоит обратить на прицип формирования массивов и название поля для внутреннего содержимого тега (text).

Обращение к полям объекта будет происходить через разделение символом точки, а главный объект будет называться 'model'. К примеру, чтобы получить название первой категории нужно выполнить следующее обращение: model.supplier_catalog.supplier.categories.category[0].text.

Пример шаблона для парсинга указанного выше xml-файла:

func get_array(item, prop)
    if object.has_key item prop
        if (object.typeof item[prop]) == "array"
            ret item[prop]
        else
            ret [item[prop]]
        end
    end
    ret []
end

func get_in_stock_amount(offer)
    in_stock_amount = "0"
    if string.starts_with offer.stock1 ">"
        in_stock_amount = string.remove_first offer.stock1 ">"
    else
        in_stock_amount = offer.stock1
    end

    ret string.to_int in_stock_amount 
end

func get_currency(offer)
    available_currencies = ["BYN", "RUB", "USD", "EUR", "UAH", "KZT"]
    
    currency_id_normalized = string.upcase offer.currencyId
    currency = currency_id_normalized == "RUR" ? "RUB" : currency_id_normalized
    
    ret array.contains available_currencies currency ? currency : null
end

categories = get_array model.supplier_catalog.supplier.categories "category"
categories_dict = {}
for category in categories
    categories_dict[string.to_long category.id] = category
end

offers = get_array model.supplier_catalog.supplier.offers "offer"

records = []
for offer in offers
    currency = get_currency offer
    if currency == null
        continue
    end 

    record = {
        Name: offer.name,
        Vendor: offer.brand,
        Article: offer.Article,
        Ean: offer.SHK,
        Category: categories_dict[string.to_long offer.categoryId].text,
        Price: offer.price_opt,
        SellerCode: offer.id,
        InStockAmount: get_in_stock_amount offer,
        PriceCurrency: currency
    } 

    records = array.add records record
end

ret records