Сообщение #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 не нужен
доработка сделана "на коленке", и прям точно не тестилась, но должна работать. Еще не делалось удобное управление этим в админке, но это доделать не сложно (при надобности).
На окай 2.1.6 PRO (от лайта не должен отличиться):
Нужно в api/Delivery.php добавить и указать где 1 - это id доставки для которой настраиваются цены, далее массив со стоимостью корзины от которой будет действовать новая стоимость доставки (стоимость доставки указывать в валюте по умолчанию)
[code]
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;
}
[/code]
В ajax/cart_ajax.php вставить изменения отмеченные комментом float_delivery_price
[code]$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));
}[/code]
В view/CartView.php вставить изменения отмеченные комментом float_delivery_price
[code]$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) {[/code]
и
[code]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());[/code]
Для окая 3.1.1: все изменения в директории Okay/Modules/OkayCMS/FloatDeliveryPrice/
создаем файл Extenders/FrontExtender.php
[spoiler]<?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;
}
}[/spoiler]
Init/Init.php [spoiler]<?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']
);
}
}
[/spoiler]
Вообще это должно быть архивом, который нужно закинуть в Modules.
Справедливости ради, я накидал модули со схожим функционалом и вариантом реализации, чтобы их можно было сравнить (это по просьбе [b]korshunov[/b]).
Не забыть еще для третьего окая установить этот модуль в разделе модулей))
UPD: обновил описание модуля для третьего окая по замечанию [b]korshunov[/b], там файл Init/services.php не нужен
Последний раз редактировалось
zyxer 31.10.2019, 09:11, всего редактировалось 1 раз.
Всё сказанное мной, является лично моим мнением, и не является официальной позицией OkayCMS