Setting up automatic generation of shipping documents in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    565
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    980

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_props with type FILE.
  • Custom table sale_order_documents with fields ORDER_ID, FILE_ID, DOC_TYPE, DATE_CREATE.
  • Save to CRM deal infoblock property if crm module 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.