Свой обработчик для службы доставки

8k
Алексей,
Свой обработчик для службы доставки
Свой обработчик для службы доставки

Расчет стоимости доставки курьером по своей формуле.

Расчет стоимости доставки курьером по своей формуле, кратко и по шагам

  1. Идем в настройки модуля интернет-магазин (/bitrix/admin/settings.php) и меняем путь к обработчикам

    Путь к собственным обработчикам расширенных систем доставки: /local/php_interface/include/sale_delivery/
  2. Создаем файл delivery_courier.php в /local/php_interface/include/sale_delivery/. Название должно содержать id доставки после нижнего подчеркивания, не знаю для чего, видимо тут так заведено :) Пишем в файл необходимый минимум:

    CModule::IncludeModule("sale");
    
    AddEventHandler("sale", "onSaleDeliveryHandlersBuildList", array('CFTeaCourier', 'Init'));
    
    class CFTeaCourier
    {
    	function Init()
    	{
    		return array(
    			
    			"SID" => "courier",
    			"NAME" => "Доставка курьером",
    			"DESCRIPTION" => "Доставка в течении дня",
    			"DESCRIPTION_INNER" => "Доставка в течении дня",
    			"BASE_CURRENCY" => COption::GetOptionString("sale", "default_currency", "RUB"),
    			"HANDLER" => __FILE__,
    
    			
    			"DBGETSETTINGS" => array("CFTeaCourier", "GetSettings"),
    			"DBSETSETTINGS" => array("CFTeaCourier", "SetSettings"),
    			"GETCONFIG" => array("CFTeaCourier", "GetConfig"),
    			"COMPABILITY" => array("CFTeaCourier", "Compability"),
    			"CALCULATOR" => array("CFTeaCourier", "Calculate"),
    
    			
    			"PROFILES" => array(
    				"courier" => array(
    					"TITLE" => "По городу",
    					"DESCRIPTION" => "Доставка в течении дня",
    					"RESTRICTIONS_WEIGHT" => array(0), // без ограничений
    					"RESTRICTIONS_SUM" => array(0), // без ограничений
    				),
    			)
    		);
    	}
    
    	
    	function GetConfig()
    	{
    		$arConfig = array(
    			"CONFIG_GROUPS" => array(),
    			"CONFIG" => array(),
    		);
    
    		return $arConfig;
    	}
    
    	
    	function SetSettings($arSettings)
    	{
    		foreach ($arSettings as $key => $value) {
    			if (strlen($value) > 0) {
    				$arSettings[$key] = doubleval($value);
    			} else {
    				unset($arSettings[$key]);
    			}
    		}
    
    		return serialize($arSettings);
    	}
    
    	
    	function GetSettings($strSettings)
    	{
    		return unserialize($strSettings);
    	}
    
    	
    	function Compability($arOrder, $arConfig)
    	{
    		return array('courier');
    	}
    
    	
    	function Calculate($profile, $arConfig, $arOrder, $STEP, $TEMP = false)
    	{
    		return array(
    			"RESULT" => "OK",
    			"VALUE" => 100
    		);
    	}
    }
  3. Переходим в список служб доставки (/bitrix/admin/sale_delivery_service_list.php) и добавляем новую автоматизированную доставку, обработчиком в которой будет созданная нами доставка (в delivery_courier.php)

    Получим то, что на скриншоте в шапке статьи

  4. Добавляем расчет доставки по формуле в метод Calculate. Я буду считать так: к заказу будет прибавляться такая сумма, что бы стоимость заказа была кратна 50 рублей, но минимум +20р.

    
    function Calculate($profile, $arConfig, $arOrder, $STEP, $TEMP = false)
    {
    	$sumResult = 0;
    	$sum = floatval($arOrder['PRICE']);
    	$o = $sum%50;
    	if ($o > 0)  {
    		$s = 50-$o;
    		if ($s < 20) {
    			$sumResult = $s+50;
    		} else {
    			$sumResult = $s;
    		}
    	}
    	return array(
    		"RESULT" => "OK",
    		"VALUE" => $sumResult
    	);
    }

    В итоге сумма заказа всегда "круглая"

    Свой обработчик для службы доставки
  5. На этом можно было бы закончить, но правильнее вынести значения "50" и "20" в настройки, а так же вынести текстовые фразы в lang файлы.

    Добавляем настройки в метод GetConfig:

    
    function GetConfig()
    {
    	$arConfig = array(
    		"CONFIG_GROUPS" => array(
    			"all" => 'Настройки стоимости',
    		),
    		"CONFIG" => array(
    			'DELIVERY_ROUND' => array(
    				"TYPE" => "STRING",
    				"DEFAULT" => "50",
    				"TITLE" => 'Округление суммы заказа',
    				"GROUP" => "all",
    			),
    			'DELIVERY_MIN_PRICE' => array(
    				"TYPE" => "STRING",
    				"DEFAULT" => "20",
    				"TITLE" => 'Минимальная стоимость доставки',
    				"GROUP" => "all",
    			),
    		),
    	);
    
    	return $arConfig;
    }
  6. Обновляем наш метод Calculate

    
    function Calculate($profile, $arConfig, $arOrder, $STEP, $TEMP = false)
    {
    	if ($arConfig["DELIVERY_ROUND"]["VALUE"] == 0) {
    		$arConfig["DELIVERY_ROUND"]["VALUE"] = 1;
    	}
    	$sumResult = 0;
    	$sum = floatval($arOrder['PRICE']);
    	$o = $sum%$arConfig["DELIVERY_ROUND"]["VALUE"];
    	if ($o > 0)  {
    		$s = $arConfig["DELIVERY_ROUND"]["VALUE"]-$o;
    		if ($s < $arConfig["DELIVERY_MIN_PRICE"]["VALUE"]) {
    			$sumResult = $s+$arConfig["DELIVERY_ROUND"]["VALUE"];
    		} else {
    			$sumResult = $s;
    		}
    	}
    	return array(
    		"RESULT" => "OK",
    		"VALUE" => $sumResult
    	);
    }

    Получаем:

Есть вопросы или нашли ошибку? Напишите комментарий (можно без регистрации), отвечать стараюсь быстро.

Опубликовано 21 апреля 2017 | Обновлено 13 октября 2017
делаюИМ, интернет-магазин, разработчику, API
Поделиться
Похожие статьи
Как сделать ИМ дружелюбнее. E-mail уведомления
Наверно это касается всех интернет-магазинов на 1С-Битрикс. Делаешь заказ и понеслось: заказ оформле...
Читать дальше » 0
Алексей,
Комментарии
❮…❯
Авторизуйтесь чтобы получать уведомления об ответе
11 мая 2020
Как можно добавить в расчет значение свойства заказа?
Алексей
11 мая 2020
Дмитрий,  как писал ниже, это пример для старого ядра, в нем нельзя получить данные из формы заказа. Ну или можно попробовать через сохранение полей в сессии.
11 мая 2020
Алексей, понял, спасибо
9 фев 2020
Как добавить в обработку рассчет еще и по габаритам?
Алексей
9 фев 2020
Дмитрий, это пример для старого ядра, информация устарела, не стоит её использовать. Для нового ядра в методе calculateConcrete можно получить заказ $order = $shipment->getCollection()->getOrder(); из него взять корзину $basket = $order->getBasket(); и из нее уже товары в которых будут параметры габаритов. Хотя наверно стоит взять товары не из заказа, а из отгрузки. Т.к. расчет доставки осуществляется для нее.
23 апр 2018
Добрый день, подскажите как в Compability($arOrder, $arConfig) в массив $arOrder добавить дополнительные поля заказа, такие как улица, дом (т.к. они туда не приходят)?
Алексей
23 апр 2018
Алексей, добрый день, если я правильно понял, то никак, т.к. эти поля еще не доступны (пользователь еще не создал заказ). Поля необходимые для рассчета (location и zip) система сохраняет сама. Но возможно я ошибаюсь. Можно сделать костыль и перед расчетом доставки сохранять поля формы в сессию, а уже в Compability брать поля из сессии :)
23 апр 2018
Алексей Будагов, спасибо за идею попробую, это какой-то звиздец, мне надо передать два свойства: улицу и дом, которые появляются после выбора способа доставки курьером и надо с учетом этих полей рассчитать доставку, уже все перерыл и пока ничего не получается, да в этом массиве приходит location и zip и все... Поменял в ядре \bitrix\modules\sale\general\delivery.php где формируется этот массив, но это же полная задница, все слетит при обновлении. Все пару свойств, а столько проблем ((
16 июн 2020
тест
16 июн 2020
Алексей, не знаю нашли ответ или нет. в Calculate можно вызвать $_REQUEST, в нем будут доступны все заполненные на момент расчета поля заказа
11 авг 2017
а как сделать чтобы вместо цены всегда была была надпись, к примеру: Стоимость доставки рассчитывается менеджером после оформления заказа.?
Алексей
11 авг 2017
Николай, нужно кастомизировать шаблон страницы заказа. Проще сделать бесплатную доставку, в описании добавить что "Стоимость доставки рассчитывается менеджером после оформления заказа." и скрыть цену (0 руб) с помощью css например.
Расчет стоимости доставки курьером по своей формуле.