Пользовательские ограничения в службах доставки
У служб доставки, как и у платежных систем имеется возможность настраивать ограничения по ряду предустановленных условий. Таким образом, например, службу доставки можно настроить так, что она будет работать только для некоторого местоположения, только для заказов такой-то стоимости,веса или выбрать другие ограничения из стандартных ограничений. Иногда таких условий может не хватать. Для расширения стандартного набора ограничений своими собственными можно использовать событие onSaleDeliveryRestrictionsClassNamesBuildList
<?Bitrix\Main\EventManager::getInstance()->addEventHandler(
'sale',
'onSaleDeliveryRestrictionsClassNamesBuildList',
'myDeliveryFunction'
);?>
Одно из последних ограничений с которым я столкнулся - это ограничение по доступности РПО "Посылка онлайн" в пункте назначения. У Почты России существует соответсвующий тариф, который дешевле чем обычная посылка. Но данным способом можно отправлять не во все отделения. Для проверки нужно использовать запрос к тарификатору Почты России
У меня получилась следующая реализация данного ограничения:
<?php
namespace Gricuk\Sale\Delivery\Restrictions;
use Bitrix\Main\Data\Cache;
use Bitrix\Main\Web\HttpClient;
use Bitrix\Sale\Delivery\Restrictions;
use Bitrix\Sale\Internals\Entity;
/** Ограничение по доступности РПО Посылка онлайн в месте назначения
* Class RestrictRusPostOnline
* @package Gricuk\Sale\Delivery\Restrictions
*/
class RestrictRusPostOnline extends Restrictions\Base
{
public static function onSaleDeliveryRestrictionsClassNamesBuildList()
{
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
array(
'\Gricuk\Sale\Delivery\Restrictions\RestrictRusPostOnline' => '/local/php_interface/lib/Gricuk/Sale/Delivery/Restrictions/RestrictRusPostOnline.php',
)
);
}
public static function getClassTitle()
{
return 'посылка/курьер онлайн';
}
public static function getClassDescription()
{
return 'доставка будет доступна только там где можно расчитать стоимость доставки для РПО Посылка онлайн';
}
/** Выполняет проверку на доступность службы доставки
* @param $zip
* @param array $restrictionParams
* @param int $serviceId
* @return bool
*/
public static function check($zip, array $restrictionParams, $serviceId = 0)
{
if (!empty($restrictionParams["COUNTRY"]) && (strlen($zip) > 0)) {
return false;//Если не заполнен ZIP
}
try {
$url = "https://tariff.russianpost.ru/tariff/v1/calculate?json&object={$restrictionParams["RPO"]}&from={$restrictionParams["ZIP_FROM"]}&to={$zip}&weight=300";
$result = self::sendRequest($url);
if (!empty($result['errors'])) {
return false;//Если есть ошибки от Почты России
}
} catch (\Exception $e) {
return false;//Если не получилось сделать запрос
}
return true;
}
/**Преобразует $shipment в то что будет передано в первый параметр метода self::check
* @param Entity $shipment
* @return mixed|string|null
* @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\NotImplementedException
*/
protected static function extractParams(Entity $shipment)
{
/** @var \Bitrix\Sale\Order $order */
$order = $shipment->getCollection()->getOrder();
return $order->getPropertyCollection()->getDeliveryLocationZip()->getValue();
}
/** Возвращает массив параметров, описывающий ограничение
* @param int $entityId
* @return array
*/
public static function getParamsStructure($entityId = 0)
{
return array(
"ZIP_FROM" => array(
"TYPE" => "STRING",
"LABEL" => "Индекс места отправления",
),
"RPO" => array(
"TYPE" => "ENUM",
"LABEL" => "РПО",
"OPTIONS" => [
"23030" => "Посылка онлайн обыкновенная",
"24030" => "Курьер онлайн обыкновенный",
]
)
);
}
/**
* @param $url
* @return mixed
*/
protected static function sendRequest($url)
{
$result = false;
$cache = Cache::createInstance();
if ($cache->initCache(86400, md5($url))) {
$result = $cache->getVars();
} elseif ($cache->startDataCache()) {
try {
$httpClient = new HttpClient([
"socketTimeout" => 5,
"streamTimeout" => 10
]);
$resultString = $httpClient->get($url);
$result = json_decode($resultString, true);
$cache->endDataCache($result);
} catch (\Exception $e) {
}
}
return $result;
}
}