Magento 2 - скидка зависит от способа оплаты не работает

13

Я захожу в Magento 2 Admin> Маркетинг> Акции> Правила цены корзины и создаю новое правило: Банковский перевод Оплата:

Информация о правиле табуляции:

  • Название правила: банковский перевод
  • Статус: Активен
  • Сайты: Главный сайт
  • Группы клиентов: выбрать все
  • Купон: нет купона
  • Использует на клиента: 0
  • От: пусто
  • До: пусто
  • Приоритет: 0
  • Публичный в RSS-канал: нет

Вкладка «Условия»:

  • Если ВСЕ эти условия истинны:
    • Способ оплаты - банковский перевод

Вкладка Действия:

  • Применить: процент от цены товара со скидкой
  • Размер скидки: 2
  • Максимальная Кол-во Скидка применяется к: 0
  • Скидка Кол-во Шаг (Купить X): 0
  • Применить к сумме доставки: нет
  • Отменить последующие правила: нет
  • Бесплатная доставка: нет
  • Примените правило только к элементам корзины, соответствующим следующим условиям (оставьте пустым для всех элементов): ничего

Затем я включаю метод оплаты банковским переводом, перехожу на страницу оформления заказа, нажимаю «Оплата банковским переводом», но цена скидки в процентах не отображается в сводке заказа.

введите описание изображения здесь

Пожалуйста, дайте мне совет. Как сделать скидку на способ оплаты на Magento 2. Для Magento 1 он работает хорошо.

Огромное спасибо

Нгуен Хонг Куанг
источник
Вы можете опубликовать свое правило здесь?
Khoa TruongDinh
Я опубликовал свое правило. Можете ли вы проверить меня, пожалуйста?
Nguyồn Hồng Quang
Попробуйте добавить дату активации правила?
Khoa TruongDinh
Я пытаюсь добавить дату начала правила, но все равно ничего не происходит в Сводке заказа, когда нажимаем на опцию Оплата банковским переводом
Nguyễn Hồng Quang
1
Благодарю. Я разместил эту проблему здесь: github.com/magento/magento2/issues/5937
Нгуен Хонг Куанг

Ответы:

11

Это правило не работает, потому что Magento 2 не сохраняет способ оплаты для котировки при выборе. И это также не перезагружает итоги при выборе способа оплаты. И, к сожалению, вам нужно написать собственный модуль для решения проблемы.

Для создания нового модуля нужно всего 4 файла:

  1. Приложение / код / ​​пространство имен / ModuleName / и т.д. / интерфейс / 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. Приложение / код / ​​пространство имен / ModuleName / контроллер / 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. Приложение / код / ​​пространство имен / ModuleName / просмотр / интерфейс / 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. Приложение / код / ​​пространство имен / ModuleName / вид / интерфейс / веб / JS / действие / выбрать-оплаты-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.

MagestyApps
источник
1
Большое спасибо MagestyApps, я создал новый модуль, следуя вашей инструкции. Тем не менее, в конце я получил эту проблему jquery.js 192.168.41.59/phoenix_checkout/checkout/applyPaymentMethod 404 (не найден). Вы получили эту ошибку раньше?
Nguyồn Hồng Quang
1
Это работает очень хорошо. Большое спасибо MagestyApps. Это решение идеально.
Нгуен Хонг Куанг
Это работает, вы сэкономили мое время. Спасибо :)
Самир Бхайани
Потрясающие вещи, спасибо. Кстати, правило цены корзины для способов оплаты было удалено ( github.com/magento/magento2/commit/… ). Я снова добавил строку «payment_method» => __ («Payment Method»), теперь я могу создавать правила цены корзины для способов оплаты.
DaFunkyAlex
Это очень помогло. Благодарю. +1 :)
Шоаиб Мунир
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>

и т.д. / интерфейс / 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>

Контроллер / 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();
    }
}

Модель / Rule / Состояние / 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'
        }
    }
};

вид / интерфейс / веб / JS / действие / выбор-оплата-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();
                }
            });

        }
    }
);
missoxd
источник
Я получаю это при попытке скомпилировать 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, поскольку вижу, что в Magento 2.2.2 нет модели AdvancedSalesRule
Alexandros
для magento 2.1.9, мы должны опустить части AdvancedSalesRule?
Дони Вибово
Получение ошибки при компиляции: Неустранимая ошибка: класс 'Magento \ AdvancedSalesRule \ Model \ Rule \ Condition \ Address \ PaymentMethod' не найден в Vendor / SalesRulesPaymentMethod / Model / Rule / Condition / FilterTextGenerator / Address / PaymentMethod.php в строке 7
Magecode
AdvancedSalesRule недоступен в Magento 2.1.5
Magecode,
2

Мы только что проверили то же правило и обнаружили, что оно не работает. При тех же условиях никакая информация о выбранном выбранном методе не отправляется, и она нигде не записывается, пока не будет размещен заказ и правило может не работать.

введите описание изображения здесь

У адреса нет способа оплаты до проверки, и он получает метод оплаты из платежного предложения, которое не существует, потому что информация не была отправлена ​​( $model->getQuote()->getPayment()->getMethod()возвращается null).

введите описание изображения здесь

Мы предполагаем, что это ошибка Magento. При выборе способа оплаты информация должна быть отправлена ​​заранее.

MageWorx
источник
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>
Tobi
источник
0

на самом деле переопределение файлов ядра magento не очень хорошая идея. Вместо переопределения Magento_Checkout/js/action/select-payment-methodлучше создайте для него миксин. И вы можете продать его, не создавая новый контроллер. Смотрите ниже (в дополнение к ответу @magestyapps)

  1. Приложение / код / ​​пространство имен / ModuleName / просмотр / интерфейс / 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. Приложение / код / ​​пространство имен / ModuleName / вид / интерфейс / 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();
                });
            });
        };
    });
Styopchik
источник