Список статусов заказов и отгрузок в 1С-Битрикс на php

24.05.2021
Понадобилось получить список всех статусов отгрузок, которые существуют в системе. Поиски в интернетах не дали результата, но все оказалось просто.

Сам список статусов (заказа/отгрузки) можно увидеть в админке 1С-Битрикс в разделе Магазин=>Настройки=>Статусы.

Страница статусов в админке 1с-Битрикс
Страница статусов в админке 1с-Битрикс

Эта страница расположена по адресу /bitrix/admin/sale_status.php попробуем открыть этот файл и видим там:

•••
php
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/sale/admin/status.php");

Идем по указанному пути ... и находим внутри файла код формирования данной страницы. Немного посмотрев обнаруживаем интересные строки напоминающие формирование запроса к БД:

•••
php
$query = \Bitrix\Sale\Internals\StatusTable::query(); $query->setSelect([ 'ID', 'SORT', 'TYPE', 'NOTIFY', 'LID' => 'STATUS_LANG.LID', 'COLOR' ,'NAME' => 'STATUS_LANG.NAME', 'DESCRIPTION' => 'STATUS_LANG.DESCRIPTION' ]); $query->where( \Bitrix\Main\ORM\Query\Query::filter() ->logic('OR') ->where('STATUS_LANG.LID', '=', LANGUAGE_ID) ->where('STATUS_LANG.LID', NULL) );

Как оказалось \Bitrix\Sale\Internals это пространство имен с классами для работы с таблицами БД модуля интернет-магазин, а вышеприведенный код использует функционал ORM 1С-Битрикс. Классы из \Bitrix\Sale\Internals подгружаются в файле /bitrix/modules/sale/autoload.php. наследуются от \Main\Entity\DataManager.

Это сообщение на странице документации. Не рекомендуется, но целый модуль построен на этом :)
Это сообщение на странице документации. Не рекомендуется, но целый модуль построен на этом :)

Быстренько читаем что там по вышеприведенным ссылкам и пробуем разобраться в коде.

Сначала нужно получить объект запроса:

•••
php
$query = \Bitrix\Sale\Internals\StatusTable::query();

Теперь нужно указать что будем выбирать из таблицы (таблица выборки уже указана в самом классе):

•••
php
$query->setSelect([ 'ID', 'SORT', 'TYPE', 'NAME' => 'STATUS_LANG.NAME' ]);

В моей задаче требовалось выбрать все статусы относящиеся к доставке, поэтому доавляем условие TYPE='D':

•••
php
$query->where( \Bitrix\Main\ORM\Query\Query::filter() ->logic("AND") ->where('TYPE', '=', "D") );

Хотелось бы поставить фильтр по языку STATUS_LANG.LID=LANGUAGE_ID, чтобы показывать для каждого языка поддерживаемого сайтом определенный статус (и те строки для которых язык не определен STATUS_LANG.LID = NULL):

•••
php
$query->where( \Bitrix\Main\ORM\Query\Query::filter() ->logic('OR') ->where('STATUS_LANG.LID', '=', LANGUAGE_ID) ->where('STATUS_LANG.LID', NULL) );

Устанавливаем сортировку по полю SORT в прямом порядке:

•••
php
$query->setOrder(["SORT" => "ASC"]);

На этом этапе можно посмотреть как будет выглядеть наш запрос к БД таким образом $query->getQuery();, получим что-то подобное:

•••
sql
SELECT `sale_internals_status`.`ID` AS `ID`, `sale_internals_status`.`SORT` AS `SORT`, `sale_internals_status`.`TYPE` AS `TYPE`, `sale_internals_status_status_lang`.`NAME` AS `NAME` FROM `b_sale_status` `sale_internals_status` LEFT JOIN `b_sale_status_lang` `sale_internals_status_status_lang` ON `sale_internals_status`.`ID` = `sale_internals_status_status_lang`.`STATUS_ID` WHERE `sale_internals_status`.`TYPE` = 'D' AND (`sale_internals_status_status_lang`.`LID` = 'ru' OR `sale_internals_status_status_lang`.`LID` IS NULL) ORDER BY `SORT` ASC

Казалось бы несколько строк кода php, а сгенерирован SQL с JOIN. Все потому что ORM и внутри уже настроены связи между объектами.

Теперь выполняем запрос и распределяем данные запроса по ассоциативному массиву:

•••
php
$aRes = $query->exec()->fetchAll(); foreach($aRes as $value) $a[$value["ID"]] = $value["NAME"];

В итоге получим что-то подобное:

•••
plaintext
Array ( [DN] => Ожидает обработки [DA] => Комплектация заказа [DG] => Ожидаем приход товара [DT] => Ожидаем забора транспортной компанией [DS] => Передан в службу доставки [DF] => Отгружен )