74 lines
2.8 KiB
Python
74 lines
2.8 KiB
Python
# export_roas_excel.py
|
|
# Genera un Excel de la tabla "Inversión por Sede" (ROAS) con el filtro
|
|
# Año=2026, Mes=Marzo (3), Día=TODOS — igual que el dashboard.
|
|
# Columnas: Sede | Programa | Conjunto | Importe Gastado | Resultados
|
|
# Usa la MISMA función roas_dashboard() del dashboard (no reinventa la logica).
|
|
# Ejecutar en backend/: python export_roas_excel.py
|
|
import services as S
|
|
from openpyxl import Workbook
|
|
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
|
|
|
ANO, MES, DIA = "2026", "3", "TODOS" # Marzo 2026
|
|
|
|
data = S.roas_dashboard(ANO, MES, DIA)
|
|
filas = data.get("filas", [])
|
|
|
|
# ── Aplanar a filas: Sede / Programa / Conjunto / Importe / Resultados ──
|
|
rows = []
|
|
for f in filas:
|
|
sede = f.get("sede", "")
|
|
# nivel sede (total de la sede)
|
|
rows.append([sede, "", "", f.get("importe", 0), f.get("resultados", 0), "sede"])
|
|
for p in (f.get("programas") or []):
|
|
prog = p.get("programa", "")
|
|
# nivel programa (total del programa)
|
|
rows.append([sede, prog, "", p.get("importe", 0), p.get("resultados", 0), "prog"])
|
|
for c in (p.get("conjuntos") or []):
|
|
rows.append([sede, prog, c.get("conjunto", ""),
|
|
c.get("importe", 0), c.get("resultados", 0), "conj"])
|
|
|
|
# ── Excel ──
|
|
wb = Workbook()
|
|
ws = wb.active
|
|
ws.title = "ROAS Marzo 2026"
|
|
|
|
azul = PatternFill("solid", fgColor="1E3A5F")
|
|
blanco = Font(bold=True, color="FFFFFF")
|
|
fill_sede = PatternFill("solid", fgColor="DBEAFE")
|
|
fill_prog = PatternFill("solid", fgColor="F1F5F9")
|
|
bord = Border(*(Side(style="thin", color="D0D7E2"),)*4)
|
|
cen = Alignment(horizontal="center", vertical="center")
|
|
izq = Alignment(horizontal="left", vertical="center")
|
|
|
|
cab = ["Sede", "Programa", "Conjunto", "Importe Gastado", "Resultados"]
|
|
for j, t in enumerate(cab, 1):
|
|
c = ws.cell(1, j, t)
|
|
c.fill = azul; c.font = blanco; c.alignment = cen; c.border = bord
|
|
|
|
r = 2
|
|
for sede, prog, conj, imp, res, nivel in rows:
|
|
ws.cell(r, 1, sede)
|
|
ws.cell(r, 2, prog)
|
|
ws.cell(r, 3, conj)
|
|
ci = ws.cell(r, 4, round(float(imp or 0), 2)); ci.number_format = '"$"#,##0.00'
|
|
cr = ws.cell(r, 5, int(res or 0)); cr.number_format = '#,##0'
|
|
for j in range(1, 6):
|
|
cell = ws.cell(r, j); cell.border = bord
|
|
cell.alignment = izq if j <= 3 else cen
|
|
if nivel == "sede":
|
|
cell.fill = fill_sede; cell.font = Font(bold=True)
|
|
elif nivel == "prog":
|
|
cell.fill = fill_prog; cell.font = Font(bold=True, color="475569")
|
|
r += 1
|
|
|
|
# anchos
|
|
for col, w in zip("ABCDE", [16, 14, 46, 16, 14]):
|
|
ws.column_dimensions[col].width = w
|
|
ws.freeze_panes = "A2"
|
|
|
|
out = "ROAS_Marzo_2026.xlsx"
|
|
wb.save(out)
|
|
print(f"\nOK -> {out}")
|
|
print(f"Filas totales: {len(rows)} (sedes: {len(filas)})")
|
|
print("Columnas: Sede | Programa | Conjunto | Importe Gastado | Resultados")
|