Налаштування управління складськими операціями у 1C-Bitrix
Система складу в Bitrix починає давати збої в конкретний момент: коли кількість складів перевищує один, а логіка резервування налаштована на рівні магазину, а не складу. Замовлення резервують остатки глобально, менеджер бачить "в наявності", але фізично товару немає на потрібному складі.
Архітектура складського обліку в модулі 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. Якщо склад у замовленні не вказаний явно, Bitrix бере перший склад з достатнім остатком — порядок визначається 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.
Синхронізація з 1C
При синхронізації остатків через CommerceML (bitrix:catalog.import.1c) оновлення остатків йдуть через b_catalog_store_product безпосередньо, минаючи документообіг. Це означає, що b_catalog_docs не містить історії змін з 1C — лише операції, створені усередину Bitrix. Якщо потрібна повна історія руху, синхронізація має створювати документи, а не оновлювати остатки безпосередньо.







