Desarrollo el método de envío para alguna empresa de logística. Esta empresa tiene muchas oficinas donde el cliente puede obtener su pedido. Puedo obtener la lista de oficinas por ciudad en API, pero ahora no sé qué mejor represento este paso.
Por ahora, acabo de establecer una nueva \Magento\Quote\Model\Quote\Address\RateResult\Method
en cada oficina en la ciudad, en la gran ciudad, cuenta> 100 y creo que no es muy bueno establecer 100 líneas en el pago.
Será un módulo público para un diseño de pago diferente, así que, ¿cómo puedo mostrar una lista desplegable con mi lista de oficinas y establecer el precio y el método después de que el usuario seleccione uno?
magento-2.1
checkout
shipping-methods
Jamess Moriarty
fuente
fuente

Respuestas:
El pago y envío de Magento no admite ningún tipo de formulario para el método de envío de datos adicionales. Pero proporciona un
shippingAdditionalbloqueo en el proceso de pago que se puede usar para esto. La siguiente solución funcionará para el pago estándar de magento.Primero preparemos nuestro contenedor donde podamos poner alguna forma. Para hacer esto, cree un archivo en
view/frontend/layout/checkout_index_index.xmlAhora cree un archivo en el
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.jsque se generará una plantilla de eliminación. Su contenido se ve asíEste archivo utiliza una plantilla de eliminación que debe colocarse en
Vendor/Module/view/frontend/web/template/checkout/shipping/form.htmlAhora tenemos un campo de selección que será visible cuando nuestro método (definido por su código) se seleccione en la tabla de métodos de envío. Es hora de llenarlo con algunas opciones. Dado que los valores dependen de la dirección, la mejor manera es crear un punto final de descanso que proporcione las opciones disponibles. En
Vendor/Module/etc/webapi.xmlAhora defina la interfaz
Vendor/Module/Api/OfficeManagementInterface.phpcomoDefinir interfaz para datos de oficina en
Vendor\Module\Api\Data\OfficeInterface.php. Esta interfaz será utilizada por el módulo webapi para filtrar datos para la salida, por lo que debe definir lo que necesite agregar a la respuesta.Tiempo para clases reales. Comience con la creación de preferencias para todas las interfaces en
Vendor/Module/etc/di.xmlAhora cree una
Vendor\Module\Model\OfficeManagement.phpclase que realmente haga la lógica de obtener los datos.Y finalmente clase para
OfficeInterfaceadentroVendor/Module/Model/Office.phpEsto debería mostrar el campo de selección y actualizarlo cuando se cambia la dirección. Pero nos falta un elemento más para la manipulación frontend. Necesitamos crear una función que llame al punto final. La llamada a él ya está incluida
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.jsy es unaVendor_Module/js/view/checkout/shipping/office-serviceclase a la que debe irVendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.jscon el siguiente código:Utiliza 2 archivos js más.
Vendor_Module/js/view/checkout/shipping/model/resource-url-managercrea una URL para el punto final y es bastante simpleVendor_Module/js/view/checkout/shipping/model/office-registryEs una forma de mantener el resultado en el almacenamiento local. Su código es:Ok, deberíamos tener a todos trabajando en la interfaz. Pero ahora hay otro problema por resolver. Dado que el proceso de pago no sabe nada sobre este formulario, no enviará el resultado de la selección al backend. Para que esto suceda, necesitamos usar la
extension_attributesfunción. Esta es una forma en magento2 de informar al sistema que se espera que haya datos adicionales en las llamadas restantes. Sin él, magento filtraría esos datos y nunca alcanzarían el código.Así que primero en
Vendor/Module/etc/extension_attributes.xmldefinir:Este valor ya está insertado en la solicitud
form.jsporthis.selectedOffice.subscribe()definición. Entonces, la configuración anterior solo la pasará en la entrada. Para buscarlo en el código, cree un complemento enVendor/Module/etc/di.xmlDentro de esa clase
Por supuesto, dónde guardará el valor depende completamente de sus requisitos. El código anterior requeriría la creación de columna adicional
carrier_officeenquote_addressysales_addressmesas y un evento (enVendor/Module/etc/events.xml)Eso copiaría los datos guardados en la dirección de presupuesto a la dirección de ventas.
Escribí esto para mi módulo para INPOST portador de esmalte así que cambié algunos nombres que podrían romper el código, pero espero que esto le dará lo que necesita.
[EDITAR]
Modelo de operador preguntado por @sangan
fuente
Estoy agregando una nueva respuesta para ampliar lo que ya se proporcionó anteriormente pero sin distorsionarlo.
Esta es la ruta que se
QuoteAddressPluginestaba conectando:El último método fue llamar,
Magento\Quote\Model\Quote\Address::setShippingMethod()que en realidad era la llamadaMagento\Quote\Model\Quote\Address::__call()que usé. En este momento encontré un lugar mejor para el complemento, es elMagento\Quote\Model\ShippingAssignment::setShipping()método. Entonces, la parte del complemento se puede reescribir en:y el complemento en sí:
fuente
@ Zefiryn, me encontré con el problema con:
quote.shippingAddress().extensionAttributes.carrier_office = office;Cuando entro en la caja la primera vez (nueva ventana privada) como invitado (pero ocurre lo mismo con el cliente registrado), la oficina de atributos no se guarda en la base de datos después del primer "Siguiente". Aunque en la consola veo la salida correcta para:
console.log(quote.shippingAddress().extensionAttributes.carrier_office);Cuando regrese a la primera página de pago y seleccione Office nuevamente, se guardará. ¿Cuál podría ser la razón de este comportamiento?
Traté de usar:
address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);pero sin éxito...
fuente
@ Zefiryn, ¿Puedes explicar en pocas palabras cómo funciona tu plugin anterior? Estoy un poco confundido porque, como sé, el método __call se ejecuta si intentamos ejecutar el método que no existe para un objeto en particular. Parece ser cierto porque en app / code / Magento / Quote / Model / Quote / Address.php no veo ese método, solo comente:
/** * Sales Quote address model ... * @method Address setShippingMethod(string $value)$subject->setInpostMachiney$subject->getCarrierOffice(null);¿Significa que el método del complemento anterior se ejecutará nuevamente ya que no hay un método setInpostMachine () y getCarrierOffice () en Adress Class? A mí me parece un lazo.setShippingMethod()? ¿Con qué frecuencia se usa este método? No encuentro intercepciones similares en el código de Magento.fuente
setShippingMethodllamada alAddressInterfaceobjeto, y dado que no existe tal método, tuve que usar around__call para ver sisetShippingMethodfue llamado o algún otro campo mágico. Ahora mismo he encontrado un lugar mejor y lo publicaré en una nueva respuesta.