В 1С-Битрикс заказ — это не плоская запись, а объектная модель D7: у заказа есть коллекция отгрузок и коллекция оплат. Отгрузка (Shipment) отвечает за то, какие товары, когда и какой службой доставки уезжают покупателю, а также за списание со склада. Разберём, как эта модель устроена и какие флаги реально управляют движением товара.
Заказ, отгрузки и оплаты: как связаны сущности
С переходом на ядро D7 заказ описывается объектом \Bitrix\Sale\Order. Внутри него живут независимые коллекции: корзина (Basket), оплаты (PaymentCollection) и отгрузки (ShipmentCollection). Деньги и товар в Битрикс разведены сознательно: за приём средств отвечает оплата, за движение товара — отгрузка.
- Order — контейнер: хранит покупателя, свойства, статус и итоговые суммы.
- Payment — факт оплаты через конкретную платёжную систему (
PAY_SYSTEM_ID). - Shipment — факт отгрузки: набор товаров, служба доставки (
DELIVERY_ID), стоимость доставки и признак списания. - ShipmentItem — строка отгрузки: сколько единиц конкретной позиции корзины уезжает в этой отгрузке.
Один заказ может иметь несколько оплат и несколько отгрузок — именно это даёт частичные оплаты и частичные отгрузки без пересборки состава.
Системная отгрузка: куда попадают товары сразу
Когда заказ только создан, в нём уже есть одна отгрузка — системная (Shipment::isSystem() === true). Это техническая сущность: в ней лежат все позиции корзины, ещё не распределённые по реальным отгрузкам. Служба доставки у системной отгрузки не выбрана.
Как только вы создаёте настоящую отгрузку и указываете службу доставки, товары «перетекают» из системной отгрузки в реальную: количество в ShipmentItem уменьшается в системной и появляется в новой. Пока часть товара осталась в системной отгрузке — заказ отгружен не полностью.
Ключевые флаги: DEDUCTED, ALLOW_DELIVERY, RESERVED
Состоянием реальной отгрузки управляют три флага «Да/Нет». Их путают чаще всего, поэтому разложим по смыслу.
| Поле | Что означает | Что происходит при Y |
|---|---|---|
DEDUCTED | Отгружено / списано со склада | Списываются остатки, снимается резерв, фиксируется DATE_DEDUCTED |
ALLOW_DELIVERY | Разрешить доставку | Отгрузка допущена к передаче в доставку, меняется статус |
RESERVED | Товар зарезервирован | Количество удерживается на складе под этот заказ |
Главный из них — DEDUCTED. Именно установка DEDUCTED = 'Y' означает физическую отгрузку: Битрикс списывает товар со склада каталога и снимает резерв. Флаг ALLOW_DELIVERY — это разрешение к доставке, а не сам факт списания; они независимы.
Резерв и связь с остатками склада
Резервирование работает на уровне строки отгрузки: у ShipmentItem есть RESERVED_QUANTITY. Зарезервированное количество удерживается на складе — доступный остаток для других покупателей уменьшается, но физически товар ещё на складе.
Момент резерва задаётся в настройках модуля sale (Магазин → Настройки → Настройки резервирования): резервировать при оформлении заказа, при оплате или при переходе отгрузки в определённый статус. Логика движения количеств такая:
- Товар зарезервирован — вычитается из доступного остатка, но не из фактического.
- Отгрузка помечена
DEDUCTED = 'Y'— резерв снимается, фактический остаток уменьшается. - Отгрузка отменена (
CANCELED = 'Y') — резерв возвращается, при уже списанном товаре остаток восстанавливается.
Привязка к доставке и статусы отгрузки
Каждая реальная отгрузка привязана к службе доставки через DELIVERY_ID и хранит стоимость доставки (PRICE_DELIVERY, BASE_PRICE_DELIVERY) и трек-номер (TRACKING_NUMBER). У отгрузки собственный статус STATUS_ID из справочника статусов доставки (тип DELIVERY_STATUS), не путайте его со статусом заказа.
Типичный жизненный цикл реальной отгрузки:
- создана, товар распределён из системной отгрузки;
- зарезервирована (если по настройке резерв на этом шаге);
ALLOW_DELIVERY = 'Y'— разрешена доставка, меняется статус;DEDUCTED = 'Y'— отгружена, склад списан.
Статус самого заказа агрегируется из отгрузок: поле заказа DEDUCTED становится 'Y', только когда отгружены все его непустые отгрузки.
События и точки автоматизации
Модель отгрузок насыщена событиями ядра, за которые удобно цеплять интеграции — уведомления, обмен с 1С, печать документов. Работать с ними правильно через объектную модель, а не прямыми UPDATE в таблицы b_sale_order_delivery.
OnSaleShipmentEntitySaved/OnShipmentDeducted— реакция на отгрузку и списание;OnSaleDeliveryAllowDeliveryChange— смена разрешения доставки;OnSaleShipmentEntitySaveError— контроль ошибок сохранения.
Программно отгрузку меняют через коллекцию: получают $order->getShipmentCollection(), вызывают setField('DEDUCTED', 'Y') у нужной отгрузки и сохраняют заказ $order->save(). Тогда Битрикс сам пересчитает резервы, остатки и статус заказа — это и есть корректный путь.
Итог
Отгрузка в 1С-Битрикс — это отдельная сущность внутри заказа, которая отвечает за товар и склад, тогда как оплата отвечает за деньги. Ключ к пониманию — три флага: RESERVED удерживает товар, ALLOW_DELIVERY разрешает доставку, а DEDUCTED фиксирует фактическое списание. Системная отгрузка хранит нераспределённые позиции, реальные — конкретные партии со службой доставки и статусом.
Мы в B2Bsite проектируем и сопровождаем магазины на Битрикс так, чтобы отгрузки, резервы и обмен с 1С работали предсказуемо: без двойных списаний, рассинхрона остатков и ручных правок в БД. Если нужно навести порядок в схеме заказ→отгрузки→оплаты или связать её с учётной системой — поможем на этапе разработки и на поддержке.
Частые вопросы
Чем отличается DEDUCTED от ALLOW_DELIVERY?
ALLOW_DELIVERY — это разрешение передать отгрузку в доставку, а DEDUCTED — факт физического списания товара со склада. Установка DEDUCTED в Y снимает резерв и уменьшает остаток, ALLOW_DELIVERY этого не делает.
Что такое системная отгрузка?
Это техническая отгрузка, которая создаётся автоматически и хранит все ещё не распределённые по реальным отгрузкам позиции корзины. У неё нет службы доставки, и пометить её отгруженной нельзя.
Когда товар резервируется на складе?
Момент резерва задаётся в настройках резервирования модуля sale: при оформлении заказа, при оплате или при переходе отгрузки в нужный статус. Резерв уменьшает доступный остаток, но не фактический.
Может ли в одном заказе быть несколько отгрузок?
Да, коллекция отгрузок поддерживает несколько записей. Это позволяет отгружать заказ частями разными службами доставки без изменения состава корзины.
Почему списание не происходит дважды при отгрузке зарезервированного товара?
Отгрузка не списывает резерв повторно, а конвертирует его в фактический расход: резерв снимается, а фактический остаток уменьшается один раз. Двойного вычитания не будет.
Как правильно менять отгрузку программно?
Через объектную модель D7: получить getShipmentCollection у заказа, изменить нужное поле через setField и сохранить заказ методом save. Прямые UPDATE в таблицы БД ломают пересчёт резервов и статусов.
Статус отгрузки и статус заказа — это одно и то же?
Нет. У отгрузки свой STATUS_ID из справочника статусов доставки, а у заказа отдельный статус. Флаг DEDUCTED заказа становится Y, только когда отгружены все его отгрузки.
Что происходит с остатком при отмене отгрузки?
При отмене отгрузки резерв возвращается, а если товар уже был списан, фактический остаток восстанавливается. Это позволяет корректно обрабатывать возвраты и ошибки оформления.
Поможем с настройкой и поддержкой 1С-Битрикс: Управление сайтом
Поможем с настройкой, доработкой и поддержкой 1С-Битрикс: Управление сайтом.