Налаштування масової прив'язки торгових пропозицій 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Налаштування масової прив'язки торгових пропозицій 1С-Бітрікс
Проста
~1 робочий день
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Налаштування масової прив'язки торгових пропозицій 1С-Бітрікс

Торгові пропозиції в Бітрікс — це елементи окремого інфоблоку, кожен із яких прив'язаний до батьківського товару через поле CML2_LINK (зберігається в b_iblock_element_property). Коли у вас тисячі SKU і ця прив'язка порушена — пропозиції не відображаються в картці товару, ціни та залишки не показуються. Завдання масової прив'язки виникає при міграції з іншої платформи, імпорті з 1С з помилками або ручному створенні бази.

Як працює зв'язок товар — торгова пропозиція

Інфоблок каталогу містить основні товари. Для торгових пропозицій створюється пов'язаний інфоблок — його ID вказується в полі OFFERS_IBLOCK_ID у b_iblock.ID. Зв'язок оголошується через b_iblock_fields або через інтерфейс: Інфоблоки → Типи інфоблоків → Торговий каталог → Редагувати.

Кожна торгова пропозиція має властивість із кодом CML2_LINK (тип «Прив'язка до елементів») — значення в b_iblock_element_property.VALUE відповідає ID батьківського товару.

-- Перевірити, у скількох пропозицій не заповнена прив'язка:
SELECT COUNT(*)
FROM b_iblock_element ie
WHERE ie.IBLOCK_ID = {offers_iblock_id}
AND NOT EXISTS (
    SELECT 1 FROM b_iblock_element_property iep
    INNER JOIN b_iblock_property ip ON ip.ID = iep.IBLOCK_PROPERTY_ID
    WHERE iep.IBLOCK_ELEMENT_ID = ie.ID
    AND ip.CODE = 'CML2_LINK'
    AND iep.VALUE IS NOT NULL
);

Знаходження ID властивості CML2_LINK

$offersIblockId = 11; // ID інфоблоку торгових пропозицій

$propRes = \Bitrix\Iblock\PropertyTable::getList([
    'filter' => ['IBLOCK_ID' => $offersIblockId, 'CODE' => 'CML2_LINK'],
    'select' => ['ID'],
])->fetch();

$linkPropertyId = $propRes['ID'];

Масова прив'язка за XML_ID

Найпоширеніший сценарій: у товарів і пропозицій в b_iblock_element.XML_ID зберігається артикул із 1С. Прив'язка робиться за збігом артикулу або за маппінговою таблицею.

// Приклад: прив'язуємо пропозиції до товарів за першими 8 символами XML_ID
// Товар: XML_ID = 'PROD-001', Пропозиції: XML_ID = 'PROD-001-S', 'PROD-001-M', 'PROD-001-L'

$catalogIblockId = 10;
$offersIblockId  = 11;

// Збираємо карту товарів: XML_ID → ID елемента
$productMap = [];
$productsRes = \CIBlockElement::GetList([], ['IBLOCK_ID' => $catalogIblockId], false, false, ['ID', 'XML_ID']);
while ($row = $productsRes->Fetch()) {
    $productMap[$row['XML_ID']] = $row['ID'];
}

// Обробляємо пропозиції пакетами
$offersRes = \CIBlockElement::GetList([], ['IBLOCK_ID' => $offersIblockId], false, false, ['ID', 'XML_ID']);

$batch = [];
while ($row = $offersRes->Fetch()) {
    // Визначаємо XML_ID батька: беремо перші N символів або парсимо за роздільником
    $parentXmlId = substr($row['XML_ID'], 0, 8); // налаштуйте під свою схему
    if (!isset($productMap[$parentXmlId])) continue;

    $parentId = $productMap[$parentXmlId];
    $batch[]  = ['offer_id' => $row['ID'], 'parent_id' => $parentId];

    if (count($batch) >= 200) {
        bindOffersToProducts($batch, $offersIblockId, $linkPropertyId);
        $batch = [];
    }
}
if (!empty($batch)) {
    bindOffersToProducts($batch, $offersIblockId, $linkPropertyId);
}

function bindOffersToProducts(array $batch, int $iblockId, int $propId): void
{
    foreach ($batch as $item) {
        // Перевіряємо, чи є вже запис
        $existing = \Bitrix\Iblock\ElementPropertyTable::getList([
            'filter' => [
                'IBLOCK_ELEMENT_ID' => $item['offer_id'],
                'IBLOCK_PROPERTY_ID' => $propId,
            ],
            'select' => ['ID'],
        ])->fetch();

        if ($existing) {
            \Bitrix\Iblock\ElementPropertyTable::update($existing['ID'], [
                'VALUE' => $item['parent_id'],
            ]);
        } else {
            \Bitrix\Iblock\ElementPropertyTable::add([
                'IBLOCK_ELEMENT_ID'  => $item['offer_id'],
                'IBLOCK_PROPERTY_ID' => $propId,
                'VALUE'              => $item['parent_id'],
            ]);
        }
    }
}

Прив'язка через CSV-маппінг

Якщо логіка визначення батька складніша — використовуйте зовнішню карту:

offer_xml_id,parent_xml_id
SKU-001-RED,PROD-001
SKU-001-BLUE,PROD-001
SKU-002-S,PROD-002
$map = parseCsv('/import/offers_mapping.csv'); // [['offer_xml_id' => ..., 'parent_xml_id' => ...]]
foreach ($map as $row) {
    $offerId  = getElementIdByXmlId($offersIblockId, $row['offer_xml_id']);
    $parentId = getElementIdByXmlId($catalogIblockId, $row['parent_xml_id']);
    if ($offerId && $parentId) {
        \CIBlockElement::SetPropertyValues($offerId, $offersIblockId, $parentId, 'CML2_LINK');
    }
}

Перевірка результату та інвалідація кешу

Після масової прив'язки обов'язково:

  1. Перевірте кілька товарів у публічній частині — пропозиції повинні відображатися в картці
  2. Скиньте кеш інфоблоків для обох інфоблоків
  3. Переіндексуйте фасетний фільтр, якщо пропозиції беруть участь у фільтрації
\Bitrix\Iblock\InformationBlock::cleanTagCache($catalogIblockId);
\Bitrix\Iblock\InformationBlock::cleanTagCache($offersIblockId);
\Bitrix\Iblock\PropertyIndex\Manager::markIblockToReindex($offersIblockId);

Терміни виконання

Обсяг Час
До 1 000 пропозицій 2–4 години (аналіз + скрипт + перевірка)
1 000–20 000 пропозицій 1 день
20 000+ пропозицій 2–3 дні (включно з відлагодженням маппінгу та верифікацією)