Установка расширенных ограничений на доставку в Magento 2

Опубликовано: 2017-05-17

В этой статье мы объясним, как скрыть способ доставки при выполнении определенных условий.

В некоторых сценариях владельцы магазинов могут захотеть ограничить варианты доставки, потому что:

  • товар имеет большие габариты и вес, поэтому не может быть отгружен стандартным способом,
  • условия хранения в замороженном виде не позволяют доставить товар в срок
  • доставка ограничена из-за местонахождения клиента (страна, регион, город )
  • C art Total не позволяет покупателю претендовать на какие-либо предложения по доставке,
  • и т.п.

Выбор вариантов доставки Magento по умолчанию не обеспечивает большой гибкости. Можно ограничить доставку только для определенных стран и регионов или когда общая сумма корзины меньше установленной суммы.

Если вам кажется, что этого недостаточно, читайте дальше.

Я расскажу вам, как создать свой собственный плагин, который позволит вам ограничить варианты доставки в соответствии с вашей бизнес-моделью, целями и условиями.

ПРИМЕЧАНИЕ

Я не буду описывать конкретные шаги, необходимые для создания расширения для Magento 2. Вы можете посмотреть, как это сделать, здесь или здесь.

Чтобы динамически отключать тот или иной метод доставки, нам нужен новый набор классов в нашем расширении — это 2 плагина . 1-й будет отвечать за проверку способа доставки, а 2-й будет их фильтровать.

Короче говоря, каждый метод, не прошедший проверку, будет помечен как « is_disabled », а на следующем шаге все методы « is_disabled » будут отфильтрованы и удалены из основного списка.

Давайте катиться.

* Поскольку подход, который я собираюсь описать, основан на принципах, используемых в расширении Shipping Suite , я буду использовать имя поставщика «Mageworx» и имя расширения «ShippingRules». ПРИМЕЧАНИЕ! Во избежание ошибок, вам нужно заменить их своими именами!

Для начала создадим плагин (класс), который будет использоваться для фильтрации. Вот как:

 > MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\Append 
 пространство имен MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

класс Добавить
{
    /**
     * @var \Magento\Checkout\Model\Session|\Magento\Backend\Model\Session\Quote
     */
    защищенная $сессия;

    /**
     * @param \Magento\Checkout\Model\Session $checkoutSession
     * @param \Magento\Backend\Model\Session\Quote $backendQuoteSession
     * @param \Magento\Framework\App\State $state
     * @internal param Сессия $session
     */
    публичная функция __construct(
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Backend\Model\Session\Quote $backendQuoteSession,
        \Magento\Framework\App\State $state
    ) {
        если ($state->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) {
            $this->session = $backendQuoteSession;
        } еще {
            $this->session = $checkoutSession;
        }
    }

    /**
     * Проверяйте каждый способ доставки перед добавлением.
     * Применить действие правил, если проверка прошла успешно.
     * Можно пометить некоторые правила как отключенные. Отключенные правила будут удалены в классе
     * @см. MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\GetAllRates
     * проверив значение этой метки в объекте ставки.
     *
     * ПРИМЕЧАНИЕ. Если у вас возникли проблемы с правилами и способами доставки, начните отладку отсюда.
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param \Magento\Quote\Model\Quote\Address\RateResult\AbstractResult|\Magento\Shipping\Model\Rate\Result $result
     * @возвратный массив
     */
    публичная функция beforeAppend($subject, $result)
    {
        if (!$result instanceof\Magento\Quote\Model\Quote\Address\RateResult\Method) {
            вернуть [$результат];
        }

        $filtableMethods = [
            'плоская ставка_плоская ставка',
            'ups_XDM',
            'ups_XPR',
            'ups_WXS',
            'carrier_method',
            // ... добавьте сюда свои коды методов
        ];
        $methodCode = $result->getCarrier() . '_' . $результат->getMethod();
        если (!in_array($methodCode, $filtableMethods)) {
            вернуть [$результат];
        }

        /** @var \Magento\Quote\Model\Quote $quote */
        $quote = $this->session->getQuote();
        $quoteItems = $quote->getAllItems();
        $heavyWeightFlag = ложь;
        foreach ($quoteItems как $item) {
            если ($item->getWeight() > 100) {
                $heavyWeightFlag = истина;
                Продолжать;
            }
        }

        если ($heavyWeightFlag == true) {
            $результат->setIsDisabled(true);
        }

        вернуть [$результат];
    }
}

Запускаем 3 проверки в теле нашего плагина:

1.

!$result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method

— гарантирует, что в точке входа мы получим то, что нам нужно: это экземпляр метода доставки. Если это не так, мы просто возвращаем его как есть.

2.

 !in_array($methodCode, $filtableMethods)

– далее проверяем, есть ли текущий метод в списке методов для фильтрации. Если это не так, мы возвращаем его как есть.

3.

 $heavyWeightFlag == истина

– последняя и основная проверка. Если флаг применяется к реальному значению, текущий метод отключается: $result->setIsDisabled(true);

Мы постараемся отфильтровать хотя бы один товар, добавленный в корзину и имеющий вес более 100 условных единиц (фунтов или килограммов).
Методы, доступные для фильтрации: «flatrate_flatrate», «ups_XDM», «ups_XPR», «ups_WXS», «carrier_method» . Они жестко запрограммированы и хранятся в массиве $filtableMethods .

Мы оперируем кодом, используя весь код метода доставки, который, как правило, состоит из кода перевозчика ($result->getCarrier()) и кода самого метода ($result->getMethod()), связанного с « _» .

Продукты, необходимые для проверки, берутся непосредственно из текущего коммерческого предложения клиента.
ПРИМЕЧАНИЕ

Небольшой фрагмент кода в конструкторе класса массива позволит вам определить котировку как во внешнем интерфейсе, так и в бэкэнде (при условии, что заказ был создан в панели администратора).

С помощью \Magento\Framework\App\State мы можем проверить, в какой области мы находимся в данный момент, и выбрать нужную цитату:
1. \Magento\Backend\Model\Session\Quote for Admin
2. \Magento\Checkout\Model\Session для внешнего интерфейса

Вот и все!

Теперь мы можем валидировать способы доставки и переходить к следующему этапу — созданию плагина для отключения недопустимых (по нашим условиям) способов доставки.

Вот как:

 > MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\GetAllRates 
 /**
 * Copyright 2016 MageWorx. Все права защищены.
 * Подробную информацию о лицензии см. в файле LICENSE.txt.
 */

пространство имен MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

класс GetAllRates
{

    /**
     * Отключить отмеченные тарифы на доставку.
     *
     * ПРИМЕЧАНИЕ. Если вы не видите некоторые тарифы на доставку, начните отладку отсюда. Сначала проверьте «is_disabled»
     * param в объекте тарифа доставки.
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param массив $результат
     * @возвратный массив
     */
    публичная функция afterGetAllRates($subject, $result)
    {
        foreach ($result as $key => $rate) {
            если ($rate->getIsDisabled()) {
                сбросить ($ результат [$ ключ]);
            }
        }

        вернуть $результат;
    }
}

Этот плагин используется для получения данных обо всех доступных способах доставки и проверки каждого из них. Если какой-то из методов имеет пометку «is_disabled» , мы просто исключаем его из списка, что позволяет нам видеть только те методы, которые соответствуют созданным в валидаторе условиям. Эти методы исключаются на любой странице веб-сайта, будь то расчетный блок доставки в корзине или страница оформления заказа.

Теперь, чтобы проверить, как работают наши плагины, нам нужно зарегистрировать их в файле:

> MageWorx/Правила доставки/etc/di.xml 
 <?xml версия="1.0"?>
<config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Shipping\Model\Rate\Result">
        <имя плагина="mageworx_shippingrules_update_rate_result"
                type="MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\Append"
                порядок сортировки = "10"
                отключено = "ложь"/>
        <plugin name="mageworx_shippingrules_update_disabled_or_enabled_rates"
                type="MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\GetAllRates"
                порядок сортировки = "11"
                отключено = "ложь"/>
    </тип>
</config>

ПРИМЕЧАНИЕ

Для наглядности плагины разделены на 2 разных класса. В обычном сценарии вы можете использовать только 1 класс для изменения 2 разных методов класса Magento\Shipping\Model\Rate\Result.

Почему это работает именно так?

Magento\Shipping\Model\Rate\Result — основной класс Magento 2, отвечающий за обработку методов доставки. Его метод getAllRates используется для получения списков способов доставки.

Между тем, добавление способов доставки обычно выполняется с помощью метода «добавить». Проверив методы при добавлении и исключив их из коллекции, мы можем получить список допустимых методов.

Сама проверка также может быть изменена.

В нашем расширении есть большой специальный класс, в котором хранится набор пользовательских фильтров с разными условиями (такими как store_id, customer_group_id, дата с/до, дни недели и т.д. ). у него также есть отдельный класс с набором действий, которые должны быть применены к способу доставки (например , включить или отключить его, переписать его стоимость в соответствии с другими условиями, добавить дополнительные расходы или скидки и т. д. ).

Результат 1-го плагина в отладке выглядит примерно так (для товара весом 1 единица):
1

Вот так это выглядит в корзине (ups_WXS пока доступен, т.к. лимит веса не превышен):

2

Однако, если вы измените вес товара на 101, этот способ доставки станет недоступен:

3

Он снова становится доступным, если вы исключили его из списка:
4

5

На кассе:

f3d3cac03678318af2d569d757fc7e79

ПРИМЕЧАНИЕ

Получить список всех доступных системных способов доставки прямо в коде можно следующим образом:

 /**
 * Возврат массива перевозчиков.
 * Если для параметра $isActiveOnlyFlag установлено значение true, будут возвращены только активные операторы связи.
 *
 * @param bool $isActiveOnlyFlag
 * @возвратный массив
 */
общедоступная функция getAvailableMethods ($ isActiveOnlyFlag = false)
{
    $carriers = $this->shippingConfig->getAllCarriers();
    foreach ($перевозчики как $carrierCode => $carrierModel) {
        if (!$carrierModel->isActive() && (bool)$isActiveOnlyFlag === true) {
            Продолжать;
        }
        $carrierMethods = $carrierModel->getAllowedMethods();
        если (!$carrierMethods) {
            Продолжать;
        }
        foreach ($carrierMethods as $methodCode => $methodTitle) {
            $methods[] = $carrierCode . '_' . $методКод;
        }
    }

    вернуть !пусто($методы) ? $методы: [];
}

Где $this->shippingConfig — это экземпляр класса Magento\Shipping\Model\Config . Используя этот код, вы можете создать исходную модель для селектора способов доставки в настройках расширения (таким образом, вам не придется хардкодить ее в плагине).

И последний по порядку но не по значимости.

Если вы не хотите создавать собственное расширение для отключения способов доставки, вы можете использовать наше решение Shipping Suite для Magento 2 .

Расширение позволяет исключить любой способ доставки, когда это необходимо, всего за пару кликов мыши.
1. Создайте новое правило доставки со следующим условием:

8

2. Выберите действие «Скрыть метод доставки» в списке и выберите, какие методы следует отключить:

9

ПРИМЕЧАНИЕ

Если вы не нашли атрибут «вес» в списке условий, проверьте, разрешено ли его использование в правилах акции:

10

Если у вас есть какие-либо вопросы или идеи по дальнейшему улучшению нашего расширения , пожалуйста, поделитесь своим мнением в разделе комментариев ниже.