Вариант 1: Единый инфоблок (без классической связки SKU)
Самый простой способ — не использовать механизм торговых предложений вовсе, а хранить все товары (включая вариации) в одном инфоблоке, где каждый элемент — это отдельный товар со своими ценой, картинкой и характеристиками.
Настройка в админке:
- Перейдите в Настройки > Настройки продукта > Настройки модулей > Торговый каталог.
- Убедитесь, что для вашего инфоблока выбран тип "Простой товар" (без торговых предложений).
Пример создания элемента через API:
// Один инфоблок — все товары как отдельные элементы
$iblockId = 3; // ID вашего инфоблока
$el = new CIBlockElement();
$elementId = $el->Add([
'IBLOCK_ID' => $iblockId,
'NAME' => 'Кроссовки Nike Air, размер 42',
'CODE' => 'nike-air-42',
'IBLOCK_SECTION_ID' => false,
'ACTIVE' => 'Y',
'PROPERTY_VALUES' => [
'CML2_BASE_UNIT' => 5,
'CML2_ARTICLE' => 'NK-42-BLACK',
'COLOR' => 147, // ID значения списка
'SIZE' => 175, // ID значения списка
'PRICE' => 5990,
],
]);
Вариант 2: Каждый элемент инфоблока ТП выводить как самостоятельный товар через компоненты
Если у вас уже настроена классическая связка "товар + ТП", можно выводить элементы из инфоблока торговых предложений напрямую, не группируя их по товару-родителю.
В компоненте bitrix:catalog.section:
- Укажите в параметре IBLOCK_ID ID инфоблока торговых предложений, а не товаров.
- Установите флаг SHOW_OFFERS — в значение, соответствующее прямому выводу.
Настройка компонента catalog.section в коде:
$APPLICATION->IncludeComponent(
'bitrix:catalog.section',
'',
[
'IBLOCK_TYPE' => 'catalog',
'IBLOCK_ID' => 7, // ID инфоблока ТОРГОВЫХ ПРЕДЛОЖЕНИЙ
'ELEMENT_SORT_FIELD' => 'sort',
'ELEMENT_SORT_ORDER' => 'asc',
'PAGE_ELEMENT_COUNT' => 30,
'PROPERTY_CODE' => [
'CML2_ARTICLE',
'COLOR',
'SIZE',
'CML2_BASE_UNIT'
],
'PRICE_CODE' => ['BASE'],
'CONVERT_CURRENCY' => 'Y',
'USE_PRICE_COUNT' => 'N',
'SHOW_OFFERS' => 'N', // Не подгружать предложения к товарам
'SET_TITLE' => 'Y',
],
$component
);
Вариант 3: Создание универсального кастомного компонента
Если нужно гибко комбинировать товары и ТП в одной выдаче, разработайте свой компонент на основе CIBlockElement с фильтром по обоим инфоблокам:
use Bitrix\Main\Loader;
Loader::includeModule('iblock');
Loader::includeModule('catalog');
// Получаем элементы из инфоблока торговых предложений
$offersFilter = [
'IBLOCK_ID' => 7, // ID инфоблока ТП
'ACTIVE' => 'Y',
'CATALOG_AVAILABLE' => 'Y',
];
$offers = CIBlockElement::GetList(
['SORT' => 'ASC'],
$offersFilter,
false,
['nPageSize' => 50],
[
'ID', 'IBLOCK_ID', 'NAME', 'PREVIEW_PICTURE',
'CATALOG_QUANTITY', 'CATALOG_GROUP_1', // цена из каталога
]
);
while ($offer = $offers->GetNextElement()) {
$arFields = $offer->GetFields();
$arProps = $offer->GetProperties();
// Каждое ТП = отдельный товар
$arResult['ITEMS'][] = [
'ID' => $arFields['ID'],
'NAME' => $arFields['NAME'],
'PRICE' => $arFields['CATALOG_PRICE_1'],
'ARTICLE' => $arProps['CML2_ARTICLE']['VALUE'],
'DETAIL_PAGE_URL' => '/catalog/item/' . $arFields['ID'] . '/',
];
}
Вариант 4: Настройка детальной страницы отдельного ТП
Если вы хотите, чтобы каждое ТП имело свою уникальную детальную страницу (detail page), настройте SEF-шаблоны компонента catalog таким образом, чтобы URL-шаблон для элемента ТП был самостоятельным:
- Перейдите в настройки комплексного компонента
bitrix:catalog. - В разделе SEF-режим задайте шаблон для
element_offer, например:#SECTION_CODE#/#ELEMENT_CODE#/. - Убедитесь, что в
.parameters.phpкомпонента прописана переменнаяSEF_URL_TEMPLATESдля offer.
Ключевые моменты
- База данных: связь товар-ТП хранится в таблице
b_catalog_product, где у ТП полеTYPE= 4 (OFFER), а у товараTYPE= 1 (PRODUCT) или 3 (SKU_PRODUCT). - Класс для работы:
CCatalogSku(файл/bitrix/modules/catalog/general/catalog_sku.php). - Методы:
CCatalogSku::getOffersList($productId)— получить список ТП для товара.CCatalogSku::getProductList($offerId)— получить товар-родитель по ID ТП.
Выберите подходящий вариант в зависимости от вашей текущей структуры данных. Если у вас уже есть настроенная система с товарами и ТП, проще всего использовать Вариант 2 — выводить элементы инфоблока ТП как самостоятельные товары через компонент catalog.section.