Magento 2 - знижка залежить від способу оплати не працює


13

Я переходжу на Magento 2 Адміністратор> Маркетинг> Акції> Правила цін на кошик і створюю нове правило: Банківський переказ:

Інформація про правила вкладки:

  • Назва правила: Банківський переказ
  • Статус: Активний
  • Веб-сайти: Основний веб-сайт
  • Групи клієнтів: виберіть усіх
  • Купон: Без купона
  • Використання на одного клієнта: 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/isissue/5937
Nguyễn Hồng Quang

Відповіді:


11

Це правило не працює, оскільки Magento 2 не зберігає спосіб оплати, щоб процитувати його, коли ви виберете його. А також не перезавантажує підсумки при виборі способу оплати. І, на жаль, вам доведеться написати спеціальний модуль, щоб вирішити проблему.

Для створення нового модуля потрібно створити лише 4 файли:

  1. app / code / Простір імен / ModuleName / тощо / 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 / Простір імен / ім'я модуля / контролер / замовлення / 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 / Простір імен / ModuleName / view / frontend / Requjs-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 / Простір імен / 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 (не знайдено). Ви раніше отримували цю помилку?
Nguyễn Hồng Quang

1
Це працює дуже добре. Велике спасибі MagestyApps Це рішення ідеально.
Nguyễn Hồng Quang

Це працює, ти врятував мій час. Дякую :)
Sameer Bhayani

Дивовижні речі, THX. Правило ціни на кошик для способів оплати було видалено btw ( github.com/magento/magento2/commit/… ). Я додав рядок "'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>

тощо / 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;
    }
}

view / frontend / Requjs-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. Я навіть намагався змінити AdvancedSalesRule на SalesRule, оскільки я можу побачити, що в Magento 2.2.2 немає моделі AdvancedSalesRule
Александрос

для magento 2.1.9, ми повинні опустити деталі AdvancedSalesRule?
Доні Вібово

Помилка отримання під час компіляції: Фатальна помилка: Клас 'Magento \ AdvancedSalesRule \ Модель \ Правило \ Умова \ Адреса \ ОплатаМетод' не знайдено у постачальниках / продажахРекламиМетод / Модель / Правило / Умова / FilterTextGenerator / Адреса / PaymentMethod.php у рядку 7
Magecode

AdvancedSalesRule недоступний у Magento 2.1.5
Magecode

2

Ми просто перевірили те саме правило і виявили, що воно не працює. Використовуючи ті самі умови, інформація про вибраний обраний метод не надсилається і не записується нікуди, поки замовлення не буде розміщено і правило може не працювати.

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

Адреса не має способу оплати до валідації, і спосіб отримання платежу отримує з котирування платежів, яка не існує, оскільки інформація не надсилається ( $model->getQuote()->getPayment()->getMethod()повертається null).

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

Ми припускаємо, що це помилка Magento. Вибираючи спосіб оплати, інформацію слід надсилати заздалегідь.


2
Відповідь від MagestyApps приймається. Дякую.
Nguyễn Hồng Quang

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 / Простір імен / ModuleName / view / frontend / Requjs-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 / Простір імен / 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();
                });
            });
        };
    });

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.