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


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

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.


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

        }
    }
);

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.


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


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>

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.