Bitrix

Битрикс — выделение отмененных заказов в панели управления

Вообще говоря, как-либо программно модифицировать панель управления Битрикс достаточно сложно и единственный способ это сделать, не нарвавшись на то, что обновлять ядро будет невозможно, — это использовать события. Какое решение я могу предложить — напишу в этой статье.

Какие события использовать?

Есть 2 события, которые нам могут пригодится: OnBeforeProlog и OnAfterEpilog: первое выполняется перед началом вывода страницы, второе — по окончанию вывода страницы. Фактически с помощью этих двух мы можем перехватить вывод страницы, что-то добавить в код и затем вывести ее пользователю.

Делается это так:

RegisterModuleDependences("main", "OnBeforeProlog", "main", "ModifyContent", "StartBuffer", "100");
RegisterModuleDependences("main", "OnAfterEpilog", "main", "ModifyContent", "EndBuffer", "100");

class ModifyContent
{
function StartBuffer()
{
if (!defined("ADMIN_SECTION")) return;
define("MYBOT_IS_ACTIVE", true);
ob_start();
}

function EndBuffer()
{
if(defined("MYBOT_IS_ACTIVE"))
{
$content = ob_get_contents();
ob_end_clean();

echo $content . "еще чего-то";

}
}
}

В методе, который вызывается при событии OnBeforeProlog идет проверка на содержание константы ADMIN_SECTION и не для панели управления данный код не выполняется. Пара функций ob_start() и ob_get_contents() позволяет перенаправить вывод страницы в буфер, а потом отдать этот вывод в переменную.

Как что-то изменить в панели управления?

Я решил выбрать способ, при котором непосредственной модификации даже выходящего код страницы панели управления не происходит, — через изменение внешнего вида с помощью javascript, а точнее библиотеки jquery.

С недавнего времени jquery в битрикс можно подключить так: CJSCore::Init( ‘jquery’ ).

Чтобы понять какой скрипт нужно написать, нужно просто посмотреть код html после генерации страницы списка заказов. Список заказов представляет собой таблицу с id tbl_sale_order, причем те строки, где непосредственно находятся заказы (т.е. не заголовок и не футер таблицы) отмечены id odd и even. Этим мы и воспользуемся для обработки данных. К тому же нам нужен ID заказа. Его можно найти в первой ячейке в значении чекбокса. Таким образом получается нехитрый скрипт поиска всех ID заказов, которые используются на данной странице заказа:

var ordersAr = [];
$('#tbl_sale_order tr.odd, #tbl_sale_order tr.even').each(function(){
var orderid = $(this).children("td:first").children("input").attr('value');
ordersAr[ordersAr.length]=orderid;
});

Далее нужно получить данные по каждому ID заказа является ли он отмененным или нет. Это очевидно нужно делать через обращение через AJAX к серверному скрипту. В скрипт будем отправлять массив ID заказов, а назад будем принимать json-объект ассоциативный массив вида:  ID заказа => Отменен или нет.

Скрипт на сервере будет выглядеть так:

<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
CModule::IncludeModule('sale');

$CancelInfo = Array();
foreach($_REQUEST["orders"] as $order)
{
$arOrder = CSaleOrder::GetByID($order);
if ($arOrder["CANCELED"] == "Y")
$CancelInfo[$order] = true;
else
$CancelInfo[$order] = false;
}

echo json_encode(array('CancelInfo' => $CancelInfo));

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");
?>

а обращение из ява-скрипта к этому скрипту и обработка данных — так:

$.getJSON("/bitrix/admin/dv/getorders.php", { orders: ordersAr },
function(data)
{
$('#tbl_sale_order tr.odd, #tbl_sale_order tr.even').each(function(){
var orderid = $(this).children("td:first").children("input").attr('value');
if (data.CancelInfo[orderid]) {
$(this).children("td").css("background-color", "#FFA7A7");
}
});
}
);

Ничего сложного в скрипте обработки нет — она просто по новой перебирает все заказы на страницы и, если в массиве, полученном с сервера, этот заказ помечен как отмененный, то скрипт перекрашивает все ячейки данной строки в другой цвет.

Серверный скрипт я привел полностью, а код вызываемый по событиям нет, исправим это:

 

if( ADMIN_SECTION ) {
CJSCore::Init( 'jquery' );
}

RegisterModuleDependences("main", "OnBeforeProlog", "main", "ModifyContent", "StartBuffer", "100");
RegisterModuleDependences("main", "OnAfterEpilog", "main", "ModifyContent", "EndBuffer", "100");


class ModifyContent
{
function StartBuffer()
{
if (!defined("ADMIN_SECTION")) return;
define("MYBOT_IS_ACTIVE", true);
ob_start();
}

function EndBuffer()
{
if(defined("MYBOT_IS_ACTIVE"))
{
$content = ob_get_contents();
ob_end_clean();
global $APPLICATION;

echo $content;

if ($APPLICATION->GetCurPage() == "/bitrix/admin/sale_order.php")
{
echo <<<EOL
<script>
$(function() {
var ordersAr = [];
$('#tbl_sale_order tr.odd, #tbl_sale_order tr.even').each(function(){
var orderid = $(this).children("td:first").children("input").attr('value');
ordersAr[ordersAr.length]=orderid;
});


$.getJSON("/bitrix/admin/dv/getorders.php", { orders: ordersAr },
function(data)
{
$('#tbl_sale_order tr.odd, #tbl_sale_order tr.even').each(function(){
var orderid = $(this).children("td:first").children("input").attr('value');
if (data.CancelInfo[orderid]) {
$(this).children("td").css("background-color", "#FFA7A7");
}
});
}
);
});
</script>
EOL;
}
}
}
}

Конечно же, данный код должен располагаться в файле /bitrix/php_interface/init.php, а код, который вызывается через AJAX в файле /bitrix/admin/dv/getorders.php . Удачного кодинга!

Комментариев: 4

  1. отлично работает!
    в последних версиях битрикса ( в частности 17.0) нужно заменить
    #tbl_sale_order tr.odd, #tbl_sale_order tr.even
    на
    #tbl_sale_order tr.adm-list-table-row

  2. Еще можно влезть в список заказов без JS, тоже через событие:
    AddEventHandler(«main», «OnAdminListDisplay», «MyOnAdminListDisplay»);
    function MyOnAdminListDisplay(&$list)
    {
    if ($list->table_id==’tbl_sale_order’) {//если это страница списка заказов
    ….
    }
    }

Отставить комментарий

Ваш электронный адрес не будет опубликован.Обязательные для заполнения поля отмечены *

тринадцать − 1 =