在 Magento 2 中设置高级发货限制

已发表: 2017-05-17

在本文中,我们将解释如何在应用某些条件时隐藏运输方式。

在某些情况下,店主可能希望限制运输选项,因为:

  • 产品尺寸重量很大,因此不能以任何标准方式运输,
  • 冷冻储存条件不允许及时交付产品
  • 由于客户所在的位置(国家、地区、城市),运输受到限制
  • C art Total不允许购物者有资格获得任何运输优惠,
  • 等等

Magento 运输选项的默认选择不提供太大的灵活性。 只有在某些县和地区或购物车总数小于设定金额时,才可以限制发货。

如果您认为这还不够,请继续阅读。

我会告诉你如何创建你自己的插件,让你根据你的商业模式、目标和条件限制运输选项。

笔记

我不会介绍为 Magento 2 创建扩展所需的具体步骤。您可以在此处或此处查看如何执行此操作。

为了动态禁用任何给定的运输方式,我们需要在我们的扩展中添加一组新的类——它们是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 参数会话 $session
     */
    公共函数 __construct(
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Backend\Model\Session\Quote $backendQuoteSession,
        \Magento\Framework\App\State $state
    ) {
        if ($state->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) {
            $this->session = $backendQuoteSession;
        } 别的 {
            $this->session = $checkoutSession;
        }
    }

    /**
     * 在附加之前验证每种运输方式。
     * 如果验证成功,则应用规则操作。
     * 可以将某些规则标记为禁用。 禁用的规则将在课程中删除
     * @see MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\GetAllRates
     * 通过在 rate 对象中检查此标记的值。
     *
     * 注意:如果您对规则和运输方式有一些问题,请从这里开始调试。
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param \Magento\Quote\Model\Quote\Address\RateResult\AbstractResult|\Magento\Shipping\Model\Rate\Result $result
     * @return 数组
     */
    公共函数 beforeAppend($subject, $result)
    {
        if (!$result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method) {
            返回[$结果];
        }

        $filtableMethods = [
            'flatrate_flatrate',
            'ups_XDM',
            'ups_XPR',
            'ups_WXS',
            'carrier_method',
            // ... 在此处添加您的方法代码
        ];
        $methodCode = $result->getCarrier() 。 '_' 。 $result->getMethod();
        if (!in_array($methodCode, $filtableMethods)) {
            返回[$结果];
        }

        /** @var \Magento\Quote\Model\Quote $quote */
        $quote = $this->session->getQuote();
        $quoteItems = $quote->getAllItems();
        $heavyWeightFlag = 假;
        foreach ($quoteItems as $item) {
            if ($item->getWeight() > 100) {
                $heavyWeightFlag = true;
                继续;
            }
        }

        if ($heavyWeightFlag == true) {
            $result->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 
 /**
 * 版权所有 2016 MageWorx。 版权所有。
 * 有关许可证的详细信息,请参阅 LICENSE.txt。
 */

命名空间 MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

类 GetAllRates
{

    /**
     *禁用标记的运费。
     *
     * 注意:如果您看不到某些运费,请从这里开始调试。 首先,检查“is_disabled”
     * 运费对象中的参数。
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param 数组 $result
     * @return 数组
     */
    公共函数 afterGetAllRates($subject, $result)
    {
        foreach ($result as $key => $rate) {
            if ($rate->getIsDisabled()) {
                未设置($result[$key]);
            }
        }

        返回$结果;
    }
}

该插件用于获取所有可用的运输方式数据并检查它们中的每一个。 如果某些方法带有“is_disabled”标记,我们只需将其从列表中排除,这使我们只能看到那些与验证器中创建的条件相对应的方法。 这些方法在网站的任何页面上都被排除在外,无论是购物车中的估计运输块,还是结帐页面。

现在,要检查插件如何工作,我们需要在文件中注册它们:

> MageWorx/ShippingRules/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">
        <plugin name="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"
                禁用=“假”/>
    </类型>
</配置>

笔记

出于描述性原因,插件分为 2 个不同的类。 在一般情况下,您可以只使用 1 个类来修改 Magento\Shipping\Model\Rate\Result 类的 2 个不同方法。

为什么它会这样工作?

Magento\Shipping\Model\Rate\Result是 Magento 2 的主要类,负责处理运输方法。 它的getAllRates方法用于获取运输方式列表。

同时,添加运输方式通常是在“附加”方法的帮助下完成的。 在追加时验证方法,并从集合中排除它们,我们可以获得有效方法的列表。

验证本身也可以修改。

我们的扩展有一个很大的特殊类,它存储了一组具有不同条件的自定义过滤器(例如store_id、customer_group_id、日期从/到、星期几等)。 它还有一个单独的类,其中包含一组应应用于运输方法的操作(例如,启用或禁用它,根据不同的条件重写其成本,添加额外的成本或折扣等

调试中第一个插件的结果看起来有点像这样(对于重量为 1 单位的产品):
1

这是它在购物车中的样子(ups_WXS 仍然可用,因为没有超过重量限制):

2

但是,如果您将产品重量更改为 101,则此运输方式将不可用:

3

如果您将其从列表中排除,它将再次可用:
4

5

在结帐时:

f3d3cac03678318af2d569d757fc7e79

笔记

您可以通过以下方式在代码中获取所有可用系统运输方式的列表:

 /**
 * 返回运营商数组。
 * 如果 $isActiveOnlyFlag 设置为 true,将只返回活跃的运营商
 *
 * @param bool $isActiveOnlyFlag
 * @return 数组
 */
公共函数 getAvailableMethods($isActiveOnlyFlag = false)
{
    $carriers = $this->shippingConfig->getAllCarriers();
    foreach ($carriers as $carrierCode => $carrierModel) {
        if (!$carrierModel->isActive() && (bool)$isActiveOnlyFlag === true) {
            继续;
        }
        $carrierMethods = $carrierModel->getAllowedMethods();
        if (!$carrierMethods) {
            继续;
        }
        foreach ($carrierMethods as $methodCode => $methodTitle) {
            $methods[] = $carrierCode 。 '_' 。 $方法代码;
        }
    }

    返回 !empty($methods) ? $方法:[];
}

其中`$this->shippingConfig``Magento\Shipping\Model\Config`类的一个实例。 使用此代码,您可以在扩展设置中为运输方式选择器创建源模型(因此,您不必在插件中对其进行硬编码)。

最后但并非最不重要。

如果您不想创建自己的扩展来禁用运输方式,您可以使用我们针对 Magento 2 的运输套件解决方案

该扩展程序可让您在需要时排除任何运输方式,只需单击几下鼠标即可。
1. 创建一个新的运输规则,条件如下:

8

2. 在列表中选择隐藏运输方式操作,并选择应禁用哪些方式:

9

笔记

如果您在条件列表中没有找到“权重”属性,请检查它是否可以在促销规则中使用:

10

如果您对如何进一步改进我们的扩展有任何疑问或想法,请在下面的评论部分分享您的意见。