Перейти к содержимому

Аудит каталога - товары без цены, картинок, дубли артикулов

Собираем скрипт проверки каталога: товары без цены и картинок, дубли артикулов, пустые обязательные свойства и понятный отчёт для контент-менеджера.

Что нужно знать заранее

Проверок должно быть немного, и каждая отвечает на один вопрос. Отчёт из двадцати колонок никто не читает, а список «сто товаров без цены» разбирают за день.

Часть проверок дешевле делать прямым запросом к базе данных. Дубли артикулов и товары без цены считаются одним запросом, а обход выборкой на десятках тысяч товаров занимает минуты.

Отчёт по каталогу полезен только со ссылками на карточки самих товаров. Список идентификаторов заставляет менеджера искать товар руками, и проверка превращается в упражнение для разработчика.

Шаги

  1. Договориться с заказчиком, что именно считается ошибкой каталога на этом проекте.
  2. Написать по одной отдельной выборке на каждую проверку и посчитать её числа.
  3. Обходить большой каталог порциями по идентификатору элемента, а не одной выборкой.
  4. Собрать отчёт отдельным файлом со ссылками на карточки товаров в административной части.
  5. Поставить проверку на расписание и запускать её руками перед выгрузками и акциями.

Решение

Ищем товары без цены:

\Bitrix\Main\Loader::includeModule('catalog');
$rs = \CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y',
'CATALOG_PRICE_1' => false], false, false, ['ID', 'NAME', 'XML_ID']);
while ($row = $rs->Fetch()) { $noPrice[] = $row; }
printf("без цены: %d\n", count($noPrice));

Товар без цены не покупается и не попадает в выгрузки. Это первая проверка любого аудита: она находит и забытые новинки, и последствия неудачного обмена.

Ищем товары без картинок:

$rs = \CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'],
false, false, ['ID', 'NAME', 'DETAIL_PICTURE', 'PREVIEW_PICTURE']);
while ($row = $rs->Fetch()) {
if (!$row['DETAIL_PICTURE'] && !$row['PREVIEW_PICTURE']) { $noPhoto[] = $row; }
}

Считаем дубли артикулов одним запросом:

SELECT PROPERTY_VALUE, COUNT(*) cnt
FROM b_iblock_element_prop_m25 -- таблица свойств вашего инфоблока
WHERE IBLOCK_PROPERTY_ID = 137 -- свойство артикула
GROUP BY PROPERTY_VALUE HAVING cnt > 1 ORDER BY cnt DESC LIMIT 50;
-- дубли артикулов ломают обмен и сверку с учётной системой

Одинаковый артикул у двух товаров ломает сопоставление при обмене. Учётная система обновляет то один товар, то другой, и остатки начинают прыгать без видимой причины.

Проверяем обязательные свойства:

$required = ['BRAND', 'COUNTRY', 'ARTICLE'];
$rs = \CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y',
['LOGIC' => 'OR'] + array_map(fn($c) => ['=PROPERTY_' . $c => false], $required),
], false, ['nTopCount' => 500], ['ID', 'NAME']);
// одна выборка вместо трёх: пустое хотя бы одно из обязательных свойств

Собираем отчёт со ссылками:

$out = fopen('/tmp/catalog-audit.csv', 'w');
fputcsv($out, ['проверка', 'ID', 'название', 'ссылка']);
foreach ($noPrice as $row) {
fputcsv($out, ['без цены', $row['ID'], $row['NAME'],
"https://example.com/bitrix/admin/iblock_element_edit.php?ID={$row['ID']}"]);
}
fclose($out);

Ставим проверку на расписание:

// агент раз в сутки, отчёт письмом ответственному менеджеру
\CAgent::AddAgent('CatalogAudit::run();', 'vendor.module', 'N', 86400);
// перед акцией тот же скрипт запускают руками и разбирают список целиком

Типичные проблемы

Скрипт аудита падает по времени на большом каталоге.

Каталог обходится одной выборкой без ограничения и без порций. Обход ведут порциями по идентификатору элемента, сохраняя место остановки между запусками.

Отчёт есть, но по нему никто ничего не делает.

В отчёте одни идентификаторы без названий и ссылок на карточки товаров. Каждая строка отчёта должна открываться в карточке товара одним кликом из файла.

Проверка находит тысячи ошибок сразу после обмена.

Аудит запускается во время обмена, когда часть данных ещё не приехала. Проверку ставят на событие завершения обмена, а не на расписание вслепую.

Дубли артикулов находятся, а обмен их не видит.

Учётная система сопоставляет товары по внешнему коду, а не по артикулу. Проверять нужно оба поля: артикул для людей, внешний код для обмена.

В список без цены попали снятые с продажи товары.

В выборку не добавлен отбор по активности и по разделу витрины. Правила о том, что считается ошибкой, согласуют с заказчиком до написания скрипта.

Частые вопросы

Что проверять в первую очередь?

Цену, наличие картинки и заполненность артикула с внешним кодом. Эти четыре проверки закрывают большую часть претензий к каталогу.

Запросом к базе или выборкой?

Дубли и агрегаты - запросом, точечные проверки со свойствами - выборкой. Прямой запрос быстрее, но привязан к структуре таблиц конкретного инфоблока.

Как часто запускать аудит?

Раз в сутки по расписанию и обязательно вручную перед акцией или выгрузкой. Регулярность важнее глубины: свежие ошибки дешевле исправлять.

Кому отдавать отчёт?

Контент-менеджеру, который ведёт каталог, а не разработчику. Разработчику достаётся только то, что не чинится правкой карточки товара.

Можно ли чинить найденное автоматически?

Часть - да: подставить картинку-заглушку или снять с публикации товар без цены. Автоматическую правку согласуют заранее, иначе она удивит менеджера.

Смежное

Первоисточник