Налаштування відображення наявності товару за точками самовивезення 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С-Бітрікс

На картці товару потрібно показати: «В наявності в 3 магазинах» або конкретно «ТЦ Центральний — 5 шт., вул. Леніна 15 — 2 шт., ТЦ Західний — немає». Стандартний компонент bitrix:catalog.element показує лише загальний залишок по всіх складах. Розбивка по точках самовивозу потребує окремого запиту до b_catalog_store_product і доопрацювання шаблону.

Структура даних складських залишків

-- Залишки товару по активних складах
SELECT
    s.ID,
    s.TITLE,
    s.ADDRESS,
    COALESCE(sp.AMOUNT, 0) as AMOUNT,
    COALESCE(sp.QUANTITY_RESERVED, 0) as RESERVED,
    COALESCE(sp.AMOUNT, 0) - COALESCE(sp.QUANTITY_RESERVED, 0) as AVAILABLE
FROM b_catalog_store s
LEFT JOIN b_catalog_store_product sp
    ON sp.STORE_ID = s.ID AND sp.PRODUCT_ID = ?
WHERE s.ACTIVE = 'Y' AND s.IS_SITE = 'Y'  -- тільки точки самовивозу
ORDER BY s.SORT ASC;

IS_SITE = 'Y' — прапор, що склад є точкою самовивозу для сайту. Встановлюється в Каталог → Склади → [Редагувати].

PHP-код для отримання залишків по точках

function getStoreAvailability(int $productId): array
{
    $result = [];

    $storesQuery = \Bitrix\Catalog\StoreTable::getList([
        'filter' => ['ACTIVE' => 'Y', 'IS_SITE' => 'Y'],
        'select' => ['ID', 'TITLE', 'ADDRESS', 'GPS_N', 'GPS_S', 'SORT'],
        'order'  => ['SORT' => 'ASC'],
    ]);

    $stores = [];
    while ($store = $storesQuery->fetch()) {
        $stores[$store['ID']] = $store;
    }

    if (empty($stores)) {
        return [];
    }

    // Залишки одним запитом для всіх складів
    $stockQuery = \Bitrix\Catalog\StoreProductTable::getList([
        'filter' => [
            'PRODUCT_ID' => $productId,
            'STORE_ID'   => array_keys($stores),
        ],
        'select' => ['STORE_ID', 'AMOUNT', 'QUANTITY_RESERVED'],
    ]);

    $stocks = [];
    while ($stock = $stockQuery->fetch()) {
        $stocks[$stock['STORE_ID']] = $stock;
    }

    foreach ($stores as $storeId => $store) {
        $amount   = (float)($stocks[$storeId]['AMOUNT'] ?? 0);
        $reserved = (float)($stocks[$storeId]['QUANTITY_RESERVED'] ?? 0);
        $available = max(0, $amount - $reserved);

        $result[] = [
            'ID'        => $storeId,
            'TITLE'     => $store['TITLE'],
            'ADDRESS'   => $store['ADDRESS'],
            'GPS_N'     => $store['GPS_N'],
            'GPS_S'     => $store['GPS_S'],
            'AMOUNT'    => $amount,
            'AVAILABLE' => $available,
            'IN_STOCK'  => $available > 0,
        ];
    }

    return $result;
}

Інтеграція в шаблон компонента картки товару

В template.php компонента bitrix:catalog.element:

\Bitrix\Main\Loader::includeModule('catalog');

$storeAvailability = getStoreAvailability($arResult['ID']);
$inStockCount = count(array_filter($storeAvailability, fn($s) => $s['IN_STOCK']));
?>

<div class="store-availability">
    <?php if ($inStockCount > 0): ?>
        <div class="in-stock-summary">
            В наявності в <?= $inStockCount ?> магазин<?= \Local\Helpers\Declension::get($inStockCount, ['і', 'и', 'ах']) ?>
        </div>
        <button class="toggle-stores" type="button">Показати всі магазини</button>
        <ul class="store-list" style="display:none">
            <?php foreach ($storeAvailability as $store): ?>
            <li class="store-item <?= $store['IN_STOCK'] ? 'in-stock' : 'out-of-stock' ?>">
                <span class="store-name"><?= htmlspecialchars($store['TITLE']) ?></span>
                <span class="store-address"><?= htmlspecialchars($store['ADDRESS']) ?></span>
                <span class="store-qty">
                    <?= $store['IN_STOCK']
                        ? $store['AVAILABLE'] . ' шт.'
                        : 'Немає в наявності' ?>
                </span>
            </li>
            <?php endforeach; ?>
        </ul>
    <?php else: ?>
        <div class="out-of-stock">Немає в наявності в магазинах</div>
    <?php endif; ?>
</div>

AJAX-оновлення при виборі торгової пропозиції

Для товарів із торговими пропозиціями (розміри, кольори) залишки потрібно оновлювати при зміні пропозиції:

document.querySelectorAll('.offer-option').forEach(function(el) {
    el.addEventListener('change', function() {
        var offerId = this.value;
        fetch('/ajax/store-availability/?product_id=' + offerId)
            .then(r => r.json())
            .then(data => updateStoreList(data.stores));
    });
});

AJAX-ендпоінт /ajax/store-availability/ — компонент або окремий PHP-файл, що повертає JSON із результатом getStoreAvailability($offerId).

Терміни налаштування

Функція отримання залишків, доопрацювання шаблону картки товару з відображенням списку складів, AJAX-оновлення при зміні торгової пропозиції — 4–8 годин.