在 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

如果您對如何進一步改進我們的擴展有任何疑問或想法,請在下面的評論部分分享您的意見。