在 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 单位的产品):
这是它在购物车中的样子(ups_WXS 仍然可用,因为没有超过重量限制):
但是,如果您将产品重量更改为 101,则此运输方式将不可用:
如果您将其从列表中排除,它将再次可用:
在结帐时:
笔记
您可以通过以下方式在代码中获取所有可用系统运输方式的列表:
/** * 返回运营商数组。 * 如果 $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. 创建一个新的运输规则,条件如下:
2. 在列表中选择隐藏运输方式操作,并选择应禁用哪些方式:
笔记
如果您在条件列表中没有找到“权重”属性,请检查它是否可以在促销规则中使用:
如果您对如何进一步改进我们的扩展有任何疑问或想法,请在下面的评论部分分享您的意见。