Дублирование товара - копия со свойствами, картинками, предложениями
Делаем копию товара со свойствами, картинками, ценами и вариантами: что копируется само, что переносят руками и какие поля обязаны стать уникальными.
Что нужно знать заранее
Копия элемента - это новый элемент с теми же значениями. Платформа не копирует ничего сама, и полнота копии целиком зависит от того, сколько полей вы прочитали у оригинала.
Картинки нельзя перенести в копию простым идентификатором уже сохранённого файла. Скопированный номер сошлётся на тот же файл, и удаление оригинала оставит копию без изображения.
Уникальные поля товара обязаны получить в копии новые собственные значения. Символьный код, внешний код и артикул повторять нельзя: они участвуют в адресах и в сопоставлении при обмене.
Шаги
- Прочитать оригинал целиком: поля, свойства, картинки, цены и привязки к разделам.
- Создать копию, сразу заменив в ней символьный код, внешний код и артикул.
- Перенести картинки массивом самого файла, а не идентификатором уже сохранённого изображения.
- Скопировать цены и товарные параметры товара отдельными вызовами модуля каталога.
- Пройтись по торговым предложениям и повторить для них ту же процедуру.
Решение
Читаем оригинал целиком:
$src = \CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'ID' => $sourceId], false, false, ['*'])->GetNextElement();$fields = $src->GetFields();$props = $src->GetProperties();// GetNextElement отдаёт объект: у него сразу есть и поля, и свойстваСвойства читают вместе с полями одним вызовом. Отдельная выборка свойств для каждого элемента - обычная причина того, что копирование сотни товаров занимает минуты вместо секунд.
Собираем значения свойств для записи:
$values = [];foreach ($props as $code => $prop) { $values[$code] = $prop['PROPERTY_TYPE'] === 'F' ? \CFile::MakeFileArray($prop['VALUE']) // файл копируем как файл : $prop['VALUE'];}Создаём копию с уникальными полями:
$el = new \CIBlockElement();$newId = $el->Add([ 'IBLOCK_ID' => $iblockId, 'NAME' => $fields['NAME'] . ' (копия)', 'CODE' => $fields['CODE'] . '-copy-' . time(), // символьный код уникален 'XML_ID' => '', // внешний код не копируем 'IBLOCK_SECTION_ID' => $fields['IBLOCK_SECTION_ID'], 'DETAIL_PICTURE' => \CFile::MakeFileArray($fields['DETAIL_PICTURE']), 'PREVIEW_PICTURE' => \CFile::MakeFileArray($fields['PREVIEW_PICTURE']), 'PROPERTY_VALUES' => $values, 'ACTIVE' => 'N', // копию показывают после правки]);Пустой внешний код спасает обмен от сюрпризов. Копия с тем же кодом при следующей выгрузке начнёт спорить с оригиналом за одни и те же данные учётной системы.
Копируем цены и товарные параметры:
$product = \CCatalogProduct::GetByID($sourceId);\CCatalogProduct::Add(['ID' => $newId, 'QUANTITY' => 0, 'QUANTITY_TRACE' => $product['QUANTITY_TRACE'], 'WEIGHT' => $product['WEIGHT']]);
$price = \CPrice::GetList([], ['PRODUCT_ID' => $sourceId, 'CATALOG_GROUP_ID' => 1])->Fetch();if ($price) { \CPrice::SetBasePrice($newId, $price['PRICE'], $price['CURRENCY']); }// остаток копии ставят нулевым: продавать её до правки нельзяКопируем торговые предложения:
$sku = \CCatalogSKU::GetInfoByProductIBlock($iblockId);$rs = \CIBlockElement::GetList([], ['IBLOCK_ID' => $sku['IBLOCK_ID'], 'PROPERTY_' . $sku['SKU_PROPERTY_ID'] => $sourceId], false, false, ['ID']);while ($row = $rs->Fetch()) { copyOffer($row['ID'], $newId, $sku); }// каждый вариант копируется той же процедурой и привязывается к новому товаруТипичные проблемы
Копия и оригинал показывают одну и ту же картинку.
Изображение перенесено идентификатором файла, а не массивом самого файла. Файлы копируют явным вызовом, иначе удаление оригинала обнулит картинку и у копии.
После обмена копия затёрла оригинал.
У копии остался внешний код исходного товара, и обмен считает их одной позицией. Внешний код у копии оставляют пустым либо задают ей заведомо новый.
Копия открывается по адресу оригинала.
Символьный код скопирован без изменений, и оба элемента претендуют на один адрес. Символьный код делают уникальным прямо в момент создания копии товара.
У копии нет вариантов, хотя у оригинала они были.
Копировался только сам товар, а его торговые предложения живут отдельными элементами. Их копируют отдельным вторым проходом и привязывают к новому товару.
Копия сразу появилась на витрине и в выгрузках.
Элемент копии создан активным и сразу же с ненулевым складским остатком. Копию заводят выключенной, а показывают уже после правки названий и цен.
Частые вопросы
Копируются ли свойства сами?
Нет, платформа копирует только то, что вы передали при создании элемента. Свойства читают у оригинала и передают в создание копии явным списком.
Почему картинку нельзя скопировать номером?
Номер ссылается на тот же файл, и два элемента начинают делить одно изображение. Удаление оригинала оставит копию без картинки.
Что делать с внешним кодом?
Оставить пустым или задать новый: он используется при обмене с учётной системой. Совпадающий код превращает копию и оригинал в одну позицию.
Как копировать товары пачкой?
Тем же кодом в цикле по списку идентификаторов, порциями и с журналом. Массовое копирование удобно для сезонных линеек и для наполнения стенда.
Нужно ли копировать остатки?
Нет, остаток копии ставят нулевым. Иначе копия сразу становится доступной к покупке, а товара на складе нет.
Смежное
- Каталог товаров - оглавление подтемы
- Массовая правка товаров: обновление свойств скриптом - тот же цикл и те же порции
- Создание торговых предложений из кода: привязка, цены, остатки - как заводят варианты копии
- Картинки товара: загрузка, размеры и вывод галереи - как устроены изображения товара
- Дубли товаров после обмена: поиск и разведение - чем опасен одинаковый внешний код
- Файлы из кода: сохранение, уменьшенные копии, удаление - работа с файлами платформы
- Аудит каталога: товары без цены, картинок, дубли артикулов - как найти забытые копии
- Каталог и продажи - устройство каталога целиком