Бесплатная доставка курьером от определенной суммы

Здравствуйте. Пожалуйста, подскажите как реализовать данный функционал:
например, до 5000 тысяч доставка 300 рублей, от 5000 тысяч – бесплатно?

joxi.ru/zAN5Mxls156329
Александр Янк
02 августа 2015, 15:23
modx.pro
14
6 622
0

Комментарии: 27

Максим Кузнецов
02 августа 2015, 18:42
7
+7
Необходимо создать кастомный класс доставки:

1) Идем в core/components/minishop2/custom/delivery/ и создаем здесь свой пхп файл (допустим, mscustomdeliveryhandler.class.php) со следующим содержимым:

<?php

//Важно: при изменении названия файла, вот в этом месте также нужно изменить класс
class mscustomdeliveryhandler extends msDeliveryHandler{

	public function getCost(msOrderInterface $order, msDelivery $delivery, $cost = 0) {
        $cart = $this->ms2->cart->status();
        
	//условие начисление доставки
        if ($cart['total_cost'] < 5000) {
            $add_price = $delivery->get('price');
            if (preg_match('/%$/', $add_price)) {
                $add_price = str_replace('%', '', $add_price);
                $add_price = $cost / 100 * $add_price;
            }
            $cost += $add_price;
        }
        
        return $cost;
    }

}

2) Идем в настройки магазина -> Варианты доставки.
Создаем новый вариант «Доставка» (или редактируем исходный), после чего заполняем в «дополнительную стоимость» требуемое значение (300 рублей), в Класс-обработчик пишем название созданного файла — mscustomdeliveryhandler, заполняем доступные способы оплаты и ставим галочку напротив «включен».
    Александр Янк
    02 августа 2015, 22:33
    0
    Работает, спасибо Вам большое!
      Ivan
      09 сентября 2016, 09:48
      0
      У меня это работает, но цены отображаемые у доставки остаются прежними. Оформление заказа я добавил в корзину.
      Я добавил снипет при выводе цены доставки (снипет сверяет данные и если больше то выдает 0), и стало вроде работать, но если мы через AJAX удаляем товары из корзины, то цена доставки не меняется AJAX'ом, не подскажете как это реализовать?
        Роман Садоян
        09 сентября 2016, 10:55
        0
        Попробуйте этот вариант — github
        Только вчера сделал pull request в доку, Василий еще не проверил его.
        Может быть подойдет пример без доработок.
          Роман Садоян
          09 сентября 2016, 11:05
          +2
            Alex
            09 октября 2016, 21:00
            0
            ЗДравствуйте, Все делаю как написанно, но при выборе класса обработчика выдает 500 ошибку:( с чем связано? уже 3 часа над этим бьюсь. Помогите пожалуста
            Михаил
            17 ноября 2016, 17:50
            0
            Может и ошибаюсь, но как по мне пример неправильный.
            Судите сами:
            1. клас обработчика Вы предлагаете создать в каталоге "/core/components/minishop2custom";
            2. А вот регистрируете уже совсем по другому адресу "{core_path}components/minishop2/custom/msDeliveryHandlerMsk.class.php";

            Или я не прав?
              Роман Садоян
              17 ноября 2016, 18:37
              0
              Это опечатка, не более. Правильный путь — minishop2/custom
              Даже исправление уже есть github.com/bezumkin/Docs/commit/f4ced34c259317da649bafef39f550c0b4d6872c
                nekto
                07 декабря 2016, 19:08
                0
                С исправлениями тоже не работает, все пути проверил 10 раз — все равно ошибка 500.
                  Андрей
                  16 апреля 2017, 17:26
                  0
                  Добрый день. Вы смогли решить проблему с 500 ошибкой?
                    Игорь Терентьев
                    08 июня 2017, 17:42
                    2
                    +1
                    У меня получилось решить данную проблему.
                    Во первых нужно удалить ранее зарегистрированные сервисы:
                    if ($miniShop2 = $modx->getService('miniShop2')) {
                        $miniShop2->removeService('delivery', 'MskDelivery');
                    }
                    Создаем файл в core/components/minishop2/custom/delivery/msdeliverycourierhandler.class.php
                    <?php
                    if (!class_exists('msDeliveryHandler')) {
                    	require_once dirname(dirname(dirname(__FILE__))) . '/model/minishop2/msdeliveryhandler.class.php';
                    }
                    
                    class msDeliveryCourierHandler extends msDeliveryHandler implements msDeliveryInterface {
                        public function getCost(msOrderInterface $order, msDelivery $delivery, $cost = 0.0) {
                    
                            $freedeliverysumm = 90;
                            $cart = $order->ms2->cart->status();
                            $cart_cost = $cart['total_cost'];
                    
                            if($cart_cost > $freedeliverysumm){
                                return $cost;
                            }else{
                                $delivery_cost = parent::getCost($order, $delivery, $cost);
                                return $delivery_cost;
                            }
                        }
                    }
                    Регистрируем:
                    if ($miniShop2 = $modx->getService('miniShop2')) {
                        $miniShop2->addService('delivery', 'msDeliveryCourierHandler',
                            '{core_path}components/minishop2/custom/delivery/msdeliverycourierhandler.class.php'
                        );
                    }
                      Эрадж Шамс
                      02 марта 2018, 23:34
                      0
                      помогло, спасибо огромное.
                      Удалять надо не только в Console, но и про файл в core/components/minishop2/custom/delivery не забываем :))
                      Дмитрий
                      23 июня 2017, 00:25
                      0
                      Еще может быть проблема в указанном в самом файле пути.
                      Попробуйте заменить на:
                      /../model/minishop2/msdeliveryhandler.class.php
                      У меня 500-я ошибка была именно из-за того, что он не мог достучаться до msdeliveryhandler.class.php
            Роман
            03 апреля 2018, 20:06
            0
            Можете немного пояснить код:
            if ($cart['total_cost'] < 5000) {
            	$add_price = $delivery->get('price');
            	if (preg_match('/%$/', $add_price)) {
            		$add_price = str_replace('%', '', $add_price);
            		$add_price = $cost / 100 * $add_price; // Я это понять не могу 
            	}
            	$cost += $add_price;
            }
            У меня немного сложнее задача:
            Если сумма до 1,000 доставка = 350 рублей
            Если сумма больше 1,000 доставка = 250 рублей
            Если сумма больше 5,000 доставка = 0 рублей

            Спасибо!
              Максим Кузнецов
              03 апреля 2018, 20:34
              0
              Если наценка указана в процентах (присутствует соответствующий символ) — то считаем наценку и прибавляем, иначе просто прибавляем.

              В вашем случае достаточно свитчить $cart['total_cost'] и, в зависисимости от требуемых условий, приплюсовывать к $cost нужную сумму.
                Роман
                03 апреля 2018, 20:39
                0
                if ($cart['total_cost'] < 1000) {
                	$add_price = $delivery->get('price');
                	if (preg_match('/%$/', $add_price)) {
                		$add_price = str_replace('%', '', $add_price);
                		$add_price = $cost + 350 * $add_price;
                	}
                	$cost += $add_price;
                }
                if ($cart['total_cost'] > 1000) {
                	$add_price = $delivery->get('price');
                	if (preg_match('/%$/', $add_price)) {
                		$add_price = str_replace('%', '', $add_price);
                		$add_price = $cost + 250 * $add_price;
                	}
                	$cost += $add_price;
                }
                if ($cart['total_cost'] > 5000) {
                	$add_price = $delivery->get('price');
                	if (preg_match('/%$/', $add_price)) {
                		$add_price = str_replace('%', '', $add_price);
                		$add_price = $cost + 0 * $add_price;
                	}
                	$cost += $add_price;
                }
                Имеете в виду, так что ли?
                  Максим Кузнецов
                  03 апреля 2018, 20:50
                  1
                  +1
                  Нет, имею ввиду вот так:
                  switch (true) {
                  	case $cart['total_cost'] <= 1000:
                  		$cost += 350;
                  		
                  		break;
                  		
                  	case $cart['total_cost'] <= 5000:
                  		$cost += 250;
                  		
                  		break;	
                  		
                  	case $cart['total_cost'] > 5000:
                  		$cost += 0;
                  		
                  		break;	
                  }
                  
                  return $cost;
                    Роман
                    03 апреля 2018, 21:02
                    0
                    Спасибо, то что нужно!

                    Вопрос, получается что в настройках в админке (http://joxi.ru/8AndjoeUqloOVm) он вообще игнорирует, если мы собственным классом все указали?
                      Максим Кузнецов
                      03 апреля 2018, 22:40
                      +1
                      В текущем варианте — да (свой класс обработки события msDeliveryHandler).

                      А вообще, зависит от того, на каком этапе формирования цены вклиниться.
                      Sergey (Sentinel)
                      21 мая 2018, 23:17
                      0
                      А не могли бы Вы подсказать, если нужно только к определенной оплате подключить бесплатную доставку, как это сделать? К примеру к payment_1 и к payment_5
                        Александр
                        21 мая 2018, 23:25
                        +1
                        1) Создать класс в core/components/minishop2/custom/delivery (инструкция)
                        2) Зарегистрировать созданный класс (инструкция)
                        3) Указать в нужных методах доставки созданный класс
                          Максим Кузнецов
                          22 мая 2018, 00:31
                          +1
                          В плагине выше допишите условие по такому принципу:
                          if ($delivery->get('id') == 'нужный_айди') {
                          	//обнуление стоимости
                          }
                            Sergey (Sentinel)
                            23 ноября 2018, 21:25
                            0
                            Вывожу отдельно для доставки цену
                            {$deliveries[4].price}
                            как обратится к ней из msdeliveryhandlermsk.class.php?
                саша
                18 мая 2020, 01:27
                0
                что может быть не так?
                  Александр
                  18 мая 2020, 11:12
                  0
                  Название класса в файле custom/delivery/my…. Обратите внимание на строку
                  class mydeliveryhandler extends msDeliveryHandler{
                  Андрей
                  04 июня 2020, 12:25
                  0
                  Подскажите, а как привязать бесплатную доставку не к сумме а к количеству товара в корзине.
                  переписал класс так, но не работает:
                  <?php
                  if(!class_exists('msDeliveryInterface')) {
                      require_once dirname(dirname(dirname(__FILE__))) . '/model/minishop2/msdeliveryhandler.class.php';
                  }
                  
                  class msDeliveryHandlerCount extends msDeliveryHandler implements msDeliveryInterface{
                  
                      public function getCount(msOrderInterface $order, msDelivery $delivery, $count = 0) {
                  
                          $freedeliverycount = 50;
                          $cart = $order->ms2->cart->status();
                          $cart_count = $cart['total_count'];
                  
                          if($cart_count > $freedeliverycount){
                              return $count;
                          }else{
                              $delivery_count = parent::getCost($order, $delivery, $count);
                              return $delivery_count;
                          }
                      }
                  }
                    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                    27