Transformar datos en decisiones es una de las habilidades más valiosas en el desarrollo de software. Cuando trabajamos con un sistema de inventario, no basta con almacenar productos: necesitamos respuestas claras sobre el valor total, los productos que se agotan y cuáles generan más ingresos. Aquí se muestra cómo LINQ y StringBuilder se combinan en C# para construir un generador de reportes profesional que produce resúmenes ejecutivos, alertas de stock bajo, rankings y exportaciones a CSV y JSON.
¿Cómo se estructura la clase GeneradorReportes?
La clase GeneradorReportes se ubica dentro de la carpeta SRC/Infrastructure y actúa como el componente responsable de analizar y presentar los datos del inventario [00:56]. Para que funcione correctamente, se necesitan las siguientes importaciones:
using System y using System.Collections.Generic para las colecciones.
using System.Linq para las consultas declarativas.
using System.Text para StringBuilder.
using System.Text.Json para la serialización JSON.
using InventarioApp.Models para acceder al modelo de producto.
El namespace corresponde a InventarioApp.Infrastructure. Dentro de la clase, se declara un campo readonly de tipo IEnumerable<Producto> llamado _productos [01:42]. El constructor recibe esta colección y la almacena, lo que permite ofrecer múltiples vistas de los mismos datos sin modificarlos.
¿Qué hace el método generar resumen?
Este método crea una instancia de StringBuilder y utiliza AppendLine para construir el reporte línea por línea [02:17]. Primero imprime el total de productos usando .Count() y luego el valor total del inventario con .Sum(), que recorre cada producto y acumula su valor total.
Para desglosar los productos por categoría, se usa GroupBy, que agrupa cada producto según su categoría [02:55]. Después, con Select, se crea un objeto anónimo con la categoría y la cantidad usando g.Count(). Un foreach recorre el resultado y lo imprime con interpolación de cadenas. Finalmente, el método retorna sb.ToString().
¿Cómo se detectan productos con stock bajo?
El método GenerarReporteStockBajo recibe un parámetro entero con valor mínimo de cinco [03:31]. Utiliza el operador Where de LINQ para filtrar productos cuya cantidad sea menor al umbral y OrderBy para ordenarlos por cantidad ascendente.
Si la colección resultante está vacía, imprime "No hay productos con stock bajo". De lo contrario, un foreach recorre cada producto e imprime su ID, nombre, cantidad y precio usando StringBuilder.
¿Cómo se generan rankings y exportaciones?
El método GenerarTopProductos también recibe un entero con valor cinco [04:21]. Aquí se aplica OrderByDescending para ordenar los productos según su valor total de manera descendente y Take para limitar la cantidad de resultados. Una variable posición se incrementa dentro del foreach para numerar cada producto en el ranking.
Para la exportación a CSV, el método ExportarCSV establece los encabezados con AppendLine: ID, nombre, precio, cantidad, categoría y valor total [05:09]. Luego ordena los productos por ID con OrderBy y escribe cada fila en el mismo orden.
¿Cómo se exporta el resumen a JSON?
El método ExportarResumenJSON construye un objeto anónimo con [05:37]:
- Total de productos calculado con
.Count().
- Valor total del inventario con
.Sum().
- Productos por categoría usando
GroupBy y Select.
- Top cinco productos con
OrderByDescending, Take(5) y Select.
Todo se serializa con JsonSerializer.Serialize, pasando JsonSerializerOptions con WriteIndented = true para una salida legible.
¿Cómo se prueba todo en Program.cs?
En Program.cs se crean seis productos mediante ProductoFactory.Crear: laptop, camisa, arroz, lámpara, balón y mesa, cada uno con precio, cantidad y categoría [06:25]. Se instancia GeneradorReportes y se imprimen los cinco métodos en consola.
La salida muestra:
- Seis productos en total con su valor de inventario.
- Un producto por categoría en este ejemplo.
- Lámpara, laptop y mesa como productos con stock bajo (menos de cinco unidades).
- Laptop en primer lugar del ranking con valor de 3600, seguida de camisa con 675, confirmando el orden descendente.
- El CSV y el JSON con todos los campos correctamente formateados.
LINQ es declarativo: expresa qué queremos obtener (filtrar, ordenar, sumar, agrupar) sin detallar cómo hacerlo paso a paso [08:27]. Esto produce código más legible y mantenible en comparación con loops manuales. Combinado con StringBuilder, que concatena cadenas de forma eficiente, se logran cinco métodos que responden preguntas reales sobre el inventario: métricas, alertas, rankings y exportación. ¿Qué otro reporte agregarías a este generador?