Setting Up Automatic Shipment Document Generation in 1C-Bitrix
Manager changes order status to "Shipped" — an invoice should generate itself. Instead, he opens a separate interface, manually enters data that's already in the order. This duplication is eliminated by a single event handler.
Order Status Change Event
The entry point is the OnSaleStatusOrderChange event in the sale module. It fires on every status change. Parameters: ORDER_ID, STATUS_ID (new status), OLD_STATUS_ID.
The handler is registered in /bitrix/php_interface/init.php or in a module:
AddEventHandler('sale', 'OnSaleStatusOrderChange', 'generateShipmentDoc');
function generateShipmentDoc($orderId, $newStatus, $oldStatus) {
// Generate document only on transition to shipment status
if ($newStatus !== 'S') return; // 'S' - example of shipment status
$order = \Bitrix\Sale\Order::load($orderId);
if (!$order) return;
generateInvoiceForOrder($order);
}
In the new Bitrix API (D7), the event is called OnSaleOrderSaved and passes an order object — recommended to use instead of the deprecated one.
Shipment Structure in Sale Module
A shipment in Bitrix is an object \Bitrix\Sale\Shipment. Each order can have multiple shipments. Table b_sale_shipment stores shipments with fields: ORDER_ID, DELIVERY_ID, STATUS_ID, PRICE_DELIVERY, CURRENCY, DEDUCTED (Y — goods deducted from warehouse).
Shipment lines — b_sale_shipment_item: SHIPMENT_ID, BASKET_ID, QUANTITY, RESERVED_QUANTITY.
When generating a shipment document, read from b_sale_shipment_item, not b_sale_basket — partial shipment quantities may differ.
PDF Invoice Generation
For PDF generation, use an external library — mpdf or tcpdf. Bitrix has no built-in PDF generator for documents, but has a print forms mechanism via bitrix:sale.order.invoice component.
Programmatic PDF creation via mpdf:
function generateInvoiceForOrder(\Bitrix\Sale\Order $order) {
$shipmentCollection = $order->getShipmentCollection();
$items = [];
foreach ($shipmentCollection as $shipment) {
if ($shipment->isSystem()) continue;
foreach ($shipment->getShipmentItemCollection() as $shipmentItem) {
$basketItem = $shipmentItem->getBasketItem();
$items[] = [
'name' => $basketItem->getField('NAME'),
'quantity' => $shipmentItem->getQuantity(),
'price' => $basketItem->getPrice(),
'sum' => $basketItem->getPrice() * $shipmentItem->getQuantity(),
];
}
}
ob_start();
include __DIR__ . '/templates/invoice.php'; // template with $items, $order
$html = ob_get_clean();
$mpdf = new \Mpdf\Mpdf(['utf-8', 'A4']);
$mpdf->WriteHTML($html);
$pdfContent = $mpdf->Output('', 'S');
// Save file
$fileId = \CFile::SaveFile([
'name' => 'invoice_' . $order->getId() . '.pdf',
'type' => 'application/pdf',
'content' => $pdfContent,
], 'sale/invoices');
// Attach to order via property or custom table
saveInvoiceFile($order->getId(), $fileId);
}
Attaching Document to Order
Bitrix has no standard place to store order files. Options:
- Order property of type "File" — added via
b_sale_order_propswith typeFILE. - Custom table
sale_order_documentswith fieldsORDER_ID,FILE_ID,DOC_TYPE,DATE_CREATE. - Save to CRM deal infoblock property if
crmmodule is enabled.
A custom table is recommended — it doesn't depend on order property structure changes.
Sending Document to Manager
After generation, the document is sent to the manager's email or CRM. Via OnSaleOrderSaved event, ORDER_ID is available — from it, get the responsible manager from b_sale_order (field RESPONSIBLE_ID) and send an email via \Bitrix\Main\Mail\Event::send() with SALE_NEW_ORDER template or custom one.
Alternative — integrate with tasks module: on status change, create a task for the manager with a link to the document.







