Bitrix sale delivery services manager

Метод возвращает массив параметров службы доставки. Метод статический.

Параметры

Параметр Описание Версия
$deliveryId Идентификатор службы.
Параметр Описание
ID Идентификатор службы
CODE Символьный код службы
PARENT_ID Идентификатор родителя
NAME Название
ACTIVE Активность
DESCRIPTION Описание
SORT Индекс сортировки
LOGOTIP Логотип
CONFIG Настройки службы доставки
CURRENCY Валюта
CLASS_NAME Класс обработчика службы доставки
TRACKING_PARAMS Параметры необходимы для отслеживания отправок
ALLOW_EDIT_SHIPMENT Разрешено ли Автоматическое изменение отгрузки, находящейся в первоначальном статусе, при изменении заказа
VAT_ID Идентификатор ставки НДС

Исключения

Примеры

Пользовательские комментарии

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

Для этого нужно всего лишь авторизоваться на сайте

Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.

Предупреждение: код работает на версиях модуля sale 16.0 и выше.

В 16 версии магазина Битрикса были переработаны обработчики служб доставки. Обработчиками доставки являются классы-наследники BitrixSaleDeliveryServicesBase. Встроенные обработчики лежат в папке /bitrix/modules/sale/handlers/delivery/. Там можно ознакомиться с примерами новых обработчиков.

Чтобы подключить свой собственный обработчик, вроде бы нужно положить папку со своим классом в /bitrix/php_interface/include/sale_delivery/ или /local/php_interface/include/sale_delivery/, но на текущей версии(16.0.5) это не сработало. Но есть рабочий альтернативный метод подключения любого класса как обработчика, в init.php добавляем:

Все пути к файлам, пространства имён и классы, относящиеся к службе доставки, приведены для примера. Конечно, нужно размещают свои классы в своих модулях и своих пространствах имён.

По указанному пути создаём класс:

Читайте также:  Xiaomi h k limited

Добавляем несколько методов, смысл которых вполне понятен из названия:

Следующий метод отвечает за настройки службы доставки:

И, наконец, за расчёт стоимости отвечает метод calculateConcrete (аналог Calculate из старых обработчиков доставки):

Обязательно кешируйте все данные, полученные от внешних API с ключом, содержащим все нужные параметры для расчёта. Как кешировать данные в D7 читайте в этой статье. Как сделать запрос читайте в статье HTTP-запросы в Битрикс D7.

Аргументом является объект класса BitrixSaleShipment, из которого можно получить объект заказа и нужные параметры расчёта:

Примечание: По информации ведущего разработчика Битрикс на данный момент (sale 16.0.5), пока не вышел обновлённый sale.order.ajax, в компоненте для совместимости в качестве $locationCode выступает ID местоположения, поэтому нужен такой временный костыль для получения кода местоположения:

Также доступен массив настроек службы доставки:

Метод calculateConcrete должен возвращать объект класса BitrixSaleDeliveryCalculationResult с доступными методами:

Если при расчёте возникла ошибка, в CalculationResult можно добавить ошибки расчёта (эта ошибка будет выведена при оформлении заказа):

Для проверки совместимости службы доставки и переданных параметров можно перегрузить метод isCompatible, например, самый простой вариант – проверить успешность расчёта, при наличии ошибок служба доставки просто не будет показываться при оформлении заказа:

Профили доставки

Для того, чтобы класс сервиса доставки мог поддерживать профили, добавляем в него поле и методы:

В методе getChildrenClassNames указали, что профили могут быть объектами класса YourNamespaceYetAnotherDeliveryProfile, создаём файл с классом и указываем его в обработчике, добавленном в начале статьи:

По указанному пути размещаем класс:

В остальном класс профиля является аналогом класса родительской службы.

Профиль также может иметь свою конфигурацию, например, профилям могут соответствовать разные тарифы доставки:

За расчёт стоимости также отвечает метод calculateConcrete:

Читайте также:  Как открыть файл хейк

В методах профиля можно получить не только настройки профиля, но и настройки родительской службы:

И также здесь можно проверять совместимость профилей (аналог метода Compability в старых службах доставки):

Во избежание случайных ошибок, при использовании профилей в методе расчёта родительского сервиса стоит выбрасывать исключение:

События расчёта доставки

После расчёта доставки вызывается событие onSaleDeliveryServiceCalculate модуля sale с параметрами RESULT – результат расчёта (BitrixSaleDeliveryCalculationResult) и SHIPMENT – отгрузка (BitrixSaleShipment). Можно использовать это событие для изменения результатов расчёта без вмешательства в код обработчика и без копирования стандартных обработчиков в свои пространства имён.

<
//If we alredy got all active services
static $isDataPrepared = false;
static $active > static $canHasProfiles = array();
static $canHasChildren = array();
static $DontHaveRestrictions >
if(is_array($restrictedIds))
<
$unPreparedRestricted > array_flip(
$restrictedIds
),
self::$cachedFields
);

$unPreparedRestricted > >
else
<
$unPreparedRestricted > >

if(!$isDataPrepared || !empty($unPreparedRestrictedIds))
<
$result = array();
self::initHandlers();

$params = array(
‘order’ => array(‘SORT’ =>’ASC’, ‘NAME’ => ‘ASC’),
‘filter’ => $filter
);

$params[‘runtime’] = array(
new BitrixMainEntityExpressionField(
‘RESTRICTIONS_EXIST’,
‘CASE WHEN EXISTS(‘.
‘SELECT 1 FROM b_sale_service_rstr SSR WHERE SSR.SERVICE_ ,
‘ID’
)
);

$params[‘select’] = array(‘*’, ‘RESTRICTIONS_EXIST’);

if(!empty($unPreparedRestrictedIds))
<
if($isDataPrepared)
<
$params[‘filter’][‘ > >
else
<
$params[‘filter’][] = array(
"LOGIC" => "OR",
"ID" => $unPreparedRestrictedIds,
‘RESTRICTIONS_EXIST’ => 0
);
>
>

$dbRes = Table::getList($params);
$profilesParents >
while($service = $dbRes->fetch())
<
if(!is_subclass_of($service["CLASS_NAME"], ‘BitrixSaleDeliveryServicesBase’))
continue;

if($service["CLASS_NAME"]::canHasChildren())
$canHasChildren[$service[" >
if ($service[‘CLASS_NAME’]::canHasProfiles())
$canHasProfiles[$service[" >
if($service["PARENT_ > $profilesParents ];

$result[$service[" >
if($service[‘ACTIVE’] == ‘Y’)
$active ];
>

foreach(array_diff_key($canHasProfiles, $profilesParentsIds) as $id => $tmp)
unset($result[$id]);

self::$cachedFields = self::$cachedFields + $result;
RestrictionsManager::prepareData(array_keys($result));
ExtraServicesManager::prepareData(array_keys($result));

if($service["CLASS_NAME"]::canHasChildren())
$canHasChildren[$stored >
if ($service[‘CLASS_NAME’]::canHasProfiles())
$canHasProfiles[$stored >
if($service[‘ACTIVE’] == ‘Y’)
$active > >
>

$active = array_intersect_key(self::$cachedFields, array_flip($activeIds));

if(is_array($restrictedIds))
<
$result = array_intersect_key($active, array_flip($DontHaveRestrictionsIds));

Читайте также:  Что можно залить эпоксидной смолой

if(!empty($restrictedIds))
$result = $result + array_intersect_key($active, array_flip($restrictedIds));
>
else
<
$result = $active;
>

/*
* Clean children if parent is not present in result.
* We mean that it doesn’t pass restrictions checks.
* Or it is not active.
*/

foreach($result as $id => $fields)
<
if(intval($fields[‘PARENT_ > continue;

if($calculatingOnly)
$result = array_diff_key($result, $canHasChildren, $canHasProfiles);

if(!empty($result))
sortByColumn($result, array("SORT" => SORT_ASC, "NAME" => SORT_ASC), ”, null, true);

Добавить комментарий

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

Adblock detector