Как сделать разную стоимость доставки в зависимости от суммы заказа?

Правила раздела: faq.php?mode=okay
Модератор: Модераторы

impulze101
impulze101
Репутация: 0
Сообщения: 11
Зарегистрирован: 15.05.2018
С нами: 5 лет 10 месяцев

Сообщение #1 impulze101 » 28.10.2019, 13:23

Добрый день, уважаемые знатоки!
Есть такая потребность у меня (пример):
Если в корзине заказов на 100 грн. доставка 50 грн.
Если в корзине заказов на 200 грн. доставка 40 грн.
Если в корзине заказов на 250 грн. доставка 30 грн.
Если в корзине заказов на 300 грн. доставка бесплатно.

Подскажите, как это реализовать!

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #2 korshunov » 28.10.2019, 14:46

Быстро парой строк такого не сделать - поработать надо.
А вообще вопрос хороший и достоин того, чтобы его реализовать из коробки...

OkayCMS M
Администратор
Аватара
OkayCMS M
Администратор
Репутация: 216
Сообщения: 1627
Зарегистрирован: 12.11.2015
С нами: 8 лет 4 месяца
Сайт Skype

Сообщение #3 OkayCMS » 28.10.2019, 15:05

korshunov писал(а):Быстро парой строк такого не сделать - поработать надо.
А вообще вопрос хороший и достоин того, чтобы его реализовать из коробки...

В коробке такое вряд-ли будет. Вариант с "Доставка бесплатна от..." как по мне достаточно хорош для коробки. Остальное - это уже индивидуальные расширения под клиента.

impulze101
impulze101
Репутация: 0
Сообщения: 11
Зарегистрирован: 15.05.2018
С нами: 5 лет 10 месяцев

Сообщение #4 impulze101 » 28.10.2019, 17:41

korshunov писал(а):Быстро парой строк такого не сделать - поработать надо.
А вообще вопрос хороший и достоин того, чтобы его реализовать из коробки...

Возможно подскажите с кодом без поддержки бэкенда? Костыль так костыль! :-)

zyxer M
zyxer M
Возраст: 32
Репутация: 77
Сообщения: 419
Зарегистрирован: 03.02.2016
С нами: 8 лет 1 месяц
Откуда: Днепр

Сообщение #5 zyxer » 28.10.2019, 19:57

Версия какая?
Всё сказанное мной, является лично моим мнением, и не является официальной позицией OkayCMS

impulze101
impulze101
Репутация: 0
Сообщения: 11
Зарегистрирован: 15.05.2018
С нами: 5 лет 10 месяцев

Сообщение #6 impulze101 » 28.10.2019, 20:55

zyxer писал(а):Версия какая?

Lite 2.1.6

zyxer M
zyxer M
Возраст: 32
Репутация: 77
Сообщения: 419
Зарегистрирован: 03.02.2016
С нами: 8 лет 1 месяц
Откуда: Днепр

Сообщение #7 zyxer » 30.10.2019, 11:54

доработка сделана "на коленке", и прям точно не тестилась, но должна работать. Еще не делалось удобное управление этим в админке, но это доделать не сложно (при надобности).

На окай 2.1.6 PRO (от лайта не должен отличиться):
Нужно в api/Delivery.php добавить и указать где 1 - это id доставки для которой настраиваются цены, далее массив со стоимостью корзины от которой будет действовать новая стоимость доставки (стоимость доставки указывать в валюте по умолчанию)

Код: Выделить всё

public $delivery_prices = array(
    1 => array(
        '20000' => 200,
        '35000' => 100,
    )
);

public function get_delivery_price($delivery, $cart) {
    if (isset($this->delivery_prices[$delivery->id])) {
        $delivery_prices = $this->delivery_prices[$delivery->id];
        krsort($delivery_prices, SORT_NUMERIC);
        foreach ($delivery_prices as $discount_from=>$delivery_price) {
            if ($cart->total_price >= $discount_from) {
                $delivery->price = $delivery_price;
                break;
            }
        }
    }
    return $delivery->price;
}

В ajax/cart_ajax.php вставить изменения отмеченные комментом float_delivery_price

Код: Выделить всё

$deliveries = $okay->delivery->get_deliveries(array('enabled'=>1));
$okay->design->assign('deliveries', $deliveries);
foreach($deliveries as $delivery) {
    /*float_delivery_price*/
    $delivery->price = $okay->delivery->get_delivery_price($delivery, $cart);
    /*/float_delivery_price*/
    $delivery->payment_methods = $okay->payment->get_payment_methods(array('delivery_id'=>$delivery->id, 'enabled'=>1));
}


В view/CartView.php вставить изменения отмеченные комментом float_delivery_price

Код: Выделить всё

$order = $this->orders->get_order($order_id);

// Стоимость доставки
$delivery = $this->delivery->get_delivery($order->delivery_id);
/*float_delivery_price*/
$delivery->price = $this->delivery->get_delivery_price($delivery, $cart);
/*/float_delivery_price*/
if(!empty($delivery) && $delivery->free_from > $order->total_price) {

и

Код: Выделить всё

public function fetch() {
    // Способы доставки
    $deliveries = $this->delivery->get_deliveries(array('enabled'=>1));
    foreach($deliveries as $delivery) {
        /*float_delivery_price*/
        $delivery->price = $this->delivery->get_delivery_price($delivery, $this->cart->get_cart());
        /*/float_delivery_price*/
        $delivery->payment_methods = $this->payment->get_payment_methods(array('delivery_id'=>$delivery->id, 'enabled'=>1));
    }
    $this->design->assign('all_currencies', $this->money->get_currencies());


Для окая 3.1.1: все изменения в директории Okay/Modules/OkayCMS/FloatDeliveryPrice/
создаем файл Extenders/FrontExtender.php
Спойлер
<?php


namespace Okay\Modules\OkayCMS\FloatDeliveryPrice\Extenders;


use Okay\Core\Cart;
use Okay\Core\EntityFactory;
use Okay\Core\FrontTranslations;
use Okay\Core\Modules\Extender\ExtensionInterface;
use Okay\Core\Money;
use Okay\Core\ServiceLocator;
use Okay\Entities\CurrenciesEntity;

class FrontExtender implements ExtensionInterface
{

private $deliveryPrices = [
1 => [
'1000' => 200,
'2000' => 100,
]
];

private function getDeliveryPrice($delivery, $totalPrice)
{
if (isset($this->deliveryPrices[$delivery->id])) {
$deliveryPrices = $this->deliveryPrices[$delivery->id];
krsort($deliveryPrices, SORT_NUMERIC);
foreach ($deliveryPrices as $discountFrom=>$deliveryPrice) {
if ($totalPrice >= $discountFrom) {
$delivery->price = $deliveryPrice;
break;
}
}
}
return $delivery->price;
}

/**
* @param $deliveries
* @param $cart
* @return array
* @throws \Exception
*
* Метод проходится по способам доставки, и подменяет текст стоимости доставки.
*
*/
public function getCartDeliveriesList($deliveries, $cart)
{
$SL = new ServiceLocator();

/** @var FrontTranslations $frontTranslations */
$frontTranslations = $SL->getService(FrontTranslations::class);

/** @var EntityFactory $entityFactory */
$entityFactory = $SL->getService(EntityFactory::class);

/** @var CurrenciesEntity $currenciesEntity */
$currenciesEntity = $entityFactory->get(CurrenciesEntity::class);
$currency = $currenciesEntity->get((int)$_SESSION['currency_id']);

/** @var Money $money */
$money = $SL->getService(Money::class);

foreach ($deliveries as $delivery) {
if ($cart->total_price < $delivery->free_from && $delivery->price>0) {
$delivery->price = $this->getDeliveryPrice($delivery, $cart->total_price);
$delivery->delivery_price_text = $money->convert($delivery->price) . ' ' . $currency->sign;
if ($delivery->separate_payment) {
$delivery->delivery_price_text .= ', ' . $frontTranslations->getTranslation('cart_paid_separate');
}
}
}
return $deliveries;
}

/**
* @param $result
* @param $delivery
* @param $order
* @return mixed
*
* Обновляем стоимость доставки, которая пришла из API.
* Важно не забывать что экстендеры работают всегда, и важно проверить что выбран именно наш способ доставки
*/
public function setCartDeliveryPrice($result, $delivery, $order)
{
$SL = new ServiceLocator();
$cart = $SL->getService(Cart::class);
$result['delivery_price'] = $this->getDeliveryPrice($delivery, $cart->get()->total_price);
return $result;
}

}

Init/Init.php
Спойлер
<?php


namespace Okay\Modules\OkayCMS\FloatDeliveryPrice\Init;


use Okay\Core\Modules\AbstractInit;
use Okay\Helpers\DeliveriesHelper;
use Okay\Modules\OkayCMS\FloatDeliveryPrice\Extenders\FrontExtender;

class Init extends AbstractInit
{

public function install()
{
$this->setModuleType(MODULE_TYPE_DELIVERY);
}

public function init()
{

$this->registerChainExtension(
['class' => DeliveriesHelper::class, 'method' => 'prepareDeliveryPriceInfo'],
['class' => FrontExtender::class, 'method' => 'setCartDeliveryPrice']
);

$this->registerChainExtension(
['class' => DeliveriesHelper::class, 'method' => 'getCartDeliveriesList'],
['class' => FrontExtender::class, 'method' => 'getCartDeliveriesList']
);

}
}

Вообще это должно быть архивом, который нужно закинуть в Modules.
Справедливости ради, я накидал модули со схожим функционалом и вариантом реализации, чтобы их можно было сравнить (это по просьбе korshunov).
Не забыть еще для третьего окая установить этот модуль в разделе модулей))

UPD: обновил описание модуля для третьего окая по замечанию korshunov, там файл Init/services.php не нужен
Последний раз редактировалось zyxer 31.10.2019, 09:11, всего редактировалось 1 раз.
Всё сказанное мной, является лично моим мнением, и не является официальной позицией OkayCMS

impulze101
impulze101
Репутация: 0
Сообщения: 11
Зарегистрирован: 15.05.2018
С нами: 5 лет 10 месяцев

Сообщение #8 impulze101 » 30.10.2019, 13:13

[quote="zyxer"]

Огромное спасибо. Вы продели большую работу! Буду тестить.


Название раздела: Вопросы по работе с OkayCMS
Правила раздела: faq.php?mode=okay

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения

   

Вернуться в «Вопросы по работе с OkayCMS»

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 26 гостей