Desarrollo de Sistema de Inventario con Lógica FIFO para Negocio Minorista

1. El Problema del Negocio La administración manual del inventario en un negocio local, como la 'Tienda Graciela', generaba cuellos de botella en la reposición de productos y dificultaba el control del stock. El reto era digitalizar este proceso sin complicar la operación diaria del usuario final.

2. La Solución Arquitectónica (Lógica FIFO) Para garantizar una rotación de inventario correcta, diseñé el sistema aplicando el principio algorítmico FIFO (First In, First Out) mediante el uso de colas. ( esto asegura que el primer producto registrado en el sistema sea el primero en descontarse al registrar una venta).

3. Tecnologías y Herramientas Para este desarrollo utilicé:

  • PHP, Java Script, Laravel y mysql 

4. Impacto Real y Resultados La implementación de este sistema logró:

  • Reducción del tiempo invertido en el cuadre de caja diario.

  • Trazabilidad exacta de las entradas y salidas de mercancía.

  • Reduccion de perdida de dinero por productos vencidos.

Para la gestión de productos, era fundamental crear un motor de búsqueda dinámico que permitiera al usuario filtrar el inventario en tiempo real sin sobrecargar el servidor.

En lugar de utilizar múltiples condicionales tradicionales que ensucian el código, implementé el método when de Eloquent en Laravel. Esto permite construir la consulta a la base de datos paso a paso, aplicando los filtros de marca, categoría o promociones únicamente si el usuario los solicita:

public function catalogo(Request $request) { // Obtener filtros del formulario $buscar = $request->input('buscar'); $marca = $request->input('marca'); $categoria = $request->input('categoria'); $promocion = $request->input('promocion');

// Construcción dinámica de la consulta con Eager Loading $productos = Producto::with(['marca', 'categoria', 'promociones']) ->when($buscar, function ($query, $buscar) { $query->where('nombre', 'like', '%' . $buscar . '%') ->orWhere('descripcion', 'like', '%' . $buscar . '%'); }) ->when($marca, function ($query, $marca) { $query->where('id_marca', $marca); }) ->when($categoria, function ($query, $categoria) { $query->where('id_categoria', $categoria); }) ->when($promocion, function ($query) { $query->whereHas('promociones'); }) ->paginate(9);

$marcas = Marca::all(); $categorias = Categoria::all();

return view('productos.catalogo', compact('productos', 'marcas', 'categorias')); }

Este enfoque no solo mantiene el controlador limpio y fácil de mantener, sino que, combinado con la paginación nativa, asegura que el sistema responda en milisegundos sin importar cuánto crezca el catálogo de la tienda.

Uno de los mayores desafíos lógicos al gestionar un inventario no es registrar una venta nueva, sino mantener la consistencia de la base de datos cuando una transacción se edita o se cancela. Si un cajero modifica una factura, el stock puede corromperse fácilmente si no se maneja bien el flujo de datos.

Para resolver esto y proteger la integridad del inventario de la tienda, diseñé un algoritmo de actualización que funciona en tres fases:

  1. Reintegra el stock original de la venta a los estantes virtuales.

  2. Limpia el historial de la factura anterior.

  3. Calcula, registra y descuenta el nuevo inventario actualizado.

public function update(Request $request, Venta $venta) { // FASE 1: Revertir el stock para cada producto en el detalle original foreach ($venta->detalleVentas as $detalle) { $producto = Producto::find($detalle->id_producto); if ($producto) { $producto->stock_actual += $detalle->cantidad; $producto->save(); } }

// Limpiar totales y prepararse para la nueva data $venta->update(['fecha_venta' => $request->fecha_venta, 'total' => 0]); $venta->detalleVentas()->delete();

// FASE 2 y 3: Calcular el nuevo total y restar el nuevo stock $totalVenta = 0; foreach ($request->productos as $productoData) { $producto = Producto::find($productoData['id_producto']); if ($producto) { $cantidad = $productoData['cantidad']; $precioVenta = $productoData['precio_venta'];

$producto->stock_actual -= $cantidad; $producto->save();

$venta->detalleVentas()->create([ 'id_producto' => $producto->id_producto, 'cantidad' => $cantidad, 'precio_unitario' => $precioVenta, 'total' => $cantidad * $precioVenta, ]);

$totalVenta += $cantidad * $precioVenta; } }

$venta->update(['total' => $totalVenta]); return redirect()->route('ventas.index')->with('success', 'Venta actualizada con éxito.'); }

Este control estricto del estado de la información garantiza que, sin importar cuántos cambios ocurran en el mostrador, el sistema y la tienda física siempre tengan exactamente la misma cantidad de productos.










 


Comments