""" Prehled lekoveho zaznamu pacienta z MySQL. Zobrazuje: 1. Lekare, kteri pacientovi predepsali leky (sestupne podle poctu predpisu) 2. Vsechny predpisy od zadaneho data — s nazvem VYDANEHO leku (ne predepsaneho) Nastaveni: RODNE_CISLO ... rodne cislo pacienta (cifry, bez lomitka) DATUM_OD ... predpisy od tohoto data ve formatu DD.MM.RRRR (None = vsechny) """ from datetime import date, datetime import sys import fdb import pymysql import pymysql.cursors # Kody odbornosti dle SUKL / VZP (posledni 3 cislice ICP) ODBORNOST = { # Základní ambulantní odbornosti "001": "Praktický lékař", "002": "Pediatr (prakt.)", "003": "Chirurgie", "004": "Ortopedie", "005": "ORL", "006": "Gynekologie", "007": "Urologie", "008": "Neurologie", "009": "Psychiatrie", "010": "Oftalmologie", "011": "Zubní lékařství", "012": "Dermatovenerologie", "013": "Infekční lékařství", "014": "Radiodiagnostika", "015": "Stomatochirurgie", "016": "Čelistní ortopedie", "017": "Dětská psychiatrie", "018": "Pneumologie", "019": "Anesteziologie", "020": "Rehabilitace", "021": "Radiodiagnostika", "022": "Radioterapie", "023": "Nukleární medicína", "024": "Klin. biochemie", "025": "Alergologie/imunologie", "026": "Hematologie", "027": "Soudní lékařství", "028": "Soudní psychiatrie", "029": "Lékařská genetika", "031": "Gastroenterologie", "032": "Nefrologie", "033": "Kardiologie", "034": "Endokrinologie/diab.", "035": "Revmatologie", "040": "Vnitřní lékařství", "041": "Geriatrie", "042": "Klin. farmakologie", "043": "Diabetologie", "044": "Endokrinologie", "045": "Hepatologie", "052": "Dětská neurologie", "060": "Dětská chirurgie", "065": "Plastická chirurgie", "066": "Cévní chirurgie", "067": "Kardiochirurgie", "072": "Foniatrie", "074": "Neurochirurgie", "077": "Maxilofaciální chir.", "079": "Hrudní chirurgie", "082": "Urologie", "083": "Andrologie", "085": "Proktologie", "091": "Gynekolog. onkologie", "092": "Reprodukční medicína", "096": "Léčebná rehabilitace", "097": "Fyzioterapie", # Interní a specializované odbornosti "101": "Vnitřní lékařství", "102": "Kardiologie", "104": "Kardiologie", "105": "Gastroenterologie", "106": "Hepatologie", "107": "Nefrologie", "108": "Nefrologie", "110": "Diabetologie", "111": "Endokrinologie", "114": "Pneumologie", "115": "Ftizeologie", "121": "Endokrinologie", "122": "Diabetologie", "129": "Andrologie", "143": "Psychiatrie", "144": "Psychoterapie", "145": "Adiktologie", "148": "Dětská psychiatrie", "155": "Oční onkologie", "156": "Hematologie", "157": "Hemostáza", "160": "Neurologie", "162": "Epileptologie", "163": "Dětská neurologie", "164": "Neurorehabilit.", "168": "Klin. neurofyziologie", "169": "Revmatologie", "174": "Ortoped. protetika", "181": "Infektologie", "183": "Tropická medicína", "185": "Mikrobiologie", "188": "Virologie", # Chirurgické a dětské odbornosti "200": "Stomatologie", "201": "Stomatochirurgie", "202": "Maxilofaciální chir.", "203": "Parodontologie", "204": "Ortodoncie", "205": "Zubní protetika", "206": "Dětská stomatologie", "220": "Pediatrie", "221": "Neonatologie", "222": "Dětská endokrinol.", "223": "Dětská gastroenterol.", "234": "Dětská hematologie", "239": "Dětská nefrologie", "243": "Dětská pneumologie", "245": "Dětská psychiatrie", "246": "Dětská revmatologie", "247": "Dětská kardiologie", "250": "Dětská neurologie", "251": "Dětská neurologie", "258": "Dětská onkologie", "261": "Dětská chirurgie", "262": "Dětská ortopedie", "263": "Urologie", "264": "Dětská stomatologie", "271": "Dětská klin. biochem.", "272": "Alergologie", "273": "Dětská alergologie", "281": "Dětská dermatologie", "282": "Dětská radiologie", "283": "Dětská neurochir.", "289": "Dětská kardiochir.", "291": "Dětská onkol. chir.", "294": "Dětská oftalmologie", "295": "Dětská gynekologie", # Onkologie a zobrazovací metody "300": "Onkologie", "301": "Klin. onkologie", "302": "Radiodiagnostika", "303": "Radioterapie", "304": "Nukleární medicína", "305": "Nukleární kardiologie", "316": "Klin. genetika", "319": "Soudní lékařství", "321": "Cytologie", "324": "Klin. onkologie", "333": "Onkologie", # Stomatologie (500-599) "501": "Zubní lékařství", "502": "Čelistní ortopedie", "503": "Stomatochirurgie", "508": "Parodontologie", "509": "Ortodoncie", "510": "Dětská stomatologie", "513": "Zubní protetika", "535": "Orální medicína", "555": "Stomatologie", "558": "Zubní lékařství", "559": "Stomatologie", "560": "Stomatologie", "562": "Stomatologie", "571": "Stomatologie", "574": "Stomatologie", "580": "Stomatologie", "581": "Stomatologie", "582": "Stomatologie", "584": "Stomatologie", "590": "Lékárenství", # Onkologie (600-699) "600": "Onkologie", "601": "Klin. onkologie", "603": "Onkologie", "606": "Radioterapie", "607": "Nukleární medicína", "615": "Onkologie", # Kardiochirurgie, ostatní (700+) "700": "Chirurgie", "701": "Cévní chirurgie", "702": "Hrudní chirurgie", "704": "Kardiochirurgie", "705": "Chirurgie", "706": "Plastická chirurgie", "719": "Dětská chirurgie", "721": "Ortopedie", "722": "Ortopedie", "723": "Ortopedie", # Fyzioterapie, rehabilitace (800+) "801": "Fyzioterapie", "802": "Ergoterapie", "852": "Fyzioterapie", "853": "Fyzioterapie", "858": "Fyzioterapie", "860": "Fyzioterapie", "862": "Fyzioterapie", "873": "Fyzioterapie", "880": "Rehabilitace", "881": "Endokrinologie", "885": "Rehabilitace", "889": "Rehabilitace", "890": "Rehabilitace", } def odbornost_z_icp(icp): """Vrati nazev odbornosti z ICP kodu (posledni 3 cislice).""" if not icp or len(icp) < 3: return "" kod = icp[-3:] return ODBORNOST.get(kod, f"odb. {kod}") # ── NASTAVENÍ ───────────────────────────────────────────────────────────────── RODNE_CISLO = "440802/018" # funguje s lomitkem i bez: 7309208104 nebo 730920/8104 DATUM_OD = "01.01.2025" # None = vsechny predpisy # ───────────────────────────────────────────────────────────────────────────── FB = dict( dsn = r"localhost:c:\medicus 3\data\medicus.fdb", user = "SYSDBA", password= "masterkey", charset = "win1250", ) DB = dict( host = "192.168.1.76", user = "root", password = "Vlado9674+", database = "medicus", charset = "utf8mb4", cursorclass = pymysql.cursors.DictCursor, ) SEP = "-" * 110 SEP2 = "-" * 165 def parse_datum(s, nazev): try: return datetime.strptime(s, "%d.%m.%Y").date() except (ValueError, TypeError): sys.exit(f"Nespravny format data '{nazev}': '{s}'. Pouzijte DD.MM.RRRR.") def normalizuj_rc(rc): """Odstrani lomitko a mezery z rodneho cisla.""" return rc.replace("/", "").replace(" ", "").strip() def najdi_v_firebirdu(rodne_cislo): """Vrati prijmeni, jmeno a datum narozeni z Medicusu podle rodneho cisla.""" rc = normalizuj_rc(rodne_cislo) conn = fdb.connect(**FB) try: cur = conn.cursor() cur.execute( "SELECT KAR.PRIJMENI, KAR.JMENO, KAR.DATNAR " "FROM KAR WHERE KAR.RODCIS = ?", (rc,) ) row = cur.fetchone() if not row: sys.exit(f"Rodne cislo '{rodne_cislo}' nenalezeno v Medicusu.") return {"prijmeni": row[0].strip(), "jmeno": row[1].strip(), "datnar": row[2]} finally: conn.close() def najdi_pacienty(cur, prijmeni, datum_narozeni): cur.execute( "SELECT id, prijmeni, jmena, datum_narozeni " "FROM pacient WHERE prijmeni = %s AND datum_narozeni = %s", (prijmeni, datum_narozeni), ) return cur.fetchall() def tiskni_lekare(cur, pacient_id, prijmeni, jmena, datum_narozeni): cur.execute( """ SELECT pr.prijmeni, pr.jmena, pr.icp, CONCAT(pr.pzs_nazev, ', ', pr.ulice, ', ', pr.psc, ' ', pr.mesto) AS adresa, COUNT(*) AS pocet_predpisu FROM zprava z JOIN predpis p ON p.zprava_id = z.id JOIN predepisujici pr ON pr.lekar_kod = p.kod_predepisujiciho WHERE z.pacient_id = %s GROUP BY pr.lekar_kod, pr.prijmeni, pr.jmena, pr.icp, pr.pzs_nazev, pr.ulice, pr.psc, pr.mesto ORDER BY pocet_predpisu DESC """, (pacient_id,), ) rows = cur.fetchall() print(f"\n{SEP}") print(f" PACIENT: {prijmeni} {jmena} | nar. {datum_narozeni.strftime('%d.%m.%Y')}") print(SEP) print(f"\nPREDEPISUJICI LEKARI:") print(f"{'#':<4} {'Lekar':<30} {'Odbornost':<25} {'Pracoviste a adresa':<50} {'Predpisu':>8}") print(SEP) for i, r in enumerate(rows, 1): lekar = f"{r['prijmeni']} {r['jmena']}" odb = odbornost_z_icp(r['icp']) print(f"{i:<4} {lekar:<30} {odb:<25} {r['adresa']:<50} {r['pocet_predpisu']:>8}") if not rows: print(" Zadne predpisy nenalezeny.") def tiskni_predpisy(cur, pacient_id, datum_od): podminka = "AND p.datum_vystaveni >= %s" if datum_od else "" params = (pacient_id, datum_od) if datum_od else (pacient_id,) cur.execute( f""" SELECT p.datum_vystaveni, COALESCE(v.nazev, p.nazev) AS vydany_lek, v.nazev IS NULL AS nevyzvednuto, p.atc, p.navod, pr.prijmeni, pr.jmena, pr.icp, CONCAT(pr.pzs_nazev, ', ', pr.ulice, ', ', pr.psc, ' ', pr.mesto) AS adresa FROM zprava z JOIN predpis p ON p.zprava_id = z.id JOIN predepisujici pr ON pr.lekar_kod = p.kod_predepisujiciho LEFT JOIN vydej v ON v.id_lp_predpis = p.id_lp_predpis WHERE z.pacient_id = %s {podminka} ORDER BY p.datum_vystaveni DESC """, params, ) rows = cur.fetchall() od_text = f"od {datum_od.strftime('%d.%m.%Y')}" if datum_od else "vse" print(f"\nVSECHNY PREDPISY ({od_text}) — celkem {len(rows)}:") print(f"{'#':<4} {'Datum':<12} {'Vydany lek':<30} {'ATC':<8} {'Navod':<20} {'Lekar':<25} {'Odbornost':<22} Adresa") print(SEP2) for i, r in enumerate(rows, 1): datum = r["datum_vystaveni"].strftime("%d.%m.%Y") lekar = f"{r['prijmeni']} {r['jmena']}" lek = (r["vydany_lek"] or "")[:28] if r["nevyzvednuto"]: lek = f"{lek} *NV" navod = (r["navod"] or "")[:19] atc = (r["atc"] or "") odb = odbornost_z_icp(r["icp"])[:21] print(f"{i:<4} {datum:<12} {lek:<30} {atc:<8} {navod:<20} {lekar:<25} {odb:<22} {r['adresa']}") if not rows: print(" Zadne predpisy nenalezeny.") print() def main(): datum_od = parse_datum(DATUM_OD, "DATUM_OD") if DATUM_OD else None # 1. Najdi pacienta v Medicusu (Firebird) podle rodneho cisla fb_pac = najdi_v_firebirdu(RODNE_CISLO) prijmeni = fb_pac["prijmeni"] datum_narozeni = fb_pac["datnar"] print(f"\nFirebird: nalezen {prijmeni} {fb_pac['jmeno']} nar. {datum_narozeni}") # 2. Dotaz do MySQL conn = pymysql.connect(**DB) try: with conn.cursor() as cur: pacienti = najdi_pacienty(cur, prijmeni, datum_narozeni) if not pacienti: print(f"Pacient '{prijmeni}' nar. {datum_narozeni} nema zaznam v MySQL (lekovy zaznam nebyl stazeny).") return for pac in pacienti: tiskni_lekare(cur, pac["id"], pac["prijmeni"], pac["jmena"], pac["datum_narozeni"]) tiskni_predpisy(cur, pac["id"], datum_od) finally: conn.close() if __name__ == "__main__": main()