Magento 2 - o desconto depende do método de pagamento não funciona

13

Vou para Magento 2 Admin> Marketing> Promoções> Regras de preço do carrinho e crio uma nova regra: Pagamento por transferência bancária:

Informações da regra da guia:

  • Nome da regra: pagamento por transferência bancária
  • Status: Ativo
  • Sites: Site Principal
  • Grupos de Clientes: selecione todos
  • Cupom: No Cupom
  • Usos por cliente: 0
  • De: blank
  • Para: em branco
  • Prioridade: 0
  • Público no feed RSS: Não

Guia Condições:

  • Se TODAS essas condições forem VERDADEIRAS:
    • O método de pagamento é Pagamento por transferência bancária

Guia Ações:

  • Aplicar: porcentagem de desconto no preço do produto
  • Valor do desconto: 2
  • O desconto máximo de quantidade é aplicado a: 0
  • Desconto Qty Step (Buy X): 0
  • Aplicar ao valor da remessa: Não
  • Descartar regras subsequentes: Não
  • Frete grátis: Não
  • Aplique a regra apenas ao carrinho de itens que atenda às seguintes condições (deixe em branco para todos os itens): nothing

Ativei o método de pagamento por transferência bancária, vá para a página de check-out, clique em Pagamento por transferência bancária, mas o preço percentual do desconto não aparece no resumo do pedido.

insira a descrição da imagem aqui

Por favor me dê um conselho. Como fazer um desconto na forma de pagamento no Magento 2. No Magento 1, ele funciona bem.

Muito obrigado

Nguyễn Hồng Quang
fonte
Você pode postar sua regra aqui?
precisa saber é o seguinte
Publiquei minha regra. Você pode me procurar por favor?
Nguyễn Hồng Quang
Tente adicionar a data ativada da regra?
precisa saber é o seguinte
Eu tento adicionar o início Data da regra, mas ainda nada acontecer para Resumo quando clique Banco opção transferência de pagamento on
Nguyễn Hồng Quang
1
Obrigado. Publiquei
Nguyễn Hồng Quang

Respostas:

11

Essa regra não funciona porque o Magento 2 não salva a forma de pagamento para citar quando você seleciona uma. E também não recarrega totais ao selecionar uma forma de pagamento. E, infelizmente, você precisa escrever um módulo personalizado para resolver o problema.

O novo módulo precisa apenas de 4 arquivos para serem criados:

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

    Isso definirá um novo controlador para o nosso módulo.

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

    Este arquivo cria uma ação do controlador para salvar a forma de pagamento selecionada para cotação

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

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

    Este arquivo permite substituir o Magento_Checkout/js/action/select-payment-methodarquivo

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

    Envia uma solicitação ajax para salvar a forma de pagamento e recarregar os totais do carrinho.

PS Partes do código foram retiradas da extensão da Taxa de pagamento do Magento 2.

MagestyApps
fonte
1
Muito obrigado MagestyApps, criei um novo módulo, siga suas instruções. No entanto, no final, eu tenho esse problema jquery.js 192.168.41.59/phoenix_checkout/checkout/applyPaymentMethod 404 (não encontrado). Você recebeu esse bug antes?
Nguyễn Hồng Quang
1
Funciona muito bem. Muito obrigado MagestyApps. Esta solução é perfeita.
Nguyễn Hồng Quang
Funciona, você economizou meu tempo. Obrigado :)
Sameer Bhayani
Coisas impressionantes, thx. A regra de preço do carrinho para métodos de pagamento foi removida ( github.com/magento/magento2/commit/… ). Adicionei a linha "'payment_method' => __ ('Método de pagamento')", novamente, agora posso criar regras de preço de carrinho para métodos de pagamento.
DaFunkyAlex
Isso ajudou muito. Obrigado. +1 :)
Shoaib Munir
3

No Magento 2.2, não consegui obter a resposta do MagestyApps para funcionar. Eu precisava adicionar alguns arquivos adicionais. Porque:

  • A regra de preço do carrinho para forma de pagamento foi removida do administrador (conforme indicado por DaFunkyAlex);
  • No Magento 2.2, o desconto não estava sendo aplicado na cotação, porque o método \Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address\PaymentMethod::generateFilterText(na verdade ele se aplica a \Magento\AdvancedSalesRule\Model\Rule\Condition\FilterTextGenerator\Address::generateFilterText), esperava que os dados payment_methodfossem definidos nos endereços da cotação;
  • Mesmo alterar o controlador da resposta do MagestyApps para definir payment_methoddados nos endereços das cotações, não funcionou quando a cotação se tornou um pedido, porque não persiste payment_method;

O seguinte módulo funcionou para mim (graças à resposta do MagestyApps, foi baseado em cima disso):

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

Modelo / Regra / Condição / FilterTextGenerator / Endereço / 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
fonte
Eu recebo isso quando tentar compilar: 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. Eu até tentei mudar AdvancedSalesRule para SalesRule quanto eu posso ver, não há modelo AdvancedSalesRule em Magento 2.2.2
Alexandros
para o magento 2.1.9, devemos omitir as partes AdvancedSalesRule?
Doni Wibowo 29/03
Obtendo erro ao compilar: Erro fatal: Classe 'Magento \ AdvancedSalesRule \ Modelo \ Regra \ Condição \ Endereço \ PaymentMethod' não encontrada em Fornecedor / SalesRulesPaymentMethod / Modelo / Regra / Condição / FilterTextGenerator / Endereço / PaymentMethod.php na linha 7
Código Mag.
AdvancedSalesRule não está disponível em Magento 2.1.5
Magecode
2

Acabamos de verificar a mesma regra e descobrimos que ela não funciona. Usando as mesmas condições, nenhuma informação sobre o método escolhido selecionado é enviada e não é registrada em nenhum lugar até que o pedido seja feito e a regra não funcione.

insira a descrição da imagem aqui

O endereço não tem método de pagamento até a validação e obtém o método de pagamento a partir de uma cotação de pagamento que não existe porque nenhuma informação foi enviada ( $model->getQuote()->getPayment()->getMethod()devoluções null).

insira a descrição da imagem aqui

Supomos que esse seja um bug do Magento. Quando você escolhe um método de pagamento, as informações devem ser enviadas com antecedência.

MageWorx
fonte
2
A resposta do MagestyApps é aceita. Obrigado.
Nguyễn Hồng Quang
1

A solução com o módulo personalizado está funcionando.

Eu apenas pensei que seria uma informação útil para os iniciantes do Magento saberem que você também precisa adicionar esses arquivos para poder adicionar e ativar este módulo:

(copie de um módulo diferente e altere os arquivos de acordo com o nome e o espaço de nome do módulo)

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

então você seria capaz de correr bin/magento setup:upgrade

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

Eu criei os arquivos e substituí os namespaces e modulename, mas acho que meus arquivos não serão executados.

Talvez um erro nos meus arquivos ??

registration.php

<?php

use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Jacor_Checkoutpayment',
__DIR__
);

compositer.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
fonte
0

na verdade, substituir os arquivos principais do magento não é uma boa ideia. Em vez de substituir, é Magento_Checkout/js/action/select-payment-methodmelhor criar um mixin para ele. E você pode resolvê-lo sem criar um novo controlador. Veja abaixo (além da resposta @magestyapps)

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