Реалізація автоматичного оновлення описів і характеристик товарів

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація автоматичного оновлення описів і характеристик товарів
Середня
~3-5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація автоматичного оновлення описів та характеристик товарів

Описи та характеристики товарів — це контент, який постачальники регулярно розширюють та уточняють. Новий ГОСТ, виправлені технічні параметри, додані сертифікати — все це повинно потрапляти в каталог без ручної роботи редакторів. При цьому якщо контент-менеджер вручну переписав опис — автоматика не повинна його затирати.

Структура даних для керованого оновлення

Ключовий принцип: розділяти джерело даних (постачальник) та фінальний контент (що показується на сайті), з прапором «вручну відредаговано».

CREATE TABLE product_content (
    product_id          int        REFERENCES products(id),
    source              varchar(30),          -- supplier_id або 'manual'
    field               varchar(50),          -- description | spec_weight | spec_color ...
    value               text,
    is_manual_override  boolean DEFAULT false,
    supplier_value      text,                 -- останнє значення від постачальника
    updated_at          timestamptz,
    PRIMARY KEY (product_id, field)
);

При автооновленні: якщо is_manual_override = true — оновлюємо тільки supplier_value, але не value. Контент-менеджер бачить розбіжність в інтерфейсі та вирішує, чи прийняти зміну постачальника.

Джерела описів

XML-фід постачальника

Більшість виробничих компаній надають XML з розширеними атрибутами:

<product article="ABC-123">
  <description lang="uk"><![CDATA[Детальний опис...]]></description>
  <attributes>
    <attribute name="weight" unit="kg">2.5</attribute>
    <attribute name="color">Чорний</attribute>
    <attribute name="material">Нержавіюча сталь</attribute>
  </attributes>
</product>

Парсер на PHP:

class XmlDescriptionSource implements DescriptionSourceInterface
{
    public function fetch(): iterable
    {
        $xml = new \XMLReader();
        $xml->open($this->url);

        while ($xml->read()) {
            if ($xml->nodeType === \XMLReader::ELEMENT && $xml->name === 'product') {
                $node = new \SimpleXMLElement($xml->readOuterXml());
                yield $this->parseProduct($node);
            }
        }
        $xml->close();
    }

    private function parseProduct(\SimpleXMLElement $node): array
    {
        $data = [
            'sku'         => (string) $node['article'],
            'description' => (string) $node->description,
            'attributes'  => [],
        ];
        foreach ($node->attributes->attribute as $attr) {
            $data['attributes'][(string) $attr['name']] = (string) $attr;
        }
        return $data;
    }
}

XMLReader читає файл потоком — не завантажує весь XML у пам'ять, що критично при каталогах від 100 000 позицій.

API з частковим оновленням

Якщо постачальник надає endpoint змін:

GET /products/updates?fields=description,attributes&since=2024-01-15T10:00:00Z

Повертає тільки товари, у яких змінилося хоча б одне з указаних полів — істотно скорочує обсяг обробки.

Оновлення характеристик з нормалізацією

Постачальник надсилає характеристики у власному форматі — потрібно привести до внутрішньої схеми сайту:

class AttributeNormalizer
{
    // Маппінг імен атрибутів постачальника → внутрішні ключі
    private array $nameMap = [
        'weight'       => 'spec_weight_kg',
        'маса'         => 'spec_weight_kg',
        'вага нето'    => 'spec_weight_kg',
        'color'        => 'spec_color',
        'колір'        => 'spec_color',
    ];

    public function normalize(string $supplierName, mixed $value): ?array
    {
        $key = $this->nameMap[mb_strtolower(trim($supplierName))] ?? null;
        if (!$key) return null;

        return ['key' => $key, 'value' => $this->castValue($key, $value)];
    }

    private function castValue(string $key, mixed $raw): mixed
    {
        return match(true) {
            str_starts_with($key, 'spec_weight') => (float) str_replace(',', '.', $raw),
            default => (string) $raw,
        };
    }
}

Job-ланцюжок для оновлення контенту

Оновлення описів тяжче за оновлення цін — контент великий, потрібно нормалізувати атрибути, порівнювати з override-флагами. Оптимальна схема: окрема чергу з низьким паралелізмом.

class UpdateProductDescriptionsJob implements ShouldQueue
{
    public int $tries = 3;
    public int $backoff = 60; // секунди між повторами

    public function handle(
        DescriptionSourceInterface $source,
        AttributeNormalizer        $normalizer,
        ContentUpdater             $updater,
    ): void {
        foreach ($source->fetch() as $item) {
            $productId = Product::where('sku', $item['sku'])->value('id');
            if (!$productId) continue;

            // Опис
            $updater->updateField($productId, 'description', $item['description']);

            // Характеристики
            foreach ($item['attributes'] as $name => $value) {
                $normalized = $normalizer->normalize($name, $value);
                if ($normalized) {
                    $updater->updateField($productId, $normalized['key'], $normalized['value']);
                }
            }
        }
    }
}

Логіка ContentUpdater

class ContentUpdater
{
    public function updateField(int $productId, string $field, mixed $newValue): void
    {
        $existing = ProductContent::where([
            'product_id' => $productId,
            'field'      => $field,
        ])->first();

        if (!$existing) {
            ProductContent::create([
                'product_id'     => $productId,
                'field'          => $field,
                'value'          => $newValue,
                'supplier_value' => $newValue,
            ]);
            return;
        }

        // Завжди оновлюємо supplier_value для відображення розбіжності
        $existing->supplier_value = $newValue;

        // Перезаписуємо тільки якщо немає ручного оверрайду
        if (!$existing->is_manual_override) {
            $existing->value = $newValue;
        }

        $existing->updated_at = now();
        $existing->save();
    }
}

Розписання та пріоритети

Тип даних Частота Причина
Характеристики (розміри, вага) Раз на день Мінливі рідко
Описи Раз на день Великий обсяг, не срочно
Статуси сертифікатів Раз на тиждень Змінюються ще рідше
Ціни Кожні 15–30 хв Висока волатильність

Інтерфейс розбіжностей в админці

Якщо value != supplier_value AND is_manual_override = true, показувати в інтерфейсі товару попередження: «Постачальник змінив значення. Поточне: X, нове від постачальника: Y. Прийняти?» з кнопками «Прийняти» та «Залишити».

Тривалість реалізації

  • Одне XML-джерело, оновлення опису та атрибутів без оверрайдів — 2–3 дні
  • Нормалізатор атрибутів з таблицею маппінгу + механізм оверрайду — +2 дні
  • Панель розбіжностей в админці — +1–2 дні