Разработка модуля управления складами 1С-Битрикс
В Битрикс встроен учёт складских остатков через модуль catalog: таблицы b_catalog_store (склады), b_catalog_store_product (остатки по складам и товарам). Для простых сайтов этого достаточно. Но когда появляются несколько реальных складов с разной логикой резервирования, приоритетами отгрузки, перемещением между складами и интеграцией с 1С — стандартный функционал нужно существенно расширять.
Что не умеет стандартный Битрикс
- Нет понятия «зарезервировано» в разрезе заказа — остаток либо есть, либо нет.
- Нет логики выбора склада для отгрузки при оформлении заказа.
- Нет учёта перемещений между складами с историей.
- Нет аналитики по оборачиваемости и дефициту.
Расширение схемы данных
Модуль добавляет несколько таблиц поверх стандартных:
Таблица b_catalog_store_reservation — резервы под заказы:
| Поле | Тип | Назначение |
|---|---|---|
| ID | int auto_increment | — |
| STORE_ID | int | FK на b_catalog_store |
| PRODUCT_ID | int | ID товарного предложения |
| ORDER_ID | int | FK на b_sale_order |
| QUANTITY | decimal(18,4) | Количество в резерве |
| RESERVED_AT | datetime | Когда зарезервировано |
| RELEASED_AT | datetime | Когда снят резерв (NULL если активный) |
Таблица b_catalog_store_movement — перемещения между складами:
| Поле | Тип | Назначение |
|---|---|---|
| ID | int auto_increment | — |
| FROM_STORE_ID | int | Склад-источник |
| TO_STORE_ID | int | Склад-приёмник |
| PRODUCT_ID | int | Товар |
| QUANTITY | decimal(18,4) | Количество |
| STATUS | enum | DRAFT, IN_TRANSIT, COMPLETED, CANCELLED |
| CREATED_BY | int | ID пользователя |
| COMPLETED_AT | datetime | Когда завершено |
Резервирование при оформлении заказа
При создании заказа товары нужно зарезервировать на складе. Логика подключается через обработчик события OnSaleOrderSaved:
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'sale',
'OnSaleOrderSaved',
[ReservationService::class, 'onOrderSaved']
);
Метод onOrderSaved проверяет, что статус заказа предполагает резерв (например, N — новый, P — оплачен). Для каждой позиции заказа определяет склад-источник и создаёт запись в b_catalog_store_reservation.
Выбор склада для отгрузки
Стратегия выбора склада настраивается в конфигурации модуля:
- FIFO по дате прихода — сначала отгружается более старый товар.
- Ближайший склад — по геолокации покупателя (требует координат складов).
-
Приоритет склада — поле
SORTвb_catalog_store, меньше = выше приоритет. - Минимальный остаток — сначала опустошать склады с наименьшим запасом.
Если на одном складе нет нужного количества, система автоматически разбивает отгрузку по нескольким складам.
Расчёт доступного остатка
Доступный остаток = физический остаток минус активные резервы:
public static function getAvailable(int $storeId, int $productId): float
{
$physical = \Bitrix\Catalog\StoreProductTable::getList([
'filter' => ['=STORE_ID' => $storeId, '=PRODUCT_ID' => $productId],
'select' => ['AMOUNT'],
])->fetch()['AMOUNT'] ?? 0;
$reserved = \Bitrix\Main\Application::getConnection()->query(
"SELECT COALESCE(SUM(QUANTITY), 0) as RES
FROM b_catalog_store_reservation
WHERE STORE_ID = {$storeId}
AND PRODUCT_ID = {$productId}
AND RELEASED_AT IS NULL"
)->fetch()['RES'] ?? 0;
return max(0, (float)$physical - (float)$reserved);
}
На карточке товара и в корзине показывается именно доступный остаток, а не физический.
Административный интерфейс
В административной части (/bitrix/admin/) добавляются разделы:
- Остатки по складам — матрица товар × склад с физическим и доступным остатком, фильтрация по категории и по складу.
- Перемещения — создание документа перемещения, подтверждение прихода на склад-приёмник.
- Резервы — список активных резервов с возможностью ручного снятия.
Интеграция с 1С
Если на проекте работает интеграция с 1С через стандартный механизм (/bitrix/admin/1c_exchange.php), остатки из модуля синхронизируются с b_catalog_store_product через обработчик события OnSuccessCatalogImport1C. Резервы при этом не затираются — остатки из 1С интерпретируются как физические, а доступный остаток пересчитывается.
Сроки разработки
| Масштаб | Состав | Срок |
|---|---|---|
| Базовый | Резервирование при заказе, доступный остаток, снятие резерва | 6–8 дней |
| Стандартный | + Перемещения между складами, стратегии отгрузки, Admin-UI | 12–16 дней |
| Расширенный | + Аналитика оборачиваемости, интеграция с 1С, мобильный интерфейс для склада | 20–28 дней |







