El Excel de avance muestra fechas REALES por tarea (primer y último día trabajado), no el calendario plan; '—' = sin iniciar

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Johann
2026-09-16 10:28:47 -06:00
parent 69e06dfd8c
commit 68aedc7863
2 changed files with 77 additions and 1 deletions
+77 -1
View File
@@ -2,7 +2,13 @@
Corte del miércoles 16-sep: sin sesiones ni desarrollo nuevos desde el 15-sep;
solo se publicó el Excel de avance en Google Sheets (Drive/Balam) y se
regeneró este corte. El corte del 15-sep no se toca. Las horas se leen de
regeneró este corte. El corte del 15-sep no se toca.
Además, a petición de Johann (16-sep), las columnas Inicio/Fin dejan de
mostrar las fechas PLAN y muestran las fechas REALES: primer y último día
trabajado de cada tarea según `Seguimiento-horas.csv`, la bitácora y los
commits ("—" = sin iniciar; las tareas en curso llevan como Fin el último día
trabajado). Las fechas plan quedan en Avance-Balam-2026-08-06b.xlsx. Las horas se leen de
`Seguimiento-horas.csv`; el script aborta si el reparto no cuadra con las
horas nuevas del CSV.
"""
@@ -61,6 +67,59 @@ ENCABEZADOS = {
"Etapa 3": (E3, 0.05),
}
# --- Fechas reales por fila (dd/mm/yyyy o "—") ---------------------------------
# Trazabilidad: CSV (fecha por actividad), REGISTRO.md y commits de ambos repos.
SIN_INICIAR = ("—", "—")
FECHAS_REALES = {
"Integracion de plataformas Balam": ("01/07/2026", "16/09/2026"), # en curso
"Etapa 0": ("01/07/2026", "24/07/2026"), # validada por Balam el 24-jul
"Sesión de arranque (kickoff)": ("01/07/2026", "01/07/2026"),
"Sesión de Discovery": ("06/07/2026", "07/07/2026"), # facturación 6-jul, cobranza 7-jul
"Entrega y validación de accesos": ("06/07/2026", "06/07/2026"),
"Validación técnica de la API de BIND": ("06/07/2026", "06/07/2026"), # 117 GETs, adelantada un día
"Prototipo visual navegable": ("08/07/2026", "10/07/2026"),
"Documento de hallazgos": ("10/07/2026", "10/07/2026"), # PDF + correo del 10-jul
"Sesión de validación del prototipo": ("23/07/2026", "24/07/2026"), # guion 23-jul, sesión 24-jul
"Etapa 1": ("13/07/2026", "03/09/2026"), # técnica cerrada 1-ago; publicación provisional 3-sep
"Demostración semanal": ("15/07/2026", "16/09/2026"), # gestión y cortes, en curso
"Repositorio privado GitHub": ("13/07/2026", "16/07/2026"), # push del scaffold 16-jul
"Backend base": ("13/07/2026", "19/07/2026"), # B0–B2 el 19-jul
"Arquitectura multi-tenant": ("14/07/2026", "01/08/2026"), # RLS 21-jul, verificación balam_app 1-ago
"Cliente de la API de BIND": ("15/07/2026", "15/07/2026"),
"Capa de escritura controlada": ("19/07/2026", "23/08/2026"), # diseño 19-jul; cotización 11-ago; prefactura 23-ago
"Sincronización de clientes": ("19/07/2026", "19/07/2026"), # B3
"Configuración de infraestructura en Azure": ("03/09/2026", "03/09/2026"), # publicación provisional en paputec.mx
"Sincronización de facturas": ("21/07/2026", "01/08/2026"), # B4 21-jul; scheduler B5 1-ago
"Sesión de reglas y dudas": ("21/07/2026", "22/07/2026"), # agenda 21-jul, sesión 22-jul
"Definición de alcance Jira": ("22/07/2026", "07/08/2026"), # v1.3 aprobada 30-jul; definiciones cerradas 7-ago
"Modelo de facturas": ("21/07/2026", "01/08/2026"), # mapper 21-jul; seeder demo 1-ago
"CI/CD": ("03/09/2026", "03/09/2026"), # deploy.sh + secretos fuera del repo
"Etapa 2": ("01/08/2026", "10/09/2026"), # en curso
"» Ajuste dentro de la Etapa 2": ("27/07/2026", "03/09/2026"), # sesión con Pedro 27-jul → tickets cotizados 3-sep
"Cliente de la API de Jira": ("29/07/2026", "06/08/2026"),
"Disparador por estatus": ("20/08/2026", "07/09/2026"), # sondeo FAC-106 → folio 1026 (21-ago) → lote 7-sep
"Trazabilidad ticket": ("10/08/2026", "03/09/2026"), # definiciones → pruebas observadas
"Andamiaje del frontend": ("16/07/2026", "01/08/2026"), # scaffold 16-jul; login JWT 1-ago
"Layout base": ("01/08/2026", "06/08/2026"),
"Listado de facturas": ("01/08/2026", "01/08/2026"),
"Detalle de factura": ("01/08/2026", "01/08/2026"), # PDF; XML pendiente
"Catálogo de clientes": ("01/08/2026", "01/08/2026"),
"Tipo de cambio del DOF": SIN_INICIAR,
"Creación de cotizaciones desde la plataforma": ("06/08/2026", "07/09/2026"), # wizard UI 6-ago → lote 7-sep
"Conversión cotización→factura": ("06/08/2026", "10/09/2026"), # simulación 6-ago → captura del endpoint 10-sep
"Exportación de facturas": ("01/08/2026", "01/08/2026"), # CSV
"Pruebas integrales": SIN_INICIAR,
"Etapa 3": ("03/09/2026", "03/09/2026"), # solo endurecimiento y runbook
"Módulo de cobranza": SIN_INICIAR,
"Alertas internas": SIN_INICIAR,
"Tablero directivo": SIN_INICIAR,
"Reporte operativo": SIN_INICIAR,
"Endurecimiento de seguridad": ("03/09/2026", "03/09/2026"),
"Documentación técnica": ("03/09/2026", "03/09/2026"),
"Sesión de capacitación": SIN_INICIAR,
"Soporte posterior": SIN_INICIAR,
}
FILAS = {
"Demostración semanal": (0.6, "🟡 En curso · el seguimiento pasó a Pedro (sesiones 'Seguimiento PAF' "
"21, 24 y 26-ago; 3, 9 y 10-sep) · corte de horas al 16-sep, publicado en "
@@ -81,6 +140,8 @@ ws["A2"] = ("Plan y avance al 16-sep-2026 · plataforma publicada en paputec.mx
"desde el ticket (individual y en lote); prefactura por API bloqueada por BIND · horas del "
"10-ago al 16-sep reconstruidas, pendientes de validar")
ws["A2"].font = Font(size=10, italic=True, color=GRIS)
ws.cell(row=4, column=2, value="Inicio (real)")
ws.cell(row=4, column=3, value="Fin (real)")
# Notas del corte anterior: se limpian antes del bucle y se reescriben abajo.
primera_nota = None
@@ -96,10 +157,20 @@ for row in range(5, ws.max_row + 1):
tope = primera_nota if primera_nota else ws.max_row + 1
aplicado = set()
fechas_aplicadas = set()
for row in range(5, tope):
nombre = str(ws.cell(row=row, column=1).value or "").strip()
if not nombre:
continue
for prefijo, (ini, fin) in FECHAS_REALES.items():
if nombre.startswith(prefijo):
for col, val in ((2, ini), (3, fin)):
cel = ws.cell(row=row, column=col, value=val)
cel.alignment = Alignment(horizontal="center", vertical="center")
if val == "—":
cel.font = Font(size=9, color=GRIS)
fechas_aplicadas.add(prefijo)
break
for prefijo, (trab, pct) in ENCABEZADOS.items():
if nombre.startswith(prefijo):
c = ws.cell(row=row, column=C_TRAB, value=round(trab, 2))
@@ -128,6 +199,8 @@ for row in range(5, tope):
faltan = set(DELTAS_TRAB) - aplicado
assert not faltan, f"Filas no encontradas en el Excel: {faltan}"
faltan_fechas = set(FECHAS_REALES) - fechas_aplicadas
assert not faltan_fechas, f"Filas sin fecha real aplicada: {faltan_fechas}"
notas = [
("✅ Completada · 🟡 En curso · 🔴 Pendiente/bloqueada · ⚪ Próxima · "
@@ -151,6 +224,9 @@ notas = [
"interno y decidir el camino (réplica, detección al timbrado o soporte de BIND).", False),
("En espera de Balam: acceso a Azure (requisitos enviados el 25-ago), cancelación del CFDI 2386 "
"y de la cotización 1026, y la definición del camino de prefactura.", False),
("Fechas: Inicio y Fin son REALES (primer y último día trabajado según el registro de horas, la "
"bitácora y los commits); las tareas en curso llevan como Fin el último día trabajado y '—' "
"significa sin iniciar. El calendario plan original está en el corte del 6-ago.", False),
]
r = primera_nota if primera_nota else ws.max_row + 2
for txt, bold in notas: