Magento 2 - rabat zależy od metody płatności nie działa

13

Idę do Magento 2 Admin> Marketing> Promocje> Reguły ceny koszyka i tworzę nową regułę: Przelew bankowy Płatność:

Informacje o regułach tabulatorów:

  • Nazwa reguły: Płatność przelewem bankowym
  • Status: Aktywny
  • Strony internetowe: strona główna
  • Grupy klientów: wybierz wszystko
  • Kupon: brak kuponu
  • Zastosowania na klienta: 0
  • Od: puste
  • Do: puste
  • Priorytet: 0
  • Publiczny w kanale RSS: Nie

Karta Warunki:

  • Jeśli WSZYSTKIE z tych warunków są PRAWDĄ:
    • Metodą płatności jest płatność przelewem bankowym

Karta Działania:

  • Zastosuj: procent rabatu cenowego produktu
  • Kwota rabatu: 2
  • Maksymalny rabat za ilość dotyczy: 0
  • Zniżka Ilość Krok (Kup X): 0
  • Zastosuj do Kwota wysyłki: Nie
  • Odrzuć kolejne zasady: Nie
  • Darmowa wysyłka: Nie
  • Zastosuj regułę tylko do koszyka produktów spełniających następujące warunki (pozostaw puste dla wszystkich przedmiotów): nic

Następnie włączam metodę płatności przelewem bankowym, przejdź do strony kasy, kliknij Płatność przelewem bankowym, ale procentowa cena rabatu nie pojawia się w Podsumowaniu zamówienia.

wprowadź opis zdjęcia tutaj

Proszę o radę. Jak zrobić rabat na metodę płatności na Magento 2. W przypadku Magento 1 dobrze się pisze.

Dziękuję bardzo

Nguyễn Hồng Quang
źródło
Możesz opublikować swoją regułę tutaj?
Khoa TruongDinh
Opublikowałem moją Regułę. Czy możesz mnie sprawdzić?
Nguyễn Hồng Quang
Czy chcesz dodać datę aktywacji reguły?
Khoa TruongDinh
Próbuję dodać datę początkową reguły, ale nadal nic się nie dzieje w Podsumowaniu zamówienia po kliknięciu opcji Płatności
przelewem bankowym
1
Dzięki. Wysłałem
Nguyễn Hồng Quang

Odpowiedzi:

11

Ta reguła nie działa, ponieważ Magento 2 nie zapisuje metody płatności, aby podać ją po wybraniu. I nie przeładowuje też sum przy wyborze metody płatności. I niestety musisz napisać niestandardowy moduł, aby rozwiązać problem.

Nowy moduł wymaga tylko 4 plików:

  1. app / code / Namespace / ModuleName / etc / frontend / tras.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>

    Spowoduje to zdefiniowanie nowego kontrolera dla naszego modułu.

  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();
        }
    }

    Ten plik tworzy akcję kontrolera, aby zapisać wybraną metodę płatności do wyceny

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

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

    Ten plik pozwala zastąpić Magento_Checkout/js/action/select-payment-methodplik

  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();
                    }
                });
    
            }
        }
    );

    Wysyła żądanie ajax, aby zapisać metodę płatności i ponownie załadować sumy koszyka.

Części kodu PS zostały pobrane z rozszerzenia Opłata za płatności dla Magento 2.

MagestyApps
źródło
1
Dzięki bardzo MagestyApps, stworzyłem nowy moduł postępuj zgodnie z twoimi instrukcjami. Jednak na koniec dostałem ten problem jquery.js 192.168.41.59/phoenix_checkout/checkout/applyPaymentMethod 404 (nie znaleziono). Czy dostałeś już ten błąd?
Nguyễn Hồng Quang
1
Działa naprawdę dobrze. Dzięki MagestyApps bardzo. To rozwiązanie jest idealne.
Nguyễn Hồng Quang
Działa, oszczędziłeś mi czas. Dziękuję :)
Sameer Bhayani,
Niesamowite rzeczy, dzięki. Reguła ceny koszyka dla metod płatności została usunięta btw ( github.com/magento/magento2/commit/… ). Dodałem ponownie wiersz „„ metoda_płatności ”=> __ („ Metoda płatności ”),„ teraz mogę teraz tworzyć reguły cen koszyka dla metod płatności.
DaFunkyAlex,
To bardzo pomogło. Dzięki. +1 :)
Shoaib Munir
3

Na Magento 2.2 nie mogłem uzyskać odpowiedzi MagestyApps na pracę. Musiałem dodać dodatkowe pliki. Bo:

  • Reguła ceny koszyka dla metody płatności została usunięta z konta administratora (jak wskazał DaFunkyAlex);
  • W Magento 2.2 zniżka nie była stosowana do wyceny, ponieważ metoda \Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address\PaymentMethod::generateFilterText(faktycznie do niej wraca \Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address::generateFilterText) oczekiwała, że ​​dane payment_methodzostaną ustawione na adresach wyceny;
  • Nawet zmiana kontrolera z odpowiedzi MagestyApps w celu ustawienia payment_methoddanych na adresach wyceny nie działała, gdy wycena stała się zamówieniem, ponieważ nie trwa payment_method;

Poniższy moduł działał dla mnie (dzięki odpowiedzi MagestyApps, był oparty na tym):

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 / trasy.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>

Kontroler / Kasa / 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();
    }
}

Model / Reguła / Warunek / FilterTextGenerator / Adres / 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 / 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();
                }
            });

        }
    }
);
missoxd
źródło
I dostać to podczas próby kompilacji: 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. Próbowałem nawet zmienić AdvancedSalesRule na SalesRule, ponieważ widzę, że nie ma modelu AdvancedSalesRule w Magento 2.2.2
Alexandros
w przypadku Magento 2.1.9, czy powinniśmy pominąć części AdvancedSalesRule?
Doni Wibowo
Błąd podczas kompilacji: Błąd krytyczny: nie znaleziono klasy Magento \ AdvancedSalesRule \ Model \ Reguła \ Warunek \ Adres \ PłatnośćMetoda w dostawcy / SalesRulesPaymentMethod / Model / Reguła / Warunek / FilterTextGenerator / Adres / PaymentMethod.php w linii 7
Magecode
AdvancedSalesRule nie jest dostępny w Magento 2.1.5
Magecode
2

Właśnie sprawdziliśmy tę samą regułę i stwierdziliśmy, że nie działa. Korzystając z tych samych warunków, żadna informacja o wybranej wybranej metodzie nie jest wysyłana i nie jest nigdzie rejestrowana, dopóki zamówienie nie zostanie złożone, a reguła może nie działać.

wprowadź opis zdjęcia tutaj

Adres nie ma metody płatności do momentu zatwierdzenia i pobiera metodę płatności z oferty płatności, która nie istnieje, ponieważ nie wysłano żadnych informacji ( $model->getQuote()->getPayment()->getMethod()zwrotów null).

wprowadź opis zdjęcia tutaj

Przypuszczamy, że jest to błąd Magento. Po wybraniu metody płatności informacje należy przesłać z góry.

MageWorx
źródło
2
Odpowiedź od MagestyApps została zaakceptowana. Dzięki.
Nguyễn Hồng Quang
1

Działa rozwiązanie z niestandardowym modułem.

Pomyślałem, że dla początkujących Magento przydatne będą informacje, że musisz także dodać te pliki, aby móc dodać i włączyć ten moduł:

(kopiuj z innego modułu i zmieniaj pliki zgodnie z nazwą modułu i przestrzenią nazw)

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

wtedy będziesz w stanie biec bin/magento setup:upgrade

Антон Скроботов
źródło
0

utworzyłem pliki i zastąpiłem przestrzenie nazw i modulename, ale myślę, że moje pliki nie zostaną wykonane.

Może błąd w moich plikach?

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
źródło
0

w rzeczywistości przesłonięcie plików rdzenia Magento nie jest dobrym pomysłem. Zamiast przesłonić, Magento_Checkout/js/action/select-payment-methodlepiej stwórz dla niego mixin. Możesz to zrobić bez tworzenia nowego kontrolera. Zobacz poniżej (oprócz odpowiedzi @magestyapps)

  1. app / code / Namespace / 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 / 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();
                });
            });
        };
    });
Styopchik
źródło