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

Дублирование товара - копия со свойствами, картинками, предложениями

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

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

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

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

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

Шаги

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

Решение

Читаем оригинал целиком:

$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); }
// каждый вариант копируется той же процедурой и привязывается к новому товару

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

Копия и оригинал показывают одну и ту же картинку.

Изображение перенесено идентификатором файла, а не массивом самого файла. Файлы копируют явным вызовом, иначе удаление оригинала обнулит картинку и у копии.

После обмена копия затёрла оригинал.

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

Копия открывается по адресу оригинала.

Символьный код скопирован без изменений, и оба элемента претендуют на один адрес. Символьный код делают уникальным прямо в момент создания копии товара.

У копии нет вариантов, хотя у оригинала они были.

Копировался только сам товар, а его торговые предложения живут отдельными элементами. Их копируют отдельным вторым проходом и привязывают к новому товару.

Копия сразу появилась на витрине и в выгрузках.

Элемент копии создан активным и сразу же с ненулевым складским остатком. Копию заводят выключенной, а показывают уже после правки названий и цен.

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

Копируются ли свойства сами?

Нет, платформа копирует только то, что вы передали при создании элемента. Свойства читают у оригинала и передают в создание копии явным списком.

Почему картинку нельзя скопировать номером?

Номер ссылается на тот же файл, и два элемента начинают делить одно изображение. Удаление оригинала оставит копию без картинки.

Что делать с внешним кодом?

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

Как копировать товары пачкой?

Тем же кодом в цикле по списку идентификаторов, порциями и с журналом. Массовое копирование удобно для сезонных линеек и для наполнения стенда.

Нужно ли копировать остатки?

Нет, остаток копии ставят нулевым. Иначе копия сразу становится доступной к покупке, а товара на складе нет.

Смежное

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