z230
This commit is contained in:
@@ -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] [31MAR2026–28APR2026 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ě] [31MAR2026–28APR2026 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
@@ -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: 01131–01133, 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, 11322–11326, 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()
|
||||
|
||||
Reference in New Issue
Block a user