Pago de Magento 2: agregue un campo personalizado entre la dirección de envío y el método de envío

21

Estoy tratando de agregar un campo personalizado entre la dirección de envío y las secciones del método de envío . Y quiero que los valores de este campo se almacenen tanto en tablas quotecomo en sales_ordertablas en última instancia. Esto es algo similar a agregar un campo de "comentario de pedido", pero este campo debe aparecer justo después de la sección de dirección de envío y antes de la sección de método de envío.

Revisé las guías de desarrollo de Magento sobre cómo agregar un campo personalizado y un formulario personalizado al pago e implementé una solución hasta cierto punto.

Lo que he hecho hasta ahora:

  1. Se actualizó el checkout_index_index.xmldiseño, se agregó un nuevo uiComponent(un contenedor) debajo del elemento "shippingAddress".
  2. Se agregó el elemento (campo) que requiero dentro del contenedor.
  3. Reemplazar /js/view/shipping.jsy shipping.phtmlen mi módulo personalizado.
  4. Invoqué el contenedor hecho arriba dentro shipping.phtmlentre la dirección de envío de pago y el método de envío (algo similar a agregar un nuevo formulario estático)

Ahora el campo que quiero se muestra en la página de pago de una página exactamente donde quiero. Pero me he encontrado con los siguientes problemas.

  1. ¿Cómo acceder al valor del campo personalizado que he agregado anteriormente? Estoy tratando de guardar el valor en un atributo de extensión shippingAddress. Agregué un mixin al setShippingInformationActioninterior que intenta hacer lo siguiente

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

Pero el código anterior realmente falla ya que el elemento no está en el shipping-address-fieldset. Es posible que pueda obtener el valor a través del windowelemento. ¿Pero hay alguna manera de acceder a esto a través de Magento?

  1. ¿Hay alguna manera de guardar el valor de este elemento en el almacenamiento en caché local ( Magento_Checkout/js/checkout-data) para que el valor persista incluso después de una actualización de la página?
ShanR
fuente
2
Echa un vistazo a esto - magento.stackexchange.com/questions/135969/…
igloczek
Consulte el siguiente enlace, espero que lo ayude magento.stackexchange.com/questions/187847/…
Pradeep Kumar

Respuestas:

1

Según su pregunta, supongo que ya tiene configurados sus atributos de extensión. He llevado a cabo una modificación similar y espero que mi respuesta ayude.

En su módulo personalizado, cree un archivo requirejs-config para extender el procesador de envío predeterminado / predeterminado

Espacio de nombres / CustomModule / view / frontend / requirejs-config.js
var config = {
    "mapa": {
        "*": {
            'Magento_Checkout / js / model / shipping-save-processor / default': 'Namespace_CustomModule / js / model / shipping-save-processor / default'
        }
    }
};

Agregue su atributo de extensión a la carga útil.

/ * definición global, alerta * /
definir(
    [
        'jquery',
        'ko',
        'Magento_Checkout / js / model / quote',
        'Magento_Checkout / js / model / resource-url-manager',
        'mago / almacenamiento',
        'Magento_Checkout / js / model / payment-service',
        'Magento_Checkout / js / model / payment / method-converter',
        'Magento_Checkout / js / model / error-processor',
        'Magento_Checkout / js / model / full-screen-loader',
        'Magento_Checkout / js / action / select-billing-address'
    ],
    función (
        PS
        ko,
        citar,
        resourceUrlManager,
        almacenamiento,
        servicio de pago,
        methodConverter,
        errorProcessor,
        fullScreenLoader,
        selectBillingAddressAction
    ) {
        'uso estricto';

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

                if (! quote.billingAddress ()) {
                    selectBillingAddressAction (quote.shippingAddress ());
                }
                // Agregar los atributos de extensión a su dirección de envío
                carga útil = {
                    Datos del Domicilio: {
                        shipping_address: quote.shippingAddress (),
                        billing_address: quote.billingAddress (),
                        shipping_method_code: quote.shippingMethod (). method_code,
                        shipping_carrier_code: quote.shippingMethod (). carrier_code,
                        atributos_extensión: {
                            custom_field: $ ('# custom_field'). val (), 
                        }
                    }
                };

                fullScreenLoader.startLoader ();

                return storage.post (
                    resourceUrlManager.getUrlForSetShippingInformation (cita),
                    JSON.stringify (carga útil)
                ).hecho(
                    función (respuesta) {
                        quote.setTotals (response.totals);
                        paymentService.setPaymentMethods (methodConverter (response.payment_methods));
                        fullScreenLoader.stopLoader ();
                    }
                ).fallar(
                    función (respuesta) {
                        errorProcessor.process (respuesta);
                        fullScreenLoader.stopLoader ();
                    }
                );
            }
        };
    }
);

Guarde el atributo en su presupuesto con un complemento (no estoy seguro si podría usar un observador aquí, no lo he verificado).

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

clase SaveAddressInformation
{
    protegido $ quoteRepository;
    función 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
     * /
    función 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);

    }
}

Guarde el atributo en su pedido con un observador 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

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

    / **
     * @param \ Magento \ Framework \ ObjectManagerInterface $ objectmanager
     * /
    función pública __construct (\ Magento \ Framework \ ObjectManagerInterface $ objectmanager)
    {
        $ this -> _ objectManager = $ objectmanager;
    }

    ejecución de función pública (EventObserver $ observer)
    {
        $ orden = $ observador-> getOrder ();
        $ quoteRepository = $ this -> _ objectManager-> create ('Magento \ Quote \ Model \ QuoteRepository');
        / ** @var \ Magento \ Quote \ Model \ Quote $ quote * /
        $ quote = $ quoteRepository-> get ($ order-> getQuoteId ());
        $ order-> setCustomField ($ quote-> getCustomField ());

        devuelve $ this;
    }
}

NathanielR
fuente
Anular los métodos básicos no es demasiado afortunado. ¿Qué pasa si otro módulo anula el tuyo? magento.stackexchange.com/questions/135969/…
vaso123
buen punto, no estaba al tanto del método alternativo. Gracias por mencionarlo.
NathanielR
@ vaso123 Parece que tampoco soy consciente de algo porque aquí Nathaniel ha creado un complemento y un observador de eventos, por lo que la función principal se anula aquí. ¿Podría explicarlo un poco más? Sería realmente útil ... Gracias
Sarvagya
@Sarvagya Cuando use require js, no lo use map *, use mixin en su lugar.
vaso123
@ vaso123 Creo que se refiere a Magento_Checkout / js / model / shipping-save-processor / default ':' Namespace_CustomModule / js / model / shipping-save-processor / default 'que, según entiendo, reemplaza a Magento_Checkout / js / model / shipping -save-procesador / predeterminado. } ha pasado un tiempo desde que escribí esto, así que Sarvagya corrígeme si me equivoco.
NathanielR
0

Crea un complemento para esto \Magento\Checkout\Block\Checkout\LayoutProcessor::process método.

Haga una entrada en di.xml en esta ruta

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

Crear clase de complemento en este directorio.

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

2 => Crear clase de complemento en este directorio. 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;
}

}

Una vez hecho esto, consulte la página de pago.

Bandini
fuente