Magento 2-支払い方法に依存する割引が機能しない


13

Magento 2 管理>マーケティング>プロモーション>カート価格ルールに移動し、新しいルールを作成します:銀行振込支払い:

タブ規則情報:

  • ルール名:銀行振込
  • ステータス:アクティブ
  • ウェブサイト:メインのウェブサイト
  • 顧客グループ:すべて選択
  • クーポン:クーポンなし
  • 顧客ごとの使用:0
  • から:空白
  • 宛先:空白
  • 優先度:0
  • RSSフィードで公開:いいえ

条件タブ:

  • これらの条件がすべてTRUEの場合:
    • 支払方法は銀行振込です

[アクション]タブ:

  • 適用:製品価格の割引率
  • 割引額:2
  • 最大数量割引の適用対象:0
  • 割引数量ステップ(購入X):0
  • 配送料に適用:いいえ
  • 後続のルールを破棄:いいえ
  • 送料無料:いいえ
  • 次の条件に一致するカートアイテムにのみルールを適用します(すべてのアイテムを空白のままにします):なし

次に、銀行振込の支払い方法を有効にし、チェックアウトページに移動し、[銀行振込の支払い]をクリックしますが、割引率は注文の概要に表示されません。

ここに画像の説明を入力してください

アドバイスをください。Magento 2の支払い方法をどのように割引できますか。Magento1の場合、うまく機能します。

どうもありがとう


ここにルールを投稿できますか?
コアトゥオンディン16

ルールを投稿しました。チェックしてくれますか?
グエンホン・クアン

ルールの有効化日を追加してみますか?
コアトゥオンディン16

銀行振込支払いオプションをクリックしたとき、私はオーダー要約にルールが、まだ何の開始日が起こるを追加しよう
グエンホン・クアン

1
ありがとう。ここに問題を投稿しました:github.com/magento/magento2/issues/5937
グエンホン・クアン

回答:


11

Magento 2では、お支払い方法を選択したときに見積もりに保存されないため、このルールは機能しません。また、支払い方法を選択するときに合計をリロードしません。残念ながら、この問題を解決するにはカスタムモジュールを作成する必要があります。

新しいモジュールの作成に必要なファイルは4つだけです。

  1. app / code / Namespace / ModuleName / etc / frontend / routes.xml

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
        <router id="standard">
            <route id="namespace_modulename" frontName="namespace_modulename">
                <module name="Namespace_ModuleName"/>
            </route>
        </router>
    </config>

    これにより、モジュールの新しいコントローラーが定義されます。

  2. app / code / Namespace / ModuleName / Controller / Checkout / ApplyPaymentMethod.php

    <?php
    
    namespace Namespace\ModuleName\Controller\Checkout;
    
    class ApplyPaymentMethod extends \Magento\Framework\App\Action\Action
    {
        /**
         * @var \Magento\Framework\Controller\Result\ForwardFactory
         */
        protected $resultForwardFactory;
    
        /**
         * @var \Magento\Framework\View\LayoutFactory
         */
        protected $layoutFactory;
    
        /**
         * @var \Magento\Checkout\Model\Cart
         */
        protected $cart;
    
        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\LayoutFactory $layoutFactory
         * @param \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory,
            \Magento\Framework\View\LayoutFactory $layoutFactory,
            \Magento\Checkout\Model\Cart $cart
        ) {
            $this->resultForwardFactory = $resultForwardFactory;
            $this->layoutFactory = $layoutFactory;
            $this->cart = $cart;
    
            parent::__construct($context);
        }
    
        /**
         * @return \Magento\Framework\Controller\ResultInterface
         */
        public function execute()
        {
            $pMethod = $this->getRequest()->getParam('payment_method');
    
            $quote = $this->cart->getQuote();
    
            $quote->getPayment()->setMethod($pMethod['method']);
    
            $quote->setTotalsCollectedFlag(false);
            $quote->collectTotals();
            $quote->save();
        }
    }

    このファイルは、選択した支払い方法を見積に保存するためのコントローラーアクションを作成します

  3. app / code / Namespace / ModuleName / view / frontend / requirejs-config.js

    var config = {
        map: {
            '*': {
                'Magento_Checkout/js/action/select-payment-method':
                    'Namespace_ModuleName/js/action/select-payment-method'
            }
        }
    };

    このファイルはオーバーライドすることができます Magento_Checkout/js/action/select-payment-methodできます

  4. app / code / Namespace / ModuleName / view / frontend / web / js / action / select-payment-method.js

    define(
        [
            'Magento_Checkout/js/model/quote',
            'Magento_Checkout/js/model/full-screen-loader',
            'jquery',
            'Magento_Checkout/js/action/get-totals',
        ],
        function (quote, fullScreenLoader, jQuery, getTotalsAction) {
            'use strict';
            return function (paymentMethod) {
                quote.paymentMethod(paymentMethod);
    
                fullScreenLoader.startLoader();
    
                jQuery.ajax('/namespace_modulename/checkout/applyPaymentMethod', {
                    data: {payment_method: paymentMethod},
                    complete: function () {
                        getTotalsAction([]);
                        fullScreenLoader.stopLoader();
                    }
                });
    
            }
        }
    );

    ajaxリクエストを送信して、支払い方法を保存し、カートの合計をリロードします。

PSコードの一部は、Magento 2の支払い手数料拡張から取得されました。


1
MagestyAppsに感謝します。私はあなたの指示に従って新しいモジュールを作成しました。ただし、最後にこの問題が発生しましたjquery.js 192.168.41.59/phoenix_checkout/checkout/applyPaymentMethod 404(Not Found)。以前にこのバグを取得しましたか?
グエンホン・クアン

1
本当にうまくいきます。MagestyAppsに感謝します。このソリューションは完璧です。
グエンホン・クアン

それは機能します、あなたは私の時間を節約しました。ありがとうございました:)
サミールバヤニ

素晴らしいもの、THX。支払い方法のカート価格ルールは削除されました(github.com/magento/magento2/commit/…)。「 'payment_method' => __( 'Payment Method')」という行を再度追加しました。支払い方法のカート価格ルールを作成できるようになりました。
-DaFunkyAlex

これは大いに役立ちました。ありがとう。+1 :)
Shoaib Munir

3

Magento 2.2では、MagestyAppsの回答を得ることができませんでした。いくつかの追加ファイルを追加する必要がありました。なぜなら:

  • 支払方法のカート価格ルールが管理者から削除されました(DaFunkyAlexが指摘)。
  • Magento 2.2では、メソッド\Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address\PaymentMethod::generateFilterText(実際にはにフォールバックする\Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address::generateFilterText)がデータを予期していたため、割引は見積もりに適用されていませんでしたpayment_method見積もりが設定されることを。
  • MagestyAppsの回答からコントローラーを変更payment_methodして見積もりアドレスにデータを設定しても、見積もりが永続化されないため、見積もりが注文になったときには機能しませんでしたpayment_method

次のモジュールがうまく機能しました(MagestyAppsの回答のおかげで、その上に基づいていました):

registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_SalesRulesPaymentMethod',
    __DIR__
);

etc / module.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_SalesRulesPaymentMethod" setup_version="1.0.0">
        <sequence>
            <module name="Magento_AdvancedSalesRule"/>
            <module name="Magento_Checkout"/>
            <module name="Magento_SalesRules"/>
            <module name="Magento_Quote"/>
        </sequence>
    </module>
</config>

etc / di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address\PaymentMethod"
                type="Vendor\SalesRulesPaymentMethod\Model\Rule\Condition\FilterTextGenerator\Address\PaymentMethod"/>
    <type name="Magento\SalesRule\Model\Rule\Condition\Address">
        <plugin name="addPaymentMethodOptionBack" type="Vendor\SalesRulesPaymentMethod\Plugin\AddPaymentMethodOptionBack" />
    </type>
</config>

etc / frontend / routes.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="salesrulespaymentmethod" frontName="salesrulespaymentmethod">
            <module name="Vendor_SalesRulesPaymentMethod"/>
        </route>
    </router>
</config>

Controller / Checkout / ApplyPaymentMethod.php

<?php

namespace Vendor\SalesRulesPaymentMethod\Controller\Checkout;

use Magento\Checkout\Model\Cart;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\Result\ForwardFactory;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\View\LayoutFactory;
use Magento\Quote\Model\Quote;

class ApplyPaymentMethod extends Action
{
    /**
     * @var ForwardFactory
     */
    protected $resultForwardFactory;

    /**
     * @var LayoutFactory
     */
    protected $layoutFactory;

    /**
     * @var Cart
     */
    protected $cart;

    /**
     * @param Context $context
     * @param LayoutFactory $layoutFactory
     * @param ForwardFactory $resultForwardFactory
     */
    public function __construct(
        Context $context,
        ForwardFactory $resultForwardFactory,
        LayoutFactory $layoutFactory,
        Cart $cart
    ) {
        $this->resultForwardFactory = $resultForwardFactory;
        $this->layoutFactory = $layoutFactory;
        $this->cart = $cart;

        parent::__construct($context);
    }

    /**
     * @return ResponseInterface|ResultInterface|void
     * @throws \Exception
     */
    public function execute()
    {
        $pMethod = $this->getRequest()->getParam('payment_method');

        /** @var Quote $quote */
        $quote = $this->cart->getQuote();

        $quote->getPayment()->setMethod($pMethod['method']);

        $quote->setTotalsCollectedFlag(false);
        $quote->collectTotals();

        $quote->save();
    }
}

モデル/ルール/条件/FilterTextGenerator/Address/PaymentMethod.php

<?php

namespace Vendor\SalesRulesPaymentMethod\Model\Rule\Condition\FilterTextGenerator\Address;

use Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address\PaymentMethod as BasePaymentMethod;

class PaymentMethod extends BasePaymentMethod
{
    /**
     * @param \Magento\Framework\DataObject $quoteAddress
     * @return string[]
     */
    public function generateFilterText(\Magento\Framework\DataObject $quoteAddress)
    {
        $filterText = [];
        if ($quoteAddress instanceof \Magento\Quote\Model\Quote\Address) {
            $value = $quoteAddress->getQuote()->getPayment()->getMethod();
            if (is_scalar($value)) {
                $filterText[] = $this->getFilterTextPrefix() . $this->attribute . ':' . $value;
            }
        }

        return $filterText;
    }
}

Plugin / AddPaymentMethodOptionBack.php

<?php

namespace Vendor\SalesRulesPaymentMethod\Plugin;

use Magento\SalesRule\Model\Rule\Condition\Address;

class AddPaymentMethodOptionBack
{
    /**
     * @param Address $subject
     * @param $result
     * @return Address
     */
    public function afterLoadAttributeOptions(Address $subject, $result)
    {
        $attributeOption = $subject->getAttributeOption();
        $attributeOption['payment_method'] = __('Payment Method');

        $subject->setAttributeOption($attributeOption);

        return $subject;
    }
}

view / frontend / requirejs-config.js

var config = {
    map: {
        '*': {
            'Magento_Checkout/js/action/select-payment-method':
                'Vendor_SalesRulesPaymentMethod/js/action/select-payment-method'
        }
    }
};

view / frontend / web / js / action / select-payment-method.js

define(
    [
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/model/full-screen-loader',
        'jquery',
        'Magento_Checkout/js/action/get-totals',
    ],
    function (quote, fullScreenLoader, jQuery, getTotalsAction) {
        'use strict';
        return function (paymentMethod) {
            quote.paymentMethod(paymentMethod);

            fullScreenLoader.startLoader();

            jQuery.ajax('/salesrulespaymentmethod/checkout/applyPaymentMethod', {
                data: {payment_method: paymentMethod},
                complete: function () {
                    getTotalsAction([]);
                    fullScreenLoader.stopLoader();
                }
            });

        }
    }
);

コンパイルしようとしたときにこれを取得します:Fatal error: Class 'Magento\AdvancedSalesRule\Model\Rule\Condition\Address\PaymentMethod' not found in Vendor/SalesRulesPaymentMethod/Model/Rule/Condition/FilterTextGenerator/Address/PaymentMethod.php on line 7。Magento 2.2.2
Alexandros

magento 2.1.9の場合、AdvancedSalesRuleパーツを省略すべきですか?
ドニウィボボ

エラーを取得する場合、コンパイル:致命的なエラー:行7にベンダー/ SalesRulesPaymentMethod /モデル/規則/条件/ FilterTextGenerator /住所/ PaymentMethod.phpで見つからないクラスのMagentoの\ AdvancedSalesRule \モデル\ルール\コンディション\アドレス\ PAYMENTMETHOD "
Magecode

AdvancedSalesRuleは、Magento 2.1.5では利用できません
Magecode

2

同じルールを確認したところ、機能しないことがわかりました。同じ条件を使用すると、選択した選択したメソッドに関する情報は送信されず、注文が出されてルールが機能しなくなるまで、どこにも記録されません。

ここに画像の説明を入力してください

検証まで住所には支払い方法がなく、情報が送信されていないために存在しない支払い見積もりから支払い方法を取得し$model->getQuote()->getPayment()->getMethod()ます(返品null)。

ここに画像の説明を入力してください

これはMagentoのバグだと思います。支払い方法を選択する際には、事前に情報を送信する必要があります。


2
MagestyAppsからの回答が受け入れられます。ありがとう。
グエンホン・クアン

1

カスタムモジュールを使用したソリューションは機能しています。

Magentoの初心者にとって、このモジュールを追加して有効にするにはこれらのファイルも追加する必要があることを知っておくと役立つと思いました。

(別のモジュールからコピーし、モジュール名と名前空間に従ってファイルを変更します)

app/code/Namespace/ModuleName/composer.js
app/code/Namespace/ModuleName/registration.php
app/code/Namespace/ModuleName/etc/module.xml

その後、実行できるようになります bin/magento setup:upgrade


0

ファイルを作成し、名前空間とモジュール名を置き換えましたが、ファイルは実行されないと思います。

ファイルにエラーがあるのでしょうか?

registration.php

<?php

use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Jacor_Checkoutpayment',
__DIR__
);

composer.json

{
"name": "jacor/checkoutpayment",
"autoload": {
    "psr-4": {
        "Jacor\\Checkoutpayment\\": ""
    },
    "files": [
        "registration.php"
    ]
}

}

module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Jacor_Checkoutpayment" setup_version="1.0.0" />
</config>

0

実際には、magentoコアファイルをオーバーライドすることはお勧めできません。オーバーライドMagento_Checkout/js/action/select-payment-methodする代わりに、そのためのミックスインを作成する方が適切です。そして、新しいコントローラーを作成せずに対処できます。以下を参照してください(@magestyappsの回答に加えて)

  1. app / code / Namespace / ModuleName / view / frontend / requirejs-config.js

        var config = {
            config: {
                mixins: {
                    'Magento_Checkout/js/action/select-payment-method': {
                        'Namespace_ModuleName/js/checkout/action/select-payment-method-mixin': true
                    },
                }
            }
        };
  2. app / code / Namespace / ModuleName / view / frontend / js / checkout / action / select-payment-method-mixin.js

        define([
        'jquery',
        'mage/utils/wrapper',
        'mage/storage',
        'Magento_Checkout/js/action/get-totals',
        'Magento_Checkout/js/model/full-screen-loader',
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/model/url-builder',
        'Magento_Customer/js/model/customer',
    ], function ($, wrapper, storage, getTotalsAction, fullScreenLoader, quote, urlBuilder, customer) {
        'use strict';
        return function (selectPaymentMethod) {
            return wrapper.wrap(selectPaymentMethod, function (originalAction, paymentMethod) {
                var serviceUrl, payload;
    
                originalAction(paymentMethod);
    
                payload = {
                    method: paymentMethod
                };
                if (customer.isLoggedIn()) {
                    serviceUrl = urlBuilder.createUrl('/carts/mine/selected-payment-method', {});
                } else {
                    serviceUrl = urlBuilder.createUrl('/guest-carts/:cartId/selected-payment-method', {
                        cartId: quote.getQuoteId()
                    });
                }
                fullScreenLoader.startLoader();
                storage.put(
                    serviceUrl,
                    JSON.stringify(payload)
                ).success(function () {
                    getTotalsAction([]);
                    fullScreenLoader.stopLoader();
                });
            });
        };
    });

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.