Настройка мультипоставщиковой логики заказов 1С-Битрикс
При дропшиппинге один заказ покупателя может содержать товары от разных поставщиков. Каждому поставщику нужно передать только его часть. Битрикс не разбивает заказы по поставщикам автоматически — логика реализуется через обработчики событий и кастомные таблицы.
Варианты реализации
Вариант 1 — единый заказ, отдельные уведомления поставщикам. Заказ в Битрикс остаётся единым в b_sale_order. При оформлении заказа обработчик OnSaleOrderSaved определяет, какие позиции корзины принадлежат каким поставщикам, и отправляет каждому поставщику уведомление только с его товарами. Проще, но не позволяет отслеживать отгрузку по каждому поставщику раздельно.
Вариант 2 — разбивка на дочерние отгрузки. Единый заказ, но объект \Bitrix\Sale\Shipment создаётся отдельно для каждого поставщика. Это нативный механизм Битрикс — в одном заказе может быть несколько отгрузок с разными параметрами.
Вариант 3 — разбивка на отдельные заказы (подзаказы). При оформлении создаётся родительский заказ и несколько дочерних по числу поставщиков. Сложнее, но даёт полную независимость статусов.
Реализация через отдельные отгрузки (вариант 2)
При сохранении заказа определяем поставщиков и создаём отгрузки:
AddEventHandler('sale', 'OnSaleOrderSaved', function(\Bitrix\Main\Event $event) {
$order = $event->getParameter('ENTITY');
$isNew = $event->getParameter('IS_NEW');
if (!$isNew) return;
$basket = $order->getBasket();
$supplierItems = [];
// Группируем позиции корзины по поставщикам
foreach ($basket->getOrderableItems() as $item) {
$supplierId = getSupplierByProductId($item->getProductId());
if ($supplierId) {
$supplierItems[$supplierId][] = $item;
}
}
$shipmentCollection = $order->getShipmentCollection();
foreach ($supplierItems as $supplierId => $items) {
$shipment = $shipmentCollection->createItem();
$shipment->setField('DELIVERY_ID', getSupplierDeliveryId($supplierId));
$shipment->setField('CUSTOM_PRICE_DELIVERY', 'N');
$shipmentItemCollection = $shipment->getShipmentItemCollection();
foreach ($items as $basketItem) {
$shipmentItem = $shipmentItemCollection->createItem($basketItem);
$shipmentItem->setQuantity($basketItem->getQuantity());
}
}
$order->save();
});
Функция getSupplierByProductId() читает свойство SUPPLIER_ID из b_iblock_element_property.
Уведомления поставщикам
Каждый поставщик получает письмо или сообщение только со своими товарами. Отправка через \Bitrix\Main\Mail\Event::send() с кастомным шаблоном:
foreach ($supplierItems as $supplierId => $items) {
$supplierEmail = getUserEmail($supplierId);
\Bitrix\Main\Mail\Event::send([
'EVENT_NAME' => 'SUPPLIER_ORDER_NOTIFY',
'LID' => SITE_ID,
'C_FIELDS' => [
'SUPPLIER_EMAIL' => $supplierEmail,
'ORDER_ID' => $order->getId(),
'ORDER_ITEMS' => formatItemsForEmail($items),
'BUYER_ADDRESS' => getOrderDeliveryAddress($order),
],
]);
}
Шаблон SUPPLIER_ORDER_NOTIFY создаётся в «Почтовые события» административной части.
Отслеживание статусов по поставщикам
HL-блок SupplierOrderStatus фиксирует статус каждой части заказа:
-
UF_ORDER_ID— ID заказа Битрикс -
UF_SUPPLIER_ID— поставщик -
UF_STATUS—new/confirmed/shipped -
UF_TRACKING_NUMBER— трек-номер
Агент проверяет, все ли поставщики установили shipped, и меняет статус основного заказа:
function checkAllSuppliersShippedAgent(): string
{
// Находим заказы, где все поставщики отгрузили товар
$connection = \Bitrix\Main\Application::getConnection();
$orders = $connection->query("
SELECT UF_ORDER_ID
FROM b_hl_supplier_order_status
GROUP BY UF_ORDER_ID
HAVING COUNT(*) = SUM(CASE WHEN UF_STATUS = 'shipped' THEN 1 ELSE 0 END)
AND UF_ORDER_ID IN (
SELECT ID FROM b_sale_order WHERE STATUS_ID NOT IN ('F','C')
)
");
while ($row = $orders->fetch()) {
$order = \Bitrix\Sale\Order::load($row['UF_ORDER_ID']);
if ($order) {
$order->setField('STATUS_ID', 'S'); // статус «Отправлен»
$order->save();
}
}
return __FUNCTION__ . '();';
}
Настройка занимает 2–5 дней в зависимости от выбранного варианта разбивки и сложности уведомлений.







