Merko es un buscador de productos y proveedores, pero en lugar de mostrar un listado de coincidencias en texto, muestra la ubicación por coordenadas de los proveedores que coincidieron con la búsqueda de sus productos o directamente, sus nombres de negocios. Está hecho con Laravel, VueJs y MySQL y por supuesto, Google Maps API.

Motivación

Cuando inició todo el confinamiento por temas de la pandemia ocasionada por el virus SARS-COV-2, mucha gente empezó a comprar productos en gran cantidad, el miedo infundió la idea de crear reservas, lo que ocasionó en algunas regiones cierta escasez. Por lo anterior, surgió el interrogante: ¿cómo podríamos encontrar la ubicación de un artículo que necesitemos con exacta precisión? Tal vez un repuesto o medicamento, alguna cosa vital; puede que muchos vendan lo mismo, pero ¿cuál es el proveedor más cercano?.

Iniciativa

Con esta idea en mente se construyó una aplicación sencilla, basada en mapas, con la capacidad de buscar en un radio fijo alrededor de la ubicación del usuario, con filtros y opciones de ampliación de radio hasta en 50 kilómetros. Todo el código y las instrucciones de instalación, pueden ser encontradas en Github como un repositorio público, además de la página demo de Merko.

En un corto tutorial, se explica su funcionamiento básico:


Arquitectura

El proyecto está diseñado sobre el patrón MVC, con las bondades de Laravel, está compuesto por cuatro grandes modelos, y otros menores :

  • User: Modelo por defecto de Laravel.
  • Location: Son los negocios que los usuarios registren, incluye toda la información de contacto y en especial, las coordenadas (latitud, longitud) para su ubicación en el mapa.
  • Order: Los pedidos que un usuario puede enviar a un vendedor o proveedor, su negociación es directa, el vendedor puede confirmar la disponibilidad de productos, es decir, confirmar un pedido.
  • Product: Productos registrados en cada uno de los negocios, incluye tres principales elementos: Una descripción, una descripción larga y el precio. La descripción larga es usada para detallar información adicional o complementaria.

Patrón repositorio

Se implementó un patrón repositorio basado en Eloquent, no se hizo una implementación pura del patrón pues hace redundancia de las ventajas que ofrece el ORM Eloquent, en su funcionamiento con Facades es posible prescindir de la inyección de dependencias en el constructor del repositorio. Los métodos implementados en la interfaz son: CREATE, GET, UPDATE y DESTROY, los cuales se encargan en las operaciones de altas, bajas y modificaciones, comúnmente conocido como CRUD (Create, Read, Update, Destroy). Esta capa se aloja en la ruta:

/app/Repositories

Cada modelo principal tiene un repositorio que implementa la interfaz Repository:

# Interfaz
/app/Repositories/Repository.php

# Repositorios
/app/Repositories/LocationRepository.php
/app/Repositories/OrderRepository.php
/app/Repositories/ProductRepository.php

Capa de servicios

Al igual que en el caso de los repositorios, cada modelo posee un servicio, cada servicio extiende de su respectivo repositorio, usa un trait para facilitar la carga de las relaciones (relationships) e implementa la interfaz Service:

# Interfaz
/app/Services/Service.php

# Trait de carga de relaciones
/app/Services/Relationships.php

# Servicios
/app/Services/LocationService.php
/app/Services/OrderService.php
/app/Services/ProductService.php

La capa de servicios se encarga de la ejecución de las operaciones con la base de datos, la idea al extender del repositorio es simplificar el código a lo sumo y acceder a los métodos del repositorio cuando el servicio sea usado en un controlador; así los controladores mantendrán un orden de responsabilidad y se garantiza la no repetición de código a lo largo de los mismos.

Scopes

Con el propósito de optimizar las consultas, se hizo aprovechamientos de los scopes de Eloquent, en cada modelo encontrarán los scopes implementados en caso de ver su uso en la capa de servicios.

Trait de nombres de columnas

El trait de nombre Queryable, permite la selección de los nombres específicos de los campos, columnas o encabezados de las tablas, está ubicado en /app/Traits/Queryable.php, de esta forma evitamos el uso del comodín asterisco (*) en las consultas a MySQL. Este toma el contenido de la propiedad $fillable y usa por defecto las columnas id, created_at y updated_at, así sólo se deben indicar los campos de llaves foráneas en caso de que se requieran cargar modelos relacionados. Casi todos los modelos hacen uso de este trait.

Carga de productos

Una vez los usuarios hayan registrado negocios, podrán crear productos individualmente o por carga masiva usando una hoja de cálculo; para ello, deberán crean un documento con con tres encabezados de columnas:

  1. description: Con longitud mínima de 20 caracteres y máxima de 126 caracteres.
  2. long_description: Con longitud máxima de 400 caracteres.
  3. price: Campo numérico.

La carga de productos desde una hoja de cálculo se hará efectiva en la primera hoja del documento, si y sólo si, los tres campos cumplen con las condiciones.

Dificultades en el proceso

El diseño inicial contemplaba la implementación de una pasarela de pagos e imágenes en el modelo de productos. La pasarela de pagos desvió la idea principal de ser un buscador, ya que conlleva a acaparar todos los pagos para luego enviar los beneficios a quienes hayan vendido en la plataforma; esta dinámica incluye costos para todos, razón por la cual fue desmontada.

Las imágenes en el modelo de los productos trajo una casi imposible tarea, la carga de una imagen por cada producto es muy complicada; un proveedor con miles de productos vería esto como un gran costo de tiempo y dinero, lo cual hace poco viable al proyecto.

Conclusiones

Libero el código del proyecto con la idea de contribuir en el mundo del código abierto y con el propósito de encontrar una solución viable al problema del aprovisionamiento, desde lo básico hasta lo vital; esta crisis ha mostrado cuán vulnerables somos, en miedos y sobre carga de información mayormente falsa, por lo tanto, construir este tipo de herramientas puede abrir puertas cuando muchas se cierran.

No olviden compartir. Gracias.

Omar Barbosa
Computer engineer, web developer with Python, PHP and Javacript
Share

Share this article in the social networks

Location

Bucaramanga - Santader
Colombia

Social networks

About

Computer engineer, web developer with Python, PHP and Javacript .