Como añadir campos personalizados al carrito y propagarlos al pedido en Magento 2
Cuando hacemos desarrollos a medida en Magento 2 generalmente necesitamos añadir datos personalizados al carrito, al pedido, o a ambos. Por ejemplo, podríamos querer que un atributo personalizado de un producto se guardara en la tabla quote_item, o añadir el país de origen del comprador a la tabla quote.
Esto en Magento 1 era bastante fácil hacerlo, simplemente poniendo unos valores en el config.xml de tu módulo bastaba, pero en Magento 2, al menos hasta la 2.3 es un poco más complejo. Vamos por partes.
Tip: Para esta guía se da por hecho que tenemos ya un módulo personalizado instalado en Magento, o que sabemos crear un módulo vacío. En este caso vamos a usar el módulo ficticio Gsoft_Custom.
1. Creamos los campos en la base de datos
Vamos a añadir un campo llamado ‘custom_field’ al carrito, y un campo llamado ‘custom_field_item’ a cada línea. El custom_field_item va a ser un atributo del producto que crearemos desde el backend.
El primer paso es añadir los campos en la tabla de la base de datos. Para ello usaremos el archivo app/code/Gsoft/Custom/Setup/UpgradeSchema.php o app/code/Gsoft/Custom/Setup/InstallScheme.php de tu módulo personalizado:
En el anterior script hemos añadido a la tabla quote y sales_order el campo ’custom_field’, y a las tablas quote_item y sales_order_item el campo ‘custom_field_item’.
Después nos vamos a la consola y escribimos (recuerda hacerlo como el usuario de Magento, nunca como root):
php bin/console setup:upgrade
Con esto ya tenemos el módulo actualizado y nuestros campos en la base de datos. Ahora lo que necesitamos, es darles algún valor.
2. Asignando un valor a nuestros campos
Asignar un valor a un campo personalizado de un carrito se puede hacer de múltiples formas, pero lo común es hacerlo usando eventos: cuando se cree un pedido, cuando se añada el producto al carrito, etc.
Vamos a suponer que queremos asignar un valor a la línea del carrito cuando se añada el producto al carrito. Primero indicaremos a Magento que cuando suceda el evento “checkout_cart_product_add_after”, llame a nuestro observador.
Creamos el archivo app/code/Gsoft/Custom/etc/events.xml y le añadimos el siguiente contenido:
Con esto ya estamos indicando a Magento que vamos a capturar el evento ‘checkout_cart_product_add_after’, el cual se produce cuando un producto se añade al carrito.
Ahora vamos a crear la clase que se encargará de interceptar el evento e interactuar con los datos que propaga.
Creamos el archivo app/code/Gsoft/Custom/Observer/ CheckoutCartProductAddAfter.php, y le damos esta estructura:
El código es bastante claro: cuando un producto se añade al carrito capturamos el valor de su campo custom_field_item (product) y lo insertamos en la línea del carrito (quote_item).
El proceso para asignar un valor al quote es el mismo, pero utilizaríamos un evento relativo al carrito, como por ejemplo “sales_quote_save_before”. Como el procedimiento es idéntico, no vamos a extendernos más en este punto.
3. Propagando el valor al pedido
Ya tenemos los valores en el carrito (quote), y si finalizamos el pedido, se guardarán en la tabla correspondiente. Ahora nos falta traspasar esos valores a la tabla del pedido. Para ello tenemos que valernos de 2 partes.
La primera parte, es crear el fichero app/code/Gsoft/Custom/etc/fieldset.xml con el siguiente contenido:
Este fichero especifica que campos queremos mover del quote al order. En Magento 1 se usaba un código similar, y era suficiente para que Magento lo interpretara e hiciera la propagación de los datos. En Magento 2 esto ha sido suprimido y necesitamos hacer nosotros esta tarea.
Por lo tanto, la segunda parte es añadir otro evento que capture el momento cuando se crea el pedido, y guardar todos los valores.
Para ello añadimos al fichero events.xml la siguiente línea:
Y creamos el fichero app/code/Gsoft/Custom/Observer/ SaveOrderBeforeSalesModelQuoteObserver.php con el siguiente contenido:
La línea:
Se encarga de leer los campos definidos en el archivo fieldsex.xml y copiar los campos personalizados del quote al order. Este funcionamiento no está implementado para copiar los valores del quote_item, por lo que el resto del código se encarga de copiar los valores de las líneas del quote a las líneas del order.
También hay que recordar vaciar la cache cuando hagamos cambios de este tipo, ya que de lo contrario no funcionarán.
php bin/console cache:flush
Siguiendo esta pequeña guía no deberías tener problemas para capturar los datos que quieras y propagarlos hasta el pedido. Y si necesitas ayuda, no dudes en contactar con nosotros.