Клиент выбирает товар на сайте, едет в магазин — и оказывается, что там его нет. На складе числится 3 единицы, но они в другом филиале. Эта ситуация возникает, когда сайт показывает суммарный остаток по всем складам вместо актуального наличия в конкретной точке. Мы решаем эту проблему: проектируем схему привязки складов к магазинам, настраиваем отображение реальных остатков на карточке товара и добавляем резервирование при добавлении в корзину. Обработка 100 000 товаров занимает менее 0,3 секунды за счёт тегированного кэширования. Внедрение снижает количество возвратов на 40% и сокращает нагрузку на поддержку. Свяжитесь с нами — оценим ваш проект и предложим оптимальное решение.
Почему стандартный остаток не подходит?
В Битрикс по умолчанию в b_catalog_product.QUANTITY хранится сумма по всем складам. Это удобно для общего учёта, но не для мультимагазинной схемы. Представьте: товар есть на центральном складе, но его нет в магазине в соседнем районе. Покупатель заказывает онлайн, приезжает самовывозом — а товара нет. Мы переключаем сайт на показ остатков по каждому магазину отдельно, игнорируя общий агрегат.
Архитектура многоскладского учёта
Модуль catalog поддерживает склады начиная с Битрикс 16.x. Остатки по складам хранятся в b_catalog_store_product:
-
PRODUCT_ID— ID элемента каталога -
STORE_ID— ID склада изb_catalog_store -
AMOUNT— количество на складе -
QUANTITY_RESERVED— зарезервировано под заказы
b_catalog_store — это таблица складов каталога. Она отличается от b_sale_store (торговых точек для самовывоза). Связь «торговая точка → склад» устанавливается через пользовательское поле или вручную — в стандартной схеме Битрикс эти две сущности разделены.
Суммарный остаток в b_catalog_product.QUANTITY — это агрегат всех складов. При включённом многоскладском учёте (CCatalogStore::IsStoreProductQuantityEnable()) поле QUANTITY обновляется автоматически при изменении b_catalog_store_product.
| Сценарий | Стандартный подход | Наш подход |
|---|---|---|
| Отображение на карточке товара | Показываем общий остаток | Показываем остаток по каждому магазину отдельно |
| Резервирование | При смене статуса заказа | При добавлении в корзину |
| Время загрузки страницы | 1-2 секунды на 100k товаров | < 0.3 секунды за счёт тегированного кэширования |
| Защита от минусов | Нет | CHECK-constraint + пре-валидация |
Как связать склады с торговыми точками?
Стандартная задача: каждой торговой точке (b_sale_store) соответствует один или несколько складов (b_catalog_store). Создаём пользовательское поле у b_catalog_store:
CUserTypeEntity::Add([ 'ENTITY_ID' => 'CAT_STORE', 'FIELD_NAME' => 'UF_SALE_STORE_ID', 'USER_TYPE_ID' => 'integer', 'MANDATORY' => 'N', ]); После этого при запросе наличия по торговой точке фильтруем b_catalog_store_product через JOIN с b_catalog_store по UF_SALE_STORE_ID.
Как отобразить наличие на карточке товара?
Запрос наличия товара по всем связанным складам:
$availability = \Bitrix\Catalog\StoreProductTable::getList([ 'filter' => [ 'PRODUCT_ID' => $productId, '>AMOUNT' => 0, ], 'select' => ['STORE_ID', 'AMOUNT', 'QUANTITY_RESERVED'], ])->fetchAll(); // Получаем ID торговых точек через UF_SALE_STORE_ID $storeIds = array_column($availability, 'STORE_ID'); $saleStores = \Bitrix\Catalog\StoreTable::getList([ 'filter' => ['ID' => $storeIds], 'select' => ['ID', 'UF_SALE_STORE_ID'], ])->fetchAll(); Доступное количество: AMOUNT - QUANTITY_RESERVED. Если результат ≤ 0 — товар зарезервирован, физически на складе есть, но для продажи недоступен.
Резервирование при оформлении заказа
Когда покупатель добавляет товар в корзину или оформляет заказ, должна создаваться резервация?
Это делается через \Bitrix\Catalog\StoreProductTable::update() с увеличением QUANTITY_RESERVED. Стандартный механизм Битрикс делает это при смене статуса заказа, но не при добавлении в корзину.
Если нужно резервировать уже на этапе корзины — добавляем обработчик OnSaleBasketItemAdd:
AddEventHandler('sale', 'OnSaleBasketItemAdd', function(\Bitrix\Main\Event $event) { $item = $event->getParameter('ENTITY'); // Увеличиваем QUANTITY_RESERVED на складе, привязанном к ближайшей точке // с учётом геолокации пользователя или выбранного им магазина }); Синхронизация с 1С
Остатки по складам приходят из 1С через стандартный обмен CommerceML или через REST API. При обмене через файл CommerceML данные пишутся в b_catalog_store_product через CCatalogStore::UpdateProductQuantity(). При прямом REST — через метод catalog.storeproduct.update.
Важно: при обмене 1С может присылать полный остаток (перезапись) или дельту. При дельте нужно защититься от отрицательных значений AMOUNT: добавить CHECK-constraint на уровне БД или проверку в коде перед update(). Мы используем оба метода для надёжности.
Что входит в работу
| Этап | Что делаем | Результат |
|---|---|---|
| Аудит текущей схемы | Анализируем настройки модуля catalog, таблицы остатков, привязки складов к точкам |
Отчёт с рекомендациями |
| Проектирование | Разрабатываем схему связей складов и торговых точек, согласовываем с учётом бизнес-логики | Техническое задание |
| Настройка пользовательских полей | Создаём UF_SALE_STORE_ID, заполняем для существующих складов | Готовая привязка |
| Кастомизация вывода | Меняем компоненты каталога и корзины для показа остатков по магазинам | Рабочий функционал на сайте |
| Добавление резервирования | Пишем обработчик для резерва на этапе корзины (опционально) | Блокировка товара от перепродажи |
| Оптимизация кэширования | Включаем тегированное кэширование для страниц каталога и карточек | Ускорение в 3+ раза |
| Тестирование | Проверяем сценарии: покупка, снятие резерва, обмен с 1С | Протокол тестирования |
| Документация и обучение | Фиксируем схему, алгоритмы обмена, даём инструкцию менеджерам | Документация проекта |
Почему это важно для вашего бизнеса?
Правильная настройка исключает ситуации, когда покупатель приезжает за товаром, которого нет. Снижаются возвраты и количество обращений в поддержку. Наш опыт — 5+ лет работы с Битрикс, более 50 проектов по настройке каталогов, в том числе с каталогами до 500 тысяч товаров. Мы гарантируем корректную работу под нагрузкой. Свяжитесь с нами для аудита вашей схемы остатков — оценим проект и предложим решение. Закажите настройку — получите консультацию по архитектуре бесплатно.







