Magento 2-折扣取决于付款方式不起作用


13

我转到Magento 2 管理员>市场营销>促销>购物车价格规则,然后创建新规则:银行转帐付款:

制表符规则信息:

  • 规则名称:银行转帐付款
  • 状态:有效
  • 网站:主要网站
  • 客户群:全选
  • 优惠券:无优惠券
  • 每个客户的使用次数:0
  • 来自:空白
  • 至:空白
  • 优先级:0
  • 在RSS Feed中公开:否

条件标签:

  • 如果所有这些条件都为TRUE:
    • 付款方式是银行转帐付款

动作标签:

  • 适用:产品价格折扣的百分比
  • 优惠金额:2
  • 最大数量折扣适用于:0
  • 折扣数量步(购买X):0
  • 适用于发货金额:否
  • 舍弃后续规则:否
  • 免费送货:否
  • 仅将规则应用于符合以下条件的购物车商品(所有商品均留空):无

然后,我启用银行转帐付款方式,转到结帐页面,单击“银行转帐付款”,但“折扣摘要”中没有显示“折扣价”。

在此处输入图片说明

请给我一个建议。如何在Magento 2的付款方式上打折。对于Magento 1,它工作得很好。

非常感谢


您可以在这里发布规则吗?
Khoa TruongDinh '16

我发布了规则。你能帮我看看吗?
阮洪广

尝试添加规则的激活日期?
Khoa TruongDinh '16

我尝试添加规则,但仍然没有开始日期恰巧在订单摘要的银行转帐付款选项时点击
阮洪广

1
谢谢。我在这里张贴的问题:github.com/magento/magento2/issues/5937
阮洪广

Answers:


11

该规则不起作用,因为当您选择一种付款方式时,Magento 2不会保存要报价的付款方式。选择付款方式时,它也不会重新加载总计。不幸的是,您必须编写一个自定义模块来解决该问题。

新模块仅需要创建4个文件:

  1. 应用程序/代码/名称空间/模块名称/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. 应用程序/代码/命名空间/模块名称/控制器/签出/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. 应用程序/代码/命名空间/模块名称/视图/前端/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. 应用程序/代码/命名空间/模块名称/视图/前端/ web / js /操作/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(未找到)。您以前收到此错误了吗?
阮洪广

1
它真的很好。非常感谢MagestyApps。这个解决方案是完美的。
阮洪广

它有效,您节省了我的时间。谢谢:)
Sameer Bhayani

很棒的东西,谢谢。付款方式的购物车价格规则已被删除(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__
);

等/ 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>

等/ 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>

控制器/结帐/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 /地址/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;
    }
}

插件/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;
    }
}

查看/前端/requirejs-config.js

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

查看/前端/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。我甚至想AdvancedSalesRule改变SalesRule,我可以看有没有AdvancedSalesRule模型Magento的2.2.2
亚历山德罗

对于magento 2.1.9,我们应该省略AdvancedSalesRule零件吗?
多尼·威博沃

编译时出错:致命错误:在第7行上的Vendor / SalesRulesPaymentMethod / Model / Rule / Condition / FilterTextGenerator / Address / PaymentMethod.php中找不到类'Magento \ AdvancedSalesRule \ Model \ Rule \ Condition \ Address \ PaymentMethod'的类
Magecode

Magento 2.1.5
Magecode '19

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. 应用程序/代码/命名空间/模块名称/视图/前端/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. 应用程序/代码/命名空间/模块名称/视图/前端/ js /结帐/操作/选择付款方法-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();
                });
            });
        };
    });
    

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.