Documenta semana 24-27 jul: validación de prototipo (aprobada), API de Jira y avance de Etapa 1
- REGISTRO #55: validación del prototipo Etapa 0 (24-jul) APROBADA; único bloqueo = definir el flujo de facturación en Jira (sesión propuesta por Araceli para el martes 28) - REGISTRO #56: sesión de API de Jira con Pedro (27-jul) — token PAF a 1 año, bandeja FAC; + seguimiento por correo del mismo día con los límites de velocidad (65k puntos/h, burst/s, por-issue) y entrega del token por Google Drive - REGISTRO #57: hilo de WhatsApp con Erika (21-27 jul) — coordinación, envío del flujo por correo y reagenda 23→24 jul; 3 imágenes inferidas - Transcripciones y correo en fuentes/; guion de validación en planeacion/ - Avance-Etapa1-2026-07-27 (nota + mensaje para Erika) y Excel del corte del 27-jul (núcleo verificado; capa de escritura en pausa por definición de Balam) - Seguimiento-horas: sesiones del 24-jul (validación) y 27-jul (API Jira) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# Corte de avance — Etapa 1
|
||||
|
||||
**Fecha:** 27-jul-2026 (corte de los lunes, formato pedido por Erika: entregable + actividad + horas por etapa)
|
||||
**Etapa:** Plataforma base y sincronización con BIND
|
||||
**Rango estimado contractual:** 32–39 h · **Horas registradas de Etapa 1:** 17.0 h
|
||||
**Adjunto:** `Plan-actividades-avance-2026-07-27.xlsx`
|
||||
|
||||
> Documento interno de Johann. El mensaje para Erika va abajo; el resto es sustento propio (no se comparte).
|
||||
|
||||
---
|
||||
|
||||
## Mensaje breve para Erika (WhatsApp)
|
||||
|
||||
> Hola Erika, buen día. Te comparto el avance de la Etapa 1 al corte de hoy (Excel adjunto, con entregable · actividad · horas por etapa como lo pediste).
|
||||
>
|
||||
> El **núcleo de la plataforma ya está construido y probado contra producción**: autenticación con roles y bitácora de auditoría, arquitectura multi-tenant con aislamiento por RLS, el cliente de la API de BIND, la sincronización de clientes, facturas y cotizaciones, el modelo central de facturas con sus estados y la cartera separada por moneda. La sincronización del histórico ya corrió y cuadró: **1,494 facturas** con sus totales de cartera coincidiendo con BIND.
|
||||
>
|
||||
> Lo que sigue pendiente es, sobre todo, la **capa de escritura (cotización→factura), que dejé en pausa a propósito hasta que definan el flujo de facturación en la sesión del martes**, ya que de ahí dependen las reglas. También quedan por cerrar el afinado de datos de prueba y la parte de Azure/CI-CD, que depende de los accesos de su lado.
|
||||
>
|
||||
> En horas voy en **17 h de Etapa 1** (rango estimado 32–39 h). Con la key de Jira que nos pasó Pedro hoy y las definiciones del martes, arranco la integración con Jira y la capa de escritura. Cualquier duda quedo al pendiente. 🙌
|
||||
|
||||
*(Nota: el ajuste de la propuesta y el conteo de horas formal van por separado; este mensaje es solo el avance de Etapa 1.)*
|
||||
|
||||
---
|
||||
|
||||
## Sustento interno
|
||||
|
||||
### Terminado y verificado contra producción
|
||||
- **Backend base:** autenticación con JWT propio, matriz de roles (Finanzas, Dirección, Operaciones, Administración) con policies, y **bitácora de auditoría universal** (logins, sync, transiciones, escritura). — *entregable contractual 1* ✅
|
||||
- **Multi-tenant + RLS real de Postgres** (no solo filtro EF): políticas `tenant_isolation` fail-closed en las 8 tablas de negocio + interceptor de conexión. — *entregable 2* ✅ *(verificación de aislamiento local pendiente de rol de app no-superusuario; las políticas ya están correctas — ver REGISTRO #53)*
|
||||
- **Cliente productivo de BIND** en C#: paginación OData, reintentos, control de cuota y errores; solo lectura por defecto. — *entregable 3* ✅
|
||||
- **Sync de clientes** (full-scan barato + hash + detalle solo de nuevos/cambiados, normalización RFC/nombre, dedup por RFC exacto). — *entregable 5* ✅
|
||||
- **Sync de facturas y cotizaciones** con estados normalizados, tipo de cambio y detección de pagos (fecha de detección, ADR-004). — *entregable 6* ✅
|
||||
- **Modelo central de facturas con estados** (Emitida, Vigente, Vencida, Pagada, Cancelada) como función pura con pruebas. — *entregable 7* ✅
|
||||
- **Cartera por moneda** (jamás suma monedas): `GET /api/cartera` verificado BD↔endpoint — MXN 17 abiertas $1,568,772.32 · USD 92 abiertas $320,379.06.
|
||||
- **Sync histórico corrido y verificado** (jamás en vivo): 1,494 facturas + 43 cotizaciones, detalle 1,494/1,494, idempotencia comprobada, 0 pagos falsos. (REGISTRO #52)
|
||||
- 26/26 pruebas unitarias verdes.
|
||||
|
||||
### En construcción / en pausa
|
||||
- **Capa de escritura controlada (cotización→factura)** — *entregable 4*. 🔴 **En pausa deliberada** hasta la definición del flujo de facturación (sesión martes 28-jul con Arturo/Araceli): de ahí salen las reglas de prefactura, PPD/PUE, alta de cliente y qué estatus de Jira dispara qué. El andamiaje (pipeline dry-run→confirm, flags apagados, `WriteOperations`) está diseñado; se implementa contra las reglas ya cerradas.
|
||||
- **Scheduler + backfill** (sync programado cada 15 min) — el sync ya funciona en manual; falta automatizarlo.
|
||||
- **Datos de prueba (seeder) + runbook** — *entregable 8*: migraciones ✅, seeder ficticio pendiente.
|
||||
- **Suite de pruebas de flujos críticos** (integración) — pendiente.
|
||||
|
||||
### Dependencias externas (lado Balam)
|
||||
- **Definición del flujo de facturación/prefacturación** — sesión martes 28-jul (Erika coordina). Desbloquea la capa de escritura.
|
||||
- **Correo del flujo de facturación de Jira** (Erika lo envió 22-jul) — a incorporar.
|
||||
- **Token de Jira (PAF)** recibido el 27-jul + docs de Atlassian; falta confirmar límites de consumo (Pedro investiga). Bandeja: **Facturación (FAC)**.
|
||||
- **Acceso a Azure + CI/CD** (Pedro/Noé) — condiciona el despliegue.
|
||||
|
||||
## Criterio de medición
|
||||
- **Horas de Etapa 1:** 17.0 h registradas de un rango de 32–39 h (**~44–53 % del esfuerzo estimado**).
|
||||
- **Entregables contractuales:** **6 de 8 terminados** (1, 2, 3, 5, 6, 7); el 8 parcial (migraciones sí, seeder no); el 4 (escritura) en pausa por definición de Balam.
|
||||
- Se reporta por hora + entregable, no un porcentaje global único, para no dar una cifra engañosa. El Excel muestra ~82 % ponderado por actividad porque el trabajo restante (escritura, seeder, scheduler) es de menor peso que el núcleo ya hecho, pero **la escritura está bloqueada por la definición pendiente de Balam**, no por avance de desarrollo.
|
||||
|
||||
## Puntos de juicio a confirmar por Johann antes de enviar
|
||||
1. **Horas 22–27 jul:** solo cargué las sesiones documentadas (reglas 22-jul 0.80 h, validación 24-jul 1.05 h como Etapa 0, API Jira 27-jul 0.20 h). Si trabajaste desarrollo adicional en esa ventana, hay que sumarlo.
|
||||
2. **% de Etapa 1 (82 %):** es el valor ponderado heredado del corte del 21-jul + avance; si prefieres una lectura más conservadora (por horas, ~50 %), lo ajusto.
|
||||
3. **Tono del mensaje:** el borrador enmarca la capa de escritura como "en pausa por la definición del 28-jul" (pone la pelota de su lado, y es verdad). Si prefieres suavizarlo, lo cambio.
|
||||
@@ -0,0 +1,119 @@
|
||||
# Guion — Validación del prototipo Etapa 0 (jue 23-jul, 7:00 pm)
|
||||
|
||||
**Material:** `../prototipo/Prototipo-Balam-Etapa0.pdf` (11 páginas) + demo en paputec.mx/balam.
|
||||
**Meta de la sesión:** que digan "sí, así opera Balam" pantalla por pantalla → cierra la Etapa 0.
|
||||
**Regla de oro:** en cada pantalla, terminar con UNA pregunta de validación. No presentar; validar.
|
||||
|
||||
---
|
||||
|
||||
## Apertura (2 min)
|
||||
|
||||
> "Gracias por el tiempo. Lo que van a ver es el proceso que ustedes me enseñaron en las sesiones con Araceli y Arturo, convertido en pantallas. Todo es dato ficticio. El objetivo de hoy es que me digan qué SÍ refleja su operación y qué corregimos — cada 'así no es' de hoy me ahorra semanas de desarrollo."
|
||||
|
||||
Aviso útil: "Ayer con Arturo y Araceli aprendí cosas nuevas (fee, flujo Jira); les voy a ir señalando dónde ya sé que hay ajustes."
|
||||
|
||||
---
|
||||
|
||||
## Pág. 2 · El flujo de principio a fin (3 min)
|
||||
|
||||
Recorre los 5 pasos: **Solicitud Jira → Cotización BIND → Prefactura → Aprobación humana → CFDI + Envío**.
|
||||
|
||||
> "Este es el mapa de todo. La automatización está donde ustedes la pidieron: después de Jira, y con validación humana antes de timbrar. Aprobar y timbrar son acciones separadas — nada se timbra solo."
|
||||
|
||||
**⚠️ AQUÍ VA LA PREGUNTA GRANDE (caja de reglas, primera línea "PPD por defecto"):**
|
||||
> "Esta regla salió del Discovery: PPD por defecto porque cobran a crédito 30–90 días. Pero al sincronizar el histórico real encontré que las 1,374 facturas con método de pago son TODAS PUE, cero PPD. ¿Es política del despacho o práctica que quieren corregir? Cambia el default de la plataforma y toca el requerimiento del SAT que ya vivieron."
|
||||
|
||||
Anotar la respuesta — define B7 (capa de escritura).
|
||||
|
||||
- Validar también: "¿Recordatorios de morosidad a todos los clientes, sin excepciones — sigue firme?" (lo decidió Ara el 6-jul).
|
||||
|
||||
## Pág. 3 · Acceso (30 seg — no gastar tiempo)
|
||||
|
||||
> "Ingreso con cuenta interna, control de sesión y roles — cada quien ve lo suyo. Esto ya está construido en el backend real."
|
||||
|
||||
## Pág. 4 · Panel de control (4 min)
|
||||
|
||||
Señalar en orden: facturado del mes **separado MXN/USD (nunca se suman monedas)** · emitidas vs pendientes · cartera vencida · bandeja "Qué necesita atención".
|
||||
|
||||
> "La bandeja es el corazón: bloqueos por falta de cotización, facturas vencidas escaladas, prefacturas esperando aprobación, clientes nuevos sin cédula, facturas emitidas sin enviar. Cada línea tiene responsable y antigüedad."
|
||||
|
||||
Dato para credibilidad: "Esto ya no es dibujo — el backend real ya sincroniza la cartera de producción: 1,494 facturas, y los totales cuadran contra BIND al centavo."
|
||||
|
||||
**Pregunta:** "¿Son estos los 4 números que quieren ver al abrir? ¿Falta o sobra una tarjeta?" (Recordar: Pedro ya tiene Power BI de aging — esto es operación, no reporteo; no duplico lo suyo.)
|
||||
|
||||
## Pág. 5 · Solicitudes (Jira) (3 min)
|
||||
|
||||
> "La entrada del flujo: sin ticket, no se factura — tal como operan hoy. Filtros por estatus: por validar, listos, bloqueados, facturados."
|
||||
|
||||
Conectar con ayer:
|
||||
> "Con lo que me mostró Arturo ayer, esto mapea directo a su space 'Facturación' y su flujo de estatus — donde 'resuelto' es el que confirma facturación válida. La sesión con Pedro para el API de Jira nos dirá si estos tickets entran solos o se capturan."
|
||||
|
||||
**Pregunta:** "¿Las columnas (tipo, cliente, moneda, monto, crédito, recurrente, estatus) son las que Arturo necesita para decidir qué facturar?"
|
||||
|
||||
## Pág. 6 · Detalle de la solicitud (3 min)
|
||||
|
||||
Señalar: datos del ticket, adjuntos (cotización, OC, horas con VoBo), doble check de administración, **cotización BIND vinculada como requisito**.
|
||||
|
||||
**Nota ⚠️ (fila "Cliente nuevo"):**
|
||||
> "Ayer Arturo me mostró el alta completa en BIND. La decisión que les pido hoy: cuando el ticket trae un cliente que NO existe en BIND, ¿la plataforma solo lo detecta y avisa a administración, o también lo da de alta? Mi recomendación para el MVP: detectar y bloquear; el alta la hace administración en BIND como hoy."
|
||||
|
||||
Anotar decisión — cruza con la estimación de ~10 h de Jira→BIND.
|
||||
|
||||
## Pág. 7 · Preparación, aprobación y emisión (4 min)
|
||||
|
||||
> "Asistente de 5 pasos: cotización BIND (sin cotización no se puede continuar) → datos de factura → conceptos e IVA 16%/0% con alerta si no cuadra → prefactura en simulación, sin timbrar → aprobación humana. Aprobar NO timbra: son dos clics distintos, de dos momentos distintos."
|
||||
|
||||
Reforzar seguridad (le importa a Noé):
|
||||
> "Y cuando llegue la escritura real: dry-run, confirmación humana por factura y feature flag apagado por defecto — como acordamos ayer, con todo el cuidado de que es producción."
|
||||
|
||||
**Pregunta:** "¿Quién aprueba en la vida real — siempre Arturo, o hay segundo aprobador?"
|
||||
|
||||
## Pág. 8 · Envío al cliente (3 min)
|
||||
|
||||
> "El proceso NO termina al timbrar: termina cuando el correo sale con los adjuntos correctos. Checklist bloqueante por cliente — ejemplo CEMEX: PDF+XML automático, Excel de horas con VoBo, asunto con su nomenclatura exacta. Si falta algo, el envío se bloquea — hoy un error de estos rebota la factura y con 90 días de crédito cada rebote empuja el cobro."
|
||||
|
||||
**Pregunta / pendiente:** "Para cargar las reglas reales necesito el Excel de particularidades por cliente que quedó con Ara y Arturo — ¿cómo va? Ya revisé los procedimientos que me mandaron el 16-jul; el Excel me completa destinatarios y nomenclaturas."
|
||||
|
||||
## Pág. 9 · Cuentas por cobrar (3 min)
|
||||
|
||||
> "El aging que hoy llevan en Excel, leído de BIND: por vencer, 1–30, 31–60, 61–90, +90 — MXN y USD siempre separados, el tipo de cambio DOF es solo informativo. Saldo y días de mora por factura."
|
||||
|
||||
Credibilidad: "Los números reales ya viven en el backend: la cartera sincronizada cuadra exacta contra BIND."
|
||||
|
||||
**Pregunta:** "¿Estos rangos de aging son los que usan? ¿Les sirve el corte por factura o necesitan también por cliente?"
|
||||
|
||||
## Pág. 10 · Pagos y recordatorios (4 min) — LA PANTALLA CON MÁS AJUSTES DE AYER
|
||||
|
||||
1. **Fee (caja "Tolerancia por comisión"):**
|
||||
> "Ayer Araceli me aclaró el proceso real: el fee bancario lo registra y deduce EL DESPACHO — Balam no hace ese asiento. Entonces esta pantalla se ajusta: la plataforma DETECTA la diferencia en pagos internacionales, la ETIQUETA como probable fee y avisa; quien salda es el despacho. ¿De acuerdo con ese ajuste?"
|
||||
|
||||
2. **Fecha de detección:** "La fecha que muestro es la del registro en BIND (lo captura el despacho), no la fecha valor del banco — BIND no expone pagos individuales. ¿Les funciona así para el MVP?"
|
||||
|
||||
3. **Recordatorios (columna derecha) — poner el límite con suavidad:**
|
||||
> "Ojo con esta parte: las alertas D+1 y el escalamiento D+15 son INTERNAS y van en el MVP. Los correos automáticos AL CLIENTE (D+5, D+30) están cotizados en el Anexo B — aquí los dejo visibles y preparados para activarse, pero no son parte de esta fase. Lo señalo para que no haya sorpresa al cierre."
|
||||
|
||||
## Pág. 11 · Bitácora (2 min)
|
||||
|
||||
> "Todo queda registrado: quién aprobó, quién emitió, qué override de IVA se hizo y por qué, con ticket Jira y folio BIND. Esto responde exactamente al problema que me contó Arturo ayer: 'dijeron que ya facturaron y no había evidencia'. Aquí la evidencia es automática. Y la bitácora ya existe en el backend real, no solo en el prototipo."
|
||||
|
||||
---
|
||||
|
||||
## Cierre (5 min)
|
||||
|
||||
1. **Pedir el veredicto explícito:**
|
||||
> "¿Validan que este flujo representa su operación? Con su OK doy por cerrada la Etapa 0, aplico los ajustes que anotamos y el demo público lo doy de baja como quedamos."
|
||||
|
||||
2. **Recap de decisiones tomadas hoy** (leerlas en voz alta): PUE/PPD · alta de cliente (detectar vs crear) · fee = despacho confirmado · recordatorios internos vs Anexo B · rangos de aging.
|
||||
|
||||
3. **Siguientes pasos** (recordar compromisos de ayer): diagrama del flujo Jira en tamaño legible · sesión con Pedro (API Jira + facturación recurrente) · Excel de particularidades de envío · Azure esta semana.
|
||||
|
||||
4. **Si el ambiente lo permite, la comercial:**
|
||||
> "Ing. Noé, ya de regreso del viaje — ¿pudieron revisar la propuesta v1.2 para lo de la facturación inicial de las 30 horas?"
|
||||
|
||||
## Chuleta de respuestas rápidas
|
||||
|
||||
- **"¿Y si queremos que también mande correos al cliente?"** → Está cotizado en Anexo B; la pantalla ya lo deja preparado. Lo activamos como ampliación cuando cierre el MVP.
|
||||
- **"¿Esto ya jala con BIND de verdad?"** → La lectura sí: clientes, facturas, cotizaciones y cartera ya sincronizan de producción, en solo-lectura. La escritura va con los candados acordados.
|
||||
- **"¿Cuándo estará?"** → Etapa 1 va adelantada (backend, auth, sync y seguridad por tenant ya construidos). Las fechas finas dependen de Azure y de las decisiones de hoy.
|
||||
- **"¿Multiempresa / Regiotour?"** → Fuera del MVP (un token BIND por empresa); el diseño ya lo soporta a futuro.
|
||||
- **"¿Forecast por contrato?"** → Lo dijo Noé ayer: no es para ahorita; queda anotado para una fase posterior.
|
||||
Binary file not shown.
@@ -28,3 +28,5 @@ fecha,semana,etapa,actividad_id,actividad,horas,estado_hora,fuente_evidencia,fac
|
||||
2026-07-21,2026-W30,1,E1-03,B6: RLS real de Postgres por tenant (migración + interceptor + filtros EF),0.50,confirmada,bitacora/REGISTRO.md#53,si,"Sesión asistida por IA; verificación manual en psql; tiempo real de sesión"
|
||||
2026-07-21,2026-W30,1,E1-05,Cierre de sesión: Excel de avance regenerado + bitácora + control de horas,0.25,confirmada,bitacora/REGISTRO.md#52-53,si,"Sesión asistida por IA; tiempo real de sesión"
|
||||
2026-07-22,2026-W30,1,E1-05,"Sesión de reglas Etapa 1 con Noé, Arturo y Araceli (alta de clientes, fee, flujo Jira)",0.80,confirmada,bitacora/REGISTRO.md#54,si,"Duración real ~48 min según transcript (7:00–7:48 am)"
|
||||
2026-07-24,2026-W30,0,E0-07,"Sesión de validación del prototipo Etapa 0 con Noé, Arturo y Araceli — APROBADO",1.05,confirmada,bitacora/REGISTRO.md#55,si,"Duración ~1 h 4 min según transcript; Etapa 0 validada, queda 1 definición de proceso (flujo Jira)"
|
||||
2026-07-27,2026-W31,1,E1-07,"Sesión de API de Jira con Pedro (token PAF, bandeja FAC)",0.20,confirmada,bitacora/REGISTRO.md#56,si,"~12 min; token PAF comprometido (1 año) por correo; integración inicia tras definición del flujo 28-jul"
|
||||
|
||||
|
@@ -0,0 +1,146 @@
|
||||
"""Genera Plan-actividades-avance-2026-07-27.xlsx a partir del del 21-jul.
|
||||
Aplica las horas y estatus reales al 27-jul: sesión de reglas (22-jul) y
|
||||
validación del prototipo (24-jul, APROBADO) completadas; sesión de API de Jira
|
||||
(27-jul) en curso; capa de escritura EN PAUSA a la espera de la definición del
|
||||
flujo de facturación (sesión 28-jul con Arturo/Araceli).
|
||||
Reutiliza el estilo/semáforo del archivo del 21-jul."""
|
||||
import re
|
||||
from datetime import date
|
||||
import openpyxl
|
||||
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
|
||||
|
||||
SRC = "/Users/johann/Desktop/Proyectos personales/BALAM/planeacion/Plan-actividades-avance-2026-07-21.xlsx"
|
||||
DST = "/Users/johann/Desktop/Proyectos personales/BALAM/planeacion/Plan-actividades-avance-2026-07-27.xlsx"
|
||||
HOY = date(2026, 7, 27)
|
||||
|
||||
CAFE, CREMA, GRIS_B, AMARILLO = "331F0E", "FDF3D8", "D9D9D9", "F7BD0C"
|
||||
V_FILL, V_FONT = "C6EFCE", "006100" # verde
|
||||
A_FILL, A_FONT = "FFEB9C", "9C6500" # amarillo
|
||||
R_FILL, R_FONT = "FFC7CE", "9C0006" # rojo
|
||||
G_FILL, G_FONT = "F2F2F2", "595959" # gris
|
||||
|
||||
C_PCT, C_BLQ, C_EST, C_TRAB, C_STAT = 7, 8, 9, 10, 11
|
||||
|
||||
# Prefijo de la actividad -> overrides de datos (pct=%, trab=horas, comienzo/fin=fechas texto)
|
||||
OVERRIDES = {
|
||||
"Integracion de plataformas Balam": dict(pct=0.67, trab=40),
|
||||
"Etapa 0": dict(pct=1.0, trab=23),
|
||||
"Documento de hallazgos": dict(pct=1.0),
|
||||
"Sesión de validación del prototipo": dict(pct=1.0, trab=1.05,
|
||||
comienzo="vie 24/07/26", fin="vie 24/07/26"),
|
||||
"Etapa 1": dict(pct=0.82, trab=17),
|
||||
"Demostración semanal": dict(trab=1.75),
|
||||
"Sesión de reglas y dudas": dict(pct=1.0, trab=0.80),
|
||||
"Definición de alcance Jira": dict(pct=0.40, trab=0.20),
|
||||
}
|
||||
|
||||
# Estatus a mano (gana sobre el semáforo automático): texto, fill, font, negrita
|
||||
K_ESPECIAL = {
|
||||
"Documento de hallazgos": ("✅ Completada", V_FILL, V_FONT, False),
|
||||
"Sesión de validación del prototipo": ("✅ Validado (aprobado)", V_FILL, V_FONT, True),
|
||||
"Demostración semanal": ("🟡 En curso (semanal)", A_FILL, A_FONT, False),
|
||||
"Modelo de facturas": ("🟡 En curso · falta seeder", A_FILL, A_FONT, False),
|
||||
"Capa de escritura controlada": ("🔴 En pausa · def. Balam 28-jul", R_FILL, R_FONT, True),
|
||||
"Sesión de reglas y dudas": ("✅ Completada", V_FILL, V_FONT, False),
|
||||
"Definición de alcance Jira": ("🟡 En curso · API Jira 27-jul", A_FILL, A_FONT, False),
|
||||
"Configuración de infraestructura en Azure": ("🟡 Pendiente (Balam)", A_FILL, A_FONT, False),
|
||||
"CI/CD": ("🔴 Pendiente · dep. Azure", R_FILL, R_FONT, True),
|
||||
}
|
||||
|
||||
def fecha(celda):
|
||||
m = re.search(r"(\d{2})/(\d{2})/(\d{2})", str(celda or ""))
|
||||
return date(2000 + int(m.group(3)), int(m.group(2)), int(m.group(1))) if m else None
|
||||
|
||||
def pinta(celda, fill, font_color, bold=False):
|
||||
celda.fill = PatternFill("solid", fgColor=fill)
|
||||
celda.font = Font(color=font_color, bold=bold, size=10)
|
||||
celda.alignment = Alignment(horizontal="center", vertical="center")
|
||||
|
||||
wb = openpyxl.load_workbook(SRC)
|
||||
ws = wb.active
|
||||
|
||||
# 1) Aplica overrides de datos por prefijo de nombre
|
||||
for row in range(2, ws.max_row + 1):
|
||||
nombre = str(ws.cell(row=row, column=1).value or "").strip()
|
||||
if not nombre:
|
||||
continue
|
||||
for prefijo, ov in OVERRIDES.items():
|
||||
if nombre.startswith(prefijo):
|
||||
if "pct" in ov: ws.cell(row=row, column=C_PCT, value=ov["pct"])
|
||||
if "trab" in ov: ws.cell(row=row, column=C_TRAB, value=ov["trab"])
|
||||
if "comienzo" in ov: ws.cell(row=row, column=3, value=ov["comienzo"])
|
||||
if "fin" in ov: ws.cell(row=row, column=4, value=ov["fin"])
|
||||
break
|
||||
|
||||
# 2) Recalcula el semáforo con HOY=27-jul (mismas reglas que el del 21-jul)
|
||||
for row in range(2, ws.max_row + 1):
|
||||
nombre = str(ws.cell(row=row, column=1).value or "").strip()
|
||||
if not nombre or nombre.startswith("✅") or nombre.startswith("▬"):
|
||||
continue
|
||||
es_etapa = nombre.startswith("Etapa") or nombre.startswith("Integracion")
|
||||
pct = ws.cell(row=row, column=C_PCT).value or 0
|
||||
fin = fecha(ws.cell(row=row, column=4).value)
|
||||
ini = fecha(ws.cell(row=row, column=3).value)
|
||||
stat = ws.cell(row=row, column=C_STAT)
|
||||
|
||||
if es_etapa:
|
||||
stat.value = ""
|
||||
elif pct >= 1:
|
||||
stat.value = "✅ Completada"; pinta(stat, V_FILL, V_FONT)
|
||||
elif fin and fin < HOY:
|
||||
stat.value = "🔴 Vencida"; pinta(stat, R_FILL, R_FONT, bold=True)
|
||||
elif ini and ini <= HOY:
|
||||
stat.value = "🟡 En curso"; pinta(stat, A_FILL, A_FONT)
|
||||
elif pct > 0:
|
||||
stat.value = "🟢 Adelantada"; pinta(stat, V_FILL, V_FONT)
|
||||
else:
|
||||
stat.value = "⚪ Próxima"; pinta(stat, G_FILL, G_FONT)
|
||||
|
||||
# semáforo en la celda de %
|
||||
pcel = ws.cell(row=row, column=C_PCT)
|
||||
if not es_etapa:
|
||||
if pct >= 1: pinta(pcel, V_FILL, V_FONT, bold=True)
|
||||
elif pct > 0: pinta(pcel, A_FILL, A_FONT, bold=True)
|
||||
elif fin and fin < HOY: pinta(pcel, R_FILL, R_FONT, bold=True)
|
||||
pcel.number_format = "0%"
|
||||
ws.cell(row=row, column=C_TRAB).number_format = "0.0"
|
||||
|
||||
# 3) Overrides finos de estatus (bloqueos y dependencias)
|
||||
for row in range(2, ws.max_row + 1):
|
||||
nombre = str(ws.cell(row=row, column=1).value or "").strip()
|
||||
for prefijo, (txt, fill, font, bold) in K_ESPECIAL.items():
|
||||
if nombre.startswith(prefijo):
|
||||
stat = ws.cell(row=row, column=C_STAT)
|
||||
stat.value = txt
|
||||
pinta(stat, fill, font, bold)
|
||||
break
|
||||
|
||||
# 4) Encabezado de la columna de estatus y pie
|
||||
ws.cell(row=1, column=C_STAT, value=f"Estatus (hoy {HOY.day}-jul)")
|
||||
|
||||
# 5) Reescribe leyenda/notas (borra las viejas de la línea de HOY del 21-jul)
|
||||
for row in range(ws.max_row, 1, -1):
|
||||
v = str(ws.cell(row=row, column=1).value or "")
|
||||
if v.startswith("✅ Completada ·") or v.startswith("▬ La línea roja"):
|
||||
for col in range(1, C_STAT + 1):
|
||||
ws.cell(row=row, column=col).value = None
|
||||
|
||||
ley = ws.max_row + 2
|
||||
notas = [
|
||||
("✅ Completada · 🟡 En curso · 🔴 Vencida/Pendiente · ⚪ Próxima", G_FONT, True),
|
||||
("Núcleo de la Etapa 1 construido y verificado contra producción: autenticación y roles, "
|
||||
"bitácora, multi-tenant con RLS, cliente de BIND, sincronización de clientes/facturas/"
|
||||
"cotizaciones, modelo de facturas con estados y cartera por moneda.", CAFE, False),
|
||||
("🔴 La capa de escritura (cotización→factura) queda EN PAUSA a la espera de la definición "
|
||||
"del flujo de facturación (sesión del martes 28-jul con Arturo y Araceli).", "9C0006", False),
|
||||
("API de Jira: token recibido el 27-jul; la integración inicia una vez definido el flujo.", CAFE, False),
|
||||
]
|
||||
for i, (txt, color, bold) in enumerate(notas):
|
||||
c = ws.cell(row=ley + i, column=1, value=txt)
|
||||
c.font = Font(italic=True, size=9, color=color, bold=bold)
|
||||
|
||||
ws.freeze_panes = "A2"
|
||||
ws.oddFooter.center.text = "Avance al 27-jul-2026 · Horas conforme al control local (pendiente conciliar con Jira)"
|
||||
|
||||
wb.save(DST)
|
||||
print("OK ->", DST)
|
||||
Reference in New Issue
Block a user