Skip to main content
GET
/
api
/
dashboard
/
rentabilidad
Reportes Avanzados del Dashboard
curl --request GET \
  --url https://api.example.com/api/dashboard/rentabilidad
{
  "200": {},
  "500": {},
  "success": true,
  "data": [
    {
      "nombre": "<string>",
      "cantidad": 123,
      "ingresos": 123,
      "costo_total": 123,
      "ganancia": 123,
      "margen_porcentaje": 123
    }
  ],
  "resumen": {
    "total_ingresos": 123,
    "total_ganancia": 123,
    "margen_general": 123
  }
}

Autenticación

Los endpoints de reportes requieren autenticación mediante token Bearer.

Reporte de Rentabilidad

GET /api/dashboard/rentabilidad Analiza la rentabilidad por producto calculando ingresos, costos, ganancia y margen de utilidad.

Parámetros de Query

fecha_inicio
date
Fecha de inicio del período (formato: Y-m-d). Por defecto: hace 7 días
fecha_fin
date
Fecha de fin del período (formato: Y-m-d). Por defecto: hoy
limit
integer
Número de productos a retornar (por defecto: 15)
empresa_id
integer
ID de la empresa a consultar

Respuesta

success
boolean
Indica si la operación fue exitosa
data
array
Lista de productos ordenados por ganancia descendente
resumen
object
Resumen financiero general

Ejemplo de Respuesta

{
  "success": true,
  "data": [
    {
      "nombre": "Arroz Extra Granel x 50kg",
      "cantidad": 245,
      "ingresos": 61250.00,
      "costo_total": 44100.00,
      "ganancia": 17150.00,
      "margen_porcentaje": 28.00
    },
    {
      "nombre": "Azúcar Rubia x 50kg",
      "cantidad": 198,
      "ingresos": 47520.00,
      "costo_total": 33660.00,
      "ganancia": 13860.00,
      "margen_porcentaje": 29.17
    },
    {
      "nombre": "Aceite Vegetal x 1L",
      "cantidad": 156,
      "ingresos": 9360.00,
      "costo_total": 7020.00,
      "ganancia": 2340.00,
      "margen_porcentaje": 25.00
    }
  ],
  "resumen": {
    "total_ingresos": 118130.00,
    "total_ganancia": 33350.00,
    "margen_general": 28.23
  }
}

Cálculo del Margen

El margen de utilidad se calcula así:
margen_porcentaje = CASE
  WHEN SUM(total) > 0
  THEN ROUND(
    ((SUM(total) - SUM(cantidad * costo)) / SUM(total)) * 100,
    2
  )
  ELSE 0
END
Esto evita división por cero y garantiza porcentajes precisos.

Uso del Reporte

  • Identificar productos más rentables para promociones
  • Detectar productos con bajo margen que necesitan ajuste de precio
  • Analizar margen general del negocio
  • Comparar rentabilidad entre productos similares

Ingresos vs Egresos

GET /api/dashboard/ingresos-egresos Compara ingresos y egresos diarios del período.

Respuesta

{
  "success": true,
  "data": [
    {
      "fecha": "2024-03-01",
      "ingresos": 5420.50,
      "egresos": 542.05
    },
    {
      "fecha": "2024-03-02",
      "ingresos": 6180.00,
      "egresos": 618.00
    },
    {
      "fecha": "2024-03-03",
      "ingresos": 4950.00,
      "egresos": 495.00
    }
  ]
}
Nota: Actualmente los egresos se estiman como el 10% de los ingresos. En una implementación futura, esto debe calcularse desde compras, gastos y movimientos de caja.

Top Fechas

GET /api/dashboard/top-fechas Identifica las fechas con mayor volumen de ventas en el período.

Parámetros

fecha_inicio
date
Por defecto: hace 30 días
fecha_fin
date
Por defecto: hoy
limit
integer
Número de fechas a retornar (por defecto: 10)

Respuesta

{
  "success": true,
  "data": [
    {
      "fecha": "2024-02-14",
      "total_ventas": 45,
      "monto_total": 18950.00
    },
    {
      "fecha": "2024-02-28",
      "total_ventas": 38,
      "monto_total": 16420.50
    },
    {
      "fecha": "2024-03-01",
      "total_ventas": 42,
      "monto_total": 15850.00
    }
  ]
}
Uso: Identificar patrones de días de mayor venta (quincenas, fin de semana, festivos).

Top Marcas

GET /api/dashboard/top-marcas Retorna las marcas más vendidas (actualmente usa la misma lógica que top-categorias). Nota: En este sistema, las marcas se gestionan mediante la tabla categorias. Si se requiere una tabla separada de marcas, este endpoint debe modificarse.

Integración de Reportes en el Frontend

Dashboard Principal

Combinar varios endpoints para una vista completa:
const [stats, setStats] = useState(null);
const [ventas, setVentas] = useState([]);
const [rentabilidad, setRentabilidad] = useState(null);

useEffect(() => {
  // Cargar datos en paralelo
  Promise.all([
    fetch('/api/dashboard/stats?fecha_inicio=2024-03-01&fecha_fin=2024-03-07'),
    fetch('/api/dashboard/ventas-por-dia?fecha_inicio=2024-03-01&fecha_fin=2024-03-07'),
    fetch('/api/dashboard/rentabilidad?fecha_inicio=2024-03-01&fecha_fin=2024-03-07')
  ]).then(([statsRes, ventasRes, rentRes]) => {
    setStats(statsRes.data);
    setVentas(ventasRes.data);
    setRentabilidad(rentRes);
  });
}, []);

Gráficos Recomendados

Ventas por Día (Línea Comparativa)

import { LineChart, Line } from 'recharts';

<LineChart data={ventas}>
  <Line dataKey="total" name="Período Actual" stroke="#c7161d" />
  <Line dataKey="total_anterior" name="Período Anterior" stroke="#ece6a3" />
</LineChart>

Métodos de Pago (Dona)

import { PieChart, Pie } from 'recharts';

<PieChart>
  <Pie data={metodosPago} dataKey="total" nameKey="nombre" />
</PieChart>

Rentabilidad (Barras Agrupadas)

import { BarChart, Bar } from 'recharts';

<BarChart data={rentabilidad.data}>
  <Bar dataKey="ingresos" fill="#82ca9d" />
  <Bar dataKey="costo_total" fill="#8884d8" />
  <Bar dataKey="ganancia" fill="#ffc658" />
</BarChart>

Ventas por Hora (Barras)

<BarChart data={ventasPorHora}>
  <Bar dataKey="total_ventas" fill="#c7161d" />
</BarChart>

Filtros Recomendados

Implementar filtros comunes en el dashboard:
const [filtros, setFiltros] = useState({
  fecha_inicio: format(subDays(new Date(), 7), 'yyyy-MM-dd'),
  fecha_fin: format(new Date(), 'yyyy-MM-dd'),
  empresa_id: 1
});

// Botones rápidos
const periodos = [
  { label: 'Hoy', dias: 0 },
  { label: 'Últimos 7 días', dias: 7 },
  { label: 'Últimos 30 días', dias: 30 },
  { label: 'Este mes', custom: true }
];

Consideraciones de Rendimiento

  • Caché: Considerar cachear resultados por 5-15 minutos
  • Paginación: Los endpoints de listas usan limit para controlar resultados
  • Índices BD: Asegurar índices en fecha_emision, id_empresa, estado
  • Agregaciones: Los cálculos de SUM/COUNT se realizan en la base de datos

Códigos de Error

Todos los endpoints de dashboard retornan:
200
object
Respuesta exitosa con datos
500
object
Error interno del servidor (poco común, los endpoints manejan excepciones)
{
  "success": false,
  "message": "Error al calcular estadísticas"
}

Próximas Mejoras

  1. Egresos reales: Integrar con compras y gastos en lugar de estimación
  2. Comparación de años: Permitir comparar mismo período del año anterior
  3. Exportar reportes: Agregar endpoints para exportar a Excel/PDF
  4. Alertas: Notificaciones automáticas cuando KPIs caen
  5. Predicciones: ML para predecir ventas futuras basado en histórico

Build docs developers (and LLMs) love