Compare commits
24 Commits
ea6ce9a96f
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| eaf87766d7 | |||
| 3423fbb982 | |||
| 58026d944e | |||
| ef7c5d77dc | |||
| e23735d07e | |||
| b6abdaddd5 | |||
| 2e00f55883 | |||
| 08a91f4988 | |||
| ac953f0334 | |||
| b317a4165b | |||
| 9afbf79155 | |||
| cc6c80fca6 | |||
| 3ea09fc4a3 | |||
| 73984c748a | |||
| 9e1dc4ed04 | |||
| a667fb8ba3 | |||
| dae0558c98 | |||
| 0b10125671 | |||
| b2b46c1571 | |||
| 068c8edbe1 | |||
| d52278ed4d | |||
| 2365a38b69 | |||
| 21aac6775b | |||
| 65978e7de9 |
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(mysql -u root -e \"SELECT pr.prijmeni, pr.jmena, pr.pzs_nazev, pr.mesto, COUNT\\(*\\) AS pocet_predpisu FROM pacient pac JOIN zprava z ON z.pacient_id = pac.id JOIN predpis p ON p.zprava_id = z.id JOIN predepisujici pr ON pr.lekar_kod = p.kod_predepisujiciho WHERE pac.prijmeni = 'Strnadová' AND pac.jmena = 'Jitka' GROUP BY pr.lekar_kod, pr.prijmeni, pr.jmena, pr.pzs_nazev, pr.mesto ORDER BY pocet_predpisu DESC;\" medicus)",
|
||||
"Bash(where mysql:*)",
|
||||
"Read(//c/Program Files/**)",
|
||||
"Read(//c/xampp/mysql/**)",
|
||||
"Bash(find /c -name \"mysql.exe\")",
|
||||
"Bash(python3 -c ':*)",
|
||||
"Bash(python -c ':*)",
|
||||
"Bash(.venv/Scripts/python.exe -c ':*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -5,9 +5,11 @@ __pycache__/
|
||||
*.pyo
|
||||
.idea/
|
||||
Thumbs.db
|
||||
*.pfx
|
||||
# *.pfx
|
||||
*.xml
|
||||
!LékovýZáznamWithClaude/odpoved_lekovy_zaznam.xml
|
||||
!LékovýZáznamWithClaude/xml_archive/
|
||||
!LékovýZáznamWithClaude/xml_archive/**
|
||||
!NačteníPředpisuWithClaude/xml_archive/
|
||||
!NačteníPředpisuWithClaude/xml_archive/**
|
||||
*.iml
|
||||
Binary file not shown.
@@ -0,0 +1,117 @@
|
||||
# CLAUDE.md — kontext projektu Recepty
|
||||
|
||||
## Uživatel
|
||||
|
||||
Vladimír Buzalka, lékař. Pracuje v ordinaci **MUDr. Michaela Buzalková**, Praha, Lovosická 440/40, PSČ 19000.
|
||||
- UUID lékaře eRecept SÚKL: `e08c89c6-2b1a-4eba-8ed9-4e3e63618379`
|
||||
- IČZ: `09305000`, IČP: `09305001`
|
||||
- Komunikuje česky
|
||||
|
||||
---
|
||||
|
||||
## Důležitá pravidla
|
||||
|
||||
- **Vždy pracovat v hlavním adresáři projektu** `C:\Users\vlado\PycharmProjects\Recepty`, nikdy ve worktree.
|
||||
- Soubory editovat přímo v projektu, ne v `.claude/worktrees/`.
|
||||
|
||||
---
|
||||
|
||||
## Infrastruktura
|
||||
|
||||
- **MySQL:** `192.168.1.76`, db `medicus`, user `root`
|
||||
- **Firebird (Medicus):** `localhost:c:\medicus 3\data\medicus.fdb`, user `SYSDBA`
|
||||
- **Dropbox root:** zjistit přes `Knihovny/najdi_dropbox.py` → `get_dropbox_root()`
|
||||
- **Python venv:** `.venv/Scripts/python`
|
||||
|
||||
---
|
||||
|
||||
## Struktura projektu
|
||||
|
||||
```
|
||||
Recepty/
|
||||
├── Knihovny/
|
||||
│ └── najdi_dropbox.py ← get_dropbox_root() — vždy použít pro Dropbox cestu
|
||||
├── LékovýZáznamWithClaude/ ← NacistLekovyZaznam (endpoint /cuer/Lekar2, ns 201912)
|
||||
│ ├── 07StahnoutVsechny.py ← hromadné stažení lékových záznamů pacientů
|
||||
│ └── xml_archive/
|
||||
├── NačteníPředpisuWithClaude/ ← NacistPredpis (endpoint /cuer/Lekar, ns 201704)
|
||||
│ ├── 10_StahnoutXML.py ← stahování XML receptů z SÚKL
|
||||
│ ├── 11_ParseXML.py ← parsování XML → MySQL (recept_doklad, recept_plp, recept_vydej)
|
||||
│ └── Testy/ ← starší skripty (08, 09)
|
||||
├── StahovánízVZPWithClaude/ ← VZP Point číselníky
|
||||
├── Dotazy/ ← analytické skripty a Excel reporty
|
||||
└── CLAUDE.md ← tento soubor
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MySQL schéma (db medicus)
|
||||
|
||||
### Lékový záznam (z NacistLekovyZaznam)
|
||||
- `pacient` — registrovaní pacienti ordinace (idpac z Medicusu)
|
||||
- `zprava` — jedno volání API = jedna zpráva
|
||||
- `predpis` + `predpis_slozka` — předepsané léky; `id_lp_predpis` = UUID léku
|
||||
- `vydej` + `vydej_slozka` — vydané léky z lékárny
|
||||
- `predepisujici` — lékaři (lekar_kod=UUID, IČZ, IČP, adresa)
|
||||
- `vydavajici` — lékárníci a lékárny
|
||||
|
||||
### Detail receptu (z NacistPredpis)
|
||||
- `recept_doklad` — jeden řádek na recept (id_dokladu = ERP kód, např. PPM4DJXHESOU)
|
||||
- stav, stav_terminal, platnost, pacient snapshot, předepisující
|
||||
- `stav_terminal=1` = terminální (PLNE_VYDANY / ZRUSENY / expirovaný) → nepřestahovat
|
||||
- `recept_plp` — PLP položky receptu; `id_lp = predpis.id_lp_predpis` (JOIN lékový záznam ↔ detail)
|
||||
- `recept_vydej` — výdeje z XML sekce Vydej; PK `(id_vydeje, id_lp_predpis)`
|
||||
- **kritická tabulka** — výdeje jsou zde dříve než v tabulce `vydej` (která čeká na 07)
|
||||
|
||||
### VZP číselník
|
||||
- `vzp_pracoviste` — IČP → odbornost, název pracoviště (import_vzp_pracoviste.py, týdně)
|
||||
|
||||
### Klíčové JOINy
|
||||
```sql
|
||||
-- lékový záznam + detail receptu + výdej z NacistPredpis
|
||||
predpis.id_lp_predpis = recept_plp.id_lp → recept_doklad (stav receptu)
|
||||
predpis.id_lp_predpis = recept_vydej.id_lp_predpis → výdej (lékárna, datum, lék)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## NacistPredpis pipeline
|
||||
|
||||
**xml_archive umístění (od 22. 4. 2026):**
|
||||
`{get_dropbox_root()}/Ordinace/Dokumentace_ke_zpracování/Zúčtovací zprávy/NačteníPředpisuWithClaude/xml_archive/`
|
||||
|
||||
**Správné pořadí:**
|
||||
```
|
||||
10_StahnoutXML.py → 11_ParseXML.py → 10_StahnoutXML.py → ...
|
||||
```
|
||||
Bez `11` po `10` se terminální recepty znovu stahují (stav_terminal zůstane 0).
|
||||
|
||||
**Zdroj ID_Dokladu:** Firebird, tabulka `recept_epodani.erp`
|
||||
|
||||
---
|
||||
|
||||
## eRecept SÚKL autentizace
|
||||
|
||||
- mTLS certifikát: `AMBSUKL214235369G_31DEC2024.pfx` (platný do 31. 12. 2026)
|
||||
- HTTP Basic user: UUID lékaře (malými písmeny)
|
||||
- Namespace NacistLekovyZaznam: `http://www.sukl.cz/erp/201912`
|
||||
- Namespace NacistPredpis: `http://www.sukl.cz/erp/201704`
|
||||
- Verze zprávy: `202501A`
|
||||
|
||||
---
|
||||
|
||||
## VZP Point — stahování zpráv
|
||||
|
||||
Projekt: `U:\OrdinaceProjekt\Insurance\StahováníZpráv\`, každá pojišťovna má podsložku (`111 VZP\` atd.).
|
||||
- `01_prihlaseni.py` — přihlášení certifikátem, uloží cookies
|
||||
- `02_stahuj_vse.py` — jednorázové stažení všech zpráv
|
||||
- `03_stahuj_nove.py` — rozdílové stažení (zastaví se při první existující)
|
||||
- Playwright `launch_persistent_context`, `channel="chrome"`, `_delete_chrome_cert_policy()` před spuštěním
|
||||
|
||||
---
|
||||
|
||||
## Dotazy / reporty
|
||||
|
||||
- `Dotazy/report_predepsane_leky.py` — Excel report předepsaných léků (jeden řádek = jeden lék)
|
||||
- Spuštění: `python report_predepsane_leky.py 2026`
|
||||
- Po uložení automaticky otevře Excel
|
||||
@@ -0,0 +1,256 @@
|
||||
# Dotazy — přehled lékového záznamu pacienta
|
||||
|
||||
Skripty pro zobrazení a export lékového záznamu konkrétního pacienta z MySQL databáze `medicus`.
|
||||
Pacient se identifikuje **rodným číslem** — to se vyhledá v lokální Firebird databázi Medicusu,
|
||||
odkud se získá příjmení a datum narození, a teprve těmito dvěma hodnotami se najde pacient v MySQL.
|
||||
|
||||
---
|
||||
|
||||
## Soubory
|
||||
|
||||
| Soubor | Co dělá |
|
||||
|--------|---------|
|
||||
| `prehled_pacienta.py` | Konzolový výpis — lékaři + předpisy pacienta |
|
||||
| `prehled_pacienta_excel.py` | Export do formátovaného souboru Excel (.xlsx) |
|
||||
|
||||
---
|
||||
|
||||
## Nastavení (obě skripty)
|
||||
|
||||
Na začátku každého souboru jsou tři proměnné:
|
||||
|
||||
```python
|
||||
RODNE_CISLO = "440802/018" # rodné číslo — funguje s lomítkem i bez: "4408020183"
|
||||
DATUM_OD = "01.01.2025" # předpisy od tohoto data; None = všechny předpisy
|
||||
VYSTUP_DIR = None # pouze excel: složka výstupu; None = stejná jako skript
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Spuštění
|
||||
|
||||
```bash
|
||||
# Konzolový výpis
|
||||
.venv\Scripts\python.exe Dotazy\prehled_pacienta.py
|
||||
|
||||
# Export do Excelu
|
||||
.venv\Scripts\python.exe Dotazy\prehled_pacienta_excel.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Zdroje dat
|
||||
|
||||
### 1. Firebird — Medicus (`medicus.fdb`)
|
||||
|
||||
Slouží výhradně k identifikaci pacienta podle rodného čísla.
|
||||
|
||||
```
|
||||
DSN: localhost:c:\medicus 3\data\medicus.fdb
|
||||
User: SYSDBA / masterkey
|
||||
Charset: win1250
|
||||
Tabulka: KAR
|
||||
```
|
||||
|
||||
Dotaz:
|
||||
```sql
|
||||
SELECT KAR.PRIJMENI, KAR.JMENO, KAR.DATNAR
|
||||
FROM KAR WHERE KAR.RODCIS = ?
|
||||
```
|
||||
|
||||
Rodné číslo se normalizuje před dotazem — odstraní se lomítko a mezery:
|
||||
```python
|
||||
rc = rc.replace("/", "").replace(" ", "").strip()
|
||||
```
|
||||
|
||||
### 2. MySQL — databáze `medicus`
|
||||
|
||||
Obsahuje lékové záznamy stažené z eReceptu SÚKL.
|
||||
|
||||
```
|
||||
Host: 192.168.1.76
|
||||
User: root
|
||||
DB: medicus
|
||||
```
|
||||
|
||||
Pacient se vyhledá podle příjmení a data narození (získaných z Firebirdu):
|
||||
```sql
|
||||
SELECT id, prijmeni, jmena, datum_narozeni
|
||||
FROM pacient
|
||||
WHERE prijmeni = %s AND datum_narozeni = %s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Co se zobrazuje
|
||||
|
||||
### Část 1 — Předepisující lékaři
|
||||
|
||||
Všichni lékaři, kteří pacientovi za celou dobu předepsali alespoň jeden lék,
|
||||
seřazeni sestupně podle počtu předpisů.
|
||||
|
||||
Sloupce: `#` | `Lékař` | `Odbornost` | `Pracoviště a adresa` | `Předpisů`
|
||||
|
||||
```sql
|
||||
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
|
||||
```
|
||||
|
||||
### Část 2 — Všechny předpisy
|
||||
|
||||
Předpisy od `DATUM_OD`, seřazené sestupně dle data vystavení.
|
||||
|
||||
Zobrazuje se **vydaný lék** (z tabulky `vydej`), nikoli předepsaný název.
|
||||
Pokud lék nebyl vyzvednut, zobrazí se předepsaný název s příznakem `*NV`.
|
||||
|
||||
Sloupce: `#` | `Datum` | `Vydaný lék` | `ATC` | `Návod` | `Lékař` | `Odbornost` | `Adresa`
|
||||
|
||||
```sql
|
||||
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
|
||||
AND p.datum_vystaveni >= %s -- pouze pokud DATUM_OD není None
|
||||
ORDER BY p.datum_vystaveni DESC
|
||||
```
|
||||
|
||||
Klíčový princip `COALESCE(v.nazev, p.nazev)`:
|
||||
- `v.nazev` — název léku, který lékárna **skutečně vydala** (může být jiná značka než předepsaná)
|
||||
- `p.nazev` — název léku, který lékař **předepsal** (zobrazí se jen pokud výdej neexistuje → `*NV`)
|
||||
|
||||
---
|
||||
|
||||
## Odbornost lékaře
|
||||
|
||||
Odbornost se odvozuje z posledních 3 číslic pole `predepisujici.icp` (IČP pracoviště).
|
||||
|
||||
```
|
||||
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:
|
||||
```python
|
||||
def odbornost_z_icp(icp):
|
||||
if not icp or len(icp) < 3:
|
||||
return ""
|
||||
return ODBORNOST.get(icp[-3:], f"odb. {icp[-3:]}")
|
||||
```
|
||||
|
||||
Pro neznámé kódy se zobrazí `odb. XXX` (XXX = třímístný kód).
|
||||
|
||||
### Zdroj dat — tabulky `vzp_pracoviste` + `odbornost` (MySQL)
|
||||
|
||||
Slovník `ODBORNOST` se **načítá dynamicky při startu skriptu** z MySQL:
|
||||
|
||||
```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ů
|
||||
|
||||
---
|
||||
|
||||
## Excel export (`prehled_pacienta_excel.py`)
|
||||
|
||||
Soubor se ukládá do stejné složky jako skript (nebo do `VYSTUP_DIR`).
|
||||
|
||||
### Pojmenování souborů
|
||||
|
||||
```
|
||||
LZ_{Prijmeni}_{Jmeno}_{datum_narozeni}.xlsx ← základní
|
||||
LZ_{Prijmeni}_{Jmeno}_{datum_narozeni}_v2.xlsx ← pokud základní existuje
|
||||
LZ_{Prijmeni}_{Jmeno}_{datum_narozeni}_v3.xlsx ← atd.
|
||||
```
|
||||
|
||||
Versioning zabrání přepsání dříve exportovaných souborů.
|
||||
|
||||
### Vzhled a formátování
|
||||
|
||||
| Prvek | Barva | Popis |
|
||||
|-------|-------|-------|
|
||||
| Záhlaví (jméno pacienta) | `#1F4E79` tmavě modrá | tučné, 14pt |
|
||||
| Záhlaví tabulky | `#1F4E79` tmavě modrá | bílý text, 10pt |
|
||||
| Nadpis sekce | `#2E75B6` střední modrá | bílý text, 11pt |
|
||||
| Info o pacientovi | `#DEEAF1` světle modrá | datum narozeni, datum tisku, předpisy od |
|
||||
| Sudé řádky | `#EBF3FB` velmi světle modrá | střídání řádků |
|
||||
| Liché řádky | `#FFFFFF` bílá | |
|
||||
| Nevyzvednuto | `#FCE4D6` lososová | zvýraznění celého řádku |
|
||||
| Ohraničení | `#B8CCE4` světle modrá | tenká linka |
|
||||
|
||||
- Font: **Arial** ve všech buňkách
|
||||
- Automatická šířka sloupců a výška řádků (`autofit`)
|
||||
- Zmrazení prvního řádku (`freeze_panes = "A2"`)
|
||||
- 8 sloupců: `#` | `Lékař/Datum` | `Odbornost/Vydaný lék` | `Pracoviště/ATC` | … | `Předpisů/Pracoviště a adresa`
|
||||
|
||||
### Tabulka lékařů (8 sloupců)
|
||||
|
||||
`#` | `Lékař` | `Odbornost` | `Pracoviště` | `Ulice` | `PSČ` | `Město` | `Předpisů`
|
||||
|
||||
### Tabulka předpisů (8 sloupců)
|
||||
|
||||
`#` | `Datum` | `Vydaný lék` | `ATC` | `Návod` | `Lékař` | `Odbornost` | `Pracoviště a adresa`
|
||||
|
||||
---
|
||||
|
||||
## Závislosti
|
||||
|
||||
```
|
||||
pymysql ← MySQL klient
|
||||
fdb ← Firebird klient
|
||||
openpyxl ← Excel export (pouze prehled_pacienta_excel.py)
|
||||
```
|
||||
|
||||
Všechny jsou součástí `requirements.txt` a nainstalují se přes `setup.ps1`.
|
||||
|
||||
---
|
||||
|
||||
## Typické chybové situace
|
||||
|
||||
| Chyba | Příčina | Řešení |
|
||||
|-------|---------|--------|
|
||||
| `Rodne cislo nenalezeno v Medicusu` | RC není v tabulce KAR | Zkontrolovat číslo, ověřit v Medicusu |
|
||||
| `Pacient nema zaznam v MySQL` | Lékový záznam nebyl stažen | Spustit `07StahnoutVsechny.py` nebo `reimport_z_xml.py` |
|
||||
| `PermissionError` při ukládání xlsx | Soubor je otevřen v Excelu | Zavřít Excel a spustit znovu — verzování uloží jako `_v2` |
|
||||
| Odbornost zobrazena jako `odb. XXX` | Kód není ve slovníku | Informativní stav — kód je platný, jen není pojmenován |
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,222 @@
|
||||
"""
|
||||
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
|
||||
|
||||
|
||||
|
||||
def odbornost_z_icp(icp):
|
||||
"""Vrati nazev odbornosti podle ICP (plny 8-znakovy kod) z tabulky vzp_pracoviste."""
|
||||
if not icp:
|
||||
return ""
|
||||
return ODBORNOST.get(icp, f"odb. {icp[-3:]}")
|
||||
|
||||
# ── 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,
|
||||
)
|
||||
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
|
||||
|
||||
|
||||
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()
|
||||
@@ -0,0 +1,354 @@
|
||||
"""
|
||||
Export prehledu lekoveho zaznamu pacienta do Excelu.
|
||||
|
||||
Nastaveni:
|
||||
RODNE_CISLO ... rodne cislo pacienta (s lomitkem i bez)
|
||||
DATUM_OD ... predpisy od tohoto data ve formatu DD.MM.RRRR (None = vsechny)
|
||||
VYSTUP_DIR ... slozka kam se ulozi Excel (None = stejna slozka jako skript)
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import fdb
|
||||
import pymysql
|
||||
import pymysql.cursors
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.styles import (Font, PatternFill, Alignment, Border, Side,
|
||||
GradientFill)
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
|
||||
|
||||
def odbornost_z_icp(icp):
|
||||
"""Vrati nazev odbornosti podle ICP (plny 8-znakovy kod) z tabulky vzp_pracoviste."""
|
||||
if not icp:
|
||||
return ""
|
||||
return ODBORNOST.get(icp, f"odb. {icp[-3:]}")
|
||||
|
||||
|
||||
# ── NASTAVENÍ ─────────────────────────────────────────────────────────────────
|
||||
RODNE_CISLO = "370315041"
|
||||
DATUM_OD = "01.01.2025" # None = vsechny predpisy
|
||||
VYSTUP_DIR = None # None = stejny adresar jako skript
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
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,
|
||||
)
|
||||
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
|
||||
C_HEADER_FG = "FFFFFF" # bila — text hlavicky
|
||||
C_TITLE_BG = "2E75B6" # stredni modra — nadpis sekce
|
||||
C_TITLE_FG = "FFFFFF"
|
||||
C_INFO_BG = "DEEAF1" # svetle modra — info o pacientovi
|
||||
C_ROW_ODD = "FFFFFF" # bila
|
||||
C_ROW_EVEN = "EBF3FB" # velmi svetle modra — striped
|
||||
C_NEVYZV_BG = "FCE4D6" # lososova — nevyzvednuto
|
||||
C_BORDER = "B8CCE4"
|
||||
|
||||
|
||||
def thin_border():
|
||||
s = Side(style="thin", color=C_BORDER)
|
||||
return Border(left=s, right=s, top=s, bottom=s)
|
||||
|
||||
|
||||
def header_fill(color):
|
||||
return PatternFill("solid", fgColor=color)
|
||||
|
||||
|
||||
def parse_datum(s, nazev):
|
||||
try:
|
||||
return datetime.strptime(s, "%d.%m.%Y").date()
|
||||
except (ValueError, TypeError):
|
||||
sys.exit(f"Spatny format data '{nazev}': '{s}'")
|
||||
|
||||
|
||||
def najdi_v_firebirdu(rc):
|
||||
rc = rc.replace("/", "").replace(" ", "")
|
||||
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 '{rc}' nenalezeno v Medicusu.")
|
||||
return {"prijmeni": row[0].strip(), "jmeno": row[1].strip(), "datnar": row[2]}
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def nacti_data(prijmeni, datum_narozeni, datum_od):
|
||||
conn = pymysql.connect(**DB)
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT id, prijmeni, jmena, datum_narozeni FROM pacient "
|
||||
"WHERE prijmeni = %s AND datum_narozeni = %s",
|
||||
(prijmeni, datum_narozeni)
|
||||
)
|
||||
pac = cur.fetchone()
|
||||
if not pac:
|
||||
sys.exit(f"Pacient '{prijmeni}' nar. {datum_narozeni} nema zaznam v MySQL.")
|
||||
|
||||
# Lekari
|
||||
cur.execute("""
|
||||
SELECT pr.prijmeni, pr.jmena,
|
||||
pr.icp,
|
||||
pr.pzs_nazev, pr.ulice, pr.psc, pr.mesto,
|
||||
COUNT(*) AS pocet
|
||||
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 DESC
|
||||
""", (pac["id"],))
|
||||
lekari = cur.fetchall()
|
||||
|
||||
# Predpisy
|
||||
podminka = "AND p.datum_vystaveni >= %s" if datum_od else ""
|
||||
params = (pac["id"], datum_od) if datum_od else (pac["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 AS lek_prijmeni, pr.jmena AS lek_jmena,
|
||||
pr.icp,
|
||||
pr.pzs_nazev, pr.ulice, pr.psc, pr.mesto
|
||||
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)
|
||||
predpisy = cur.fetchall()
|
||||
|
||||
return pac, lekari, predpisy
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def nastav_sirky(ws, sirky):
|
||||
for col, width in sirky.items():
|
||||
ws.column_dimensions[col].width = width
|
||||
|
||||
|
||||
def autofit(ws, min_width=5, max_width=60, padding=2):
|
||||
"""Autofit sloupcu a radku podle obsahu."""
|
||||
col_widths = {}
|
||||
for row in ws.iter_rows():
|
||||
for cell in row:
|
||||
if cell.value is None:
|
||||
continue
|
||||
# Preskoc mergnuté bunky — jejich sirka se pocita ze zakladni bunky
|
||||
if isinstance(cell, type(cell)) and hasattr(cell, 'column'):
|
||||
text = str(cell.value)
|
||||
# Tučný text je trochu širší
|
||||
factor = 1.15 if (cell.font and cell.font.bold) else 1.0
|
||||
width = len(text) * factor + padding
|
||||
col = get_column_letter(cell.column)
|
||||
col_widths[col] = max(col_widths.get(col, min_width), width)
|
||||
|
||||
for col, width in col_widths.items():
|
||||
ws.column_dimensions[col].width = min(max(width, min_width), max_width)
|
||||
|
||||
# Autofit výšky řádků (wrap_text obsah)
|
||||
for row in ws.iter_rows():
|
||||
max_lines = 1
|
||||
for cell in row:
|
||||
if cell.value and cell.alignment and cell.alignment.wrap_text:
|
||||
col_w = ws.column_dimensions[get_column_letter(cell.column)].width or 10
|
||||
lines = max(1, int(len(str(cell.value)) / max(col_w, 1)) + 1)
|
||||
max_lines = max(max_lines, lines)
|
||||
row_num = row[0].row
|
||||
if max_lines > 1:
|
||||
ws.row_dimensions[row_num].height = max(ws.row_dimensions[row_num].height or 15,
|
||||
max_lines * 14)
|
||||
|
||||
|
||||
def zapis_nadpis_sekce(ws, row, text, n_cols):
|
||||
ws.merge_cells(start_row=row, start_column=1, end_row=row, end_column=n_cols)
|
||||
cell = ws.cell(row=row, column=1, value=text)
|
||||
cell.font = Font(name="Arial", bold=True, size=11, color=C_TITLE_FG)
|
||||
cell.fill = header_fill(C_TITLE_BG)
|
||||
cell.alignment = Alignment(horizontal="left", vertical="center", indent=1)
|
||||
ws.row_dimensions[row].height = 20
|
||||
return row + 1
|
||||
|
||||
|
||||
def zapis_hlavicku(ws, row, hlavicka, n_cols=None):
|
||||
for col, text in enumerate(hlavicka, 1):
|
||||
cell = ws.cell(row=row, column=col, value=text)
|
||||
cell.font = Font(name="Arial", bold=True, size=10, color=C_HEADER_FG)
|
||||
cell.fill = header_fill(C_HEADER_BG)
|
||||
cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||
cell.border = thin_border()
|
||||
ws.row_dimensions[row].height = 28
|
||||
return row + 1
|
||||
|
||||
|
||||
def zapis_radek(ws, row, hodnoty, highlight=False):
|
||||
bg = C_NEVYZV_BG if highlight else (C_ROW_EVEN if row % 2 == 0 else C_ROW_ODD)
|
||||
fill = header_fill(bg)
|
||||
for col, val in enumerate(hodnoty, 1):
|
||||
cell = ws.cell(row=row, column=col, value=val)
|
||||
cell.font = Font(name="Arial", size=10)
|
||||
cell.fill = fill
|
||||
cell.alignment = Alignment(vertical="center", wrap_text=True)
|
||||
cell.border = thin_border()
|
||||
ws.row_dimensions[row].height = 18
|
||||
return row + 1
|
||||
|
||||
|
||||
def vytvor_excel(pac, lekari, predpisy, datum_od, fb_pac):
|
||||
wb = Workbook()
|
||||
ws = wb.active
|
||||
ws.title = "Lekovy zaznam"
|
||||
|
||||
# ── Záhlaví — info o pacientovi ──────────────────────────────────────────
|
||||
n_cols = 8
|
||||
ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=n_cols)
|
||||
title_cell = ws.cell(row=1, column=1,
|
||||
value=f"LÉKOVÝ ZÁZNAM — {pac['prijmeni'].upper()} {fb_pac['jmeno'].upper()}")
|
||||
title_cell.font = Font(name="Arial", bold=True, size=14, color=C_HEADER_FG)
|
||||
title_cell.fill = header_fill(C_HEADER_BG)
|
||||
title_cell.alignment = Alignment(horizontal="left", vertical="center", indent=1)
|
||||
ws.row_dimensions[1].height = 32
|
||||
|
||||
info = [
|
||||
("Datum narození:", pac["datum_narozeni"].strftime("%d.%m.%Y")),
|
||||
("Datum tisku:", datetime.today().strftime("%d.%m.%Y")),
|
||||
("Předpisy od:", datum_od.strftime("%d.%m.%Y") if datum_od else "vše"),
|
||||
]
|
||||
for i, (label, val) in enumerate(info, 2):
|
||||
ws.merge_cells(start_row=i, start_column=1, end_row=i, end_column=2)
|
||||
ws.merge_cells(start_row=i, start_column=3, end_row=i, end_column=n_cols)
|
||||
lbl = ws.cell(row=i, column=1, value=label)
|
||||
lbl.font = Font(name="Arial", bold=True, size=10)
|
||||
lbl.fill = header_fill(C_INFO_BG)
|
||||
lbl.alignment = Alignment(vertical="center", indent=1)
|
||||
val_cell = ws.cell(row=i, column=3, value=val)
|
||||
val_cell.font = Font(name="Arial", size=10)
|
||||
val_cell.fill = header_fill(C_INFO_BG)
|
||||
val_cell.alignment = Alignment(vertical="center")
|
||||
ws.row_dimensions[i].height = 16
|
||||
|
||||
row = len(info) + 3 # prázdný řádek
|
||||
|
||||
# ── Tabulka lékařů ───────────────────────────────────────────────────────
|
||||
row = zapis_nadpis_sekce(ws, row, "PŘEDEPISUJÍCÍ LÉKAŘI", n_cols)
|
||||
row = zapis_hlavicku(ws, row, ["#", "Lékař", "Odbornost", "Pracoviště", "Ulice", "PSČ", "Město", "Předpisů"])
|
||||
for i, r in enumerate(lekari, 1):
|
||||
adresa_ulice = r.get("ulice") or ""
|
||||
row = zapis_radek(ws, row, [
|
||||
i,
|
||||
f"{r['prijmeni']} {r['jmena']}",
|
||||
odbornost_z_icp(r.get("icp")),
|
||||
r.get("pzs_nazev") or "",
|
||||
adresa_ulice,
|
||||
r.get("psc") or "",
|
||||
r.get("mesto") or "",
|
||||
r["pocet"],
|
||||
])
|
||||
|
||||
row += 1 # prázdný řádek
|
||||
|
||||
# ── Tabulka předpisů ─────────────────────────────────────────────────────
|
||||
od_text = datum_od.strftime("%d.%m.%Y") if datum_od else "vše"
|
||||
row = zapis_nadpis_sekce(ws, row, f"VŠECHNY PŘEDPISY (od {od_text}) — celkem {len(predpisy)}", n_cols)
|
||||
row = zapis_hlavicku(ws, row, ["#", "Datum", "Vydaný lék", "ATC", "Návod", "Lékař", "Odbornost", "Pracoviště a adresa"])
|
||||
for i, r in enumerate(predpisy, 1):
|
||||
nevyzv = bool(r["nevyzvednuto"])
|
||||
adresa = (f"{r.get('pzs_nazev') or ''}, {r.get('ulice') or ''}, "
|
||||
f"{r.get('psc') or ''} {r.get('mesto') or ''}").strip(", ")
|
||||
row = zapis_radek(ws, row, [
|
||||
i,
|
||||
r["datum_vystaveni"].strftime("%d.%m.%Y") if r["datum_vystaveni"] else "",
|
||||
r["vydany_lek"],
|
||||
r.get("atc") or "",
|
||||
r.get("navod") or "",
|
||||
f"{r['lek_prijmeni']} {r['lek_jmena']}",
|
||||
odbornost_z_icp(r.get("icp")),
|
||||
adresa,
|
||||
], highlight=nevyzv)
|
||||
|
||||
# ── Autofit sloupců a řádků ───────────────────────────────────────────────
|
||||
autofit(ws, min_width=5, max_width=60)
|
||||
|
||||
# Zmraz záhlaví
|
||||
ws.freeze_panes = "A2"
|
||||
|
||||
return wb
|
||||
|
||||
|
||||
def main():
|
||||
datum_od = parse_datum(DATUM_OD, "DATUM_OD") if DATUM_OD else None
|
||||
|
||||
fb_pac = najdi_v_firebirdu(RODNE_CISLO)
|
||||
prijmeni = fb_pac["prijmeni"]
|
||||
datum_narozeni = fb_pac["datnar"]
|
||||
|
||||
print(f"Nacitam data: {prijmeni} {fb_pac['jmeno']} nar. {datum_narozeni} ...")
|
||||
pac, lekari, predpisy = nacti_data(prijmeni, datum_narozeni, datum_od)
|
||||
print(f" {len(lekari)} lekaru, {len(predpisy)} predpisu")
|
||||
|
||||
wb = vytvor_excel(pac, lekari, predpisy, datum_od, fb_pac)
|
||||
|
||||
vyst = Path(VYSTUP_DIR) if VYSTUP_DIR else Path(__file__).parent
|
||||
zaklad = vyst / f"LZ_{prijmeni}_{fb_pac['jmeno']}_{datum_narozeni}.xlsx"
|
||||
if not zaklad.exists():
|
||||
soubor = zaklad
|
||||
else:
|
||||
i = 2
|
||||
while True:
|
||||
soubor = vyst / f"LZ_{prijmeni}_{fb_pac['jmeno']}_{datum_narozeni}_v{i}.xlsx"
|
||||
if not soubor.exists():
|
||||
break
|
||||
i += 1
|
||||
wb.save(soubor)
|
||||
print(f"Ulozeno: {soubor}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,94 @@
|
||||
"""
|
||||
Report: předepsané léky — jeden řádek na lék.
|
||||
Výstup: report_predepsane_leky_RRRR.xlsx
|
||||
|
||||
Spuštění:
|
||||
python report_predepsane_leky.py # aktuální rok
|
||||
python report_predepsane_leky.py 2025 # jiný rok
|
||||
"""
|
||||
|
||||
import sys
|
||||
import io
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
|
||||
import pymysql
|
||||
import pymysql.cursors
|
||||
import openpyxl
|
||||
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
|
||||
|
||||
DB = dict(
|
||||
host="192.168.1.76",
|
||||
user="root",
|
||||
password="Vlado9674+",
|
||||
database="medicus",
|
||||
charset="utf8mb4",
|
||||
cursorclass=pymysql.cursors.DictCursor,
|
||||
)
|
||||
|
||||
ROK = int(sys.argv[1]) if len(sys.argv) > 1 else date.today().year
|
||||
|
||||
SQL = """
|
||||
SELECT
|
||||
p.datum_vystaveni,
|
||||
pac.prijmeni,
|
||||
pac.jmena,
|
||||
pac.datum_narozeni,
|
||||
rd.cp,
|
||||
rd.zp_nazev,
|
||||
p.nazev AS predepsany_lek,
|
||||
p.atc,
|
||||
p.forma,
|
||||
p.sila,
|
||||
p.baleni,
|
||||
p.mnozstvi,
|
||||
p.navod,
|
||||
p.typ_leku,
|
||||
rp.uhrada,
|
||||
rp.prekroceni,
|
||||
rd.stav,
|
||||
rd.platnost_do,
|
||||
rd.opakovani,
|
||||
rd.akutni,
|
||||
rd.modry_pruh,
|
||||
rd.pozn AS poznamka_na_receptu,
|
||||
v.datum_vydeje,
|
||||
v.nazev AS vydany_lek,
|
||||
v.mnozstvi AS vydane_mnozstvi,
|
||||
vyd.pzs_nazev AS lekarna,
|
||||
p.id_lp_predpis,
|
||||
rd.id_dokladu
|
||||
FROM predpis p
|
||||
JOIN zprava z ON z.id = p.zprava_id
|
||||
JOIN pacient pac ON pac.id = z.pacient_id
|
||||
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
|
||||
LEFT JOIN vydavajici vyd ON vyd.lekarnik_kod = v.kod_vydavajiciho
|
||||
WHERE YEAR(p.datum_vystaveni) = %s
|
||||
ORDER BY p.datum_vystaveni DESC, pac.prijmeni, pac.jmena, p.nazev
|
||||
"""
|
||||
|
||||
conn = pymysql.connect(**DB)
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(SQL, (ROK,))
|
||||
rows = cur.fetchall()
|
||||
conn.close()
|
||||
|
||||
print(f"Načteno {len(rows)} řádků za rok {ROK}")
|
||||
|
||||
wb = openpyxl.Workbook()
|
||||
ws = wb.active
|
||||
ws.title = f"Předpisy {ROK}"
|
||||
|
||||
if rows:
|
||||
ws.append(list(rows[0].keys()))
|
||||
for row in rows:
|
||||
ws.append([str(v) if v is not None else "" for v in row.values()])
|
||||
|
||||
out = Path(__file__).parent / f"report_predepsane_leky_{ROK}.xlsx"
|
||||
wb.save(out)
|
||||
print(f"Uloženo: {out}")
|
||||
import os
|
||||
os.startfile(out)
|
||||
Binary file not shown.
@@ -0,0 +1,62 @@
|
||||
import winreg
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
def get_dropbox_root() -> str:
|
||||
"""
|
||||
Vrátí kořenovou cestu složky Dropbox na tomto počítači.
|
||||
|
||||
Dropbox může být nainstalován na různých discích (C:, U:, Z: …),
|
||||
ale struktura složek uvnitř zůstává vždy stejná. Tato funkce zjistí
|
||||
aktuální umístění, takže ostatní skripty nemusí cestu napevno zadávat.
|
||||
|
||||
Postup hledání (v tomto pořadí):
|
||||
1. Registr HKCU\\Software\\Dropbox\\ks — hlavní klíč, hodnota "Personal"
|
||||
je uložena jako byte array v kódování UTF-16 LE.
|
||||
2. Registr HKCU\\Software\\Dropbox\\ks1 — alternativní klíč používaný
|
||||
novějšími verzemi klienta Dropbox.
|
||||
3. Soubor info.json v %APPDATA%\\Dropbox\\ nebo %LOCALAPPDATA%\\Dropbox\\
|
||||
— záložní metoda, pokud registr cestu neobsahuje.
|
||||
|
||||
Vrací:
|
||||
str: Absolutní cesta ke kořenové složce Dropboxu, např. "U:\\Dropbox".
|
||||
|
||||
Vyvolá:
|
||||
RuntimeError: Pokud se cestu nepodaří zjistit žádnou z metod.
|
||||
|
||||
Příklad použití:
|
||||
from Knihovny.najdi_dropbox import get_dropbox_root
|
||||
import os
|
||||
|
||||
ROOT = get_dropbox_root()
|
||||
PACIENTI = os.path.join(ROOT, "Ordinace", "Pacienti")
|
||||
"""
|
||||
|
||||
# Metoda 1 a 2: registr HKCU\Software\Dropbox\ks a ks1
|
||||
for subkey in (r"Software\Dropbox\ks", r"Software\Dropbox\ks1"):
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, subkey) as key:
|
||||
value, _ = winreg.QueryValueEx(key, "Personal")
|
||||
path = bytes(value).decode("utf-16-le").rstrip("\x00")
|
||||
if path:
|
||||
return path
|
||||
except (OSError, UnicodeDecodeError):
|
||||
continue
|
||||
|
||||
# Metoda 3: záložní — info.json v AppData
|
||||
for base in (os.getenv("APPDATA", ""), os.getenv("LOCALAPPDATA", "")):
|
||||
info_path = os.path.join(base, "Dropbox", "info.json")
|
||||
if os.path.isfile(info_path):
|
||||
with open(info_path, encoding="utf-8") as f:
|
||||
info = json.load(f)
|
||||
path = (info.get("personal") or info.get("business") or {}).get("path", "")
|
||||
if path:
|
||||
return path
|
||||
|
||||
raise RuntimeError("Nepodařilo se zjistit cestu k Dropboxu.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = get_dropbox_root()
|
||||
print(f"Dropbox root: {root}")
|
||||
@@ -10,18 +10,67 @@ z eRecept SÚKL API a jejich uložení do relační databáze MySQL.
|
||||
| Soubor | Co dělá |
|
||||
|--------|---------|
|
||||
| `05UlozitOdpoved.py` | Stáhne XML pro **jednoho** pacienta (ruční test/ladění) |
|
||||
| `06UlozitDoMySQL.py` | DDL schématu, parsování XML, import do MySQL — používá se jako knihovna i samostatně |
|
||||
| `06UlozitDoMySQL.py` | DDL schématu, parsování XML, import do MySQL — používá se jako **knihovna**, ne spouštět přímo! |
|
||||
| `07StahnoutVsechny.py` | **Hlavní skript** — načte pacienty z Medicusu, stáhne lékové záznamy, uloží XML i DB záznamy |
|
||||
| `reimport_z_xml.py` | Reimport XML ze zálohy bez volání API — viz sekce níže |
|
||||
|
||||
```
|
||||
LékovýZáznamWithClaude/
|
||||
├── 05UlozitOdpoved.py
|
||||
├── 06UlozitDoMySQL.py
|
||||
├── 07StahnoutVsechny.py
|
||||
├── LEKOVY_ZAZNAM_DB.md
|
||||
├── Logs/ ← log každého běhu (UTF-8, YYYY-MM-DD_HH-MM-SS.log)
|
||||
├── Tests/ ← starší vývojové skripty
|
||||
└── xml_archive/ ← archiv XML odpovědí (YYYY-MM-DD/Prijmeni_Jmena_datnar.xml)
|
||||
recept/
|
||||
├── setup.ps1 ← vytvoří .venv, nainstaluje závislosti, Playwright chromium
|
||||
├── requirements.txt ← seznam Python závislostí
|
||||
├── .venv/ ← virtuální prostředí (Python 3.x)
|
||||
│
|
||||
├── LékovýZáznamWithClaude/
|
||||
│ ├── 05UlozitOdpoved.py
|
||||
│ ├── 06UlozitDoMySQL.py
|
||||
│ ├── 07StahnoutVsechny.py
|
||||
│ ├── reimport_z_xml.py
|
||||
│ ├── LEKOVY_ZAZNAM_DB.md ← tento soubor
|
||||
│ ├── Logs/ ← log každého běhu (UTF-8, YYYY-MM-DD_HH-MM-SS.log)
|
||||
│ ├── Tests/ ← starší vývojové skripty
|
||||
│ └── xml_archive/ ← archiv XML odpovědí (YYYY-MM-DD/Prijmeni_Jmena_datnar.xml)
|
||||
│
|
||||
└── Dotazy/
|
||||
├── prehled_pacienta.py ← konzolový přehled pacienta
|
||||
├── prehled_pacienta_excel.py ← export přehledu pacienta do Excelu
|
||||
└── DOTAZY.md ← dokumentace dotazovacích skriptů
|
||||
```
|
||||
|
||||
> **⚠️ NIKDY nespouštět `06UlozitDoMySQL.py` přímo** — zavolá `vytvor_schema()`,
|
||||
> která provede `DROP TABLE` a smaže celou databázi.
|
||||
> Pro import dat vždy použít `07StahnoutVsechny.py` nebo `reimport_z_xml.py`.
|
||||
|
||||
---
|
||||
|
||||
## Nastavení prostředí (jednorázově)
|
||||
|
||||
```powershell
|
||||
# PowerShell — spustit jednou po naklonování projektu
|
||||
cd U:\recept
|
||||
.\setup.ps1
|
||||
```
|
||||
|
||||
`setup.ps1` provede:
|
||||
1. Vytvoří `.venv` s Python interpretem z `C:\Python\python.exe`
|
||||
2. Nainstaluje všechny závislosti z `requirements.txt`
|
||||
3. Nainstaluje Playwright Chromium (pro případné automatizace)
|
||||
|
||||
Po nastavení aktivace:
|
||||
```powershell
|
||||
.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
### requirements.txt
|
||||
|
||||
```
|
||||
requests
|
||||
requests-pkcs12
|
||||
pymysql
|
||||
fdb
|
||||
zeep
|
||||
mysql-connector-python
|
||||
playwright
|
||||
openpyxl
|
||||
```
|
||||
|
||||
---
|
||||
@@ -29,9 +78,6 @@ LékovýZáznamWithClaude/
|
||||
## Typické spuštění
|
||||
|
||||
```bash
|
||||
# Čistý start — jednou (DROP + CREATE schéma, importuje odpoved_lekovy_zaznam.xml)
|
||||
python 06UlozitDoMySQL.py
|
||||
|
||||
# Hromadné stažení všech registrovaných pacientů
|
||||
python 07StahnoutVsechny.py
|
||||
|
||||
@@ -40,6 +86,9 @@ python 07StahnoutVsechny.py --prijmeni Buzalka,Buzalková,Kusinová
|
||||
|
||||
# Dávkování po částech
|
||||
python 07StahnoutVsechny.py --offset 100 --limit 50
|
||||
|
||||
# Reimport ze zálohy XML (bez volání API) — viz níže
|
||||
python reimport_z_xml.py
|
||||
```
|
||||
|
||||
---
|
||||
@@ -275,7 +324,7 @@ Lékaři, kteří pacientovi předepisovali (ze všech ordinací).
|
||||
| `prijmeni` | VARCHAR(35) | |
|
||||
| `jmena` | VARCHAR(24) | |
|
||||
| `icz` | CHAR(8) | IČZ zdravotnického zařízení |
|
||||
| `icp` | CHAR(8) | IČP pracoviště |
|
||||
| `icp` | CHAR(8) | IČP pracoviště — **poslední 3 číslice = kód odbornosti** (001 = prakt. lékař, 272 = alergologie…) |
|
||||
| `pzs_nazev` | VARCHAR(200) | název zdravotnického zařízení |
|
||||
| `ulice` | VARCHAR(150) | |
|
||||
| `mesto` | VARCHAR(100) | |
|
||||
@@ -374,10 +423,96 @@ SELECT prijmeni, jmena, datum_narozeni, poznamka
|
||||
FROM pacient
|
||||
WHERE poznamka IS NOT NULL
|
||||
ORDER BY prijmeni;
|
||||
|
||||
-- lékaři dle odbornosti — kolik předpisů pochází od které speciality
|
||||
SELECT RIGHT(pr.icp, 3) AS odb_kod, COUNT(*) AS pocet_predpisu
|
||||
FROM predpis p
|
||||
JOIN predepisujici pr ON pr.lekar_kod = p.kod_predepisujiciho
|
||||
WHERE pr.icp IS NOT NULL
|
||||
GROUP BY RIGHT(pr.icp, 3)
|
||||
ORDER BY pocet_predpisu DESC;
|
||||
|
||||
-- lékový záznam pacienta dle rodného čísla (přes Firebird → MySQL)
|
||||
-- krok 1: z Medicusu zjistit příjmení a datum narozeni pro RC 7309208104
|
||||
-- krok 2:
|
||||
SELECT pac.prijmeni, pac.jmena, pac.datum_narozeni,
|
||||
p.datum_vystaveni,
|
||||
COALESCE(v.nazev, p.nazev) AS vydany_lek,
|
||||
v.nazev IS NULL AS nevyzvednuto,
|
||||
p.atc, p.navod,
|
||||
pr.prijmeni AS lekar, RIGHT(pr.icp, 3) AS odb_kod
|
||||
FROM pacient pac
|
||||
JOIN zprava z ON z.pacient_id = pac.id
|
||||
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 pac.prijmeni = 'Buzalka' AND pac.datum_narozeni = '1973-09-20'
|
||||
ORDER BY p.datum_vystaveni DESC;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reimport ze zálohy XML (`reimport_z_xml.py`)
|
||||
|
||||
Slouží k opětovnému naplnění MySQL databáze z lokálních XML souborů **bez volání eRecept API**.
|
||||
Použití: obnova po neúmyslném smazání databáze, migrace na nový server, re-parsování při změně schématu.
|
||||
|
||||
### Jak funguje
|
||||
|
||||
1. Načte všechny registrované pacienty z Firebirdu (ICP `09305001`, odbornost `001`)
|
||||
2. Pro každý XML soubor v archivu:
|
||||
- Naparsuje XML (volá `parsuj_xml()` z `06UlozitDoMySQL.py`)
|
||||
- Dohledá pacienta v Firebirdu dle příjmení + data narození z XML
|
||||
- Pokud je registrovaný → `upsert` pacienta do MySQL (INSERT ON DUPLICATE KEY UPDATE)
|
||||
- Zavolá `uloz()` — INSERT IGNORE, takže duplicity se ignorují
|
||||
3. Výpis průběhu: `[ 1/1177] Buzalka_Vladimir_1973-09-20.xml OK 12p 18v`
|
||||
|
||||
### Spuštění
|
||||
|
||||
```bash
|
||||
# Výchozí adresář: xml_archive/2026-04-11
|
||||
python reimport_z_xml.py
|
||||
|
||||
# Konkrétní podadresář
|
||||
python reimport_z_xml.py xml_archive/2026-04-11
|
||||
|
||||
# Celý archiv rekurzivně (všechna data)
|
||||
python reimport_z_xml.py xml_archive
|
||||
```
|
||||
|
||||
### Konfigurace v souboru
|
||||
|
||||
```python
|
||||
XML_ADRESAR = Path(__file__).parent / "xml_archive" / "2026-04-11" # výchozí adresář
|
||||
ICP = "09305001" # IČP ordinace pro filtr registrovaných pacientů
|
||||
ODB = "001" # odbornost (001 = praktický lékař)
|
||||
```
|
||||
|
||||
### Poznámky
|
||||
|
||||
- Pacienti, kteří nejsou v Firebirdu registrováni pod daným ICP/ODB, se přeskočí
|
||||
(pokud ale existují v MySQL z předchozího importu, data se aktualizují)
|
||||
- Firebird slouží jako autoritativní zdroj identit — `idpac` z KAR se propíše do MySQL `pacient.idpac`
|
||||
- `INSERT IGNORE` zajistí idempotentnost — opakované spuštění nepřidá duplikáty
|
||||
|
||||
---
|
||||
|
||||
## Dotazovací skripty (`Dotazy/`)
|
||||
|
||||
Viz samostatnou dokumentaci: [`Dotazy/DOTAZY.md`](../Dotazy/DOTAZY.md)
|
||||
|
||||
Stručný přehled:
|
||||
|
||||
| Skript | Co dělá |
|
||||
|--------|---------|
|
||||
| `prehled_pacienta.py` | Konzolový výpis lékového záznamu pacienta (lékaři + předpisy) |
|
||||
| `prehled_pacienta_excel.py` | Totéž, ale exportuje do formátovaného souboru Excel (.xlsx) |
|
||||
|
||||
Pacient se identifikuje **rodným číslem** (nastavení `RODNE_CISLO` v záhlaví skriptu).
|
||||
Oba skripty zobrazují **vydaný lék** (ne předepsaný), **odbornost lékaře** a příznak `*NV` pro nevyzvednuto.
|
||||
|
||||
---
|
||||
|
||||
## Závislosti (Python)
|
||||
|
||||
```
|
||||
@@ -385,10 +520,15 @@ requests
|
||||
requests-pkcs12
|
||||
pymysql
|
||||
fdb
|
||||
zeep
|
||||
mysql-connector-python
|
||||
playwright
|
||||
openpyxl
|
||||
```
|
||||
|
||||
```bash
|
||||
pip install requests requests-pkcs12 pymysql fdb
|
||||
# Instalace (nebo použít setup.ps1)
|
||||
pip install requests requests-pkcs12 pymysql fdb openpyxl
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
"""
|
||||
Reimport vsech XML souboru z xml_archive do MySQL — bez volani API.
|
||||
|
||||
Pouziti:
|
||||
python reimport_z_xml.py # vsechna XML z 2026-04-11
|
||||
python reimport_z_xml.py xml_archive/2026-04-11 # konkretni adresar
|
||||
python reimport_z_xml.py xml_archive # vsechny podadresare rekurzivne
|
||||
"""
|
||||
|
||||
import sys
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
from datetime import date
|
||||
import fdb
|
||||
import pymysql
|
||||
import pymysql.cursors
|
||||
|
||||
# Windows konzole
|
||||
if hasattr(sys.stdout, "reconfigure"):
|
||||
sys.stdout.reconfigure(errors="replace")
|
||||
|
||||
# ── Konfigurace ───────────────────────────────────────────────────────────────
|
||||
XML_ADRESAR = Path(__file__).parent / "xml_archive" / "2026-04-11"
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
ICP = "09305001"
|
||||
ODB = "001"
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# Nacteni parsovaci logiky z 06UlozitDoMySQL.py
|
||||
_spec = importlib.util.spec_from_file_location(
|
||||
"m06", Path(__file__).parent / "06UlozitDoMySQL.py"
|
||||
)
|
||||
_m06 = importlib.util.module_from_spec(_spec)
|
||||
_spec.loader.exec_module(_m06)
|
||||
|
||||
parsuj_xml = _m06.parsuj_xml
|
||||
uloz = _m06.uloz
|
||||
inicializuj_schema = _m06.inicializuj_schema
|
||||
|
||||
|
||||
def nacti_pacienty_z_fb():
|
||||
"""Vrati slovnik {(prijmeni_upper, datnar): idpac} ze vsech pacientu v Medicusu."""
|
||||
conn = fdb.connect(**FB)
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
dnes = date.today().isoformat()
|
||||
cur.execute("""
|
||||
SELECT KAR.IDPAC, KAR.PRIJMENI, KAR.JMENO, KAR.DATNAR
|
||||
FROM KAR
|
||||
WHERE KAR.vyrazen = 'N'
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM registr r
|
||||
JOIN icp i ON r.idicp = i.idicp
|
||||
WHERE r.idpac = kar.idpac
|
||||
AND r.datum <= ?
|
||||
AND (r.datum_zruseni IS NULL OR r.datum_zruseni >= ?)
|
||||
AND r.priznak IN ('V','D','A')
|
||||
AND i.icp = ?
|
||||
AND i.odb = ?
|
||||
)
|
||||
""", (dnes, dnes, ICP, ODB))
|
||||
result = {}
|
||||
for row in cur.fetchall():
|
||||
idpac, prijmeni, jmeno, datnar = row
|
||||
klic = (prijmeni.strip().upper(), datnar)
|
||||
result[klic] = {"idpac": idpac, "prijmeni": prijmeni.strip(), "jmeno": jmeno.strip(), "datnar": datnar}
|
||||
print(f"Firebird: nacteno {len(result)} registrovanych pacientu")
|
||||
return result
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def upsert_pacient(cur, pac):
|
||||
cur.execute("""
|
||||
INSERT INTO pacient (idpac, prijmeni, jmena, datum_narozeni)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
prijmeni = VALUES(prijmeni),
|
||||
jmena = VALUES(jmena)
|
||||
""", (pac["idpac"], pac["prijmeni"], pac["jmeno"], pac["datnar"]))
|
||||
cur.execute("SELECT id FROM pacient WHERE idpac = %s", (pac["idpac"],))
|
||||
return cur.fetchone()["id"]
|
||||
|
||||
|
||||
def main():
|
||||
# Adresar z argumentu nebo default
|
||||
adresar = Path(sys.argv[1]) if len(sys.argv) > 1 else XML_ADRESAR
|
||||
if not adresar.is_dir():
|
||||
sys.exit(f"Adresar neexistuje: {adresar}")
|
||||
|
||||
# Najdi vsechna XML rekurzivne
|
||||
xml_soubory = sorted(adresar.rglob("*.xml"))
|
||||
if not xml_soubory:
|
||||
sys.exit(f"Zadne XML soubory nalezeny v: {adresar}")
|
||||
print(f"Nalezeno {len(xml_soubory)} XML souboru v: {adresar}")
|
||||
|
||||
# Nacti pacienty z Firebirdu
|
||||
fb_pacienti = nacti_pacienty_z_fb()
|
||||
|
||||
# Pripoj se k MySQL a inicializuj schema
|
||||
conn = pymysql.connect(**DB)
|
||||
try:
|
||||
inicializuj_schema(conn)
|
||||
|
||||
ok = chyba = preskoceno = 0
|
||||
p_celkem = v_celkem = 0
|
||||
|
||||
for i, xml_path in enumerate(xml_soubory, 1):
|
||||
rel = xml_path.relative_to(Path(__file__).parent)
|
||||
try:
|
||||
zprava, predpisy, vydeji, predepisujici, vydavajici = parsuj_xml(xml_path)
|
||||
except Exception as e:
|
||||
print(f"[{i:4}/{len(xml_soubory)}] {xml_path.name:<45} CHYBA parsovani: {e}")
|
||||
chyba += 1
|
||||
continue
|
||||
|
||||
# Zjisti prijmeni a datum narozeni z XML odpovedi
|
||||
pac_prijmeni = (zprava.get("pacient_prijmeni") or "").upper()
|
||||
pac_datnar = zprava.get("pacient_datum_narozeni") # string YYYY-MM-DD nebo None
|
||||
|
||||
# Prevod na date objekt pro porovnani s Firebirdem
|
||||
if pac_datnar and isinstance(pac_datnar, str):
|
||||
try:
|
||||
from datetime import datetime
|
||||
pac_datnar_d = datetime.strptime(pac_datnar[:10], "%Y-%m-%d").date()
|
||||
except ValueError:
|
||||
pac_datnar_d = None
|
||||
elif hasattr(pac_datnar, "year"):
|
||||
pac_datnar_d = pac_datnar
|
||||
else:
|
||||
pac_datnar_d = None
|
||||
|
||||
klic = (pac_prijmeni, pac_datnar_d)
|
||||
fb_pac = fb_pacienti.get(klic)
|
||||
|
||||
if not fb_pac:
|
||||
# Pacient neni registrovan — uloz bez idpac (bude ignorovan pri hromadnem behu)
|
||||
# Zkus najit v MySQL podle jmena a data
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT id FROM pacient WHERE prijmeni = %s AND datum_narozeni = %s",
|
||||
(zprava.get("pacient_prijmeni"), pac_datnar)
|
||||
)
|
||||
row = cur.fetchone()
|
||||
if row:
|
||||
pacient_id = row["id"]
|
||||
else:
|
||||
preskoceno += 1
|
||||
print(f"[{i:4}/{len(xml_soubory)}] {xml_path.name:<45} PRESKOCENO (neni v registru)")
|
||||
continue
|
||||
else:
|
||||
with conn.cursor() as cur:
|
||||
pacient_id = upsert_pacient(cur, fb_pac)
|
||||
conn.commit()
|
||||
|
||||
try:
|
||||
stats = uloz(conn, zprava, predpisy, vydeji, predepisujici, vydavajici,
|
||||
pacient_id=pacient_id, xml_soubor=str(rel))
|
||||
conn.commit()
|
||||
p_celkem += stats["predpisy_novych"]
|
||||
v_celkem += stats["vydeji_novych"]
|
||||
print(f"[{i:4}/{len(xml_soubory)}] {xml_path.name:<45} OK "
|
||||
f"{stats['predpisy_novych']:3}p {stats['vydeji_novych']:3}v")
|
||||
ok += 1
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(f"[{i:4}/{len(xml_soubory)}] {xml_path.name:<45} CHYBA ukladani: {e}")
|
||||
chyba += 1
|
||||
|
||||
print()
|
||||
print(f"Hotovo: {ok} OK, {chyba} chyb, {preskoceno} preskoceno")
|
||||
print(f"Celkem vlozeno: {p_celkem} predpisu, {v_celkem} vydejuu")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><NacistLekovyZaznamOdpoved xmlns="http://www.sukl.cz/erp/201912"><Doklad><Pacient><Jmeno><Prijmeni>ADAMEC</Prijmeni><Jmena>PETR</Jmena></Jmeno><DatumNarozeni>1981-01-19</DatumNarozeni></Pacient><PredepisujiciSeznam /><VydavajiciSeznam /><PredpisSeznam /><VydejSeznam /><DuplicitaSeznam /></Doklad><Zprava><ID_Zpravy>CC97F0EA-5522-4D5F-99B3-E187C9421C43</ID_Zpravy><Verze>202501A</Verze><Odeslano>2026-04-11T12:09:14.5490742+02:00</Odeslano><Aplikace>Informační systém eRecept, v. 1.108.2.22758</Aplikace><ID_Podani>F6BDB49A-4974-4134-AD62-645DDE5E6DE4</ID_Podani><Prijato>2026-04-11T12:09:14.3577236+02:00</Prijato></Zprava></NacistLekovyZaznamOdpoved></soap:Body></soap:Envelope>
|
||||
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><NacistLekovyZaznamOdpoved xmlns="http://www.sukl.cz/erp/201912"><Doklad><Pacient><Jmeno><Prijmeni>ADLEROVÁ</Prijmeni><Jmena>IRENA</Jmena></Jmeno><DatumNarozeni>1937-07-05</DatumNarozeni></Pacient><PredepisujiciSeznam><Predepisujici><Lekar><Kod>83607a3f-d44d-42e2-b4eb-57a983ec4d0c</Kod><Jmeno><Prijmeni>Buzalková</Prijmeni><Jmena>Michaela</Jmena></Jmeno></Lekar><ICZ>09305000</ICZ><ICP>09305001</ICP><PZS><Nazev>MUDr. Michaela Buzalková</Nazev><Adresa><NazevUlice>Lovosická</NazevUlice><CisloPopisne>440</CisloPopisne><CisloOrientacni>40</CisloOrientacni><NazevObce>Praha</NazevObce><PSC>19000</PSC></Adresa></PZS><Telefon>266010136</Telefon></Predepisujici><Predepisujici><Lekar><Kod>455cff31-b5ea-460c-ad81-907dec80fe0d</Kod><Jmeno><Prijmeni>Tychka</Prijmeni><Jmena>Viktoriia</Jmena></Jmeno></Lekar><ICP>09246001</ICP><PZS><Nazev>Derma CZ s.r.o.</Nazev><Adresa><NazevUlice>Lovosická</NazevUlice><CisloPopisne>440</CisloPopisne><CisloOrientacni>40</CisloOrientacni><NazevObce>Praha - Prosek</NazevObce><PSC>19000</PSC></Adresa></PZS><Telefon>266 010 225</Telefon></Predepisujici></PredepisujiciSeznam><VydavajiciSeznam><Vydavajici><Lekarnik><Kod>50957296-9aac-4366-8e82-286bbb2079a5</Kod><Jmeno><Prijmeni>Moravcová</Prijmeni><Jmena>Marie</Jmena></Jmeno></Lekarnik><PZS><Nazev>Hrouda CZ s.r.o.</Nazev><Telefon>228229843</Telefon><Adresa><NazevUlice>Chlumčanského</NazevUlice><CisloPopisne>497</CisloPopisne><CisloOrientacni>5</CisloOrientacni><NazevObce>Praha</NazevObce><PSC>18000</PSC></Adresa></PZS></Vydavajici><Vydavajici><Lekarnik><Kod>563bcaba-b5d9-4102-9086-f8cc7399b58f</Kod><Jmeno><Prijmeni>Sokolová</Prijmeni><Jmena>Pavlína</Jmena></Jmeno></Lekarnik><PZS><Nazev>ČESKÁ LÉKÁRNA HOLDING, a.s.</Nazev><Telefon>225574234</Telefon><Adresa><NazevUlice>Vysočanská</NazevUlice><CisloPopisne>242</CisloPopisne><CisloOrientacni>111</CisloOrientacni><NazevObce>Praha</NazevObce><PSC>19000</PSC></Adresa></PZS></Vydavajici></VydavajiciSeznam><PredpisSeznam><Predpis><ID_LP_Predpis>92A0A7AA-DA19-4683-9E4E-7B7038522AEA</ID_LP_Predpis><KodPredepisujiciho>83607a3f-d44d-42e2-b4eb-57a983ec4d0c</KodPredepisujiciho><DatumVystaveni>2026-04-10</DatumVystaveni><Mnozstvi>1</Mnozstvi><Navod>1-0-0</Navod><HVLPReg><Kod>0265451</Kod><ATC>A12AX</ATC><Nazev>CALCICHEW D3 LEMON</Nazev><Forma>TBL MND</Forma><Sila>500MG/400IU</Sila><CestaPodani>POR</CestaPodani><Baleni>60</Baleni></HVLPReg></Predpis><Predpis><ID_LP_Predpis>8082AD1E-69C7-4D28-AF48-271649BB8D91</ID_LP_Predpis><KodPredepisujiciho>455cff31-b5ea-460c-ad81-907dec80fe0d</KodPredepisujiciho><DatumVystaveni>2026-03-17</DatumVystaveni><Mnozstvi>1</Mnozstvi><Navod>2x týdně</Navod><HVLPReg><Kod>0045304</Kod><ATC>D01AE16</ATC><Nazev>LOCERYL</Nazev><Forma>LAC UGC</Forma><Sila>50MG/ML</Sila><CestaPodani>DRM</CestaPodani><Baleni>1X2,5ML I</Baleni></HVLPReg></Predpis></PredpisSeznam><VydejSeznam><Vydej><ID_LP_Vydej>3B60510F-548D-4B2E-9D8F-B46166DD01B4</ID_LP_Vydej><ID_LP_Predpis>92A0A7AA-DA19-4683-9E4E-7B7038522AEA</ID_LP_Predpis><KodVydavajiciho>50957296-9aac-4366-8e82-286bbb2079a5</KodVydavajiciho><DatumVydeje>2026-04-10</DatumVydeje><Mnozstvi>1</Mnozstvi><Navod>1-0-0</Navod><Sarze>12523499</Sarze><HVLPReg><Kod>0265451</Kod><ATC>A12AX</ATC><Nazev>CALCICHEW D3 LEMON</Nazev><Forma>TBL MND</Forma><Sila>500MG/400IU</Sila><CestaPodani>POR</CestaPodani><Baleni>60</Baleni></HVLPReg></Vydej><Vydej><ID_LP_Vydej>4B067971-E978-40D2-A7C3-B48044542BFF</ID_LP_Vydej><ID_LP_Predpis>8082AD1E-69C7-4D28-AF48-271649BB8D91</ID_LP_Predpis><KodVydavajiciho>563bcaba-b5d9-4102-9086-f8cc7399b58f</KodVydavajiciho><DatumVydeje>2026-03-17</DatumVydeje><Mnozstvi>1</Mnozstvi><Navod>2x týdně</Navod><Exspirace>2028-08-31</Exspirace><Sarze>5212458</Sarze><HVLPReg><Kod>0185977</Kod><ATC>D01AE16</ATC><Nazev>LOCERYL</Nazev><Forma>LAC UGC</Forma><Sila>50MG/ML</Sila><CestaPodani>DRM</CestaPodani><Baleni>1X2,5ML II</Baleni></HVLPReg></Vydej></VydejSeznam><DuplicitaSeznam /></Doklad><Zprava><ID_Zpravy>3A657B88-E7F7-4078-9A9A-E693AB1C27F7</ID_Zpravy><Verze>202501A</Verze><Odeslano>2026-04-11T12:09:31.3646059+02:00</Odeslano><Aplikace>Informační systém eRecept, v. 1.108.2.22758</Aplikace><ID_Podani>804C8B7E-6BC8-4388-BEE8-46CF9C824C4F</ID_Podani><Prijato>2026-04-11T12:09:31.1458623+02:00</Prijato></Zprava></NacistLekovyZaznamOdpoved></soap:Body></soap:Envelope>
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><NacistLekovyZaznamOdpoved xmlns="http://www.sukl.cz/erp/201912"><Doklad><Pacient><Jmeno><Prijmeni>ALEXOVIČOVÁ</Prijmeni><Jmena>JULIE</Jmena></Jmeno><DatumNarozeni>1978-10-27</DatumNarozeni></Pacient><PredepisujiciSeznam /><VydavajiciSeznam /><PredpisSeznam /><VydejSeznam /><DuplicitaSeznam /></Doklad><Zprava><ID_Zpravy>3D01F477-6BB9-45E0-8063-BECC18F77F5A</ID_Zpravy><Verze>202501A</Verze><Odeslano>2026-04-11T12:10:02.5458887+02:00</Odeslano><Aplikace>Informační systém eRecept, v. 1.108.2.22758</Aplikace><ID_Podani>1805D199-B265-4C10-B011-DE8EBA7C6225</ID_Podani><Prijato>2026-04-11T12:10:02.4017063+02:00</Prijato></Zprava></NacistLekovyZaznamOdpoved></soap:Body></soap:Envelope>
|
||||
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><NacistLekovyZaznamOdpoved xmlns="http://www.sukl.cz/erp/201912"><Doklad><Pacient><Jmeno><Prijmeni>ANDERLE</Prijmeni><Jmena>PETR</Jmena></Jmeno><DatumNarozeni>1975-02-07</DatumNarozeni></Pacient><PredepisujiciSeznam /><VydavajiciSeznam /><PredpisSeznam /><VydejSeznam /><DuplicitaSeznam /></Doklad><Zprava><ID_Zpravy>4E402F97-C38C-4494-9D38-5561E80D7595</ID_Zpravy><Verze>202501A</Verze><Odeslano>2026-04-11T12:10:18.6298555+02:00</Odeslano><Aplikace>Informační systém eRecept, v. 1.108.2.22758</Aplikace><ID_Podani>8A79C9BF-BBCF-42FE-9931-584D97D81FF1</ID_Podani><Prijato>2026-04-11T12:10:18.3798287+02:00</Prijato></Zprava></NacistLekovyZaznamOdpoved></soap:Body></soap:Envelope>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-4
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><NacistLekovyZaznamOdpoved xmlns="http://www.sukl.cz/erp/201912"><Doklad><Pacient><Jmeno><Prijmeni>BILLOUZ</Prijmeni><Jmena>DAVID MAURICE JEAN</Jmena></Jmeno><DatumNarozeni>1973-12-04</DatumNarozeni></Pacient><PredepisujiciSeznam><Predepisujici><Lekar><Kod>53484083-fabc-4d6a-97ae-12cf43d80783</Kod><Jmeno><Prijmeni>Buzalková</Prijmeni><Jmena>Michaela</Jmena></Jmeno></Lekar><ICZ>09305000</ICZ><ICP>09305001</ICP><PZS><Nazev>MUDr. Michaela Buzalková</Nazev><Adresa><NazevUlice>Lovosická</NazevUlice><CisloPopisne>440</CisloPopisne><CisloOrientacni>40</CisloOrientacni><NazevObce>Praha</NazevObce><PSC>19000</PSC></Adresa></PZS><Telefon>266010136</Telefon></Predepisujici><Predepisujici><Lekar><Kod>aa587d67-541f-4111-88b6-24741ab770bb</Kod><Jmeno><Prijmeni>Bludovský</Prijmeni><Jmena>Jaroslav</Jmena></Jmeno></Lekar><ICZ>09085000</ICZ><ICP>09085001</ICP><PZS><Nazev>MUDr. Jaroslav Bludovský</Nazev><Adresa><NazevUlice>Lovosická</NazevUlice><CisloPopisne>440</CisloPopisne><CisloOrientacni>40</CisloOrientacni><NazevObce>Praha 9</NazevObce><PSC>19000</PSC></Adresa></PZS><Telefon>266010235</Telefon></Predepisujici></PredepisujiciSeznam><VydavajiciSeznam><Vydavajici><Lekarnik><Kod>0edfa837-89b2-4b6d-b13f-0cdde919524a</Kod><Jmeno><Prijmeni>Škodová</Prijmeni><Jmena>Eva</Jmena></Jmeno></Lekarnik><PZS><Nazev>Poliklinika Prosek a.s.</Nazev><Telefon>266010257</Telefon><Adresa><NazevUlice>Lovosická</NazevUlice><CisloPopisne>440</CisloPopisne><CisloOrientacni>40</CisloOrientacni><NazevObce>Praha</NazevObce><PSC>19000</PSC></Adresa></PZS></Vydavajici><Vydavajici><Lekarnik><Kod>a3278ff1-5f58-446f-a1be-7abbbbe9d3d0</Kod><Jmeno><Prijmeni>Langová</Prijmeni><Jmena>Michaela</Jmena></Jmeno></Lekarnik><PZS><Nazev>BENU Česká republika s.r.o.</Nazev><Telefon>703462221</Telefon><Adresa><NazevUlice>Střelničná</NazevUlice><CisloPopisne>2270</CisloPopisne><CisloOrientacni>46</CisloOrientacni><NazevObce>Praha</NazevObce><PSC>18000</PSC></Adresa></PZS></Vydavajici><Vydavajici><Lekarnik><Kod>5390a32a-191f-403f-ae13-f34b259df0f0</Kod><Jmeno><Prijmeni>Radoňová</Prijmeni><Jmena>Daniela</Jmena></Jmeno></Lekarnik><PZS><Nazev>Poliklinika Prosek a.s.</Nazev><Telefon>266010257</Telefon><Adresa><NazevUlice>Lovosická</NazevUlice><CisloPopisne>440</CisloPopisne><CisloOrientacni>40</CisloOrientacni><NazevObce>Praha 9</NazevObce><PSC>19000</PSC></Adresa></PZS></Vydavajici></VydavajiciSeznam><PredpisSeznam><Predpis><ID_LP_Predpis>95174A02-5182-4B2B-9357-4C900E6D75AC</ID_LP_Predpis><KodPredepisujiciho>53484083-fabc-4d6a-97ae-12cf43d80783</KodPredepisujiciho><DatumVystaveni>2025-12-11</DatumVystaveni><Mnozstvi>1</Mnozstvi><Navod>dle pp max 14 dnů</Navod><HVLPReg><Kod>0262102</Kod><ATC>D07AB02</ATC><Nazev>LOCOID LIPOCREAM 0,1%</Nazev><Forma>CRM</Forma><Sila>1MG/G</Sila><CestaPodani>DRM</CestaPodani><Baleni>1X30G</Baleni></HVLPReg></Predpis><Predpis><ID_LP_Predpis>65518391-85C6-47D6-BD71-B12C2CCB6943</ID_LP_Predpis><KodPredepisujiciho>53484083-fabc-4d6a-97ae-12cf43d80783</KodPredepisujiciho><DatumVystaveni>2025-10-20</DatumVystaveni><Mnozstvi>1</Mnozstvi><Navod>dle návodu</Navod><HVLPReg><Kod>0237830</Kod><ATC>R01AX06</ATC><Nazev>BACTROBAN NASAL</Nazev><Forma>NAS UNG</Forma><Sila>20MG/G</Sila><CestaPodani>NAS</CestaPodani><Baleni>1X3G</Baleni></HVLPReg></Predpis><Predpis><ID_LP_Predpis>BB2DF7E4-18BD-4DB3-8799-DA8E5D555587</ID_LP_Predpis><KodPredepisujiciho>53484083-fabc-4d6a-97ae-12cf43d80783</KodPredepisujiciho><DatumVystaveni>2025-03-03</DatumVystaveni><Mnozstvi>1</Mnozstvi><Navod>1-1-0</Navod><HVLPReg><Kod>0092757</Kod><ATC>R05CB15</ATC><Nazev>ERDOMED</Nazev><Forma>CPS DUR</Forma><Sila>300MG</Sila><CestaPodani>POR</CestaPodani><Baleni>10</Baleni></HVLPReg></Predpis><Predpis><ID_LP_Predpis>7ABDCBD1-A5CC-4188-B9B8-0F8E005DADC7</ID_LP_Predpis><KodPredepisujiciho>aa587d67-541f-4111-88b6-24741ab770bb</KodPredepisujiciho><DatumVystaveni>2024-11-07</DatumVystaveni><Mnozstvi>1</Mnozstvi><Navod>uk</Navod><IPLP><PostupPripravy>Sol. alum. acet.-tartarici 4,0
|
||||
Sol. acidi borici 1,5% 12,0
|
||||
Spir. vini diluti ad 20,0
|
||||
MDS. ušní kapky 3x denně po 2 do obou uší</PostupPripravy><Nazev>UK Alsol</Nazev></IPLP></Predpis></PredpisSeznam><VydejSeznam><Vydej><ID_LP_Vydej>935C6BD3-ED97-49F5-BDAB-257BE1B699A4</ID_LP_Vydej><ID_LP_Predpis>95174A02-5182-4B2B-9357-4C900E6D75AC</ID_LP_Predpis><KodVydavajiciho>0edfa837-89b2-4b6d-b13f-0cdde919524a</KodVydavajiciho><DatumVydeje>2025-12-11</DatumVydeje><Mnozstvi>1</Mnozstvi><Navod>dle pp max 14 dnů</Navod><Sarze>24L17A</Sarze><Pozn>Neuvedena</Pozn><HVLPReg><Kod>0262102</Kod><ATC>D07AB02</ATC><Nazev>LOCOID LIPOCREAM 0,1%</Nazev><Forma>CRM</Forma><Sila>1MG/G</Sila><CestaPodani>DRM</CestaPodani><Baleni>1X30G</Baleni></HVLPReg></Vydej><Vydej><ID_LP_Vydej>BF36F2FB-B19A-47BB-B189-2E04ECE51CBD</ID_LP_Vydej><ID_LP_Predpis>65518391-85C6-47D6-BD71-B12C2CCB6943</ID_LP_Predpis><KodVydavajiciho>a3278ff1-5f58-446f-a1be-7abbbbe9d3d0</KodVydavajiciho><DatumVydeje>2025-10-20</DatumVydeje><Mnozstvi>1</Mnozstvi><Navod>dle návodu</Navod><Sarze>AY7Y</Sarze><HVLPReg><Kod>0237830</Kod><ATC>R01AX06</ATC><Nazev>BACTROBAN NASAL</Nazev><Forma>NAS UNG</Forma><Sila>20MG/G</Sila><CestaPodani>NAS</CestaPodani><Baleni>1X3G</Baleni></HVLPReg></Vydej><Vydej><ID_LP_Vydej>5076BA10-3929-48F0-8A86-6F934F33051E</ID_LP_Vydej><ID_LP_Predpis>BB2DF7E4-18BD-4DB3-8799-DA8E5D555587</ID_LP_Predpis><KodVydavajiciho>5390a32a-191f-403f-ae13-f34b259df0f0</KodVydavajiciho><DatumVydeje>2025-03-03</DatumVydeje><Mnozstvi>1</Mnozstvi><Navod>1-1-0</Navod><Sarze>0599</Sarze><Pozn>Neuvedena</Pozn><HVLPReg><Kod>0092757</Kod><ATC>R05CB15</ATC><Nazev>ERDOMED</Nazev><Forma>CPS DUR</Forma><Sila>300MG</Sila><CestaPodani>POR</CestaPodani><Baleni>10</Baleni></HVLPReg></Vydej><Vydej><ID_LP_Vydej>5EEC1651-1A7B-45DF-B14E-F000775EF6E3</ID_LP_Vydej><ID_LP_Predpis>7ABDCBD1-A5CC-4188-B9B8-0F8E005DADC7</ID_LP_Predpis><KodVydavajiciho>5390a32a-191f-403f-ae13-f34b259df0f0</KodVydavajiciho><DatumVydeje>2024-11-07</DatumVydeje><Mnozstvi>1</Mnozstvi><Navod>uk</Navod><Sarze>20241106037</Sarze><Pozn>Neuvedena</Pozn><IPLP><KodVZP>0001002</KodVZP><Nazev>Ušní kapky se sol.alumin.acetico tartar.</Nazev><Slozka><Mnozstvi>1</Mnozstvi><Jednotka>ks</Jednotka><Nazev>PO Příprava čistých obalů sk.2.1.1</Nazev><Sarze>NA</Sarze></Slozka><Slozka><Mnozstvi>1</Mnozstvi><Jednotka>ks</Jednotka><Nazev>Lékovka hnědá s pipetou 25ml**</Nazev><Sarze>F280324</Sarze></Slozka><Slozka><Mnozstvi>1</Mnozstvi><Jednotka>ks</Jednotka><Nazev>TP Dispenzace sk.1.11</Nazev><Sarze>NA</Sarze></Slozka><Slozka><Mnozstvi>20</Mnozstvi><Jednotka>ks</Jednotka><Nazev>Taxa laborum ...</Nazev><Sarze>NA</Sarze></Slozka><Slozka><Mnozstvi>20</Mnozstvi><Jednotka>g</Jednotka><Nazev>Ušní kapky se sol. alumin.acet.tartar.MEZIPRODUKT</Nazev><Sarze>20241106029</Sarze></Slozka><Slozka><Mnozstvi>1</Mnozstvi><Jednotka>ks</Jednotka><Nazev>SIGNATURA NOVÁ</Nazev><Sarze>260224</Sarze></Slozka></IPLP></Vydej></VydejSeznam><DuplicitaSeznam /></Doklad><Zprava><ID_Zpravy>C610F496-AF68-453E-BDB6-8640AF8E0559</ID_Zpravy><Verze>202501A</Verze><Odeslano>2026-04-11T12:20:25.5419241+02:00</Odeslano><Aplikace>Informační systém eRecept, v. 1.108.2.22758</Aplikace><ID_Podani>734EC9EB-69E6-4114-9A67-202E376837F0</ID_Podani><Prijato>2026-04-11T12:20:25.3192135+02:00</Prijato></Zprava></NacistLekovyZaznamOdpoved></soap:Body></soap:Envelope>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><NacistLekovyZaznamOdpoved xmlns="http://www.sukl.cz/erp/201912"><Doklad><Pacient><Jmeno><Prijmeni>BUZALKA</Prijmeni><Jmena>VLADIMÍR</Jmena></Jmeno><DatumNarozeni>2003-08-02</DatumNarozeni></Pacient><PredepisujiciSeznam /><VydavajiciSeznam /><PredpisSeznam /><VydejSeznam /><DuplicitaSeznam /></Doklad><Zprava><ID_Zpravy>1C34C759-CF78-4788-A1EE-8C30AFB5A58B</ID_Zpravy><Verze>202501A</Verze><Odeslano>2026-04-11T12:32:58.4738373+02:00</Odeslano><Aplikace>Informační systém eRecept, v. 1.108.2.22758</Aplikace><ID_Podani>2C05838C-658C-4C69-8A5A-BF99D7DE5D7D</ID_Podani><Prijato>2026-04-11T12:32:58.3288862+02:00</Prijato></Zprava></NacistLekovyZaznamOdpoved></soap:Body></soap:Envelope>
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><NacistLekovyZaznamOdpoved xmlns="http://www.sukl.cz/erp/201912"><Doklad><Pacient><Jmeno><Prijmeni>BUZALKOVÁ</Prijmeni><Jmena>MICHAELA</Jmena></Jmeno><DatumNarozeni>2007-09-05</DatumNarozeni></Pacient><PredepisujiciSeznam><Predepisujici><Lekar><Kod>cae47885-9e51-468f-86b1-3a9d9bb3447b</Kod><Jmeno><Prijmeni>Buzalka</Prijmeni><Jmena>Vladimír</Jmena></Jmeno></Lekar><ICZ>09305000</ICZ><ICP>09305001</ICP><PZS><Nazev>MUDr. Michaela Buzalková</Nazev><Adresa><NazevUlice>Lovosická</NazevUlice><CisloPopisne>440</CisloPopisne><CisloOrientacni>40</CisloOrientacni><NazevObce>Praha</NazevObce><PSC>19000</PSC></Adresa></PZS><Telefon>266010136</Telefon></Predepisujici></PredepisujiciSeznam><VydavajiciSeznam><Vydavajici><Lekarnik><Kod>3b709dea-bf11-49b0-8897-9de3b57e0fb4</Kod><Jmeno><Prijmeni>Hefjuková</Prijmeni><Jmena>Anna</Jmena></Jmeno></Lekarnik><PZS><Nazev>ČESKÁ LÉKÁRNA HOLDING, a.s.</Nazev><Telefon>225574455</Telefon><Adresa><NazevUlice>Kostelecká</NazevUlice><CisloPopisne>822</CisloPopisne><CisloOrientacni>75</CisloOrientacni><NazevObce>Praha</NazevObce><PSC>19600</PSC></Adresa></PZS></Vydavajici></VydavajiciSeznam><PredpisSeznam><Predpis><ID_LP_Predpis>48721638-DFCC-47E5-B89F-FC184D60E8B8</ID_LP_Predpis><KodPredepisujiciho>cae47885-9e51-468f-86b1-3a9d9bb3447b</KodPredepisujiciho><DatumVystaveni>2026-03-13</DatumVystaveni><Mnozstvi>1</Mnozstvi><Navod>při bolesti</Navod><HVLPReg><Kod>0017187</Kod><ATC>M01AX17</ATC><Nazev>NIMESIL</Nazev><Forma>POR GRA SUS</Forma><Sila>100MG</Sila><CestaPodani>POR</CestaPodani><Baleni>30</Baleni></HVLPReg></Predpis><Predpis><ID_LP_Predpis>BCF0AA03-2603-46D7-B571-FD205186BEE5</ID_LP_Predpis><KodPredepisujiciho>cae47885-9e51-468f-86b1-3a9d9bb3447b</KodPredepisujiciho><DatumVystaveni>2026-03-13</DatumVystaveni><Mnozstvi>1</Mnozstvi><Navod>1-0-0</Navod><HVLPReg><Kod>0155685</Kod><ATC>R06AE07</ATC><Nazev>ZYRTEC</Nazev><Forma>TBL FLM</Forma><Sila>10MG</Sila><CestaPodani>POR</CestaPodani><Baleni>50</Baleni></HVLPReg></Predpis></PredpisSeznam><VydejSeznam><Vydej><ID_LP_Vydej>CAB3980B-D50B-4FB3-9BDF-D838C1A870F8</ID_LP_Vydej><ID_LP_Predpis>48721638-DFCC-47E5-B89F-FC184D60E8B8</ID_LP_Predpis><KodVydavajiciho>3b709dea-bf11-49b0-8897-9de3b57e0fb4</KodVydavajiciho><DatumVydeje>2026-03-13</DatumVydeje><Mnozstvi>1</Mnozstvi><Navod>při bolesti</Navod><Exspirace>2028-11-30</Exspirace><Sarze>54970</Sarze><HVLPReg><Kod>0017187</Kod><ATC>M01AX17</ATC><Nazev>NIMESIL</Nazev><Forma>POR GRA SUS</Forma><Sila>100MG</Sila><CestaPodani>POR</CestaPodani><Baleni>30</Baleni></HVLPReg></Vydej><Vydej><ID_LP_Vydej>E409ADF5-2F2A-4A55-858C-CC0CE97D0731</ID_LP_Vydej><ID_LP_Predpis>BCF0AA03-2603-46D7-B571-FD205186BEE5</ID_LP_Predpis><KodVydavajiciho>3b709dea-bf11-49b0-8897-9de3b57e0fb4</KodVydavajiciho><DatumVydeje>2026-03-13</DatumVydeje><Mnozstvi>1</Mnozstvi><Navod>1-0-0</Navod><Exspirace>2028-09-30</Exspirace><Sarze>381624</Sarze><HVLPReg><Kod>0155685</Kod><ATC>R06AE07</ATC><Nazev>ZYRTEC</Nazev><Forma>TBL FLM</Forma><Sila>10MG</Sila><CestaPodani>POR</CestaPodani><Baleni>50</Baleni></HVLPReg></Vydej></VydejSeznam><DuplicitaSeznam /></Doklad><Zprava><ID_Zpravy>CA219D0B-89F7-4E74-BD55-55017160D9E3</ID_Zpravy><Verze>202501A</Verze><Odeslano>2026-04-11T12:33:31.67695+02:00</Odeslano><Aplikace>Informační systém eRecept, v. 1.108.2.22758</Aplikace><ID_Podani>1192D3D7-6B00-414C-A2B6-0CB0F2EFC4F2</ID_Podani><Prijato>2026-04-11T12:33:31.5176122+02:00</Prijato></Zprava></NacistLekovyZaznamOdpoved></soap:Body></soap:Envelope>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user