когда нечего делать, а творческая душа требует реализации и хочется что-то сделать или написать, то я пишу сюда или делаю что-то на этом сайте. Кому интересна web-разработка, wordpress и то что рядом с этим, то заходите на мой сайт и читайте всякое...
Скидка на доставку в зависимости от суммы заказа Bitrix
Йо-йо! Сейчас я занимаюсь созданием одного очень интересного для меня сайта. Интересен он тем, что в нём есть довольно обширная система лояльности клиентов. Там есть и скидки по дисконтным картам, которые хранятся в 1С и несколько групп служб доставок на каждую из которые есть своя скидка. А ещё есть особая группа служб доставок на которые нужно дать особую скидку.
Задача
Есть несколько служб доставок, которые ограничены регионами. В том случае если сумма товаров с учётом скидок более 20000 рублей то если цена на доставку меньше или равно 10% от стоимости товаров то дать скидку на доставку 50%, а если больше то дать скидку на доставку равную 10% от стоимости товаров.
Давайте запишем в виде формулы
$basketPrice = цена товаров
$deliveryPrice = цена на доставку
$maxDeliveryPrice = $basketPrice * (10 / 100); максимально возможная скидка на доставку
$newValue = новое значение цены на доставку - то, что мы в итоге считаем
if($basketPrice > 20000){
$prepareValue = $deliveryPrice / 2; - 50% от стоимости доставки
if($prepareValue >= $maxDeliveryPrice){
$newValue = $deliveryPrice - $maxDeliveryPrice;
} else {
$newValue = $prepareValue;
}
}
Думаю, что сейчас вам стало понятно, что конкретно нужно вычислить.
Проблемы с которыми я столкнулся
Мы же говорим о битриксе, да… Так вот для того, чтобы применить новую цену на доставку нужно использовать событие «onSaleDeliveryServiceCalculate«, но фишка в том, что это событие не содержит объект корзины или заказа, чтобы из него получить сумму товаров. Я попробовал использовать метод для получения корзины:
Из статьи «Работа с корзиной в битрикс d7«, но увидел, что сильно замедлился расчёт стоимости доставки. По-этому решил делать иначе.
Решение
Мне понадобиться обработать 2 события: «OnSaleComponentOrderCreated» и «onSaleDeliveryServiceCalculate». На OnSaleComponentOrderCreated я получу цену на товары, а на onSaleDeliveryServiceCalculate я получу цену на доставку, посчитаю скидку и применю новую цену на доставку.
Получение цены товаров
// Получить цену товаров при создании корзины
AddEventHandler("sale", "OnSaleComponentOrderCreated", "xakpl_OnSaleComponentOrderCreated");
function xakpl_OnSaleComponentOrderCreated($order, &$arUserResult, $request, &$arParams, &$arResult, &$arDeliveryServiceAll, &$arPaySystemServiceAll){
$_SESSION['XAKPL_ORDER_BASKET_PRICE'] = $order->getBasket()->getPrice();
}
Я получил из событие объект заказа, из него объект корзины и цену на товары со скидками и наценками. Если вам будет нужно посчитать без учёта скидок и наценок то взамен getPrice() используйте getBasePrice().
Расчёт цена на доставку
// Изменить цену доставки после получения расчёта стоимости
AddEventHandler("sale", "onSaleDeliveryServiceCalculate", "xakpl_onSaleDeliveryServiceCalculate");
function xakpl_onSaleDeliveryServiceCalculate($result, $shipment, $deliveryID){
if(isset($_SESSION['XAKPL_ORDER_BASKET_PRICE']) )
{
$basketPrice = $_SESSION['XAKPL_ORDER_BASKET_PRICE'];
// Получаем цену доставки
$deliveryPrice = $result->getDeliveryPrice();
// Считаем максимально возможную цену на доставку
$maxDeliveryPrice = intval($basketPrice) * (10 / 100); // 10%
$newValue = $deliveryPrice;
if($basketPrice > 20000){
// Считаем цену на доставку со скидкой 50%
$prepareValue = $deliveryPrice / 2;
if($prepareValue >= $maxDeliveryPrice){
$newValue = $deliveryPrice - $maxDeliveryPrice;
} else {
$newValue = $prepareValue;
}
// Записываем новое значение цены на доставку
$shipment->setBasePriceDelivery($newValue, true);
}
}
}
Тут пояснения лишние, комментарии говорят сами за себя.
Применяем к списку служб доставки
На этом можно было бы остановиться, но нужно ещё учесть, что нужно применять скидку только к определённым службам доставки.
Для идентификации службы доставки у нас в событии есть переменная $deliveryID. Сам идентификатор нужной службы доставки мы можем найти в админке, в списке служб доставки. Ну и я не стал заморачиваться и получилось в итоге вот что:
// Изменить цену доставки после получения расчёта стоимости
AddEventHandler("sale", "onSaleDeliveryServiceCalculate", "xakpl_onSaleDeliveryServiceCalculate");
function xakpl_onSaleDeliveryServiceCalculate($result, $shipment, $deliveryID){
// Проверка id службы доставки
if($deliveryID == 61 || $deliveryID == 75 || $deliveryID == 67 || $deliveryID == 94 || $deliveryID == 76 ){
if(isset($_SESSION['XAKPL_ORDER_BASKET_PRICE']) )
{
$basketPrice = $_SESSION['XAKPL_ORDER_BASKET_PRICE'];
// Получаем цену доставки
$deliveryPrice = $result->getDeliveryPrice();
// Считаем максимально возможную цену на доставку
$maxDeliveryPrice = intval($basketPrice) * (10 / 100); // 10%
$newValue = $deliveryPrice;
if($basketPrice > 20000){
// Считаем цену на доставку со скидкой 50%
$prepareValue = $deliveryPrice / 2;
if($prepareValue >= $maxDeliveryPrice){
$newValue = $deliveryPrice - $maxDeliveryPrice;
} else {
$newValue = $prepareValue;
}
// Записываем новое значение цены на доставку
$shipment->setBasePriceDelivery($newValue, true);
}
}
}
}
Поддержи Xakplant
Я давно хочу развить видеоверсию, но пока этого не получается из-за нехватки ресурсов. Сейчас я собираю деньги на новый компьютер и микрофон. Поддержи xaklant и ты увидишь полезные видео быстрее.