Настройка управления складскими операциями через 1С-Битрикс
Склад в Битриксе начинает давать сбои в конкретный момент: когда количество складов превышает один, а логика резервирования настроена на уровне магазина, а не склада. Заказы резервируют остатки глобально, менеджер видит «в наличии», физически товара нет на нужном складе.
Архитектура складского учёта в модуле catalog
Складской учёт реализован через модуль catalog. Каждый склад — запись в таблице b_catalog_store. Остатки хранятся в b_catalog_store_product с полями STORE_ID, PRODUCT_ID, AMOUNT, QUANTITY_RESERVED. Связь со складом происходит через STORE_ID.
Движение товаров фиксируется в b_catalog_docs_element — строки документов прихода/расхода/перемещения. Сам документ — b_catalog_docs с полями DOC_TYPE (A — приход, S — расход, M — перемещение, I — инвентаризация) и STATUS (N — черновик, Y — проведён).
API для работы со складами:
// Получить остатки по складу
$storeProducts = \Bitrix\Catalog\StoreProductTable::getList([
'filter' => ['STORE_ID' => 3, '>AMOUNT' => 0],
'select' => ['PRODUCT_ID', 'AMOUNT', 'QUANTITY_RESERVED'],
]);
// Доступный остаток = AMOUNT - QUANTITY_RESERVED
Резервирование и его конфликты
Резервирование управляется через настройки модуля sale — параметр allow_reservation в b_option. Резерв может быть привязан к конкретному складу заказа или к любому складу с остатком. Второй вариант — источник проблем при мультисклад.
При создании заказа резерв создаётся методом \Bitrix\Sale\Internals\ReserveTable. Записи связывают ORDER_ID, BASKET_ITEM_ID, STORE_ID и QUANTITY. Если склад в заказе не указан явно, Битрикс берёт первый склад с достаточным остатком — порядок определяется SORT в b_catalog_store.
Правильная настройка мультисклада требует включения "выбора склада при оформлении" в настройках компонента bitrix:sale.order.ajax. Параметр компонента ALLOW_STORE_AMOUNT должен быть Y, иначе покупатель не видит распределение по складам.
Документооборот складских операций
Документы склада создаются и проводятся через \Bitrix\Catalog\Document\DocManager. Проведение документа — метод conduct(), откат — cancel(). При проведении пересчитываются остатки в b_catalog_store_product и обновляется общий остаток в b_catalog_product (поле QUANTITY).
Ручное создание документа расхода:
$doc = new \Bitrix\Catalog\Document\DocBuilder();
$doc->setDocType(\Bitrix\Catalog\StoreDocumentTable::TYPE_SALES_ORDERS);
$doc->setStoreFrom(3); // склад отгрузки
$doc->addItem($productId, $quantity);
$result = $doc->save();
if ($result->isSuccess()) {
\Bitrix\Catalog\Document\DocManager::conductDocument($result->getId());
}
Интеграция со статусами заказов
Автоматическое списание со склада при смене статуса заказа настраивается через обработчик события OnOrderStatusChange в модуле sale. Стандартный механизм — настройка в Магазин → Настройки → Склады: для каждого статуса заказа можно задать автоматическое проведение складского документа.
Но этот механизм не работает корректно при частичной отгрузке. Если заказ на 10 единиц отгружается двумя партиями, стандартный обработчик проведёт расход на все 10 при первой смене статуса. Для частичной отгрузки нужен собственный обработчик, который создаёт документ на фактически отгружаемое количество из b_sale_order_delivery_basket.
Синхронизация с 1С
При синхронизации остатков через CommerceML (bitrix:catalog.import.1c) обновления остатков идут через b_catalog_store_product напрямую, минуя документооборот. Это означает, что b_catalog_docs не содержит истории изменений из 1С — только операции, созданные внутри Битрикса. Если нужна полная история движения, синхронизация должна создавать документы, а не обновлять остатки напрямую.







