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:
- Se actualizó el
checkout_index_index.xmldiseño, se agregó un nuevouiComponent(un contenedor) debajo del elemento "shippingAddress". - Se agregó el elemento (campo) que requiero dentro del contenedor.
- Reemplazar
/js/view/shipping.jsyshipping.phtmlen mi módulo personalizado. - 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.
¿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 siguienteshippingAddress['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?
- ¿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?

Respuestas:
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
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
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; } }fuente
map *, use mixin en su lugar.Crea un complemento para esto
\Magento\Checkout\Block\Checkout\LayoutProcessor::processmétodo.Haga una entrada en di.xml en esta ruta
Crear clase de complemento en este directorio.
2 => Crear clase de complemento en este directorio.
app/code/CompanyName\Module\Model\Plugin\Checkout}
Una vez hecho esto, consulte la página de pago.
fuente