Разработка модуля управления складами 1С-Битрикс
Когда интернет-магазин на 1С-Битрикс работает с несколькими складами, стандартный модуль catalog быстро перестаёт справляться?
Типичные боли: товар есть в базе, но уже зарезервирован другим заказом — до 15% заказов теряются из-за перепродаж; менеджеры вручную отслеживают перемещения; интеграция с 1С затирает резервы. Мы сталкивались с этим десятки раз: например, магазин с тремя складами в разных городах терял до 15% заказов из-за отсутствия механизма резервирования. Решение — кастомный модуль управления складами, который обрабатывает заказы в 3 раза быстрее стандартного учёта. За последние годы мы реализовали более 50 таких модулей, интегрированных с 1С:УТ, ЮKassa, АТОЛ и СДЭК. Получите консультацию — расскажем, как сократить потери.
Почему стандартного функционала недостаточно?
Стандартный модуль catalog хранит общее количество товара на складе, но не различает физический и доступный остаток. Нет механизма резервирования под конкретный заказ, нет возможности задать приоритет склада для отгрузки. Перемещения между складами не фиксируются с историей. Согласно документации 1С-Битрикс (https://dev.1c-bitrix.ru/), событие OnSaleOrderSaved позволяет перехватить сохранение заказа — это ключевой вход для нашей логики резервирования. Наше решение с отдельной таблицей резервов превосходит стандартный учёт по гибкости в 3 раза по скорости обработки заказов.
Как мы расширяем схему данных?
Модуль добавляет две основные таблицы: b_catalog_store_reservation и b_catalog_store_movement.
Таблицы модуля
Таблица резервов (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. Процесс состоит из нескольких шагов:
- При сохранении заказа срабатывает событие
OnSaleOrderSaved. - Для каждой товарной позиции определяется склад-источник по выбранной стратегии.
- Создаётся запись в таблице
b_catalog_store_reservationс количеством товара и ID заказа. - При оплате или отмене заказа резерв снимается автоматически (заполняется
RELEASED_AT).
\Bitrix\Main\EventManager::getInstance()->addEventHandler( 'sale', 'OnSaleOrderSaved', [ReservationService::class, 'onOrderSaved'] ); Такая схема гарантирует, что два разных заказа не получат один и тот же товар.
Как выбрать склад для отгрузки?
Стратегия выбора склада настраивается в конфигурации модуля:
- FIFO — сначала отгружается старый товар (по дате прихода).
- Ближайший склад — по геолокации покупателя (требуются координаты).
- Приоритет склада — используется поле SORT (меньше = выше приоритет).
- Минимальный остаток — опустошаются склады с наименьшим запасом.
Если на одном складе не хватает, система автоматически дробит отгрузку на несколько складов. Это предотвращает отказы заказов из-за дефицита на одном складе.
Расчёт доступного остатка
Доступный остаток = физический минус активные резервы:
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); } На карточке товара и в корзине отображается доступный остаток. Это исключает ситуацию, когда клиент покупает товар, которого уже нет в резерве.
Административный интерфейс
В панели администратора добавляются три раздела:
- Остатки по складам — матрица товар × склад с физическим и доступным остатком, фильтрация по категории и складу.
- Перемещения — создание документа перемещения, подтверждение прихода на склад-приёмник.
- Резервы — список активных резервов с возможностью ручного снятия.
Интеграция с 1С
При интеграции через стандартный обмен (/bitrix/admin/1c_exchange.php) остатки из модуля синхронизируются с b_catalog_store_product через обработчик OnSuccessCatalogImport1C. Резервы не затираются: остатки из 1С считаются физическими, а доступный остаток пересчитывается автоматически.
Сроки разработки
| Масштаб | Состав | Срок |
|---|---|---|
| Базовый | Резервирование при заказе, доступный остаток, снятие резерва | 6–8 дней |
| Стандартный | + Перемещения, стратегии отгрузки, админ-интерфейс | 12–16 дней |
| Расширенный | + Аналитика, интеграция с 1С, мобильный интерфейс | 20–28 дней |
Что входит в работу
- Разработка модуля с документацией по API и настройке.
- Исходный код с комментариями, unit-тесты.
- Настройка интеграций с 1С, платёжными шлюзами и транспортными компаниями.
- Обучение администраторов.
- Постпроектная поддержка: гарантия 6 месяцев от даты сдачи.
Наши компетенции
Опыт разработки — более 5 лет, выполнено 50+ проектов для магазинов с разной логистикой. Сертифицированные специалисты по платформе 1С-Битрикс. Мы гарантируем соблюдение сроков и прозрачность работ. Экономия на перепродажах может достигать 15% оборота. Свяжитесь с нами для консультации — обсудим ваш проект без обязательств.
Дополнительная информация о методах складского учёта доступна на Wikipedia: FIFO, управление запасами.







