#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import traceback from pathlib import Path from datetime import date import customtkinter as ctk from tkinter import messagebox PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent.parent sys.path.insert(0, str(PROJECT_ROOT)) from Knihovny.vzpb2b_client import VZPB2BClient from Knihovny.EmailMessagingGraph import send_mail EMAIL_CHYBY = "vladimir.buzalka@buzalka.cz" def _zpracuj_chybu(exc: BaseException): """Zobrazí chybový dialog a pošle email. Nikdy nevyhodí výjimku.""" detail = traceback.format_exc() try: root = ctk.CTk() root.withdraw() messagebox.showerror("Chyba — KdoJeLekarApp", f"Nastala chyba:\n{exc}\n\nByla odeslána na email.") root.destroy() except Exception: pass try: send_mail( to=EMAIL_CHYBY, subject=f"KdoJeLekarApp — chyba ({date.today().isoformat()})", body=(f"Pacient: {PRIJMENI} {JMENO} / RC: {RODCIS}\n\n{detail}"), ) except Exception: pass # ── KONFIGURACE ─────────────────────────────────────────────────────────────── PFX_PATH = PROJECT_ROOT / "Insurance" / "Certificates" / "picka.pfx" PFX_PASS = "Vlado7309208104+" ODBORNOSTI_NAZVY = { "001": "Praktický lékař", "002": "Gynekolog", "014": "Stomatolog", } # Default hodnoty (přepíší argumenty z Medicusu) JMENO = "Michaela" PRIJMENI = "Buzalková" RODCIS = "7155111821" # ── ARGUMENTY Z MEDICUSU ───────────────────────────────────────────────────── if len(sys.argv) >= 4: JMENO = sys.argv[1] PRIJMENI = sys.argv[2] RODCIS = sys.argv[3] elif len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help"): print("Usage: KdoJeLekarApp.py JMENO PRIJMENI RODCIS") sys.exit(0) # ── VZP DOTAZ ──────────────────────────────────────────────────────────────── def zjisti_lekare(rodcis: str) -> list[dict]: vzp = VZPB2BClient("prod", str(PFX_PATH), PFX_PASS) xml = vzp.registrace_lekare(rc=rodcis, k_datu=date.today().isoformat()) return vzp.parse_registrace_lekare(xml) # ── GUI ─────────────────────────────────────────────────────────────────────── class KdoJeLekarApp(ctk.CTk): def __init__(self, zaznamy: list[dict]): super().__init__() self.title("Registrující lékař — VZP B2B") self.geometry("560x560") self.minsize(480, 380) self.resizable(True, True) ctk.set_appearance_mode("light") ctk.set_default_color_theme("blue") outer = ctk.CTkFrame(self, corner_radius=10) outer.pack(expand=True, fill="both", padx=20, pady=20) outer.columnconfigure(0, weight=1) ctk.CTkLabel(outer, text="Registrující lékaři", font=("Arial", 20, "bold")).grid(row=0, column=0, pady=(10, 8)) # Pacient poj = zaznamy[0].get("poj_zkratka", "") if zaznamy else "" pac = ctk.CTkFrame(outer, corner_radius=8) pac.grid(row=1, column=0, sticky="ew", padx=10, pady=(0, 8)) ctk.CTkFrame(pac, height=6, fg_color="transparent").pack() for label, value in [ ("Příjmení:", PRIJMENI), ("Jméno:", JMENO), ("Rodné číslo:", RODCIS), ("Pojišťovna:", poj), ]: row = ctk.CTkFrame(pac, fg_color="transparent") row.pack(fill="x", padx=12, pady=0) ctk.CTkLabel(row, text=label, font=("Arial", 12, "bold"), width=100, anchor="w", height=20).pack(side="left", pady=0) ctk.CTkLabel(row, text=value, font=("Arial", 12), anchor="w", height=20).pack(side="left", pady=0) ctk.CTkFrame(pac, height=4, fg_color="transparent").pack() # Karty lékařů cards = ctk.CTkFrame(outer, corner_radius=0, fg_color="transparent") cards.grid(row=2, column=0, sticky="ew", padx=10) if not zaznamy: ctk.CTkLabel(cards, text="VZP neeviduje žádného registrujícího lékaře.", font=("Arial", 13), text_color="#c0392b").pack(pady=20) else: for z in zaznamy: self._render_zaznam(cards, z) ctk.CTkLabel(outer, text=f"Dotaz k datu: {date.today().isoformat()} | © Ordinace MUDr. Buzalková", font=("Arial", 10), text_color="#888").grid(row=3, column=0, pady=(4, 6)) self._autosize() def _render_zaznam(self, parent, z: dict): kod = z.get("kod_odbornosti", "") nazev_odb = ODBORNOSTI_NAZVY.get(kod, f"Odbornost {kod}") lekar = z.get("nazev_zzz") or "—" pracoviste = z.get("nazev_lekare") or "—" od = z.get("datum_zahajeni") or "?" do = z.get("datum_ukonceni") or "?" card = ctk.CTkFrame(parent, corner_radius=8, fg_color="#eaf4fb") card.pack(fill="x", pady=4) ctk.CTkLabel(card, text=f" {nazev_odb} ({kod})", font=("Arial", 13, "bold"), text_color="#1a5276").pack(anchor="w", padx=10, pady=(6, 1)) for label, value in [ ("Lékař:", lekar), ("Pracoviště:", pracoviste), ("ICZ / ICP:", f"{z.get('ICZ') or '—'} / {z.get('ICP') or '—'}"), ("Registrace:", z.get("datum_registrace") or "?"), ("Platí od:", od), ("Platí do:", "bez omezení" if do == "3000-01-01" else do), ]: row = ctk.CTkFrame(card, fg_color="transparent") row.pack(fill="x", padx=14, pady=0) ctk.CTkLabel(row, text=label, font=("Arial", 11, "bold"), width=90, anchor="w", height=20).pack(side="left", pady=0) ctk.CTkLabel(row, text=value, font=("Arial", 11), anchor="w", height=20).pack(side="left", pady=0) ctk.CTkFrame(card, height=4, fg_color="transparent").pack() def _autosize(self): self.update_idletasks() w = 560 h = self.winfo_reqheight() sw, sh = self.winfo_screenwidth(), self.winfo_screenheight() self.geometry(f"{w}x{h}+{(sw-w)//2}+{(sh-h)//2}") # ── MAIN ───────────────────────────────────────────────────────────────────── if __name__ == "__main__": try: zaznamy = zjisti_lekare(RODCIS) app = KdoJeLekarApp(zaznamy) app.mainloop() except Exception as exc: _zpracuj_chybu(exc) sys.exit(1)