Magento 2 - Rabatt abhängig von Zahlungsmethode funktioniert nicht

13

Ich gehe zu Magento 2 Admin> Marketing> Promotions> Cart Price Rules und erstelle eine neue Regel: Banküberweisung Zahlung:

Informationen zu Tab-Regeln:

  • Regelname: Banküberweisung Zahlung
  • Status: Aktiv
  • Websites: Hauptwebsite
  • Kundengruppen: Alle auswählen
  • Coupon: Kein Coupon
  • Verwendung pro Kunde: 0
  • Von: leer
  • An: leer
  • Priorität: 0
  • Öffentlich im RSS-Feed: Nein

Registerkarte "Bedingungen":

  • Wenn ALLE dieser Bedingungen WAHR sind:
    • Zahlungsmethode ist Überweisung

Registerkarte "Aktionen":

  • Anwenden: Prozent vom Produktpreisrabatt
  • Rabattbetrag: 2
  • Maximaler Mengenrabatt gilt für: 0
  • Rabatt Menge Schritt (Kaufen X): 0
  • Gilt für Versandmenge: Nein
  • Nachfolgende Regeln verwerfen: Nein
  • Kostenloser Versand: Nein
  • Wenden Sie die Regel nur auf Artikel an, die den folgenden Bedingungen entsprechen (lassen Sie das Feld für alle Artikel leer): nichts

Dann aktiviere ich die Zahlungsmethode "Überweisung", gehe zur Kasse und klicke auf "Überweisung", aber der prozentuale Rabatt wird in der Bestellübersicht nicht angezeigt.

Bildbeschreibung hier eingeben

Bitte geben Sie mir einen Rat. Wie kann man bei Magento 2 einen Rabatt auf die Zahlungsmethode gewähren? Bei Magento 1 funktioniert das sehr gut.

Vielen Dank

Nguyễn Hồng Quang
quelle
Sie können Ihre Regel hier posten?
Khoa TruongDinh
Ich habe meine Regel gepostet. Können Sie bitte nach mir suchen?
Nguyễn Hồng Quang
Versuchen Sie, das aktivierte Datum der Regel hinzuzufügen?
Khoa TruongDinh
Ich versuche , den Starttermin der Regel hinzufügen , aber noch nichts in Bestellübersicht geschehen , wenn der Bank Option Überweisung Zahlung klicken
Nguyễn Hồng Quang
1
Vielen Dank. Ich habe das Problem hier gepostet: github.com/magento/magento2/issues/5937
Nguyễn Hồng Quang

Antworten:

11

Diese Regel funktioniert nicht, da Magento 2 die Zahlungsmethode nicht speichert, wenn Sie eine auswählen. Außerdem werden bei der Auswahl einer Zahlungsmethode keine Summen neu geladen. Und leider müssen Sie ein benutzerdefiniertes Modul schreiben, um das Problem zu lösen.

Für das neue Modul müssen nur 4 Dateien erstellt werden:

  1. app / code / Namespace / Modulname / 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>

    Dadurch wird ein neuer Controller für unser Modul definiert.

  2. app / code / Namespace / Modulname / 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();
        }
    }

    Diese Datei erstellt eine Controller-Aktion, um die ausgewählte Zahlungsmethode für das Angebot zu speichern

  3. app / code / Namespace / Modulname / view / frontend / requirejs-config.js

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

    Diese Datei ermöglicht das Überschreiben der Magento_Checkout/js/action/select-payment-methodDatei

  4. app / code / Namespace / Modulname / 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();
                    }
                });
    
            }
        }
    );

    Sendet eine Ajax-Anfrage, um die Zahlungsmethode zu speichern und den Gesamtbetrag des Einkaufswagens neu zu laden.

PS Teile des Codes wurden aus der Zahlungsgebühr- Erweiterung für Magento 2 entnommen .

MagestyApps
quelle
1
Vielen Dank MagestyApps, ich habe ein neues Modul erstellt, folgen Sie Ihren Anweisungen. Am Ende bekam ich jedoch dieses Problem: jquery.js 192.168.41.59/phoenix_checkout/checkout/applyPaymentMethod 404 (Not Found). Hast du diesen Bug schon mal bekommen?
Nguyễn Hồng Quang
1
Es funktioniert wirklich gut Vielen Dank an MagestyApps. Diese Lösung ist perfekt.
Nguyễn Hồng Quang
Es funktioniert, du hast mir Zeit gespart. Vielen Dank :)
Sameer Bhayani
Super Zeug, danke. Die Warenkorb-Preisregel für Zahlungsmethoden wurde übrigens entfernt ( github.com/magento/magento2/commit/… ). Ich habe die Zeile "'payment_method' => __ ('Payment Method')" erneut hinzugefügt, jetzt kann ich Warenkorb-Preisregeln für Zahlungsmethoden erstellen.
DaFunkyAlex
Das hat sehr geholfen. Vielen Dank. +1 :)
Shoaib Munir
3

Auf Magento 2.2 konnte ich MagestyApps nicht zum Laufen bringen. Ich musste einige zusätzliche Dateien hinzufügen. Weil:

  • Die Warenkorb- Preisregel für die Zahlungsmethode wurde vom Administrator entfernt (wie von DaFunkyAlex hervorgehoben).
  • In Magento 2.2 wurde der Rabatt nicht auf das Angebot angewendet, da die Methode \Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address\PaymentMethod::generateFilterText(auf die es tatsächlich zurückgreift \Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address::generateFilterText) die Daten erwartetepayment_method für die Angebotsadressen festgelegt werden.
  • Selbst das Ändern des Controllers von der MagestyApps-Antwort zum Festlegen von payment_methodDaten für die Angebotsadressen funktionierte nicht, als das Angebot zu einer Bestellung wurde, da es nicht fortbesteht payment_method.

Das folgende Modul hat für mich funktioniert (dank der Antwort von MagestyApps basierte es darauf):

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

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

Model / Rule / Condition / FilterTextGenerator / Address / 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 / requirejs-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
quelle
Ich erhalte diese , wenn zu kompilieren versuchen: 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. Ich habe sogar versucht, AdvancedSalesRule in SalesRule zu ändern, da ich sehe, dass es in Magento 2.2.2
Alexandros
Sollten wir für Magento 2.1.9 AdvancedSalesRule-Teile weglassen?
Doni Wibowo
Fehler beim Kompilieren erhalten: Schwerwiegender Fehler: Klasse 'Magento \ AdvancedSalesRule \ Model \ Rule \ Condition \ Address \ PaymentMethod' in Vendor / SalesRulesPaymentMethod / Model / Rule / Condition / FilterTextGenerator / Address / PaymentMethod.php in Zeile 7
Magecode
AdvancedSalesRule ist in Magento 2.1.5
Magecode
2

Wir haben die gleiche Regel überprüft und festgestellt, dass sie nicht funktioniert. Unter den gleichen Bedingungen werden keine Informationen über die ausgewählte Methode gesendet und sie werden nirgendwo aufgezeichnet, bis die Bestellung aufgegeben wird und die Regel möglicherweise nicht funktioniert.

Bildbeschreibung hier eingeben

Die Adresse hat bis zur Bestätigung keine Zahlungsmethode und erhält die Zahlungsmethode aus dem nicht vorhandenen Zahlungsangebot, da keine Informationen gesendet wurden ( $model->getQuote()->getPayment()->getMethod()Retouren null).

Bildbeschreibung hier eingeben

Wir nehmen an, dass dies ein Magento-Fehler ist. Wenn Sie eine Zahlungsmethode auswählen, sollten die Informationen im Voraus gesendet werden.

MageWorx
quelle
2
Die Antwort von MagestyApps wird akzeptiert. Vielen Dank.
Nguyễn Hồng Quang
1

Die Lösung mit dem benutzerdefinierten Modul funktioniert.

Ich dachte nur, dass es für Magento-Anfänger nützlich wäre, zu wissen, dass Sie auch diese Dateien hinzufügen müssen, um dieses Modul hinzufügen und aktivieren zu können:

(Kopieren Sie von einem anderen Modul und ändern Sie die Dateien entsprechend Ihrem Modulnamen und Namespace.)

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

dann könntest du rennen bin/magento setup:upgrade

Антон Скроботов
quelle
0

Ich habe die Dateien erstellt und die Namespaces und Modulnamen ersetzt, aber ich glaube, meine Dateien werden nicht ausgeführt.

Vielleicht ein Fehler in meinen Dateien?

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
quelle
0

Das Überschreiben von Magento-Kerndateien ist eigentlich keine gute Idee. Anstatt zu überschreiben Magento_Checkout/js/action/select-payment-method, sollte ein Mixin dafür erstellt werden. Und Sie können es deaktivieren, ohne einen neuen Controller zu erstellen. Siehe unten (zusätzlich zu @magestyapps Antwort)

  1. app / code / Namespace / Modulname / view / frontend / 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. app / code / Namespace / Modulname / 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
quelle