Magento 2 checkout - adicione um campo personalizado entre o endereço e o método de envio

21

Estou tentando adicionar um campo personalizado entre as seções de endereço e método de envio . E eu quero que os valores desse campo sejam armazenados em ambas quotee sales_ordertabelas. Isso é semelhante à adição de um campo "comentário do pedido", mas esse campo deve aparecer logo após a seção de endereço de entrega e antes da seção de método de entrega.

Analisei os guias de desenvolvimento do Magento sobre como adicionar um campo personalizado e um formulário personalizado ao checkout e implementei uma solução em certa medida.

O que eu fiz até agora:

  1. Atualizado o checkout_index_index.xmllayout, adicionado um novo uiComponent(um contêiner) no item "shippingAddress".
  2. Adicionado o elemento (campo) necessário dentro do contêiner.
  3. Substituir o /js/view/shipping.jse shipping.phtmlno meu módulo personalizado.
  4. Invocou o contêiner criado acima, shipping.phtmlentre o endereço de entrega da verificação geral e o método de entrega (algo semelhante à adição de um novo formulário estático)

Agora, o campo que eu quero está sendo renderizado no checkout de uma página exatamente onde eu quero. Mas eu encontrei problemas abaixo.

  1. Como acessar o valor do campo personalizado que adicionei acima? Estou tentando salvar o valor em um atributo de extensão shippingAddress. Eu adicionei um mixin para setShippingInformationActiondentro que tenta fazer o abaixo

    shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];

Mas o código acima realmente falha, pois o elemento não está no shipping-address-fieldset. Talvez eu consiga obter o valor através do windowelemento Mas existe uma maneira de acessar isso através do Magento?

  1. Existe uma maneira de salvar o valor desse elemento no armazenamento em cache local ( Magento_Checkout/js/checkout-data) para que o valor persista mesmo após a atualização da página?
ShanR
fonte
2
Dê uma olhada nisso - magento.stackexchange.com/questions/135969/...
igloczek
Por favor, consulte o link abaixo espero que irá ajudá-lo magento.stackexchange.com/questions/187847/...
Pradeep Kumar

Respostas:

1

Com base na sua pergunta, suponho que você já tenha os atributos de extensão configurados. Realizei uma modificação semelhante e espero que minha resposta ajude.

Em seu módulo Customizado, crie um arquivo requirejs-config para estender o processador de remessa padrão /

Namespace / CustomModule / view / frontend / requirejs-config.js
var config = {
    "mapa": {
        "*": {
            'Magento_Checkout / js / model / envio-salvar-processador / padrão': 'Namespace_CustomModule / js / modelo / envio-salvar-processador / padrão'
        }
    }
};

Adicione seu atributo de extensão à carga útil.

/ * definição global, alerta * /
definir(
    [
        'jquery',
        'ko',
        'Magento_Checkout / js / model / quote',
        'Magento_Checkout / js / model / resource-url-manager',
        «mago / armazenamento»,
        'Magento_Checkout / js / model / payment-service',
        'Magento_Checkout / js / model / payment / method-converter',
        'Magento_Checkout / js / model / error-processing',
        'Magento_Checkout / js / model / carregador de tela cheia',
        'Magento_Checkout / js / action / select-billing-address'
    ],
    função (
        $,
        ko
        citar,
        resourceUrlManager,
        armazenamento,
        paymentService,
        methodConverter,
        errorProcessor,
        fullScreenLoader,
        selectBillingAddressAction
    ) {
        'use strict';

        Retorna {
            saveShippingInformation: function () {
                var carga útil;

                if (! quote.billingAddress ()) {
                    selectBillingAddressAction (quote.shippingAddress ());
                }
                // Adicionando os atributos de extensão ao seu endereço de entrega
                carga = {
                    Informação de Endereço: {
                        shipping_address: quote.shippingAddress (),
                        billing_address: quote.billingAddress (),
                        shipping_method_code: quote.shippingMethod (). method_code,
                        shipping_carrier_code: quote.shippingMethod (). carrier_code,
                        extension_attributes: {
                            custom_field: $ ('# custom_field'). val (), 
                        }
                    }
                };

                fullScreenLoader.startLoader ();

                retornar storage.post (
                    resourceUrlManager.getUrlForSetShippingInformation (quote),
                    JSON.stringify (carga útil)
                ).feito(
                    função (resposta) {
                        quote.setTotals (response.totals);
                        paymentService.setPaymentMethods (methodConverter (response.payment_methods));
                        fullScreenLoader.stopLoader ();
                    }
                ).falhou(
                    função (resposta) {
                        errorProcessor.process (resposta);
                        fullScreenLoader.stopLoader ();
                    }
                );
            }
        };
    }
);

Salve o atributo da sua cotação com um plug-in (não tenho certeza se você poderia usar um observador aqui, eu não marquei).

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">
    <type name="Magento\Checkout\Model\ShippingInformationManagement">
        <plugin name="Namespace_CustomModule_save_delivery_date_in_quote" type="Namespace\CustomModule\Plugin\Checkout\SaveAddressInformation" />
    </type>

</config>

SaveAddressInformation.php

classe SaveAddressInformation
{
    protegido $ quoteRepository;
    função pública __construct (
        \ Magento \ Quote \ Model \ QuoteRepository $ quoteRepository
    ) {
        $ this-> quoteRepository = $ quoteRepository;
    }
    / **
     * @param \ Magento \ Checkout \ Model \ ShippingInformationManagement $ subject
     * @param $ cartId
     * @param \ Magento \ Checkout \ Api \ Data \ ShippingInformationInterface $ addressInformation
     * /
    função pública beforeSaveAddressInformation (
        \ Magento \ Checkout \ Model \ ShippingInformationManagement $ subject,
        $ cartId,
        \ Magento \ Checkout \ Api \ Data \ ShippingInformationInterface $ addressInformation
    ) {
        $ extensionAttributes = $ addressInformation-> getExtensionAttributes ();
        $ customField = $ extensionAttributes-> getCustomField ();
        $ quote = $ this-> quoteRepository-> getActive ($ cartId);
        $ quote-> setCustomField ($ customField);

    }
}

Salve o Atributo no seu pedido com um Observer events.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_model_service_quote_submit_before">
        <observer name="unique_observer_name" instance="Namespace\CustomModule\Observer\SaveCustomFieldToOrder"/>
    </event>
</config>

SaveCustomFieldToOrder.php

classe SaveCustomFieldToOrder implementa ObserverInterface
{
    / **
     * @var \ Magento \ Framework \ ObjectManagerInterface
     * /
    protegido $ _objectManager;

    / **
     * @param \ Magento \ Framework \ ObjectManagerInterface $ objectmanager
     * /
    função pública __construct (\ Magento \ Framework \ ObjectManagerInterface $ objectmanager)
    {
        $ this -> _ objectManager = $ objectmanager;
    }

    função pública execute (EventObserver $ observer)
    {
        $ order = $ observer-> getOrder ();
        $ quoteRepository = $ this -> _ objectManager-> create ('Magento \ Quote \ Model \ QuoteRepository');
        / ** @var \ Magento \ Quote \ Model \ Quote $ quote * /
        $ quote = $ quoteRepository-> get ($ order-> getQuoteId ());
        $ order-> setCustomField ($ quote-> getCustomField ());

        retorne $ this;
    }
}

NathanielR
fonte
Substituir os métodos principais não tem muita sorte. E se outro módulo substituir o seu? magento.stackexchange.com/questions/135969/...
vaso123
bom ponto, não estava ciente do método alternativo. Obrigado por apontar isso.
NathanielR
@ vaso123 Parece que eu também não estou ciente de algo, porque aqui Nathaniel criou um plugin e um observador de eventos, de modo que a função principal é substituída aqui. Você poderia por favor explicar pouco mais, seria realmente útil ... Obrigado
Sarvagya
@Sarvagya Quando você usa exigir js, não use map *, use mixin.
precisa saber é o seguinte
@ vaso123 Acredito que ele esteja se referindo ao Magento_Checkout / js / model / shipping-save-processor / default ':' Namespace_CustomModule / js / model / shipping-save-processor / default 'que, como eu entendo, substitui o Magento_Checkout / js / model / shipping -save-processador / padrão. } já faz um tempo desde que escrevi isso, então Sarvagya, por favor, me corrija se estiver errado.
NathanielR
0

Crie um plug-in para este \Magento\Checkout\Block\Checkout\LayoutProcessor::processmétodo.

Faça uma entrada em di.xml neste caminho

app/code/CompanyName/Module/etc/frontend/di.xml

Crie uma classe de plug-in neste diretório.

app/code/CompanyName\Module\Model\Plugin\Checkout

2 => Criar classe de plug-in neste diretório. app/code/CompanyName\Module\Model\Plugin\Checkout

    $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
    ['shippingAddress']['children']['shipping-address-fieldset']['children']['custom_field'] = [
        'component' => 'Magento_Ui/js/form/element/abstract',
        'config' => [
            'customScope' => 'shippingAddress.custom_attributes',
            'template' => 'ui/form/field',
            'elementTmpl' => 'ui/form/element/input',
            'options' => [],
            'id' => 'custom-field'
        ],
        'dataScope' => 'shippingAddress.custom_attributes.custom_field',
        'label' => 'Custom Field',
        'provider' => 'checkoutProvider',
        'visible' => true,
        'validation' => [],
        'sortOrder' => 250,
        'id' => 'custom-field'
    ];


    return $jsLayout;
}

}

Feito isso, verifique a página de checkout.

Bandini
fonte