Etapa 1: plan de ejecución, corte de avance del 16-jul y fuentes
- Plan-Etapa1.md: plan detallado por fases/bloques (B0-B9) con horas, decisiones de arquitectura y lo bloqueado hasta el 22-jul - Avance-Etapa1-2026-07-16.md + Excel de avance ordenado por fechas (con script generador y de ordenamiento) - WhatsApp 16-jul: invitación al Git recibida, procedimientos de clientes enviados por correo, Erika pide avance de Etapa 1 - Actualiza PENDIENTES y REGISTRO
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"""Genera el Excel de avance que se compartirá con Erika el 16-jul-2026."""
|
||||
|
||||
from copy import copy
|
||||
from pathlib import Path
|
||||
from shutil import copy2
|
||||
|
||||
import openpyxl
|
||||
|
||||
|
||||
DIRECTORY = Path(__file__).parent
|
||||
SOURCE = DIRECTORY / "Plan-actividades-avance-2026-07-10-ajustado.xlsx"
|
||||
TARGET = DIRECTORY / "Plan-actividades-avance-2026-07-16.xlsx"
|
||||
|
||||
|
||||
def find_row(sheet, task):
|
||||
for row in range(2, sheet.max_row + 1):
|
||||
if sheet.cell(row, 1).value == task:
|
||||
return row
|
||||
raise ValueError(f"No se encontró la actividad: {task}")
|
||||
|
||||
|
||||
copy2(SOURCE, TARGET)
|
||||
workbook = openpyxl.load_workbook(TARGET)
|
||||
sheet = workbook["Plan"]
|
||||
|
||||
sheet.cell(1, 8, "Horas al 16/07")
|
||||
|
||||
updates = {
|
||||
"Integracion de plataformas Balam": (
|
||||
0.20,
|
||||
"Corte de avance al 16-jul; Etapa 0 en validación y Etapa 1 en curso",
|
||||
),
|
||||
"Etapa 0": (
|
||||
0.91,
|
||||
"22 h registradas; prototipo entregado y validación agendada para el 23-jul",
|
||||
),
|
||||
"Etapa 1": (
|
||||
0.20,
|
||||
"8 h registradas; 1 de 8 entregables terminado y plataforma base parcial",
|
||||
),
|
||||
"Backend base: autenticación, roles y bitácora de auditoría": (
|
||||
0.30,
|
||||
"API, health check y DbContext base listos; autenticación, roles y auditoría pendientes",
|
||||
),
|
||||
"Repositorio privado GitHub": (
|
||||
0.90,
|
||||
"Invitación recibida y acceso confirmado el 16-jul; falta validar permiso de escritura",
|
||||
),
|
||||
"Arquitectura multi-tenant (tenant_id + RLS)": (
|
||||
0.25,
|
||||
"Diseño técnico inicial; entidades tenant y políticas RLS pendientes",
|
||||
),
|
||||
"Cliente de la API de BIND (reintentos, OData, errores)": (
|
||||
1.00,
|
||||
"Terminado: cliente C# solo lectura, paginación, reintentos y cuota; 13/13 pruebas aprobadas",
|
||||
),
|
||||
"Modelo de facturas + migraciones + datos de prueba": (
|
||||
0.10,
|
||||
"Base operativa con SyncCheckpoint y AuditLog; modelo de facturas y migración pendientes",
|
||||
),
|
||||
"Demostración semanal (viernes) + reporte de horas": (
|
||||
0.50,
|
||||
"Corte del 16-jul preparado; control local mientras se habilita Jira",
|
||||
),
|
||||
}
|
||||
|
||||
for task, (progress, note) in updates.items():
|
||||
row = find_row(sheet, task)
|
||||
sheet.cell(row, 7, progress)
|
||||
sheet.cell(row, 10, note)
|
||||
|
||||
stage1_row = find_row(sheet, "Etapa 1")
|
||||
sheet.cell(stage1_row, 8, "=SUM(H12:H24)")
|
||||
|
||||
for row in range(2, sheet.max_row + 1):
|
||||
sheet.cell(row, 7).number_format = "0%"
|
||||
|
||||
sheet.oddFooter.center.text = (
|
||||
"Avance al 16-jul-2026 · Horas reconstruidas pendientes de conciliación con Jira"
|
||||
)
|
||||
|
||||
# Conserva los estilos y usa el nombre de archivo como título impreso.
|
||||
sheet.oddHeader.center.text = "Plan de actividades y avance · Proyecto Balam"
|
||||
for cell in sheet[1]:
|
||||
cell._style = copy(cell._style)
|
||||
|
||||
temporary = TARGET.with_suffix(".tmp.xlsx")
|
||||
workbook.save(temporary)
|
||||
|
||||
check = openpyxl.load_workbook(temporary, data_only=False)["Plan"]
|
||||
assert check.cell(find_row(check, "Etapa 1"), 7).value == 0.20
|
||||
assert check.cell(
|
||||
find_row(check, "Cliente de la API de BIND (reintentos, OData, errores)"), 7
|
||||
).value == 1.00
|
||||
assert check.cell(find_row(check, "Etapa 1"), 8).value == "=SUM(H12:H24)"
|
||||
|
||||
temporary.replace(TARGET)
|
||||
print(f"Generado: {TARGET}")
|
||||
Reference in New Issue
Block a user