Создание торговых предложений из кода - привязка, цены, остатки
Заводим варианты товара скриптом: инфоблок предложений, свойство привязки, создание элемента, цена, остаток и проверка результата на витрине.
Что нужно знать заранее
Торговое предложение - обычный элемент другого инфоблока. Особенным его делает свойство привязки к товару, а всё остальное работает как у любого элемента каталога.
Цена и остаток не хранятся в самом элементе. Они лежат в таблицах торгового каталога, и записывают их отдельными вызовами после создания элемента.
Номер инфоблока предложений в коде не пишут. Его находят по инфоблоку товаров, и тогда скрипт переживает перенос на другой стенд без правок.
Шаги
- Найти инфоблок предложений и свойство привязки по инфоблоку товаров.
- Создать элемент предложения с заполненной привязкой к нужному товару.
- Пометить предложение товаром каталога и задать его остаток.
- Поставить базовую цену предложения в нужной валюте.
- Проверить вывод варианта в карточке товара и в выборке.
Решение
Находим инфоблок предложений и привязку:
\Bitrix\Main\Loader::includeModule('catalog');$sku = \CCatalogSKU::GetInfoByProductIBlock($catalogIblockId);printf("предложения: %d, свойство привязки: %d\n", $sku['IBLOCK_ID'], $sku['SKU_PROPERTY_ID']);// пустой ответ означает, что предложения у этого каталога не включеныСвязка каталога и предложений задаётся один раз в настройках. Скрипт её не меняет, а читает, и это единственный правильный способ узнать нужные номера на конкретном стенде.
Создаём предложение с привязкой:
$el = new \CIBlockElement();$offerId = $el->Add([ 'IBLOCK_ID' => $sku['IBLOCK_ID'], 'NAME' => $product['NAME'] . ' - ' . $size, 'XML_ID' => $product['XML_ID'] . '#' . $size, // код для повторных запусков 'PROPERTY_VALUES' => [$sku['SKU_PROPERTY_ID'] => $productId, 'SIZE' => $size],]);if (!$offerId) { echo $el->LAST_ERROR; }Внешний код предложения собирают из кода товара и признака варианта. Тогда повторный запуск скрипта находит уже созданное предложение и обновляет его, а не плодит вторые копии.
Делаем предложение товаром и задаём остаток:
\CCatalogProduct::Add(['ID' => $offerId, 'QUANTITY' => 10, 'QUANTITY_TRACE' => 'Y', 'CAN_BUY_ZERO' => 'N', 'WEIGHT' => 300]); // вес нужен для расчёта доставки// без этой записи элемент останется обычным элементом инфоблокаЭлемент без записи товарных параметров не продаётся. Он виден в списке, но не попадает в корзину, и это самая частая причина «предложение есть, а купить нельзя».
Ставим цену предложения:
\CPrice::SetBasePrice($offerId, 1990, 'RUB');// для других типов цен используют запись цены с указанием типаЦену ставят у предложения, а не у товара. Товар с предложениями своей цены не имеет: на витрине показывается минимальная цена среди его вариантов.
Проверяем результат выборкой:
$rs = \CIBlockElement::GetList([], ['IBLOCK_ID' => $sku['IBLOCK_ID'], 'PROPERTY_' . $sku['SKU_PROPERTY_ID'] => $productId], false, false, ['ID', 'NAME', 'CATALOG_QUANTITY', 'CATALOG_PRICE_1']);while ($row = $rs->Fetch()) { print_r($row); }Типичные проблемы
Предложение создано, но в карточке товара его нет.
Не заполнено свойство привязки к товару или заполнено не тем идентификатором. Номер свойства привязки берут из настроек каталога, а не пишут числом в коде.
Вариант виден, но кнопка покупки не работает.
Элементу не заданы товарные параметры, и он не считается товаром каталога. Запись товарных параметров делают сразу после создания элемента предложения.
На витрине у товара нет цены.
Цена задана у самого товара, а не у его торговых предложений. Товар с предложениями показывает минимальную цену среди вариантов, своей цены у него нет.
Повторный запуск скрипта наплодил дубли вариантов.
Предложения создаются без внешнего кода и без поиска уже существующих. Внешний код собирают из кода товара и признака варианта, а перед созданием ищут по нему.
После массового создания витрина показывает старые данные.
Кэш каталога и фасетный индекс не пересобирались после скрипта. После массовых операций сбрасывают кэш и помечают индекс на пересборку.
Частые вопросы
Как узнать инфоблок предложений в коде?
Спросить его по инфоблоку товаров штатным методом каталога. Он же вернёт номер свойства привязки, который нужен для создания варианта.
Можно ли создавать предложения обычным добавлением элемента?
Да, предложение и есть элемент инфоблока, но без привязки и товарных параметров оно бесполезно. Оба шага делают сразу за созданием.
Где задавать цену: у товара или у предложения?
У предложения. Товар с предложениями своей цены не имеет, а на витрине показывается минимальная цена среди вариантов.
Как обновлять уже созданные варианты?
Искать по внешнему коду и вызывать обновление вместо создания. Такой скрипт можно запускать повторно без страха развести дубли.
Что делать после массового создания?
Сбросить кэш каталога и пересобрать фасетный индекс обоих инфоблоков. Иначе фильтр и витрина какое-то время показывают прежнюю картину.
Смежное
-
Торговые предложения - оглавление подтемы
-
Торговые предложения: настройка и связь с товаром - как включают предложения в каталоге
-
Свойства торговых предложений: вывод выбора и связь с товаром - какие свойства делают вариант выбираемым
-
Торговые предложения не выводятся: разбор причин - что проверять после скрипта
-
Выборка товаров вместе с предложениями: цены, наличие, фильтр - чтение созданных вариантов
-
Массовая правка товаров: обновление свойств скриптом - порции и журнал прохода
-
Фильтр по свойствам предложений: настройка, индекс, вывод - индекс после массового создания
-
Каталог и продажи - устройство каталога целиком
-
Дублирование товара: копия со свойствами, картинками, предложениями - копирование вариантов вместе с товаром