This commit is contained in:
2026-05-25 16:44:34 +02:00
parent 215742fd78
commit c2d721bf8a
2 changed files with 382 additions and 0 deletions
@@ -1586,5 +1586,41 @@
{
"original": "510417052 2026-05-18 Hejkrlík, Jan [LZ urologie] [st.p. DVP 22.6.23 kontinent, erekce 0, CaP gs 3+4 ISUP2 pT2cN0M0 R-, PSA <0.006, E.coli 10^5 IMC].pdf",
"corrected": "510417052 2026-05-18 Hejkrlík, Jan [LZ urologie] [st.p. DVP 22.6.23 kontinent, erekce 0, CaP gs 3+4 ISUP2 pT2cN0M0 R-, PSA 0.006, E.coli 10^5 IMC].pdf"
},
{
"original": "0261070194 2021-11-09 Krähe, Yirka [LZ pediatrie] [výpis zdrav. dok.; trans. chlapec, HRT Nebido od 8/2020, st.p. panic. ataka].pdf",
"corrected": "0261070194 2021-11-09 Krähe, Yirka [LZ pediatrie] [výpis zdrav. dok.; trans. chlapec, HRT Nebido od 82020, st.p. panic. ataka].pdf"
},
{
"original": "471130030 2026-05-20 Ouředník, František [LZ plicní] [CHOPN 3. st., Trimbo a Berodual 1x/den s efektem, stac. stav, bez exacerbace].pdf",
"corrected": "471130030 2026-05-20 Ouředník, František [LZ plicní] [CHOPN 3. st., Trimbo a Berodual 1xden s efektem, stac. stav, bez exacerbace].pdf"
},
{
"original": "496203179 2026-05-20 Netřebská, Blanka [LZ kardiologie] [st.p. resekci levé ledviny pro tumor, TK 115/75, EKG SR 75/min PQ 240ms, holter bez záchytu aryt.].pdf",
"corrected": "496203179 2026-05-20 Netřebská, Blanka [LZ kardiologie] [st.p. resekci levé ledviny pro tumor, TK 11575, EKG SR 75min PQ 240ms, holter bez záchytu aryt.].pdf"
},
{
"original": "505521223 2026-05-19 Vejlupková, Miluše [žádost o výpis zdravotní dokumentace] [žádost o zaslání veškerých informací o léčbě TAT].pdf",
"corrected": "505521223 2026-05-19 Vejlupková, Miluše [žádost o výpis zdravotní dokumentace] [žádost o zaslání veškerých informací o léčbě TAT, MUDr. Miloš Bareš s.r.o.].pdf"
},
{
"original": "510214143 2026-05-07 Šotola, Radomír [LZ kardiologie] [st.p. SAVR 10/2022 SJM Epic No25, DM2, ICHS, aortální stenóza, námahová dušnost].pdf",
"corrected": "510214143 2026-05-07 Šotola, Radomír [LZ kardiologie] [plánovaná kontrola, st.p. SAVR 102022 SJM Epic No25, DM2, ICHS, aortální stenóza, námahová dušnost].pdf"
},
{
"original": "510214143 2026-04-28 Šotola, Radomír [PZ rehabilitace] [31MAR202628APR2026 TEP L kyčle 28.1.2026, VAS LSpáteře, neuropatie DKK, DM2, hypertenze, ICHS].pdf",
"corrected": "510214143 2026-04-28 Šotola, Radomír [PZ lázně] [31MAR202628APR2026 TEP L kyčle 28.1.2026, VAS LSpáteře, neuropatie DKK, DM2, hypertenze, ICHS].pdf"
},
{
"original": "6454232378 2026-05-14 Vaváková, Dagmar [LZ radiační onkologie] [inflam. ca prsu l.dx. ypT2 ypN2a, adj. RT hrud. stěny vpravo 42.56 Gy16fr, ukončena 14.5.2026].pdf",
"corrected": "6454232378 2026-05-12 Vaváková, Dagmar [LZ radiační onkologie] [inflam. ca prsu l.dx. ypT2 ypN2a, adj. RT hrud. stěny vpravo 42.56 Gy16fr, ukončena 14.5.2026].pdf"
},
{
"original": "7108290002 2025-08-18 Hašek, Milan [LZ diabetologie] [DM2 PAD od 2/2025, HbA1c 78 (min.97), kompenzace zlepšena, nad cílem, důraz diety].pdf",
"corrected": "7108290002 2025-08-18 Hašek, Milan [LZ diabetologie] [DM2 PAD od 22025, HbA1c 78 (min.97), kompenzace zlepšena, nad cílem, důraz diety].pdf"
},
{
"original": "9353050003 Dufková, Kateřina split_013.pdf",
"corrected": "9353050003 2026-05-22 Dufková, Kateřina [EKG] [normální křivka].pdf"
}
]
+346
View File
@@ -419,6 +419,352 @@ def safe_query(sql: str, params: Optional[list] = None) -> dict:
raise
@mcp.tool()
def get_patient_prescriptions(idpac: int, months: int = 6) -> dict:
"""Vrátí seznam předepsaných léků pacienta z receptů za posledních N měsíců (výchozí 6).
Výsledek: pacient (jmeno, prijmeni, rc) + seznam receptů (datum, lek, dsig).
"""
try:
cur = conn.cursor()
cur.execute("SELECT JMENO, PRIJMENI, RODCIS FROM KAR WHERE IDPAC = ?", [idpac])
pac = cur.fetchone()
if not pac:
return {'error': f'Pacient IDPAC={idpac} nenalezen'}
cur.execute("""
SELECT DATUM, LEK, DSIG
FROM RECEPT
WHERE IDPAC = ?
AND DATUM >= DATEADD(-? MONTH TO CURRENT_DATE)
ORDER BY DATUM DESC, ID DESC
""", [idpac, months])
import datetime
recepty = [
{
'datum': r[0].isoformat() if isinstance(r[0], datetime.date) else r[0],
'lek': r[1],
'dsig': r[2] or '',
}
for r in cur.fetchall()
]
return {
'pacient': {'jmeno': pac[0], 'prijmeni': pac[1], 'rc': pac[2]},
'obdobi_mesice': months,
'pocet': len(recepty),
'recepty': recepty,
}
except Exception:
log(f"get_patient_prescriptions chyba: {traceback.format_exc()}")
raise
@mcp.tool()
def get_patient_dxa_files(idpac: int) -> dict:
"""Zjistí, zda má pacient fyzicky uložený DXA/denzitometrický nález v tabulce FILES.
Hledá v FILENAME výrazy: DXA, DENZIT, OSTEOPOR (bez rozlišení velikosti písmen).
Vrátí: pacient + seznam nalezených souborů (id, filename, datum, poznamka).
"""
try:
cur = conn.cursor()
cur.execute("SELECT JMENO, PRIJMENI, RODCIS FROM KAR WHERE IDPAC = ?", [idpac])
pac = cur.fetchone()
if not pac:
return {'error': f'Pacient IDPAC={idpac} nenalezen'}
cur.execute("""
SELECT ID, FILENAME, DATUM, POZNAMKA
FROM FILES
WHERE IDPAC = ?
AND UPPER(FILENAME) LIKE '%DXA%'
ORDER BY DATUM DESC, ID DESC
""", [idpac])
import datetime
soubory = [
{
'id': r[0],
'filename': r[1],
'datum': r[2].isoformat() if isinstance(r[2], datetime.date) else r[2],
'poznamka': r[3] or '',
}
for r in cur.fetchall()
]
return {
'pacient': {'jmeno': pac[0], 'prijmeni': pac[1], 'rc': pac[2]},
'ma_dxa': len(soubory) > 0,
'pocet': len(soubory),
'soubory': soubory,
}
except Exception:
log(f"get_patient_dxa_files chyba: {traceback.format_exc()}")
raise
@mcp.tool()
def get_patient_vaccinations(idpac: int) -> dict:
"""Vrátí všechna očkování pacienta z tabulky OCKZAZ.
Výsledek: pacient + seznam očkování (datum, latka, zkratka, nazev, davka, por, priste, poznamka).
Řazení: od nejnovějšího. Zrušené záznamy (ZRUSENO='T') jsou označeny.
"""
try:
cur = conn.cursor()
cur.execute("SELECT JMENO, PRIJMENI, RODCIS FROM KAR WHERE IDPAC = ?", [idpac])
pac = cur.fetchone()
if not pac:
return {'error': f'Pacient IDPAC={idpac} nenalezen'}
cur.execute("""
SELECT DATUM, LATKA, ZKRATKA, NAZEV, DAVKA, POR, PRISTE, POZNAMKA, ZRUSENO
FROM OCKZAZ
WHERE IDPAC = ?
ORDER BY DATUM DESC, ID DESC
""", [idpac])
import datetime
ockovani = [
{
'datum': r[0].isoformat() if isinstance(r[0], datetime.date) else r[0],
'latka': r[1] or '',
'zkratka': r[2] or '',
'nazev': r[3] or '',
'davka': r[4] or '',
'poradi': r[5],
'priste': r[6].isoformat() if isinstance(r[6], datetime.date) else r[6],
'poznamka': r[7] or '',
'zruseno': r[8] == 'T',
}
for r in cur.fetchall()
]
return {
'pacient': {'jmeno': pac[0], 'prijmeni': pac[1], 'rc': pac[2]},
'pocet': len(ockovani),
'ockovani': ockovani,
}
except Exception:
log(f"get_patient_vaccinations chyba: {traceback.format_exc()}")
raise
@mcp.tool()
def get_patient_psa_lab(idpac: int) -> dict:
"""Vrátí laboratorní výsledky PSA pacienta: datum, hodnota, jednotka, referenční meze (dolní/horní).
Hledá všechny metody jejichž název obsahuje PSA (Total PSA, Free PSA, PSA celkový atd.).
Výsledek seřazen od nejnovějšího.
"""
try:
cur = conn.cursor()
cur.execute("SELECT JMENO, PRIJMENI, RODCIS FROM KAR WHERE IDPAC = ?", [idpac])
pac = cur.fetchone()
if not pac:
return {'error': f'Pacient IDPAC={idpac} nenalezen'}
cur.execute("""
SELECT
h.DATUM,
m.NAZEV,
d.VYSL,
j.JEDN,
s.NORMDOL,
s.NORMHOR
FROM LABVH h
JOIN LABVD d ON d.IDVH = h.IDVH
JOIN LABMETOD m ON m.IDMETOD = d.IDMETOD
LEFT JOIN LABJEDN j ON j.IDJEDN = d.IDJEDN
LEFT JOIN LABSKALY s ON s.IDSKALY = d.IDSKALY AND s.TYP = '4'
WHERE h.IDPACIENT = ?
AND UPPER(m.NAZEV) LIKE '%PSA%'
ORDER BY h.DATUM DESC, h.IDVH DESC
""", [idpac])
import datetime
vysledky = [
{
'datum': r[0].isoformat() if isinstance(r[0], datetime.date) else r[0],
'metoda': r[1],
'hodnota': r[2],
'jednotka': r[3] or '',
'ref_dolni': r[4],
'ref_horni': r[5],
}
for r in cur.fetchall()
]
return {
'pacient': {'jmeno': pac[0], 'prijmeni': pac[1], 'rc': pac[2]},
'pocet': len(vysledky),
'vysledky': vysledky,
}
except Exception:
log(f"get_patient_psa_lab chyba: {traceback.format_exc()}")
raise
@mcp.tool()
def get_patient_sick_leaves(idpac: int) -> dict:
"""Vrátí přehled pracovních neschopností pacienta z tabulky NES.
Výsledek: pacient + seznam neschopností (od, do, diagnóza, stav, zaměstnavatel, počet dní, ECN číslo).
Stornované záznamy jsou označeny. Řazení od nejnovějšího.
"""
try:
cur = conn.cursor()
cur.execute("SELECT JMENO, PRIJMENI, RODCIS FROM KAR WHERE IDPAC = ?", [idpac])
pac = cur.fetchone()
if not pac:
return {'error': f'Pacient IDPAC={idpac} nenalezen'}
cur.execute("""
SELECT ZACNES, KONNES, DIAGNO, PRACNE, PRICINA, PODNIK, PROFES,
STORNO, ECN, DUVOD_UKONCENI
FROM NES
WHERE IDPAC = ?
ORDER BY ZACNES DESC, ID DESC
""", [idpac])
import datetime
def fmt_date(v):
return v.isoformat() if isinstance(v, datetime.date) else v
def pocet_dni(zacnes, konnes, pracne):
if not zacnes:
return None
konec = konnes if konnes else datetime.date.today()
if isinstance(zacnes, datetime.date) and isinstance(konec, datetime.date):
return (konec - zacnes).days + 1
return None
neschopenky = [
{
'od': fmt_date(r[0]),
'do': fmt_date(r[1]),
'diagno': (r[2] or '').strip(),
'stav': 'aktivní' if r[3] == 'A' else 'ukončená',
'pricina': r[4] or '',
'zamestnavatel': r[5] or '',
'profes': r[6] or '',
'storno': r[7] == 'T',
'ecn': r[8] or '',
'duvod_ukonceni': r[9] or '',
'pocet_dni': pocet_dni(r[0], r[1], r[3]),
}
for r in cur.fetchall()
]
aktivni = sum(1 for n in neschopenky if n['stav'] == 'aktivní' and not n['storno'])
return {
'pacient': {'jmeno': pac[0], 'prijmeni': pac[1], 'rc': pac[2]},
'pocet_celkem': len(neschopenky),
'pocet_aktivnich': aktivni,
'neschopenky': neschopenky,
}
except Exception:
log(f"get_patient_sick_leaves chyba: {traceback.format_exc()}")
raise
PSA_KODY = ('01131', '01132', '01133', '81227', '81530', '81718', '81800', '93225')
@mcp.tool()
def get_psa_records(idpac: Optional[int] = None, rok: Optional[int] = None) -> dict:
"""Vrátí přehled vykázaných PSA výkonů z DOKLADD.
Sledované kódy: 0113101133, 81227, 81530, 81718, 81800, 93225.
idpac: filtr konkrétního pacienta (None = všichni).
rok: filtr roku (None = vše).
Výsledek: počet + seznam (datum, kód, název, příjmení, jméno, rc).
"""
try:
cur = conn.cursor()
kody_placeholder = ','.join(['?' for _ in PSA_KODY])
params = list(PSA_KODY)
sql = f"""
SELECT d.DATOSE, d.KOD, v.NAZ, k.PRIJMENI, k.JMENO, d.RODCIS
FROM DOKLADD d
JOIN KAR k ON k.RODCIS = d.RODCIS
JOIN VYKONY v ON v.KOD = d.KOD
AND d.DATOSE BETWEEN v.PLATIOD AND COALESCE(v.PLATIDO, CURRENT_DATE)
WHERE d.KOD IN ({kody_placeholder})
"""
if idpac:
sql += " AND k.IDPAC = ?"
params.append(idpac)
if rok:
sql += " AND EXTRACT(YEAR FROM d.DATOSE) = ?"
params.append(rok)
sql += " ORDER BY d.DATOSE DESC, k.PRIJMENI"
cur.execute(sql, params)
import datetime
zaznamy = [
{
'datum': r[0].isoformat() if isinstance(r[0], datetime.date) else r[0],
'kod': r[1],
'naz': r[2],
'prijmeni': r[3],
'jmeno': r[4],
'rc': r[5].strip() if r[5] else '',
}
for r in cur.fetchall()
]
return {
'idpac': idpac,
'rok': rok,
'pocet': len(zaznamy),
'zaznamy': zaznamy,
}
except Exception:
log(f"get_psa_records chyba: {traceback.format_exc()}")
raise
DXA_KODY = ('10035', '11320', '11321', '11322', '11323', '11324', '11325', '11326')
@mcp.tool()
def get_dxa_records(rok: Optional[int] = None) -> dict:
"""Vrátí přehled vykázaných DXA výkonů (osteoporóza, denzitometrie).
Sledované kódy: 11320, 11321, 1132211326, 10035.
rok: filtr roku (např. 2025), None = vše.
Výsledek: celkový počet + seznam záznamů (datum, kód, název kódu, příjmení, jméno, rc).
"""
try:
cur = conn.cursor()
kody_placeholder = ','.join(['?' for _ in DXA_KODY])
params = list(DXA_KODY)
sql = f"""
SELECT d.DATOSE, d.KOD, v.NAZ, k.PRIJMENI, k.JMENO, d.RODCIS
FROM DOKLADD d
JOIN KAR k ON k.RODCIS = d.RODCIS
JOIN VYKONY v ON v.KOD = d.KOD
AND d.DATOSE BETWEEN v.PLATIOD AND COALESCE(v.PLATIDO, CURRENT_DATE)
WHERE d.KOD IN ({kody_placeholder})
"""
if rok:
sql += " AND EXTRACT(YEAR FROM d.DATOSE) = ?"
params.append(rok)
sql += " ORDER BY d.DATOSE DESC, k.PRIJMENI"
cur.execute(sql, params)
import datetime
zaznamy = [
{
'datum': r[0].isoformat() if isinstance(r[0], datetime.date) else r[0],
'kod': r[1],
'naz': r[2],
'prijmeni': r[3],
'jmeno': r[4],
'rc': r[5].strip() if r[5] else '',
}
for r in cur.fetchall()
]
return {
'rok': rok,
'pocet': len(zaznamy),
'zaznamy': zaznamy,
}
except Exception:
log(f"get_dxa_records chyba: {traceback.format_exc()}")
raise
if __name__ == '__main__':
log("MCP Firebird server spuštěn (FastMCP)")
mcp.run()