# 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 |
