Yandex Metrika
sanches.free 20 просмотров

Кастомизация формы заказа в админке Bitrix на D7: сводная панель и собственные вкладки

С чего это начиналось

На конференции Bitrix Day летом 2016 показали расширяемость карточки заказа в панели управления магазина. Практически те же возможности живут и в более свежих ветках: модуль sale на D7 держит отдельные точки для сводной «жёлтой» полосы и для пользовательских вкладок редактуры. Ниже — только админские сценарии, без публичного оформления.

Сводка сверху: onSaleAdminOrderInfoBlockShow

Событие принадлежит модулю sale. Из параметров удобно забирать ORDER (экземпляр объекта заказа) и при необходимости ORDER_BASKET (активную корзину заказа). Обработчик обязан вернуть Bitrix\Main\EventResult со списком ассоциативных записей для вывода в сводном блоке.

  • TITLE — подпись параметра менеджеру;
  • VALUE — то, что увидят в строке сводки; ядро не экранирует значение автоматически, поэтому вывод произвольного HTML возможен осознанно, а текст из внешних источников лучше фильтровать;
  • ID — необязательный идентификатор узла полосы, если нужно ссылаться на него напрямую.

В примере выведем текстовое представление локации доставки через справочник местоположений.

$hookBus = \Bitrix\Main\EventManager::getInstance();
$hookBus->addEventHandler('sale', 'onSaleAdminOrderInfoBlockShow', 'renderAdminOrderLocationChip');

function renderAdminOrderLocationChip(\Bitrix\Main\Event $payload)
{
    /** @var \Bitrix\Sale\Order $commerceDraft */
    $commerceDraft = $payload->getParameter('ORDER');
    // $positionsSnapshot = $payload->getParameter('ORDER_BASKET');

    $buyerTraits = $commerceDraft->getPropertyCollection();
    $geoLocatorValue = \Bitrix\Sale\Location\Admin\LocationHelper::getLocationStringByCode(
        $buyerTraits->getDeliveryLocation()->getValue()
    );

    return new \Bitrix\Main\EventResult(
        \Bitrix\Main\EventResult::SUCCESS,
        [
            [
                'TITLE' => 'Населённый пункт доставки:',
                'VALUE' => $geoLocatorValue,
                'ID' => 'delivery_geo_label',
            ],
        ]
    );
}

Собственные вкладки через события main

Для регистрации вкладочного набора цепляются не к sale, а к модулю main. Выбирайте нужный хук под режим карточки:

  • OnAdminSaleOrderCreate — создание заказа;
  • OnAdminSaleOrderEdit — изменение сохранённого заказа;
  • OnAdminSaleOrderView — просмотр в режиме «только чтение».

От обработчика ждётся массив с ключами описания вкладочного набора: TABSET, методы построения (GetTabs, ShowTab) и сохранения (Action, Check). Внутри вкладочных методов при необходимости можно прервать сценарий сохранения, выбросив исключение через CMain::ThrowException(); для формы просмотра ветки Action/Check почти всегда пусты, но оставить их можно для единого каркаса.

Аргументы вкладочных методов приходят в виде массива параметров строки адреса админки, а не готового HttpRequest; при необходимости текущий запрос можно взять из \Bitrix\Main\Application::getInstance()->getContext(), как описано для объекта приложения на D7.

$hookBus = \Bitrix\Main\EventManager::getInstance();
$hookBus->addEventHandler('main', 'OnAdminSaleOrderView', ['BackofficeSaleOrderTabs', 'wireTabKit']);

class BackofficeSaleOrderTabs
{
    public static function wireTabKit()
    {
        return [
            'TABSET' => 'OpsNotesRibbon',
            'GetTabs' => [__CLASS__, 'collectTabs'],
            'ShowTab' => [__CLASS__, 'paintTab'],
            'Action' => [__CLASS__, 'persistTab'],
            'Check' => [__CLASS__, 'guardBeforePersist'],
        ];
    }

    public static function collectTabs(array $routingBag)
    {
        return [
            [
                'DIV' => 'ops_support_stub',
                'TAB' => 'Служебные пометки',
                'TITLE' => 'Вывод дополнительного текста оператору',
                'SORT' => 80,
            ],
        ];
    }

    public static function paintTab($paneCode, array $routingBag, array $formMirror)
    {
        if ($paneCode === 'ops_support_stub') {
            echo '<p>Здесь размещаются подсказки отделу логистики или ссылка на внутренний конвейер SLA.</p>';
        }
    }

    public static function guardBeforePersist(array $routingBag)
    {
        return true;
    }

    public static function persistTab(array $routingBag)
    {
        return true;
    }
}

На что опираться дальше

Структуру объектов заказа и строк корзины удобно сверять с общими заметками про Bitrix\Sale\Order и работу корзины; административная карточка использует те же сущности, только оборачивает их управленческим UI.

  • Используйте отдельные классы описателей вкладок, если на разных вкладках нужны собственные SQL- или REST-агрегации.
  • Помните, что свободный HTML в VALUE блока информации упрощает оформление, но добавляет XSS-риск для произвольного контента менеджеров.
  • Вкладочные сохранение-процедуры вызываются только там, где карточка реально сохраняет POST-поля карточки заказа.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии