# Fórmulas exactas de KPIs · Troost
**Fecha:** 2026-05-15
**Sprint:** 8
> Este documento define la fórmula exacta de cada uno de los 8 KPIs estándar que Troost calcula y muestra al usuario. Para credibilidad ante consultores, contadores y auditores.
Cada KPI incluye:
- **Fórmula**: definición matemática
- **Fuente de datos**: tabla(s) y campos
- **Frecuencia de cálculo**: cuándo se recalcula
- **RPC**: función SQL que lo implementa
- **Meta industria**: umbral de referencia
- **Caveat**: limitaciones / supuestos
---
## KPI 1 · CPK (Costo Por Kilómetro)
### Fórmula
```
CPK_real = (gastos_fiscales + gastos_no_fiscales) / km_totales
CPK_fiscal = gastos_fiscales / km_totales
```
### Fuente de datos
- `v_finanzas_unificadas` (vista) — agrega gastos por categoría (combustible, mantenimiento, sueldos, misc, no_fiscal)
- `cargas_combustible.km_odometro` — kilómetros derivados de `MAX(km_odometro) - MIN(km_odometro)` por unidad (requiere ≥2 cargas/unidad)
### Frecuencia
On-demand al cargar `/dashboard` o `/reportes`. Recálculo cada vez.
### RPC
`public.cpk_completo(empresa_id, desde, hasta)` → JSONB con `cpk_real`, `cpk_fiscal`, desglose por categoría.
### Meta industria
**$28 MXN/km o menos** (estándar consultor para flotas de carga general en México).
### Caveat
- Si en el período hay <2 cargas de combustible por unidad, los km de esa unidad no cuentan. Resultado: CPK puede estar subestimado.
- "No fiscal" incluye mordidas, propinas, regalos. Esto hace el CPK_real más estricto que estándares de competencia que solo usan CFDI.
---
## KPI 2 · Utilidad por viaje (margen)
### Fórmula
```
margen_pct = (ingresos - gastos) / ingresos * 100
```
A nivel **empresa** (todo el período).
A nivel **flete individual** (futuro, no implementado aún): mismo cálculo pero `ingresos = precio_flete` y `gastos = gastos atribuibles a ese flete vía v_finanzas_unificadas.relacionado_id`.
### Fuente de datos
- `kpis_dashboard` RPC retorna `margen_pct` empresa
- `top_unidades` RPC retorna `margen_pct` por unidad
### Frecuencia
On-demand.
### RPC
`public.kpis_dashboard(empresa_id, desde, hasta)` → field `margen_pct`.
### Meta industria
**15% o más** (margen bruto antes de depreciación y financiamiento).
### Caveat
- Hoy se mide a nivel empresa-mes. Por flete individual queda como gap (ver auditoría KPI).
- No considera depreciación contable de las unidades. Un transportista con flota vieja sin pagar puede mostrar margen mayor que uno con flota nueva en pagos.
---
## KPI 3 · Rentabilidad por unidad
### Fórmula
```
rentabilidad_pct_unidad = (ingresos_unidad - gastos_unidad) / ingresos_unidad * 100
```
Donde `gastos_unidad` se agrega de `v_finanzas_unificadas WHERE relacionado_tipo = 'unidad' AND relacionado_id = unidad.id`.
### Fuente de datos
- `top_unidades` RPC
### Frecuencia
On-demand al cargar `/reportes` tab "Por Unidad".
### RPC
`public.top_unidades(empresa_id, desde, hasta, criterio)` → array con `margen_pct` por unidad.
### Meta industria
**>20%** de unidades de la flota con margen >20% (un consultor diría "más del 50% de tu flota debe estar arriba del 20% de margen, idealmente todas").
### Caveat
- No reasigna gastos compartidos (sueldo de oficina, alquiler) — son `relacionado_tipo = 'empresa'`, no se cargan a unidades.
- Una unidad con poca actividad pero gastos fijos altos sale negativa. Eso es honesto.
---
## KPI 4 · Rendimiento de diésel (km/L)
### Fórmula
```
kml_unidad = (MAX(km_odometro) - MIN(km_odometro)) / SUM(litros)
```
Por unidad en el período. Promedio global ponderado por km totales.
### Fuente de datos
- `cargas_combustible.km_odometro`, `cargas_combustible.litros`
### Frecuencia
On-demand.
### RPC
`public.rendimiento_diesel(empresa_id, desde, hasta)` → JSONB con `kml_global` y `por_unidad`.
### Meta industria
**2.8 km/L o más** (flota de carga pesada diésel · estándar mexicano).
### Caveat
- Requiere ≥2 cargas/unidad para calcular delta odómetro. Una unidad con 1 carga no aparece.
- Si el operador olvida actualizar odómetro en una carga, el cálculo se distorsiona.
- No distingue tipo de combustible (diésel vs gasolina). Asume diésel.
---
## KPI 5 · Ralentí (% tiempo motor encendido sin movimiento)
### Fórmula
```
ralenti_pct = tiempo_motor_encendido_sin_movimiento / tiempo_motor_encendido_total * 100
```
### Fuente de datos
**No implementado.** Requiere:
- Campo `posiciones_gps.ignicion_motor BOOLEAN` (NO existe hoy)
- O hardware OBD-II que reporte estado de ignición
### Frecuencia
N/A (no implementado).
### RPC
N/A. Pendiente: `ralenti_por_unidad(empresa, desde, hasta)`.
### Meta industria
**<5%** del tiempo en operación.
### Caveat
- Sin hardware específico (kit GPS+Cámara $1,500 MXN/unidad disponible en `/hardware`) no se puede calcular con precisión.
- Aproximación posible (sin hardware): unidad estática >15 min mientras flete está `en_transito` cuenta como ralentí presunto. Es proxy débil — no se publica como KPI sin el kit.
---
## KPI 6 · Kilómetros vacíos (% deadhead)
### Fórmula
```
km_vacios_pct = km_sin_carga / km_totales * 100
```
### Fuente de datos
**No implementado.** Requiere:
- Captura explícita de `fletes.km_retorno_vacio` o
- Inferencia: para cada par de fletes consecutivos de la misma unidad, km entre destino_flete_n y origen_flete_n+1 son vacíos. Hoy no se calcula automáticamente.
### Frecuencia
N/A.
### RPC
N/A. Pendiente: `km_vacios_por_unidad(empresa, desde, hasta)`.
### Meta industria
**<20%** del kilometraje total.
### Caveat
- Schema requiere agregar columnas: `fletes.km_cargado NUMERIC` y `fletes.km_retorno_vacio NUMERIC`.
- Marketplace de retornos vacíos (incluido en plan Pro) reduce este KPI naturalmente.
---
## KPI 7 · Entregas a tiempo
### Fórmula
```
pct_a_tiempo = COUNT(fletes entregados ON TIME) / COUNT(fletes entregados) * 100
donde "ON TIME" = fecha_entrega_real <= fecha_entrega_estimada
```
### Fuente de datos
- `fletes.fecha_entrega_real`, `fletes.fecha_entrega_estimada`, `fletes.estado = 'entregado'`
### Frecuencia
On-demand.
### RPC
- `public.top_operadores(...)` retorna `pct_a_tiempo` por operador
- `public.kpis_industria_consolidado(...)` retorna `entregas_a_tiempo` global empresa
### Meta industria
**>95%** (cliente shipper típico exige >95%).
### Caveat
- Fletes sin `fecha_entrega_estimada` (que el dispatcher olvidó capturar) se excluyen del cálculo. Recomendación: el form de creación de flete debe requerir fecha estimada.
- Definición de "a tiempo" usa la fecha COMPROMETIDA al cliente. Si el dispatcher infla la ETA para "siempre llegar a tiempo", se distorsiona. La buena práctica es no permitir editar `fecha_entrega_estimada` después de que el flete entra en estado `confirmado` — pendiente de implementar.
---
## KPI 8 · Fallas mecánicas
### Fórmula
```
tasa_fallas_pct = (servicios_correctivos + servicios_emergencia) / fletes_periodo * 100
```
### Fuente de datos
- `servicios_mantenimiento.tipo_servicio IN ('correctivo','emergencia')` (Sprint 8 · nueva columna)
- `fletes` count del período
### Frecuencia
On-demand.
### RPC
`public.tasa_fallas_mecanicas(empresa_id, desde, hasta)` → JSONB con `tasa_pct`, conteos por tipo.
### Meta industria
**<2%** (lo controlable por el transportista — mantenimiento preventivo bien hecho lo logra).
### Caveat
- Distingue preventivo (planeado · servicio en taller) vs correctivo (falla detectada · arreglo necesario) vs emergencia (la unidad se quedó parada).
- Solo cuenta correctivos + emergencias contra fletes totales. Si la unidad estuvo parada 5 días por falla, no se penaliza adicionalmente.
- Pre-Sprint 8 todos los servicios eran "preventivos" por default. Para datos históricos previos, el founder debe corregir la categorización a mano.
---
## Validación cruzada
El bloque `BloqueKPIsIndustria` en `/dashboard` consume la RPC `kpis_industria_consolidado` que internamente llama a las RPCs específicas de cada KPI. Si en algún momento un KPI muestra un valor que el founder considera incorrecto, debe verificarse:
1. Que los datos de origen están presentes (cargas de combustible, fletes con `fecha_entrega_real`, servicios con `tipo_servicio` correcto, etc.)
2. Que el período seleccionado tiene actividad suficiente
3. Que no hay registros con `soft_delete_at NOT NULL` que el cliente no esperaba
---
## Referencias industria
- **CESVI México** — costo promedio incidente vehicular
- **AMESIS** — recuperación 95.5% con monitoreo activo · tiempos respuesta 45 min foráneo / 28 min urbano
- **CANACAR · ANTP** — costos operativos transporte carga México
- **Overhaul** — Reporte Anual de Robo de Carga
- **BBVA-AMPIP** — encuesta de parques industriales
---
Querétaro · Mayo 2026
Documentación pública
Fórmulas exactas de los 8 KPIs
Si un consultor, contador o auditor te pregunta cómo calcula Troost un KPI, esta página tiene la respuesta exacta. Compartido públicamente como compromiso de honestidad operativa.