Files
janssen/Feasibility/77242113UCO2001/report_77242113UCO2001_v1.2.py
T
2026-06-19 14:28:54 +02:00

228 lines
7.6 KiB
Python

# -*- coding: utf-8 -*-
# =============================================================================
# Nazev: report_77242113UCO2001_v1.2.py
# Verze: 1.2
# Datum: 2026-06-19
# Popis: Generator Excel reportu z Mongo feasibility.investigators.
# v1.2 - pridan PRVNI list "Prehled KROK": A=KROK, B=pocet,
# C=seznam jmen zkousejicich (oddeleno strednikem) v jedne bunce.
# List Investigators nasleduje jako druhy.
# v1.1 - sloupec KROK hned pred STATUS + barevne odliseni dle KROK.
# Projekt: 77242113UCO2001 (DAWN / spravny kod 77242113UCO3002)
# Vystup: u:\Dropbox\!!!Days\Downloads Z230\ (verzovany nazev s timestampem)
# =============================================================================
import os
from datetime import datetime
from pymongo import MongoClient
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter
# --- Připojení k MongoDB ---
MONGO_URI = os.environ.get("MONGO_URI", "mongodb://192.168.1.76:27017")
client = MongoClient(MONGO_URI)
db = client["feasibility"]
col = db["investigators"]
# --- Načtení dat ---
docs = list(col.find({}))
print(f"Načteno {len(docs)} záznamů.")
# --- Cílová složka ---
OUTPUT_DIR = r"u:\Dropbox\!!!Days\Downloads Z230"
os.makedirs(OUTPUT_DIR, exist_ok=True)
datum = datetime.now().strftime("%Y%m%d_%H%M")
filename = f"77242113UCO2001_investigators_{datum}.xlsx"
filepath = os.path.join(OUTPUT_DIR, filename)
# --- Definice sloupců ---
# Pořadí: jméno, email, KROK, STATUS, kriticka_poznamka, pak ostatní
# KROK je ZÁMĚRNĚ hned PŘED STATUS.
FIXED_COLS = [
("prijmeni", "Příjmení"),
("jmeno", "Jméno"),
("email", "Email"),
("KROK", "KROK"),
("STATUS", "STATUS"),
("kriticka_poznamka", "Kritická poznámka"),
("zeme", "Země"),
("pracoviste", "Pracoviště"),
("internet_summary","Internet summary"),
]
# Klíče, které přeskočíme (složité nested objekty)
SKIP_KEYS = {"_id", "excel", "sites_illuminator", "maf", "zdroje", "studie",
"Viper_Performance", "Viper_Contacts", "cda", "history",
"zpracovane_emaily", "sipiq"}
# Ostatní skalární pole
fixed_keys = {c[0] for c in FIXED_COLS}
extra_keys = set()
for doc in docs:
for k in doc.keys():
if k not in fixed_keys and k not in SKIP_KEYS:
extra_keys.add(k)
extra_keys = sorted(extra_keys)
ALL_COLS = FIXED_COLS + [(k, k) for k in extra_keys]
# --- Barvy podle KROK ---
def krok_color(krok):
if not krok:
return None
k = krok.strip()
if k.startswith("5") or k.startswith("6") or k.startswith("7"):
return "FFC6EFCE" # zelená - CDA podepsáno / SIPIQ
if k.startswith("4"):
return "FFB7E1CD" # tmavší zelená - CDA vyžádáno
if k.startswith("3.1"):
return "FFDDEBF7" # světle modrá - zájem
if k.startswith("3.2"):
return "FFFFC7CE" # červená - nezájem
if k.startswith("2"):
return "FFFFF2CC" # světle žlutá - připomenuto
if k.startswith("1"):
return "FFDCE6F1" # modrá - nabídka odeslána
if k.startswith("0"):
return "FFD9D9D9" # šedá - mimo
return None
# --- Pomocná funkce: setřídění KROK dle čísla prefixu ---
def krok_sort_key(krok):
k = (krok or "").strip()
num = ""
for ch in k:
if ch.isdigit() or ch == ".":
num += ch
else:
break
try:
return (0, float(num)) if num else (1, 0.0)
except ValueError:
return (1, 0.0)
# --- Agregace pro přehledový list ---
def cele_jmeno(doc):
p = (doc.get("prijmeni") or "").strip()
j = (doc.get("jmeno") or "").strip()
return (p + " " + j).strip() or "(bez jména)"
skupiny = {} # krok -> list jmen
for doc in docs:
krok = str(doc.get("KROK", "") or "").strip() or "(nezařazeno)"
skupiny.setdefault(krok, []).append(cele_jmeno(doc))
prehled_rows = []
for krok in sorted(skupiny, key=krok_sort_key):
jmena = sorted(skupiny[krok])
prehled_rows.append((krok, len(jmena), "; ".join(jmena)))
# --- Styly ---
header_font = Font(bold=True, color="FFFFFFFF")
header_fill = PatternFill("solid", fgColor="FF1F4E79")
header_align = Alignment(horizontal="center", vertical="center", wrap_text=True)
cell_align = Alignment(vertical="top", wrap_text=True)
thin = Side(style="thin", color="FFB0B0B0")
border = Border(left=thin, right=thin, top=thin, bottom=thin)
# --- Vytvoření workbooku ---
wb = openpyxl.Workbook()
# === LIST 1: Přehled KROK ===
ws_p = wb.active
ws_p.title = "Přehled KROK"
PREHLED_COLS = [("KROK", 30), ("Počet", 10), ("Zkoušející (jména)", 120)]
for col_idx, (label, w) in enumerate(PREHLED_COLS, 1):
c = ws_p.cell(row=1, column=col_idx, value=label)
c.font = header_font
c.fill = header_fill
c.alignment = header_align
c.border = border
ws_p.column_dimensions[get_column_letter(col_idx)].width = w
ws_p.row_dimensions[1].height = 26
for r, (krok, pocet, jmena) in enumerate(prehled_rows, 2):
bg = krok_color(krok)
vals = [krok, pocet, jmena]
for col_idx, val in enumerate(vals, 1):
c = ws_p.cell(row=r, column=col_idx, value=val)
c.alignment = cell_align
c.border = border
if bg:
c.fill = PatternFill("solid", fgColor=bg)
if col_idx == 1:
c.font = Font(bold=True)
if col_idx == 2:
c.alignment = Alignment(horizontal="center", vertical="top")
# Řádek CELKEM
tot_r = len(prehled_rows) + 2
ws_p.cell(row=tot_r, column=1, value="CELKEM").font = Font(bold=True)
tc = ws_p.cell(row=tot_r, column=2, value=sum(p for _, p, _ in prehled_rows))
tc.font = Font(bold=True)
tc.alignment = Alignment(horizontal="center")
for col_idx in range(1, 4):
ws_p.cell(row=tot_r, column=col_idx).border = border
ws_p.freeze_panes = "A2"
ws_p.auto_filter.ref = f"A1:C{len(prehled_rows) + 1}"
# === LIST 2: Investigators ===
ws = wb.create_sheet("Investigators")
# Záhlaví
for col_idx, (key, label) in enumerate(ALL_COLS, 1):
cell = ws.cell(row=1, column=col_idx, value=label)
cell.font = header_font
cell.fill = header_fill
cell.alignment = header_align
cell.border = border
ws.row_dimensions[1].height = 30
# Data
for row_idx, doc in enumerate(docs, 2):
krok_val = str(doc.get("KROK", "") or "")
bg = krok_color(krok_val)
for col_idx, (key, label) in enumerate(ALL_COLS, 1):
val = doc.get(key, "")
if isinstance(val, list):
val = ", ".join(str(v) for v in val)
elif isinstance(val, dict):
val = str(val)
elif val is None:
val = ""
else:
val = str(val)
cell = ws.cell(row=row_idx, column=col_idx, value=val)
cell.alignment = cell_align
cell.border = border
if bg:
cell.fill = PatternFill("solid", fgColor=bg)
if key == "KROK":
cell.font = Font(bold=True)
# Šířky sloupců
col_widths = {
"prijmeni": 18, "jmeno": 15, "email": 35,
"KROK": 26, "STATUS": 45, "kriticka_poznamka": 60,
"zeme": 12, "pracoviste": 35, "internet_summary": 60,
}
for col_idx, (key, label) in enumerate(ALL_COLS, 1):
w = col_widths.get(key, 20)
ws.column_dimensions[get_column_letter(col_idx)].width = w
ws.freeze_panes = "A2"
ws.auto_filter.ref = ws.dimensions
# --- Uložení ---
wb.save(filepath)
print(f"Ulozeno: {filepath}")
print(f"List 1 'Přehled KROK': {len(prehled_rows)} kroků, celkem {sum(p for _,p,_ in prehled_rows)} zkoušejících.")
print("List 2 'Investigators':", len(docs), "radku.")