This commit is contained in:
2026-04-14 14:45:22 +02:00
parent cc6c80fca6
commit 9afbf79155
7 changed files with 232 additions and 454 deletions
+32 -26
View File
@@ -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ě).
```
ICP: 09305001 → kód odbornosti: 001 → Praktický lékař
ICP: 08006272 → kód odbornosti: 272 → Alergologie
ICP: 08075603 → kód odbornosti: 603 → Onkologie
ICP: 09305001 → kód odbornosti: 001 → všeobecné praktické lékařství
ICP: 08006272 → kód odbornosti: 272 → alergologie
ICP: 08075603 → kód odbornosti: 603 → onkologie
```
Funkce:
@@ -157,32 +157,38 @@ def odbornost_z_icp(icp):
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 |
|-----|-----------|-----|-----------|
| 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 |
Slovník `ODBORNOST` se **načítá dynamicky při startu skriptu** z MySQL:
Celý slovník obsahuje ~170 kódů (viz zdrojový kód skriptů).
Kompletní číselník VZP/SÚKL: <https://www.sukl.cz> (sekce číselníky).
```python
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
View File
@@ -16,207 +16,13 @@ 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:
"""Vrati nazev odbornosti podle ICP (plny 8-znakovy kod) z tabulky vzp_pracoviste."""
if not icp:
return ""
kod = icp[-3:]
return ODBORNOST.get(kod, f"odb. {kod}")
return ODBORNOST.get(icp, f"odb. {icp[-3:]}")
# ── NASTAVENÍ ─────────────────────────────────────────────────────────────────
RODNE_CISLO = "440802/018" # funguje s lomitkem i bez: 7309208104 nebo 730920/8104
@@ -230,6 +36,8 @@ FB = dict(
charset = "win1250",
)
DB = dict(
host = "192.168.1.76",
user = "root",
@@ -238,6 +46,28 @@ DB = dict(
charset = "utf8mb4",
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
SEP2 = "-" * 165
+27 -188
View File
@@ -18,198 +18,13 @@ from openpyxl.styles import (Font, PatternFill, Alignment, Border, Side,
GradientFill)
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):
"""Vrati nazev odbornosti z ICP kodu (posledni 3 cislice)."""
if not icp or len(icp) < 3:
"""Vrati nazev odbornosti podle ICP (plny 8-znakovy kod) z tabulky vzp_pracoviste."""
if not icp:
return ""
return ODBORNOST.get(icp[-3:], f"odb. {icp[-3:]}")
return ODBORNOST.get(icp, f"odb. {icp[-3:]}")
# ── NASTAVENÍ ─────────────────────────────────────────────────────────────────
@@ -225,6 +40,8 @@ FB = dict(
charset = "win1250",
)
DB = dict(
host = "192.168.1.76",
user = "root",
@@ -233,6 +50,28 @@ DB = dict(
charset = "utf8mb4",
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 ─────────────────────────────────────────────────────────────────────
C_HEADER_BG = "1F4E79" # tmave modra — hlavicka tabulky