MOC: Pipeline de Costos
tags:
- ingelcoding
- pipeline
- costos
- moc created: 2026-04-11 type: moc status: activo portal: id: costos ejecutiva: | Calcula el costo operativo mensual por brigada (personal, flota, gastos generales) usando el plantel con vigencias y el tarifario que mantiene gerencia en Google Sheets. Alimenta las hojas COSTOS OS/CH y METAS MES que cruzan contra HH presupuestadas para medir rentabilidad — reemplaza la hoja manual que se armaba cada mes. tecnica: | Patrón: SCD en memoria (plantel × calendario y tarifario × calendario con forward-fill) resuelto por cross join vectorizado — permite backfill histórico cambiando solo date_range. Cantidades con sentinels en config/costos_cantidades_fijas.yaml (-1 = trabajadores activos, -2 = 20 × n_trabajadores para alimentación, 0, N>0). Salida: ResultadoCostos dataclass con 3 niveles (detalle, por_brigada_mes, costo_por_hh) → Excel local + COSTOS OS/CH + METAS MES en Sheets. Rentabilidad esperada vive en config/costos_rentabilidad.yaml (política separada de Brigadas-P). Detalle: MOC con 5 sub-notas (Fuentes de Verdad, Reglas de Negocio, Golden Values, Arquitectura Python, Plan de Implementación).
Este MOC centraliza la documentación del pipeline que reemplaza las hojas de cálculo de costos por un cálculo estructurado y vectorizado en memoria usando Python y pandas. Su objetivo final es generar costos operativos mensuales por brigada (HH_Deseada).
Índice de Contenidos
Sección titulada «Índice de Contenidos»- Pipeline Costos - Fuentes de Verdad
- Pipeline Costos - Reglas de Negocio
- Pipeline Costos - Golden Values y Validacion
- Pipeline Costos - Arquitectura Python
- Pipeline Costos - Plan de Implementacion
Implementación actual verificada (2026-06-07)
Sección titulada «Implementación actual verificada (2026-06-07)»El pipeline Python computa toda la lógica de costos por brigada-mes de forma autónoma; no depende de fórmulas de Google Sheets. Lee insumos crudos directamente:
- Hoja “Brigadas (P)” — plantel con vigencias (SCD en memoria, forward-fill)
- Hoja “TARIFARIO COSTOS” — tarifas con vigencias (SCD en memoria, forward-fill)
config/costos_cantidades_fijas.yaml— sentinels:-1= trabajadores activos,-2= 20 × n_trabajadores (alimentación),0,N>0config/costos_rentabilidad.yaml— rentabilidad esperada por brigada (política separada)
Reconstruye en Python: cross-join brigada × mes × ítem, conteo personal/vehículos (_FLOTA_MAP), convención -1/-2 de gastos, rentabilidad por brigada, costo por HH con divisor 20 días.
Salida ResultadoCostos — 3 niveles:
| Nivel | Columnas | Descripción |
|---|---|---|
detalle | 9 cols | Grano brigada × mes × ítem |
por_brigada_mes | 11 cols | Resumen por brigada y mes |
costo_por_hh | 16 cols | Métricas HH por brigada y mes |
Mapeo fila hoja COSTOS OSORNO → campo Python (verificado contra la hoja real):
| Fila | Campo Python | Etiqueta / Nota |
|---|---|---|
| 37 | total_sin_vehiculos | Subtotal sin flota |
| 38 | total_valor_brigada | Total con flota |
| 39 | rentabilidad | Rentabilidad (REAL) |
| 40 | total_sin_vhc_utilidad | Sin vehículos + utilidad |
| 41 | total_costos_utilidad | ”META ZONAL” — con vehículos + utilidad |
| 44 | hb_dia_total | ”HB Día Total 20 días” — etiqueta col B “MANT. CORRECTIVO”, CON vehículos (ex hb_dia_esperado, rename 2026-06-08) |
| 47 | hb_mensual_sv | HB mensual sin vehículos |
| 48 | hb_dia_prod | Etiqueta “PROGRAMACIÓN” — SIN vehículos (ex hb_dia_esperado_sv, rename 2026-06-08) |
| 49 | id_Brigada | Identificador de brigada |
| 52 | selector MES | — |
Estado de persistencia actual: escribe a Excel (costos_report.xlsx), GSheets (hojas COSTOS OSORNO / CHILOÉ) y a data_warehouse.db vía export_costos() integrada en populate() (commit 64febc8, 2026-06-08). No está registrado en run_pipeline.py (PIPELINES_V2) — la integración es por populate(), no por el orquestador de pipelines V2.
Decode de METAS MES0 / METAS MES (verificado)
Sección titulada «Decode de METAS MES0 / METAS MES (verificado)»METAS MES0 NO es un cálculo: es un reshape (transpose). Fórmulas de la hoja:
=TRANSPONER('COSTOS OSORNO'!D49:P49)→ columnaid_Brigada=TRANSPONER('COSTOS OSORNO'!D44:P44)→ columnaHB Día Esperado
Las 13 brigadas de Osorno están como columnas (D:P) en la planilla; TRANSPONER las vuelve filas. Resultado: tabla de 2 columnas [id_Brigada, HB Día Esperado] para el mes del selector.
METAS MES = solo apila verticalmente los METAS MES0 de varios meses (serie histórica). Existe por la limitación de que la planilla calcula 1 mes a la vez; para obtener la serie se repite el proceso manualmente mes a mes y se concatenan las filas.
Migración a .db — IMPLEMENTADO (2026-06-08, commit 64febc8)
Sección titulada «Migración a .db — IMPLEMENTADO (2026-06-08, commit 64febc8)»El ADR de diseño (ahora con status Implementada/Aceptada) está en ADR-Costos-Metas-a-DW.
Qué se construyó (change SDD costos-metas-a-dw, archivado en openspec/changes/archive/2026-06-08-costos-metas-a-dw/):
export_costos()enscripts/db/data_warehouse.py: ejecuta fases 1–3 del pipeline, extraeResultadoCostos.costo_por_hhy persiste enfact_costos_hhcon replace+guard de vacío. Integrada enpopulate()con flag--no-costos. Índiceidx_fact_costos_hh_zonal_brigada_mes.- Tabla
fact_costos_hh: grano(zonal, id_Brigada, mes), 16 columnas, endata_warehouse.db. - Vista
metas_mes:SELECT mes, zonal, id_Brigada, hb_dia_total FROM fact_costos_hh. Reemplaza el reshape+acumulación manual de la planilla GSheets. - Rename de campos (BREAKING):
hb_dia_esperado → hb_dia_total(fila 44, CON vehículos) yhb_dia_esperado_sv → hb_dia_prod(fila 48, SIN vehículos). Propagado vía constanteCOSTO_POR_HH_COLSencostos_schema.pya los 4 consumidores Python. Nombres en SQLite quedan en Title_Case (Hb_Dia_Total,Hb_Dia_Prod) por normalización desave_dataframe. - Mapping Supabase:
fact_costos_hhañadida aMAPPINGS_DATA_WAREHOUSEenmigrate_config.py. - Tests: 7/7 PASSED en
tests/test_export_costos.py. Suite global sin regresiones.
⚠️ BREAKING CHANGE: el rename es destructivo para consumidores externos (Excel/GSheets/PBI) que referencien
hb_dia_esperadoohb_dia_esperado_sv. Actualizar Power BI antes de conectarfact_costos_hhal modelo.
Pendiente (fuera de scope del change implementado):
- Conectar
fact_costos_hhcondim_calendarioy dimensión de brigadas en Power BI - Deprecar hojas COSTOS OS/CH y METAS MES manuales en GSheets (post-validación DW)
- Considerar
fact_costos_detalle(granobrigada × mes × ítem) para auditoría