z230
This commit is contained in:
@@ -7,7 +7,8 @@
|
|||||||
"Read(//c/xampp/mysql/**)",
|
"Read(//c/xampp/mysql/**)",
|
||||||
"Bash(find /c -name \"mysql.exe\")",
|
"Bash(find /c -name \"mysql.exe\")",
|
||||||
"Bash(python3 -c ':*)",
|
"Bash(python3 -c ':*)",
|
||||||
"Bash(python -c ':*)"
|
"Bash(python -c ':*)",
|
||||||
|
"Bash(.venv/Scripts/python.exe -c ':*)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-26
@@ -144,9 +144,9 @@ Klíčový princip `COALESCE(v.nazev, p.nazev)`:
|
|||||||
Odbornost se odvozuje z posledních 3 číslic pole `predepisujici.icp` (IČP pracoviště).
|
Odbornost se odvozuje z posledních 3 číslic pole `predepisujici.icp` (IČP pracoviště).
|
||||||
|
|
||||||
```
|
```
|
||||||
ICP: 09305001 → kód odbornosti: 001 → Praktický lékař
|
ICP: 09305001 → kód odbornosti: 001 → všeobecné praktické lékařství
|
||||||
ICP: 08006272 → kód odbornosti: 272 → Alergologie
|
ICP: 08006272 → kód odbornosti: 272 → alergologie
|
||||||
ICP: 08075603 → kód odbornosti: 603 → Onkologie
|
ICP: 08075603 → kód odbornosti: 603 → onkologie
|
||||||
```
|
```
|
||||||
|
|
||||||
Funkce:
|
Funkce:
|
||||||
@@ -157,32 +157,38 @@ def odbornost_z_icp(icp):
|
|||||||
return ODBORNOST.get(icp[-3:], f"odb. {icp[-3:]}")
|
return ODBORNOST.get(icp[-3:], f"odb. {icp[-3:]}")
|
||||||
```
|
```
|
||||||
|
|
||||||
Pro neznámé kódy se zobrazí `odb. XXX` (XXX = třímístný číselný kód).
|
Pro neznámé kódy se zobrazí `odb. XXX` (XXX = třímístný kód).
|
||||||
|
|
||||||
### Slovník ODBORNOST — vybrané klíčové kódy
|
### Zdroj dat — tabulky `vzp_pracoviste` + `odbornost` (MySQL)
|
||||||
|
|
||||||
| Kód | Odbornost | Kód | Odbornost |
|
Slovník `ODBORNOST` se **načítá dynamicky při startu skriptu** z MySQL:
|
||||||
|-----|-----------|-----|-----------|
|
|
||||||
| 001 | Praktický lékař | 101 | Vnitřní lékařství |
|
|
||||||
| 002 | Pediatr (prakt.) | 104 | Kardiologie |
|
|
||||||
| 003 | Chirurgie | 105 | Gastroenterologie |
|
|
||||||
| 004 | Ortopedie | 108 | Nefrologie |
|
|
||||||
| 005 | ORL | 110 | Diabetologie |
|
|
||||||
| 006 | Gynekologie | 121 | Endokrinologie |
|
|
||||||
| 007 | Urologie | 156 | Hematologie |
|
|
||||||
| 008 | Neurologie | 169 | Revmatologie |
|
|
||||||
| 009 | Psychiatrie | 263 | Urologie |
|
|
||||||
| 012 | Dermatovenerologie | 272 | Alergologie |
|
|
||||||
| 018 | Pneumologie | 283 | Dětská neurochir. |
|
|
||||||
| 021 | Radiodiagnostika | 302 | Radiodiagnostika |
|
|
||||||
| 024 | Klin. biochemie | 324 | Klin. onkologie |
|
|
||||||
| 060 | Dětská chirurgie | 590 | Lékárenství |
|
|
||||||
| 074 | Neurochirurgie | 603 | Onkologie |
|
|
||||||
| 091 | Gynekolog. onkologie | 704 | Kardiochirurgie |
|
|
||||||
| 096 | Léčebná rehabilitace | 801 | Fyzioterapie |
|
|
||||||
|
|
||||||
Celý slovník obsahuje ~170 kódů (viz zdrojový kód skriptů).
|
```python
|
||||||
Kompletní číselník VZP/SÚKL: <https://www.sukl.cz> (sekce číselníky).
|
def _nacti_odbornosti():
|
||||||
|
conn = pymysql.connect(**DB)
|
||||||
|
try:
|
||||||
|
with conn.cursor(pymysql.cursors.Cursor) as cur:
|
||||||
|
cur.execute("""
|
||||||
|
SELECT vp.icp, o.nazev
|
||||||
|
FROM vzp_pracoviste vp
|
||||||
|
JOIN odbornost o ON o.kod = vp.odbornost
|
||||||
|
WHERE CURDATE() BETWEEN vp.platnost_od AND vp.platnost_do
|
||||||
|
ORDER BY vp.platnost_od DESC
|
||||||
|
""")
|
||||||
|
result = {}
|
||||||
|
for icp, nazev in cur.fetchall():
|
||||||
|
result.setdefault(icp, nazev)
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
ODBORNOST = _nacti_odbornosti()
|
||||||
|
```
|
||||||
|
|
||||||
|
- `vzp_pracoviste` — oficiální číselník VZP (stahován týdně z VZP Point přes `import_vzp_pracoviste.py`), obsahuje ~52 000 záznamů s přímou vazbou ICP → kód odbornosti
|
||||||
|
- `odbornost` — číselník názvů odborností importovaný z Firebird tabulky `odborn` (360 aktuálně platných kódů)
|
||||||
|
- Vyhledávání probíhá podle **plného 8-znakového ICP** — spolehlivé i pro pracoviště, která změnila odbornost
|
||||||
|
- Slovník obsahuje ~43 000 aktuálně platných ICP kódů
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+27
-197
@@ -16,207 +16,13 @@ import fdb
|
|||||||
import pymysql
|
import pymysql
|
||||||
import pymysql.cursors
|
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):
|
def odbornost_z_icp(icp):
|
||||||
"""Vrati nazev odbornosti z ICP kodu (posledni 3 cislice)."""
|
"""Vrati nazev odbornosti podle ICP (plny 8-znakovy kod) z tabulky vzp_pracoviste."""
|
||||||
if not icp or len(icp) < 3:
|
if not icp:
|
||||||
return ""
|
return ""
|
||||||
kod = icp[-3:]
|
return ODBORNOST.get(icp, f"odb. {icp[-3:]}")
|
||||||
return ODBORNOST.get(kod, f"odb. {kod}")
|
|
||||||
|
|
||||||
# ── NASTAVENÍ ─────────────────────────────────────────────────────────────────
|
# ── NASTAVENÍ ─────────────────────────────────────────────────────────────────
|
||||||
RODNE_CISLO = "440802/018" # funguje s lomitkem i bez: 7309208104 nebo 730920/8104
|
RODNE_CISLO = "440802/018" # funguje s lomitkem i bez: 7309208104 nebo 730920/8104
|
||||||
@@ -230,6 +36,8 @@ FB = dict(
|
|||||||
charset = "win1250",
|
charset = "win1250",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DB = dict(
|
DB = dict(
|
||||||
host = "192.168.1.76",
|
host = "192.168.1.76",
|
||||||
user = "root",
|
user = "root",
|
||||||
@@ -238,6 +46,28 @@ DB = dict(
|
|||||||
charset = "utf8mb4",
|
charset = "utf8mb4",
|
||||||
cursorclass = pymysql.cursors.DictCursor,
|
cursorclass = pymysql.cursors.DictCursor,
|
||||||
)
|
)
|
||||||
|
def _nacti_odbornosti():
|
||||||
|
"""Nacteni odbornosti z MySQL: vzp_pracoviste JOIN odbornost (aktualne platne ICP)."""
|
||||||
|
conn = pymysql.connect(**DB)
|
||||||
|
try:
|
||||||
|
with conn.cursor(pymysql.cursors.Cursor) as cur:
|
||||||
|
cur.execute("""
|
||||||
|
SELECT vp.icp, o.nazev
|
||||||
|
FROM vzp_pracoviste vp
|
||||||
|
JOIN odbornost o ON o.kod = vp.odbornost
|
||||||
|
WHERE CURDATE() BETWEEN vp.platnost_od AND vp.platnost_do
|
||||||
|
ORDER BY vp.platnost_od DESC
|
||||||
|
""")
|
||||||
|
result = {}
|
||||||
|
for icp, nazev in cur.fetchall():
|
||||||
|
result.setdefault(icp, nazev)
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
ODBORNOST = _nacti_odbornosti()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SEP = "-" * 110
|
SEP = "-" * 110
|
||||||
SEP2 = "-" * 165
|
SEP2 = "-" * 165
|
||||||
|
|||||||
@@ -18,198 +18,13 @@ from openpyxl.styles import (Font, PatternFill, Alignment, Border, Side,
|
|||||||
GradientFill)
|
GradientFill)
|
||||||
from openpyxl.utils import get_column_letter
|
from openpyxl.utils import get_column_letter
|
||||||
|
|
||||||
# Kody odbornosti dle SUKL / VZP (posledni 3 cislice ICP)
|
|
||||||
ODBORNOST = {
|
|
||||||
"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",
|
|
||||||
"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",
|
|
||||||
"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",
|
|
||||||
"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",
|
|
||||||
"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í",
|
|
||||||
"600": "Onkologie",
|
|
||||||
"601": "Klin. onkologie",
|
|
||||||
"603": "Onkologie",
|
|
||||||
"606": "Radioterapie",
|
|
||||||
"607": "Nukleární medicína",
|
|
||||||
"615": "Onkologie",
|
|
||||||
"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",
|
|
||||||
"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):
|
def odbornost_z_icp(icp):
|
||||||
"""Vrati nazev odbornosti z ICP kodu (posledni 3 cislice)."""
|
"""Vrati nazev odbornosti podle ICP (plny 8-znakovy kod) z tabulky vzp_pracoviste."""
|
||||||
if not icp or len(icp) < 3:
|
if not icp:
|
||||||
return ""
|
return ""
|
||||||
return ODBORNOST.get(icp[-3:], f"odb. {icp[-3:]}")
|
return ODBORNOST.get(icp, f"odb. {icp[-3:]}")
|
||||||
|
|
||||||
|
|
||||||
# ── NASTAVENÍ ─────────────────────────────────────────────────────────────────
|
# ── NASTAVENÍ ─────────────────────────────────────────────────────────────────
|
||||||
@@ -225,6 +40,8 @@ FB = dict(
|
|||||||
charset = "win1250",
|
charset = "win1250",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DB = dict(
|
DB = dict(
|
||||||
host = "192.168.1.76",
|
host = "192.168.1.76",
|
||||||
user = "root",
|
user = "root",
|
||||||
@@ -233,6 +50,28 @@ DB = dict(
|
|||||||
charset = "utf8mb4",
|
charset = "utf8mb4",
|
||||||
cursorclass = pymysql.cursors.DictCursor,
|
cursorclass = pymysql.cursors.DictCursor,
|
||||||
)
|
)
|
||||||
|
def _nacti_odbornosti():
|
||||||
|
"""Nacteni odbornosti z MySQL: vzp_pracoviste JOIN odbornost (aktualne platne ICP)."""
|
||||||
|
conn = pymysql.connect(**DB)
|
||||||
|
try:
|
||||||
|
with conn.cursor(pymysql.cursors.Cursor) as cur:
|
||||||
|
cur.execute("""
|
||||||
|
SELECT vp.icp, o.nazev
|
||||||
|
FROM vzp_pracoviste vp
|
||||||
|
JOIN odbornost o ON o.kod = vp.odbornost
|
||||||
|
WHERE CURDATE() BETWEEN vp.platnost_od AND vp.platnost_do
|
||||||
|
ORDER BY vp.platnost_od DESC
|
||||||
|
""")
|
||||||
|
result = {}
|
||||||
|
for icp, nazev in cur.fetchall():
|
||||||
|
result.setdefault(icp, nazev)
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
ODBORNOST = _nacti_odbornosti()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ── Barvy ─────────────────────────────────────────────────────────────────────
|
# ── Barvy ─────────────────────────────────────────────────────────────────────
|
||||||
C_HEADER_BG = "1F4E79" # tmave modra — hlavicka tabulky
|
C_HEADER_BG = "1F4E79" # tmave modra — hlavicka tabulky
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ DDL = [
|
|||||||
COMMENT 'UUID PLP = predpis.id_lp_predpis',
|
COMMENT 'UUID PLP = predpis.id_lp_predpis',
|
||||||
id_dokladu VARCHAR(20) NOT NULL,
|
id_dokladu VARCHAR(20) NOT NULL,
|
||||||
|
|
||||||
uhrada ENUM('ZAKLADNI','ZVYSENA','NEHRAZENY'),
|
uhrada VARCHAR(20),
|
||||||
prekroceni TINYINT(1),
|
prekroceni TINYINT(1),
|
||||||
|
|
||||||
FOREIGN KEY (id_dokladu) REFERENCES recept_doklad (id_dokladu)
|
FOREIGN KEY (id_dokladu) REFERENCES recept_doklad (id_dokladu)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ if hasattr(sys.stdout, "reconfigure"):
|
|||||||
sys.stdout.reconfigure(errors="replace")
|
sys.stdout.reconfigure(errors="replace")
|
||||||
|
|
||||||
# ── Konfigurace eRecept ──────────────────────────────────────────────────────
|
# ── Konfigurace eRecept ──────────────────────────────────────────────────────
|
||||||
PFX_FILE = r"C:\Users\vlado\PycharmProjects\Recepty\AMBSUKL214235369G_31DEC2024.pfx"
|
PFX_FILE = Path(__file__).parent.parent / "AMBSUKL214235369G_31DEC2024.pfx"
|
||||||
PFX_PASS = "Vlado7309208104++"
|
PFX_PASS = "Vlado7309208104++"
|
||||||
API_USER = "e08c89c6-2b1a-4eba-8ed9-4e3e63618379"
|
API_USER = "e08c89c6-2b1a-4eba-8ed9-4e3e63618379"
|
||||||
API_PASS = "Buzalka@Vladimir2025"
|
API_PASS = "Buzalka@Vladimir2025"
|
||||||
@@ -64,7 +64,7 @@ XML_DIR = Path(__file__).parent / "xml_archive"
|
|||||||
|
|
||||||
# ── Parametry spuštění (uprav zde) ───────────────────────────────────────────
|
# ── Parametry spuštění (uprav zde) ───────────────────────────────────────────
|
||||||
DATUM_OD = "2025-01-01" # recepty od tohoto data
|
DATUM_OD = "2025-01-01" # recepty od tohoto data
|
||||||
LIMIT = 10 # max počet receptů ke stažení; None = bez omezení
|
LIMIT = None # max počet receptů ke stažení; None = bez omezení
|
||||||
|
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -11,12 +11,18 @@ které hromadný dotaz nevrací.
|
|||||||
| Soubor | Co dělá |
|
| Soubor | Co dělá |
|
||||||
|--------|---------|
|
|--------|---------|
|
||||||
| `NacistPredpis_FUNKCNI.py` | Stáhne detail **jednoho** receptu dle hardcoded ID_Dokladu (ruční test) |
|
| `NacistPredpis_FUNKCNI.py` | Stáhne detail **jednoho** receptu dle hardcoded ID_Dokladu (ruční test) |
|
||||||
| `08StahnoutPredpisy.py` | **Hlavní skript** — načte ERP kódy z Medicusu, stáhne detaily, uloží XML |
|
| `08StahnoutPredpisy.py` | Starší skript bez DB integrace — nahrazen `10_StahnoutXML.py` |
|
||||||
|
| `09_VytvorTabulky.py` | Vytvoří tabulky `recept_doklad` a `recept_plp` v MySQL |
|
||||||
|
| `10_StahnoutXML.py` | **Stahování** — načte ERP kódy z Medicusu, přeskočí terminální, uloží XML |
|
||||||
|
| `11_ParseXML.py` | **Parsování** — naparsuje XML archiv a uloží data do MySQL |
|
||||||
|
|
||||||
```
|
```
|
||||||
NačteníPředpisuWithClaude/
|
NačteníPředpisuWithClaude/
|
||||||
├── NacistPredpis_FUNKCNI.py ← test jednoho receptu
|
├── NacistPredpis_FUNKCNI.py ← test jednoho receptu
|
||||||
├── 08StahnoutPredpisy.py ← hromadné stahování
|
├── 08StahnoutPredpisy.py ← starší skript (bez DB)
|
||||||
|
├── 09_VytvorTabulky.py ← DDL MySQL tabulek
|
||||||
|
├── 10_StahnoutXML.py ← hromadné stahování s přeskakováním
|
||||||
|
├── 11_ParseXML.py ← parsování XML do MySQL
|
||||||
├── NacistPredpis_DOKUMENTACE.md ← tento soubor
|
├── NacistPredpis_DOKUMENTACE.md ← tento soubor
|
||||||
├── xml_archive/ ← archiv XML odpovědí (YYYY-MM-DD/ERP_KOD.xml)
|
├── xml_archive/ ← archiv XML odpovědí (YYYY-MM-DD/ERP_KOD.xml)
|
||||||
├── MedicusDebug/ ← zachycené SOAP požadavky z Medicusu
|
├── MedicusDebug/ ← zachycené SOAP požadavky z Medicusu
|
||||||
@@ -38,7 +44,7 @@ jednoho konkrétního receptu, včetně:
|
|||||||
| Pole | Popis |
|
| Pole | Popis |
|
||||||
|------|-------|
|
|------|-------|
|
||||||
| `ID_Dokladu` | Alfanumerický kód receptu (např. `PPIBVF93285E`) |
|
| `ID_Dokladu` | Alfanumerický kód receptu (např. `PPIBVF93285E`) |
|
||||||
| `Stav` | Stav receptu: PREDEPSANY, CASTECNE_VYDANY, PLNE_VYDANY, ZRUSENY… |
|
| `Stav` | Stav receptu: PREDEPSANY, CASTECNE_VYDANY, PLNE_VYDANY, ZRUSENY |
|
||||||
| `PlatnostDo` | Datum konce platnosti receptu |
|
| `PlatnostDo` | Datum konce platnosti receptu |
|
||||||
| `VypisDo` | Prodloužení platnosti výpisem |
|
| `VypisDo` | Prodloužení platnosti výpisem |
|
||||||
| `Akutni` | Příznak akutní péče |
|
| `Akutni` | Příznak akutní péče |
|
||||||
@@ -54,7 +60,7 @@ jednoho konkrétního receptu, včetně:
|
|||||||
|
|
||||||
| Pole | Popis |
|
| Pole | Popis |
|
||||||
|------|-------|
|
|------|-------|
|
||||||
| `Uhrada` | ZAKLADNI / ZVYSENA / NEHRAZENY |
|
| `Uhrada` | ZAKLADNI / ZVYSENA / NEHRAZENY / PACIENT |
|
||||||
| `Prekroceni` | Překročení limitu |
|
| `Prekroceni` | Překročení limitu |
|
||||||
|
|
||||||
### Údaje o pacientovi
|
### Údaje o pacientovi
|
||||||
@@ -64,7 +70,7 @@ jednoho konkrétního receptu, včetně:
|
|||||||
| `CP` | Číslo pojištěnce (rodné číslo) |
|
| `CP` | Číslo pojištěnce (rodné číslo) |
|
||||||
| `ZP` | Zdravotní pojišťovna (kód + název) |
|
| `ZP` | Zdravotní pojišťovna (kód + název) |
|
||||||
| `Adresa` | Kompletní adresa pacienta |
|
| `Adresa` | Kompletní adresa pacienta |
|
||||||
| `Pohlavi` | M / Z |
|
| `Pohlavi` | M / F (ne M/Z jak uvádí XSD — reálně posíláno M/F) |
|
||||||
| `Telefon` | Telefonní číslo |
|
| `Telefon` | Telefonní číslo |
|
||||||
| `Notifikace` | SMS / Email |
|
| `Notifikace` | SMS / Email |
|
||||||
|
|
||||||
@@ -72,6 +78,7 @@ jednoho konkrétního receptu, včetně:
|
|||||||
|
|
||||||
| Pole | Popis |
|
| Pole | Popis |
|
||||||
|------|-------|
|
|------|-------|
|
||||||
|
| `Lekar.Kod` | UUID lékaře — nebo `"skryto"` (ukládáme jako NULL) |
|
||||||
| `Odbornost` | Kód + název (např. 001 — všeobecné praktické lékařství) |
|
| `Odbornost` | Kód + název (např. 001 — všeobecné praktické lékařství) |
|
||||||
| `Email` | Email lékaře |
|
| `Email` | Email lékaře |
|
||||||
|
|
||||||
@@ -92,6 +99,7 @@ jméno lékárníka (často „skryto"), datum vydeje, vydané léky.
|
|||||||
| **Identifikace** | ID_Dokladu (alfanumerický kód receptu) | jméno + datum narození pacienta |
|
| **Identifikace** | ID_Dokladu (alfanumerický kód receptu) | jméno + datum narození pacienta |
|
||||||
| **Výsledek** | detail jednoho receptu | celý lékový záznam pacienta (roky) |
|
| **Výsledek** | detail jednoho receptu | celý lékový záznam pacienta (roky) |
|
||||||
| **Velikost odpovědi** | ~3.5–4.5 KB | ~227 KB |
|
| **Velikost odpovědi** | ~3.5–4.5 KB | ~227 KB |
|
||||||
|
| **Pokrytí** | pouze naše ordinace (ERP kód z Medicusu) | všichni lékaři pacienta |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -106,6 +114,8 @@ jméno lékárníka (často „skryto"), datum vydeje, vydané léky.
|
|||||||
| XML namespace | `http://www.sukl.cz/erp/201704` |
|
| XML namespace | `http://www.sukl.cz/erp/201704` |
|
||||||
| Verze zprávy | `202501A` |
|
| Verze zprávy | `202501A` |
|
||||||
|
|
||||||
|
Certifikát se hledá relativně ke skriptu: `../../AMBSUKL214235369G_31DEC2024.pfx`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Zdroj ID_Dokladu — Medicus (Firebird)
|
## Zdroj ID_Dokladu — Medicus (Firebird)
|
||||||
@@ -118,6 +128,9 @@ RECEPT.id_epodani → RECEPT_EPODANI.id
|
|||||||
RECEPT_EPODANI.erp = ID_Dokladu (např. "PPIBVF93285E")
|
RECEPT_EPODANI.erp = ID_Dokladu (např. "PPIBVF93285E")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Důsledek:** Detaily receptů lze stáhnout **pouze pro naši ordinaci**.
|
||||||
|
> O předpisech cizích lékařů víme jen to, co vrací lékový záznam.
|
||||||
|
|
||||||
### SQL dotaz
|
### SQL dotaz
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
@@ -130,6 +143,9 @@ WHERE r.datum >= '2025-01-01' AND ep.erp IS NOT NULL
|
|||||||
ORDER BY r.datum DESC
|
ORDER BY r.datum DESC
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Pozor: `LIMIT` v `10_StahnoutXML.py` omezuje počet řádků z Firebirdu před deduplikací.
|
||||||
|
> Po deduplikaci (jeden recept = více léků = více řádků) může být výsledný počet receptů nižší.
|
||||||
|
|
||||||
### Statistika (duben 2026)
|
### Statistika (duben 2026)
|
||||||
|
|
||||||
- **13 571** receptů s ERP kódem od 1. 1. 2025
|
- **13 571** receptů s ERP kódem od 1. 1. 2025
|
||||||
@@ -137,58 +153,144 @@ ORDER BY r.datum DESC
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 08StahnoutPredpisy.py — hlavní skript
|
## Databázové schéma — MySQL
|
||||||
|
|
||||||
|
### Relační diagram
|
||||||
|
|
||||||
|
```
|
||||||
|
recept_doklad (1) ────────────────── (N) recept_plp
|
||||||
|
id_dokladu PK id_lp PK ──────► predpis.id_lp_predpis
|
||||||
|
id_dokladu FK
|
||||||
|
```
|
||||||
|
|
||||||
|
Tabulka `recept_plp.id_lp` = `predpis.id_lp_predpis` — přímý JOIN s lékovým záznamem.
|
||||||
|
|
||||||
|
### Tabulka `recept_doklad`
|
||||||
|
|
||||||
|
Jeden řádek na celý recept (ID_Dokladu).
|
||||||
|
|
||||||
|
| Sloupec | Typ | Poznámka |
|
||||||
|
|---------|-----|----------|
|
||||||
|
| `id_dokladu` | VARCHAR(20) PK | ERP kód |
|
||||||
|
| `stav` | ENUM | PREDEPSANY / CASTECNE_VYDANY / PLNE_VYDANY / ZRUSENY |
|
||||||
|
| `stav_terminal` | TINYINT(1) | 1 = nepotřebuje další stahování |
|
||||||
|
| `datum_vystaveni` | DATE | |
|
||||||
|
| `platnost_do` | DATE | |
|
||||||
|
| `vypis_do` | DATE | prodloužení výpisem |
|
||||||
|
| `akutni` | TINYINT(1) | |
|
||||||
|
| `rodina` | TINYINT(1) | ad usum proprium |
|
||||||
|
| `opakovani` | INT | NULL = není opakovací |
|
||||||
|
| `druh_pojisteni` | ENUM | VEREJNE / OSTATNI |
|
||||||
|
| `modry_pruh` | TINYINT(1) | |
|
||||||
|
| `pozn` | VARCHAR(1000) | |
|
||||||
|
| `zap_doplatek` | DECIMAL(10,2) | ZapocitatelnyDoplatekZbyvaDoLimitu |
|
||||||
|
| `zalozeni` / `zmena` | DATETIME | z eReceptu |
|
||||||
|
| `lekar_kod` | CHAR(36) | UUID lékaře; NULL pokud "skryto" |
|
||||||
|
| `odbornost_kod` / `odbornost_nazev` | VARCHAR | |
|
||||||
|
| `lekar_email` | VARCHAR(100) | |
|
||||||
|
| `cp` | VARCHAR(10) | číslo pojištěnce |
|
||||||
|
| `zp_kod` / `zp_nazev` | VARCHAR | pojišťovna při předpisu (snapshot) |
|
||||||
|
| `pac_telefon` | VARCHAR(20) | |
|
||||||
|
| `pac_notifikace` | ENUM | SMS / EMAIL |
|
||||||
|
| `pac_pohlavi` | VARCHAR(5) | M / F |
|
||||||
|
| `xml_soubor` | VARCHAR(255) | cesta k poslednímu XML |
|
||||||
|
| `stazeno` | DATETIME | poslední aktualizace |
|
||||||
|
|
||||||
|
### Tabulka `recept_plp`
|
||||||
|
|
||||||
|
Jeden řádek na PLP položku (lék na receptu).
|
||||||
|
|
||||||
|
| Sloupec | Typ | Poznámka |
|
||||||
|
|---------|-----|----------|
|
||||||
|
| `id_lp` | CHAR(36) PK | UUID = `predpis.id_lp_predpis` |
|
||||||
|
| `id_dokladu` | VARCHAR(20) FK | |
|
||||||
|
| `uhrada` | VARCHAR(20) | ZAKLADNI / ZVYSENA / NEHRAZENY / PACIENT |
|
||||||
|
| `prekroceni` | TINYINT(1) | |
|
||||||
|
|
||||||
|
### JOIN lékový záznam + detail receptu
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT p.datum_vystaveni, p.nazev, p.atc, p.navod,
|
||||||
|
rd.stav, rd.platnost_do, rd.zp_nazev,
|
||||||
|
rp.uhrada,
|
||||||
|
v.datum_vydeje
|
||||||
|
FROM predpis p
|
||||||
|
LEFT JOIN recept_plp rp ON rp.id_lp = p.id_lp_predpis
|
||||||
|
LEFT JOIN recept_doklad rd ON rd.id_dokladu = rp.id_dokladu
|
||||||
|
LEFT JOIN vydej v ON v.id_lp_predpis = p.id_lp_predpis
|
||||||
|
WHERE p.atc LIKE 'C09%'
|
||||||
|
ORDER BY p.datum_vystaveni DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
> LEFT JOIN — pro cizí lékaře `rd` a `rp` budou NULL (nemáme jejich ERP kód).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10_StahnoutXML.py — stahování
|
||||||
|
|
||||||
### Parametry (editovat přímo v souboru)
|
### Parametry (editovat přímo v souboru)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
LIMIT = 100 # max počet receptů ke stažení
|
DATUM_OD = "2025-01-01" # recepty od tohoto data
|
||||||
DATUM_OD = "2025-01-01" # recepty od tohoto data
|
LIMIT = None # max počet receptů; None = bez omezení
|
||||||
PRIJMENI = ["Buzalka"] # filtr příjmení (list), nebo None = všichni
|
```
|
||||||
|
|
||||||
|
### Logika přeskakování
|
||||||
|
|
||||||
|
Na začátku načte z MySQL jeden dotaz:
|
||||||
|
```sql
|
||||||
|
SELECT id_dokladu FROM recept_doklad WHERE stav_terminal = 1
|
||||||
|
```
|
||||||
|
Výsledek = Python set. Pro každý ERP kód z Medicusu:
|
||||||
|
- je v setu → přeskočit (vydaný / zrušený / expirovaný)
|
||||||
|
- není v setu → stáhnout
|
||||||
|
|
||||||
|
### Co je terminální (`stav_terminal = 1`)
|
||||||
|
|
||||||
|
- `stav IN ('PLNE_VYDANY', 'ZRUSENY')`
|
||||||
|
- nebo `platnost_do < dnes` (expirovaný bez vyzvednutí)
|
||||||
|
|
||||||
|
### Ošetření chyb
|
||||||
|
|
||||||
|
| Kód | Popis | Chování |
|
||||||
|
|-----|-------|---------|
|
||||||
|
| **D003** | Předpis zrušen lékařem | Uloží `_CHYBA.xml`, pokračuje |
|
||||||
|
| HTTP 500 | SOAP Fault | Uloží `_CHYBA.xml`, pokračuje |
|
||||||
|
| Exception | Síťová chyba | Vypíše EXCEPTION, pokračuje |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11_ParseXML.py — parsování do MySQL
|
||||||
|
|
||||||
|
### Parametry (editovat přímo v souboru)
|
||||||
|
|
||||||
|
```python
|
||||||
|
DATUM_FILTR = None # např. "2026-04-14", nebo None = celý archiv
|
||||||
```
|
```
|
||||||
|
|
||||||
### Co dělá
|
### Co dělá
|
||||||
|
|
||||||
1. Připojí se k Firebirdu, načte unikátní ERP kódy (deduplikované — jeden recept může mít více léků)
|
1. Najde nejnovější XML pro každý ERP kód (nejvyšší datum v adresářové struktuře)
|
||||||
2. Pro každý ERP kód zavolá `NacistPredpis` přes SOAP API
|
2. Naparsuje stav, platnost, pacient, předepisující, PLP položky
|
||||||
3. Uloží XML odpověď do `xml_archive/YYYY-MM-DD/{ERP_KOD}.xml`
|
3. `recept_doklad`: INSERT ... ON DUPLICATE KEY UPDATE (stav se může změnit)
|
||||||
4. Chybové odpovědi uloží jako `{ERP_KOD}_CHYBA.xml`
|
4. `recept_plp`: INSERT IGNORE (UUID je stabilní)
|
||||||
5. Pauza 5 sekund mezi voláními
|
|
||||||
|
|
||||||
### Výstup v konzoli
|
### Správné pořadí spuštění
|
||||||
|
|
||||||
```
|
```
|
||||||
[ 1/55] Buzalka Vladimír PPM5HM49EBF9 OK 3.6 KB EZETIMIB/ATORVASTATIN STADA 10MG/20MG TB
|
10_StahnoutXML.py → 11_ParseXML.py → 10_StahnoutXML.py → ...
|
||||||
[ 25/55] Buzalka Vladimír POMOTIAJ77PI CHYBA HTTP 500 D003 - Předpis zrušen...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ošetření chyb
|
`10` se spoléhá na `stav_terminal` v MySQL, který nastavuje `11`.
|
||||||
|
Bez spuštění `11` budou terminální recepty znovu stahovány.
|
||||||
| Kód | Popis | Chování skriptu |
|
|
||||||
|-----|-------|-----------------|
|
|
||||||
| **D003** | Předpis byl zrušen lékařem | Uloží `_CHYBA.xml`, pokračuje dál |
|
|
||||||
| HTTP 500 | SOAP Fault (obecný) | Uloží `_CHYBA.xml`, pokračuje dál |
|
|
||||||
| Timeout / Exception | Síťová chyba | Vypíše EXCEPTION, pokračuje dál |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Ověřeno (14. 4. 2026)
|
## Ověřeno (14. 4. 2026)
|
||||||
|
|
||||||
Testovací běh na receptech pacienta Buzalka od 1. 1. 2025:
|
- Hromadné stažení od 1. 1. 2025 spuštěno (`LIMIT = None`)
|
||||||
|
- Průběžně zpracováno 2 167 / 9 595 receptů bez chyb
|
||||||
- **55** unikátních ERP kódů nalezeno v Medicusu
|
- Odhad celkového běhu: ~16 hodin při 4–6s náhodné pauze
|
||||||
- **51** úspěšně staženo (OK)
|
|
||||||
- **4** chyby D003 (zrušené recepty)
|
|
||||||
- XML uloženy do `xml_archive/2026-04-14/`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Další kroky (plán)
|
|
||||||
|
|
||||||
1. **MySQL tabulka `recept`** — uložit detail receptu (stav, platnost, úhrada, pojišťovna…)
|
|
||||||
2. **Parsování XML** — extrakce dat z odpovědí do MySQL
|
|
||||||
3. **Inkrementální stahování** — procházet jen nové recepty od posledního běhu
|
|
||||||
4. **Stažení všech 13 571 receptů** od 1. 1. 2025 (odhad: ~19 hodin při 5s pauze)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user