182 lines
7.2 KiB
Python
182 lines
7.2 KiB
Python
#!/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 = Path(r"U:\OrdinaceProjekt\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 = ""
|
|
PRIJMENI = ""
|
|
RODCIS = ""
|
|
|
|
# ── ARGUMENTY Z MEDICUSU ─────────────────────────────────────────────────────
|
|
|
|
if len(sys.argv) >= 4:
|
|
JMENO = sys.argv[1]
|
|
PRIJMENI = sys.argv[2]
|
|
RODCIS = sys.argv[3].replace("/", "")
|
|
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__":
|
|
if not RODCIS:
|
|
root = ctk.CTk()
|
|
root.withdraw()
|
|
messagebox.showerror("Chyba", "Nebyl předán pacient z Medicusu.\nSpusťte aplikaci z menu Medicusu nad vybraným pacientem.")
|
|
sys.exit(1)
|
|
try:
|
|
zaznamy = zjisti_lekare(RODCIS)
|
|
app = KdoJeLekarApp(zaznamy)
|
|
app.mainloop()
|
|
except Exception as exc:
|
|
_zpracuj_chybu(exc)
|
|
sys.exit(1)
|