z230
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
# -*- 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.")
|
||||
Reference in New Issue
Block a user