Magento 2 で高度な配送制限を設定する

公開: 2017-05-17

この記事では、特定の条件が適用されたときに配送方法を非表示にする方法について説明します。

一部のシナリオでは、店舗の所有者が配送オプションを制限したい場合があります。理由は次のとおりです。

  • 製品の寸法重量が大きいため、標準的な方法で出荷することはできません。
  • 冷凍保管のため納期が間に合わない
  • お客様の所在地(国、地域、都市)により配送が制限されます
  • the 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 
 namespace MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

クラス追加
{
    /**
     * @var \Magento\Checkout\Model\Session|\Magento\Backend\Model\Session\Quote
     */
    保護された $session;

    /**
     * @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
    ) {
        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 配列
     */
    public function beforeAppend($subject, $result)
    {
        if (!$result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method) {
            [$結果] を返します。
        }

        $filterableMethods = [
            '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 = false;
        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 標準単位 (ポンドまたはキロ) を超える製品を少なくとも 1 つ除外しようとします。
フィルタリングに使用できるメソッドは、'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をご覧ください。
 */

namespace MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result;

クラス GetAllRates
{

    /**
     * マークされた配送料を無効にします。
     *
     * 注: 送料の一部が表示されない場合は、ここからデバッグを開始してください。 まず「is_disabled」にチェックを入れる
     * 配送料オブジェクトのパラメーター。
     *
     * @param \Magento\Shipping\Model\Rate\Result $subject
     * @param 配列 $結果
     * @return 配列
     */
    パブリック関数 afterGetAllRates($subject, $result)
    {
        foreach ($result as $key => $rate) {
            if ($rate->getIsDisabled()) {
                unset($結果[$キー]);
            }
        }

        $結果を返します。
    }
}

このプラグインは、利用可能なすべての配送方法データを取得し、それぞれをチェックするために使用されます。 一部のメソッドに「is_disabled」マークが付いている場合は、リストから除外するだけで、バリデーターで作成された条件に対応するメソッドのみを表示できます。 これらのメソッドは、ショッピング カートの推定配送ブロックやチェックアウト ページなど、Web サイトのどのページでも除外されます。

プラグインがどのように機能するかを確認するには、プラグインをファイルに登録する必要があります。

> 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">
        <プラグイン名="mageworx_shippingrules_update_rate_result"
                type="MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\Append"
                sortOrder="10"
                無効="偽"/>
        <プラグイン名="mageworx_shippingrules_update_disabled_or_enabled_rates"
                type="MageWorx\ShippingRules\Model\Plugin\Shipping\Rate\Result\GetAllRates"
                sortOrder="11"
                無効="偽"/>
    </タイプ>
</config>

ノート

説明上の理由から、プラグインは 2 つの異なるクラスに分けられます。 通常のシナリオでは、1 つのクラスだけを使用して、クラス Magento\Shipping\Model\Rate\Result の 2 つの異なるメソッドを変更できます。

なぜこのように機能するのですか?

Magento\Shipping\Model\Rate\Resultは、配送方法の処理を担当するメインの Magento 2 クラスです。 そのgetAllRatesメソッドは、配送方法のリストを取得するために使用されます。

一方、配送方法の追加は通常、'append' メソッドを使用して行います。 追加中にメソッドを検証し、それらをコレクションから除外すると、有効なメソッドのリストを取得できます。

検証自体も変更できます。

私たちの拡張機能には、さまざまな条件 ( store_id、customer_group_id、開始日/終了日、曜日など) を持つカスタム フィルターのコレクションを格納する大きな特別なクラスがあります。 また、配送方法に適用するアクションのコレクションを含む別のクラスもあります (たとえば、配送方法を有効または無効にする、さまざまな条件に応じてコストを書き換える、追加のコストや割引を追加するなど)。

デバッグでの最初のプラグインの結果は、次のようになります (重量が 1 ユニットの製品の場合)。
1

これは、ショッピング カートでどのように表示されるかです (重量制限を超えていないため、ups_WXS は引き続き使用できます)。

2

ただし、商品の重量を 101 に変更すると、この配送方法は利用できなくなります。

3

リストから除外すると、再び利用可能になります。
4

5

チェックアウト時:

f3d3cac03678318af2d569d757fc7e79

ノート

次の方法で、利用可能なすべてのシステム配送方法のリストをコードで直接取得できます。

 /**
 * キャリアの配列を返します。
 * $isActiveOnlyFlag が true に設定されている場合、アクティブなキャリアのみが返されます
 *
 * @param bool $isActiveOnlyFlag
 * @return 配列
 */
public function 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 . 「_」。 $methodCode;
        }
    }

    return !empty($methods) ? $メソッド: [];
}

`$this->shippingConfig`はクラス`Magento\Shipping\Model\Config`のインスタンスです。 このコードを使用して、拡張機能の設定で配送方法のセレクターのソース モデルを作成できます (したがって、プラグインでハードコードする必要はありません)。

最後になりましたが、重要なことです。

配送方法を無効にする独自の拡張機能を作成したくない場合は、Magento 2 の配送スイート ソリューションを使用できます。

この拡張機能を使用すると、マウスを数回クリックするだけで、必要なときにいつでも配送方法を除外できます。
1. 次の条件で新しい配送ルールを作成します。

8

2. リストで [配送方法を非表示] アクションを選択し、無効にする方法を選択します。

9

ノート

条件のリストに「重量」属性が見つからない場合は、プロモーション ルールでの使用が有効になっているかどうかを確認します。

10

拡張機能をさらに改善する方法について質問やアイデアがある場合は、下のコメント セクションで意見を共有してください。