Дубли товаров после обмена - поиск и разведение
Находим дубли товаров, появившиеся после обмена, и разводим их так, чтобы не потерять историю заказов.
Решение
Ищем повторяющиеся внешние коды:
$res = CIBlockElement::GetList([], ['IBLOCK_ID' => 5], ['XML_ID']);while ($row = $res->Fetch()) { if ($row['CNT'] > 1) { printf("код %-24s повторяется %d раз\n", $row['XML_ID'], $row['CNT']); }}Повторяющийся внешний код означает, что обмен создал позицию заново вместо обновления существующей. Это главный признак дубля: одинаковые названия при разных кодах - совсем другая история.
Ищем дубли по названию при разных кодах:
$res = CIBlockElement::GetList([], ['IBLOCK_ID' => 5], ['NAME']);while ($row = $res->Fetch()) { if ($row['CNT'] > 1) { printf("название %-40s встречается %d раз\n", mb_substr($row['NAME'], 0, 40), $row['CNT']); }}Одинаковые названия при разных кодах - обычно не дубли, а разные позиции номенклатуры. Прежде чем чистить такие пары, стоит убедиться, что перед вами действительно один товар, а не два похожих между собой.
Смотрим, у какой позиции есть заказы:
use Bitrix\Sale\Internals\BasketTable;
$rows = BasketTable::getList([ 'select' => ['ORDER_ID'], 'filter' => ['=PRODUCT_ID' => $elementId, '!=ORDER_ID' => null], 'limit' => 5,])->fetchAll();printf("заказов с этой позицией: %d\n", count($rows));Позицию, на которую ссылаются заказы, удалять нельзя ни при каких условиях: история продаж потеряет связь с товаром. Из пары дублей оставляют именно эту позицию, а вторую деактивируют.
Разводим найденные дубли:
$el = new CIBlockElement();// лишнюю позицию не удаляем, а снимаем с публикации и метим кодом$el->Update($duplicateId, [ 'ACTIVE' => 'N', 'XML_ID' => 'DUP-' . $duplicateId, // освобождаем код для основной позиции]);Смена внешнего кода у лишней позиции освобождает его для основной записи. После этого обмен снова находит нужный товар и перестаёт плодить всё новые копии.
Дубли разделов ведут себя точно так же и появляются даже чаще товарных. Смена структуры групп в учётной системе создаёт новые разделы вместо переименования старых, и каталог получает две ветки с одинаковыми названиями.
Чистка накопленных дублей всегда идёт по одному правилу: сначала выясняют, какая из позиций участвует в заказах, и только потом решают судьбу второй. Обратный порядок приводит к потере истории продаж, а восстановить её потом уже нечем.
Предотвращение дублей обходится заметно дешевле их чистки. Внешние коды не меняют после первой выгрузки, один инфоблок связывают с одним источником, а переносы базы проверяют на копии сайта - это закрывает почти все сценарии появления дублей.
Типичные проблемы
После переноса базы каталог удвоился.
Внешние коды товаров не совпали с прежними значениями. Обмен не нашёл существующие позиции и создал их все заново.
Дубли появляются после каждой выгрузки.
Учётная система присылает новые внешние коды при каждом обмене. Это настройка именно на её стороне, а вовсе не на стороне самого сайта.
Удаление дубля сломало старые заказы.
Позиции старых заказов ссылались именно на удалённый элемент. Из пары дублей оставляют ту позицию, что участвует в заказах.
В каталоге две одинаковые ветки разделов.
Структура групп в учётной системе менялась, и разделы приехали как новые. Прежние разделы при этом остаются на своём месте.
Одинаковые названия оказались не дублями.
Это разные позиции номенклатуры с разными внешними кодами. Совпадение одних только названий дублем не является.
Частые вопросы
Можно ли объединить дубли автоматически?
Штатного объединения нет: платформа не знает, какая позиция главная. Пары разводят скриптом по своим правилам с ручной проверкой списка.
Что делать с картинками дубля?
Оставить у основной позиции, если у неё их нет. Файлы дубля после деактивации остаются на диске и чистятся отдельно.
Почему нельзя просто удалить лишние позиции?
На них могут ссылаться заказы, подписки и связанные товары. Деактивация обратима, удаление - нет.
Как убедиться, что дубли перестали появляться?
Повторить поиск повторяющихся кодов после следующего обмена. Пустой результат означает, что причина устранена.
Смежное
-
Обмен: выгрузка товаров - оглавление подтемы
-
Выгрузка товаров из 1С на сайт - как работает сопоставление
-
Структура каталога при обмене - разделы и их коды
-
Обмен с 1С и HTTP - устройство обмена целиком
-
Импорт каталога из файла: CSV, повторный запуск, свои поля - вторая частая причина дублей
-
Дублирование товара: копия со свойствами, картинками, предложениями - как копировать товар и не получить дубль обмена
-
Артикулы товаров: хранение, уникальность, поиск - сопоставление позиций по артикулу