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
shippingAdditional
bloqueo 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.xml
Ahora cree un archivo en el
Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.js
que 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.html
Ahora 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.xml
Ahora defina la interfaz
Vendor/Module/Api/OfficeManagementInterface.php
comoDefinir 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.xml
Ahora cree una
Vendor\Module\Model\OfficeManagement.php
clase que realmente haga la lógica de obtener los datos.Y finalmente clase para
OfficeInterface
adentroVendor/Module/Model/Office.php
Esto 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.js
y es unaVendor_Module/js/view/checkout/shipping/office-service
clase a la que debe irVendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.js
con el siguiente código:Utiliza 2 archivos js más.
Vendor_Module/js/view/checkout/shipping/model/resource-url-manager
crea una URL para el punto final y es bastante simpleVendor_Module/js/view/checkout/shipping/model/office-registry
Es 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_attributes
funció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.xml
definir:Este valor ya está insertado en la solicitud
form.js
porthis.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.xml
Dentro 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_office
enquote_address
ysales_address
mesas 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
QuoteAddressPlugin
estaba 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->setInpostMachine
y$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
setShippingMethod
llamada alAddressInterface
objeto, y dado que no existe tal método, tuve que usar around__call para ver sisetShippingMethod
fue llamado o algún otro campo mágico. Ahora mismo he encontrado un lugar mejor y lo publicaré en una nueva respuesta.