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

Торговые предложения - настройка и связь с товаром

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

Решение

Находим инфоблок предложений и свойство привязки:

$sku = CCatalogSku::GetInfoByProductIBlock($productIblockId);
// IBLOCK_ID - инфоблок предложений, SKU_PROPERTY_ID - свойство привязки в нём
print_r($sku);
// пустой результат означает, что связка инфоблоков не настроена

Вкладка «Торговые предложения» появляется в карточке товара только после того, как у инфоблока включён торговый каталог и заведён связанный инфоблок предложений. Пока связи нет, вкладки не будет.

Смотрим, к какому товару привязано предложение:

$parent = CCatalogSku::GetProductInfo($offerId, $offerIblockId);
echo $parent ? "родитель: {$parent['ID']}\n" : "предложение без родителя\n";

Метод возвращает false, когда свойство привязки пустое или указывает на удалённый элемент. Такое предложение существует в базе, но в каталоге не показывается: показывать его негде.

Создаём предложение из кода:

$element = new CIBlockElement();
$offerId = $element->Add([
'IBLOCK_ID' => $sku['IBLOCK_ID'],
'NAME' => 'Футболка, синяя, M',
'ACTIVE' => 'Y',
'PROPERTY_VALUES' => [
$sku['SKU_PROPERTY_ID'] => $productId, // привязка к товару
'COLOR' => $colorEnumId,
'SIZE' => $sizeEnumId,
],
]);
CCatalogProduct::Add(['ID' => $offerId, 'QUANTITY' => 10]); // остаток обязателен

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

Ищем предложения, оставшиеся без родителя:

$res = CIBlockElement::GetList([], [
'IBLOCK_ID' => $sku['IBLOCK_ID'],
'!PROPERTY_' . $sku['SKU_PROPERTY_ID'] => false, // привязка заполнена
], false, false, ['ID', 'NAME', 'PROPERTY_' . $sku['SKU_PROPERTY_ID']]);
// предложения без привязки не покупаются: их ищут этим же фильтром наоборот

Инвертированный фильтр по свойству привязки быстро отделяет живые предложения от осиротевших. После обмена с 1С такая выборка - первое, что стоит выполнить.

Идентификатор свойства привязки на каждом проекте свой, и зашивать его числом в код нельзя. Он меняется при пересоздании инфоблока предложений, а такое бывает чаще, чем кажется: на переносе проекта, на разворачивании копии для разработки. Метод GetInfoByProductIBlock отдаёт актуальное значение и кеширует его сам.

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

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

Вкладки «Торговые предложения» нет в карточке товара.

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

Предложения выгрузились, а к товарам не привязались.

Товар не доехал или сменил внешний код. Предложение связывается с родителем по XML_ID товара, и без совпадения привязка остаётся пустой.

При каждом обмене создаются новые предложения.

Внешние коды предложений в 1С меняются от сеанса к сеансу. Сайт не находит прежних и заводит новые рядом, старые остаются активными.

Предложение есть в базе, но в каталоге не видно.

Либо оно без родителя, либо у него нет записи в торговом каталоге. Первое проверяют методом GetProductInfo, второе - наличием строки в таблице каталога.

Список значений свойства предложения пустой.

Свойство типа «список» заполняется значениями только при выгрузке справочника. Если справочник не приехал, значения не создаются, и выбирать в карточке нечего.

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

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

Выборкой по инфоблоку предложений с фильтром по свойству привязки: PROPERTY_<id> => $productId. Идентификатор свойства берут из CCatalogSku::GetInfoByProductIBlock, зашивать его числом в код не стоит - он свой на каждом проекте.

Можно ли у товара иметь и свою цену, и предложения?

Технически да, но покупателю продаётся предложение. Цена товара в такой схеме используется только для витрины, и её приходится поддерживать отдельно от цен предложений.

Как сгруппировать предложения по свойству в карточке?

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

Что будет с предложениями, если удалить товар?

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

Смежное

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