Розробка кастомної логіки зміни статусів замовлення 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка кастомної логіки зміни статусів замовлення 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка кастомної логіки зміни статусів замовлення 1С-Бітрікс

Стандартний механізм статусів Бітрікс дозволяє менеджеру вручну переводити замовлення до будь-якого статусу за наявності відповідних прав доступу. Але реальний процес обробки замовлення складніший: перехід у «доставляється» має бути можливим лише з «збирається», перехід у «скасовано» — лише якщо замовлення не оплачено, повернення зі «завершено» — лише для адміністратора. Все це — кастомна логіка переходів, яка не реалізується через стандартні налаштування.

Валідація переходів: подієва модель

Бітрікс надає подію OnSaleOrderBeforeStatusChange — обробник може заблокувати перехід і повернути помилку:

// /local/php_interface/init.php
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
    'sale',
    'OnSaleOrderBeforeStatusChange',
    ['\App\Order\StatusValidator', 'validate']
);
// /local/lib/Order/StatusValidator.php
namespace App\Order;

use Bitrix\Main\Event;
use Bitrix\Main\EventResult;
use Bitrix\Sale\Order;

class StatusValidator
{
    // Матриця допустимих переходів
    private static array $allowedTransitions = [
        'N' => ['P', 'A'],           // Новий → Прийнято або Скасовано
        'P' => ['W', 'ASSEMBLY', 'A'], // Прийнято → Очікує оплати, Збирання, Скасовано
        'W' => ['P', 'ASSEMBLY', 'A'], // Очікує оплати → Прийнято, Збирання, Скасовано
        'ASSEMBLY' => ['D', 'A'],     // Збирання → Доставляється, Скасовано
        'D' => ['F'],                 // Доставляється → Завершено
        'F' => [],                    // Завершено — фінальний
        'A' => [],                    // Скасовано — фінальний
    ];

    public static function validate(Event $event): EventResult
    {
        /** @var Order $order */
        $order = $event->getParameter('ENTITY');
        $newStatus = $event->getParameter('VALUE');
        $currentStatus = $order->getField('STATUS_ID');

        $allowed = self::$allowedTransitions[$currentStatus] ?? [];

        if (!in_array($newStatus, $allowed, true)) {
            return new EventResult(
                EventResult::ERROR,
                [
                    'message' => sprintf(
                        'Перехід зі статусу "%s" до "%s" заборонено',
                        $currentStatus,
                        $newStatus
                    ),
                ],
                'sale'
            );
        }

        // Додаткова бізнес-перевірка: не можна скасувати оплачене замовлення
        if ($newStatus === 'A' && $order->isPaid()) {
            return new EventResult(
                EventResult::ERROR,
                ['message' => 'Не можна скасувати оплачене замовлення. Оформіть повернення.'],
                'sale'
            );
        }

        return new EventResult(EventResult::SUCCESS);
    }
}

Додаткова валідація за ролями

Адміністратор може виконувати дії, недоступні менеджеру:

public static function validate(Event $event): EventResult
{
    global $USER;

    $order = $event->getParameter('ENTITY');
    $newStatus = $event->getParameter('VALUE');
    $currentStatus = $order->getField('STATUS_ID');

    // Повернення з фінального статусу — тільки адміністратор
    if ($currentStatus === 'F' && !$USER->IsAdmin()) {
        return new EventResult(
            EventResult::ERROR,
            ['message' => 'Зміна завершеного замовлення доступна лише адміністратору'],
            'sale'
        );
    }

    // ... інші перевірки
}

Реакція на перехід: постобробка

Після успішного переходу спрацьовує подія OnSaleOrderStatusChange:

\Bitrix\Main\EventManager::getInstance()->addEventHandler(
    'sale',
    'OnSaleOrderStatusChange',
    function(Event $event) {
        $order = $event->getParameter('ENTITY');
        $newStatus = $event->getParameter('VALUE');
        $oldStatus = $event->getParameter('OLD_VALUE');

        switch ($newStatus) {
            case 'ASSEMBLY':
                // Створити завдання на складі
                WarehouseIntegration::createPickingTask($order);
                break;

            case 'D':
                // Передати до служби доставки
                DeliveryService::registerShipment($order);
                // Надіслати покупцю трек-номер
                Notifications::sendTrackingNumber($order);
                break;

            case 'F':
                // Нарахувати бонусні бали
                LoyaltyProgram::creditPoints($order);
                // Запросити відгук через 3 дні
                ReviewRequest::schedule($order->getUserId(), 3);
                break;

            case 'A':
                // Повернути резерв на складі
                if ($oldStatus !== 'N') {
                    StockManager::releaseReservation($order);
                }
                // Ініціювати повернення оплати якщо потрібно
                if ($order->isPaid()) {
                    RefundManager::initiate($order);
                }
                break;
        }
    }
);

Програмна зміна статусу

При зміні статусу з коду — не через setField напряму, а через коректний метод:

$order = \Bitrix\Sale\Order::load($orderId);

// Правильний спосіб — з тригером всіх подій
$result = $order->setField('STATUS_ID', 'D');

if ($result->isSuccess()) {
    $saveResult = $order->save();
    if (!$saveResult->isSuccess()) {
        // Обробка помилок збереження
        $errors = $saveResult->getErrorMessages();
    }
} else {
    // Подія OnSaleOrderBeforeStatusChange повернула помилку
    $errors = $result->getErrorMessages();
}

Журнал переходів

Усі зміни статусів логуються до b_sale_order_change автоматично. Для кастомного аудиту — власна таблиця з історією переходів та причинами:

// При кожній зміні статусу
\App\Order\StatusLog::record([
    'order_id'   => $order->getId(),
    'from_status' => $oldStatus,
    'to_status'   => $newStatus,
    'user_id'     => $GLOBALS['USER']->GetID(),
    'comment'     => $comment,
    'timestamp'   => new \Bitrix\Main\Type\DateTime(),
]);

Інтерфейс зміни статусу з коментарем

Стандартний інтерфейс не надає поле коментаря при зміні статусу. Це вирішується кастомним AJAX-обробником на сторінці деталі замовлення в адмінці:

// /local/ajax/change_order_status.php
$orderId = (int)$_POST['order_id'];
$newStatus = htmlspecialchars($_POST['status']);
$comment = htmlspecialchars($_POST['comment']);

$order = \Bitrix\Sale\Order::load($orderId);
// Зберігаємо коментар у сесії/глобалі для обробника події
$_SESSION['order_status_comment'][$orderId] = $comment;

$order->setField('STATUS_ID', $newStatus);
$result = $order->save();

Терміни виконання

Матриця переходів з валідацією та обробники реакцій на 3–5 статусів — 1–2 робочих дні. Повноцінна система з журналом, інтерфейсом коментарів, інтеграцією зі складом і службою доставки — 3–5 робочих днів.