393 lines
12 KiB
Python
393 lines
12 KiB
Python
"""
|
|
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()
|