From d4b9531f57935c0708f7aa1717e11eea4f9fd138 Mon Sep 17 00:00:00 2001 From: Vladimir Buzalka Date: Sat, 28 Mar 2026 11:05:19 +0100 Subject: [PATCH] notebook vb --- .claude/worktrees/vigorous-davinci | 1 + CLAUDE.md | 51 ++++ MedicusWithClaudeFaktury/faktury_report.py | 272 ++++++++++++++++++++ MedicusWithClaudeSelects/FakturaceADavky.md | 252 ++++++++++++++++++ 4 files changed, 576 insertions(+) create mode 160000 .claude/worktrees/vigorous-davinci create mode 100644 CLAUDE.md create mode 100644 MedicusWithClaudeFaktury/faktury_report.py create mode 100644 MedicusWithClaudeSelects/FakturaceADavky.md diff --git a/.claude/worktrees/vigorous-davinci b/.claude/worktrees/vigorous-davinci new file mode 160000 index 0000000..45a1642 --- /dev/null +++ b/.claude/worktrees/vigorous-davinci @@ -0,0 +1 @@ +Subproject commit 45a1642df8e0402415c6dc52891b3fcc8a8cd740 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..bc03a29 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,51 @@ +# Medicus + Claude – kontext projektu + +## Přečti si prosím tyto soubory na začátku každé konverzace + +1. `MedicusWithClaude/CLAUDE_NOTES.md` – hlavní poznámky: DB připojení, klíčové tabulky, RTF formát, import pipeline +2. `MedicusWithClaudeSelects/SELECTS.md` – SQL dotazy (registrovaní pacienti atd.) +3. `MedicusWithClaudeSelects/FakturaceADavky.md` – tabulky FAK, FAKDET, FAKDAV, PORTAL, kódování dávek + +## O projektu + +Firebird DB lékařského SW **Medicus** pro praktického lékaře. Lékařka je **MUDr. Buzalková Michaela** (IDUZI=4). Vladimír Buzalka (IDUZI=6) je manžel a správce systému – s ním probíhají tyto konverzace. + +## Připojení k DB + +```python +import fdb +conn = fdb.connect( + dsn=r'localhost:c:\medicus 3\data\medicus.fdb', + user='SYSDBA', password='masterkey', charset='win1250' +) +``` + +## Počítač "reporter" + +Na tomto stroji běží pravidelná automatická tvorba reportů. Připojení k DB funguje stejně jako výše (ostrá DB, čerstvá data). Hlavní report skript: `MedicusWithClaudeFaktury/faktury_report.py` + +### Co report dělá +- Generuje Excel s listy: **FAK**, **FAKDET**, **PORTAL**, **PORTAL_DATA** +- Ukládá do `u:\Dropbox\!!!Days\Downloads Z230\` +- Název souboru: `YYYY-MM-DD_HH-MM-SS_faktury.xlsx` +- Maže předchozí verze ze stejné složky +- Řazení: nejnovější záznamy nahoře +- Hyperlinky: FAK → FAKDET, PORTAL ↔ PORTAL_DATA + +### Důležité – kódování dávek +KDAVKA/FDAVKA jsou v **CP852** (DOS). fdb je vrací jako string dekódovaný win1250 – nutno re-enkódovat: +```python +spravny_text = s.encode('cp1250', errors='replace').decode('cp852', errors='replace') +``` + +## Klíčové adresáře + +| Adresář | Obsah | +|---|---| +| `MedicusWithClaude/` | průzkumné skripty, import pipeline (s03soubory.py) | +| `MedicusWithClaudeSelects/` | SQL dotazy, dokumentace tabulek | +| `MedicusWithClaudeFaktury/` | fakturační reporty | + +## Co chceme na reporteru nastavit + +Pravidelná automatická tvorba reportu `faktury_report.py` – např. každý den ráno, aby byl vždy čerstvý Excel s fakturami v Dropboxu. diff --git a/MedicusWithClaudeFaktury/faktury_report.py b/MedicusWithClaudeFaktury/faktury_report.py new file mode 100644 index 0000000..ec2fdbd --- /dev/null +++ b/MedicusWithClaudeFaktury/faktury_report.py @@ -0,0 +1,272 @@ +import fdb +import openpyxl +from openpyxl.styles import Font, PatternFill, Alignment +from openpyxl.utils import get_column_letter +from datetime import datetime +import os +import sys + +# --- Připojení --- +conn = fdb.connect( + dsn=r'localhost:c:\medicus 3\data\medicus.fdb', + user='SYSDBA', password='masterkey', charset='win1250' +) +cur = conn.cursor() + +# --- Výstupní soubor --- +output_dir = r'u:\Dropbox\!!!Days\Downloads Z230' +now = datetime.now() +filename = now.strftime('%Y-%m-%d_%H-%M-%S') + '_faktury.xlsx' +output_path = os.path.join(output_dir, filename) + +# --- Smazání předchozích verzí --- +for f in os.listdir(output_dir): + if f.endswith('_faktury.xlsx'): + os.remove(os.path.join(output_dir, f)) + +wb = openpyxl.Workbook() + +# ===================== +# Pomocné funkce +# ===================== + +HEADER_FILL = PatternFill('solid', fgColor='2F5496') +HEADER_FONT = Font(bold=True, color='FFFFFF') +LINK_FONT = Font(color='0563C1', underline='single') +ZEBRA_FILL = PatternFill('solid', fgColor='DCE6F1') + +def style_header(ws): + for cell in ws[1]: + cell.fill = HEADER_FILL + cell.font = HEADER_FONT + cell.alignment = Alignment(horizontal='center') + +def autofit(ws): + for col in ws.columns: + max_len = max((len(str(cell.value)) if cell.value is not None else 0) for cell in col) + ws.column_dimensions[get_column_letter(col[0].column)].width = min(max_len + 2, 40) + +def fmt(val): + if val is None: + return '' + return val + +# ===================== +# List 1 – FAK +# ===================== + +ws1 = wb.active +ws1.title = 'FAK' + +cur.execute(''' + SELECT + ID, CISFAK, POJ, DATUMOD, DATUMDO, DATVYS, DATODE, + VYKONY, KAPITACE, ZALOHA, CENA, ZAPLACENO, ZUM, HOSPAUSAL, + PROPLACENO, SPLAT, DRUH, TYP, ROK, OBDOB, + NAZFAK, POZFAK, OBDFAK, + ICO, BANKA, UCET, + ODJMENO, ODULICE, ODMISTO, ODPSC, + PLNAZEV, PLULICE, PLMISTO, PLPSC, + ICZ, ICZ1, IDICZ, PORCISLO, DRUHPOJ, POZNAMKA + FROM FAK + ORDER BY ID DESC +''') +fak_cols = [d[0] for d in cur.description] +fak_rows = cur.fetchall() + +ws1.append(fak_cols) +for i, row in enumerate(fak_rows, start=2): + ws1.append([fmt(v) for v in row]) + if i % 2 == 0: + for cell in ws1[i]: + cell.fill = ZEBRA_FILL + +style_header(ws1) +ws1.freeze_panes = 'A2' +autofit(ws1) + +# ===================== +# List 2 – FAKDET +# ===================== + +ws2 = wb.create_sheet('FAKDET') + +cur.execute(''' + SELECT + fd.ID, fd.IDFAK, + f.CISFAK, f.POJ, f.DATUMOD, f.DATUMDO, f.ROK, + fd.ICP, fd.ODB, fd.IDUZI, + u.PRIJMENI, u.JMENO, + fd.CENAVYK, fd.CENALEC, fd.CENAKAP + FROM FAKDET fd + JOIN FAK f ON f.ID = fd.IDFAK + LEFT JOIN UZIVATEL u ON u.IDUZI = fd.IDUZI + ORDER BY fd.IDFAK DESC, fd.ID DESC +''') +det_cols = [d[0] for d in cur.description] +det_rows = cur.fetchall() + +ws2.append(det_cols) +for i, row in enumerate(det_rows, start=2): + ws2.append([fmt(v) for v in row]) + if i % 2 == 0: + for cell in ws2[i]: + cell.fill = ZEBRA_FILL + +style_header(ws2) +ws2.freeze_panes = 'A2' +autofit(ws2) + +# ===================== +# List 3 – PORTAL (krátké sloupce) +# ===================== + +ws3 = wb.create_sheet('PORTAL') + +cur.execute(''' + SELECT ID, IDFAK, ODESLANO, CHYBA, STAV, ID_PODANI, IDPODANI, IDCERT, + DAVKA_ROK, DAVKA_DISK, DAVKA_IDICZ, DAVKA_DATUMOD, DAVKA_DATUMDO, + DAVKA_CASTKA, BB_DAVKA, BB_FAKTURA + FROM PORTAL + ORDER BY ID DESC +''') +portal_cols = [d[0] for d in cur.description] +portal_rows = cur.fetchall() + +ws3.append(portal_cols) +for i, row in enumerate(portal_rows, start=2): + ws3.append([fmt(v) for v in row]) + if i % 2 == 0: + for cell in ws3[i]: + cell.fill = ZEBRA_FILL + +style_header(ws3) +ws3.freeze_panes = 'A2' +autofit(ws3) + +# ===================== +# List 4 – PORTAL_DATA (BLOBy) +# ===================== + +ws4 = wb.create_sheet('PORTAL_DATA') + +cur.execute(''' + SELECT ID, ID_PODANI, DAVKA_ROK, DAVKA_DISK, DAVKA_DATUMOD, DAVKA_DATUMDO, + KDAVKA, FDAVKA, DATA + FROM PORTAL + ORDER BY ID DESC +''') +pdata_rows = cur.fetchall() + +pdata_cols = ['ID', 'ID_PODANI', 'DAVKA_ROK', 'DAVKA_DISK', 'DAVKA_DATUMOD', 'DAVKA_DATUMDO', + 'KDAVKA', 'FDAVKA', 'DATA'] +ws4.append(pdata_cols) + +WRAP = Alignment(wrap_text=True, vertical='top') + +# Indexy BLOB sloupců: KDAVKA=6, FDAVKA=7, DATA=8 +# DATA je XML v win1250, KDAVKA/FDAVKA jsou latin2 +BLOB_ENCODINGS = {6: 'cp852', 7: 'cp852', 8: 'cp1250'} + +def decode_blob(v, enc): + if hasattr(v, 'read'): + raw = v.read() + else: + raw = v + if not raw: + return '' + if isinstance(raw, str): + # fdb dekódoval jako win1250 – vrátíme zpět na bytes, pak dekódujeme správně + raw = raw.encode('cp1250', errors='replace') + return raw.decode(enc, errors='replace') + +for i, row in enumerate(pdata_rows, start=2): + out = [] + for col_idx, v in enumerate(row): + if col_idx in BLOB_ENCODINGS: + enc = BLOB_ENCODINGS[col_idx] + out.append(decode_blob(v, enc)) + else: + out.append(fmt(v)) + ws4.append(out) + if i % 2 == 0: + for cell in ws4[i]: + cell.fill = ZEBRA_FILL + for cell in ws4[i]: + cell.alignment = WRAP + ws4.row_dimensions[i].height = 80 + +style_header(ws4) +ws4.freeze_panes = 'A2' + +# Šířky sloupců PORTAL_DATA +for col, width in zip(['A','B','C','D','E','F','G','H','I'], [6, 26, 8, 6, 12, 12, 80, 20, 60]): + ws4.column_dimensions[col].width = width + +# ===================== +# Hyperlinky PORTAL ↔ PORTAL_DATA +# ===================== + +# Mapa: portal_id → řádek v každém listu +portal_id_to_ws3_row = {} +for i, row in enumerate(portal_rows, start=2): + portal_id_to_ws3_row[row[0]] = i # row[0] = ID + +portal_id_to_ws4_row = {} +for i, row in enumerate(pdata_rows, start=2): + portal_id_to_ws4_row[row[0]] = i # row[0] = ID + +# PORTAL → PORTAL_DATA (sloupec A = ID) +for i, row in enumerate(portal_rows, start=2): + pid = row[0] + cell = ws3.cell(row=i, column=1) + if pid in portal_id_to_ws4_row: + cell.hyperlink = f'#PORTAL_DATA!A{portal_id_to_ws4_row[pid]}' + cell.font = LINK_FONT + +# PORTAL_DATA → PORTAL (sloupec A = ID) +for i, row in enumerate(pdata_rows, start=2): + pid = row[0] + cell = ws4.cell(row=i, column=1) + if pid in portal_id_to_ws3_row: + cell.hyperlink = f'#PORTAL!A{portal_id_to_ws3_row[pid]}' + cell.font = LINK_FONT + cell.alignment = WRAP + +# ===================== +# Hyperlinky FAK → FAKDET +# ===================== + +# Mapa: IDFAK → první řádek na listu FAKDET (řádek 1 = záhlaví, data od 2) +idfak_to_row = {} +for i, row in enumerate(det_rows, start=2): + idfak = row[1] # IDFAK je druhý sloupec + if idfak not in idfak_to_row: + idfak_to_row[idfak] = i + +# Přidat sloupec "→FAKDET" jako první sloupec na listu FAK +ws1.insert_cols(1) +ws1.cell(row=1, column=1, value='FAKDET').fill = HEADER_FILL +ws1.cell(row=1, column=1).font = HEADER_FONT +ws1.cell(row=1, column=1).alignment = Alignment(horizontal='center') +ws1.column_dimensions['A'].width = 9 + +for i, row in enumerate(fak_rows, start=2): + fak_id = row[0] # ID je první sloupec z DB + cell = ws1.cell(row=i, column=1) + if fak_id in idfak_to_row: + target_row = idfak_to_row[fak_id] + cell.value = '>> det' + cell.hyperlink = f'#FAKDET!A{target_row}' + cell.font = LINK_FONT + else: + cell.value = '' + +# ===================== +# Uložení +# ===================== + +conn.close() +wb.save(output_path) +sys.stdout.buffer.write(f'Ulozeno: {output_path}\n'.encode('utf-8')) +sys.stdout.buffer.write(f'FAK: {len(fak_rows)} radku, FAKDET: {len(det_rows)} radku, PORTAL: {len(portal_rows)} radku\n'.encode('utf-8')) diff --git a/MedicusWithClaudeSelects/FakturaceADavky.md b/MedicusWithClaudeSelects/FakturaceADavky.md new file mode 100644 index 0000000..204a49b --- /dev/null +++ b/MedicusWithClaudeSelects/FakturaceADavky.md @@ -0,0 +1,252 @@ +# Fakturace a dávky – poznámky pro Clauda + +## Přehled tabulek + +### FAK – faktury pojišťovnám +- **844 záznamů** (k 2026-03-28) +- Primární klíč: `ID` + +| Sloupec | Popis | +|---|---| +| `ID` | primární klíč | +| `CISFAK` | číslo faktury (10 znaků) | +| `POJ` | pojišťovna (3 znaky, např. 111=VZP, 205=ČPZP, 207=OZP) | +| `ICZ`, `ICZ1` | IČZ ordinace | +| `IDICZ` | FK → ICZ.IDICZ (jen jedna ordinace, neřešit) | +| `PORCISLO` | pořadové číslo | +| `DATUMOD`, `DATUMDO` | období faktury (od–do) | +| `DATVYS` | datum vystavení | +| `DATODE` | datum odeslání | +| `OBDOB` | období (5 znaků, např. "20260") | +| `VYKONY` | částka za výkony (Kč) | +| `KAPITACE` | kapitační platba (Kč) | +| `ZALOHA` | záloha | +| `CENA` | celková cena faktury (Kč) | +| `DRUH` | druh faktury (např. "konečná") | +| `TYP` | typ (1 znak) | +| `ROK` | rok | +| `SPLAT` | datum splatnosti | +| `PROPLACENO` | datum proplacení (NULL = nezaplaceno) | +| `ZAPLACENO` | zaplacená částka | +| `ZUM` | ? | +| `HOSPAUSAL` | hospitalizační/paušální? | +| `FDAVKA` | BLOB – odkaz na dávku | +| `KAPDETAIL`, `AGRDETAIL` | BLOBy – detaily kapitace/agregace | +| `NAZFAK`, `POZFAK`, `OBDFAK` | název, poznámka, období faktury (texty) | +| `ICO`, `BANKA`, `UCET` | IČO, banka, účet | +| `ODJMENO/ULICE/MISTO/PSC` | adresa odesílatele | +| `PLNAZEV/ULICE/MISTO/PSC` | adresa plátce (pojišťovny) | +| `DRUHPOJ` | druh pojištění | + +--- + +### FAKDET – finanční detail faktury +- **1021 záznamů** +- Vazba: `IDFAK` → FAK.ID +- Typicky 1–2 řádky na fakturu (breakdown podle lékaře/IDUZI) + +| Sloupec | Popis | +|---|---| +| `ID` | primární klíč | +| `IDFAK` | FK → FAK.ID | +| `ICP` | IČP ordinace (např. 09305001) | +| `ODB` | odbornost (001 = praktický lékař) | +| `IDUZI` | FK → UZIVATEL.IDUZI – který lékař | +| `CENAVYK` | výkony (Kč) | +| `CENALEC` | léky (Kč) | +| `CENAKAP` | kapitace (Kč) | + +**Poznámka:** IDUZI=0 = systémový záznam (kapitace bez konkrétního lékaře). + +--- + +### FAKDAV – dávky zahrnuté ve faktuře +- **1296 záznamů** +- Vazba: `IDFAK` → FAK.ID + +| Sloupec | Popis | +|---|---| +| `ID` | primární klíč | +| `IDFAK` | FK → FAK.ID | +| `CISDAV` | číslo dávky | +| `DRUH` | druh dávky | +| `CENA` | celková cena dávky | +| `CENAVYK` | výkony | +| `CENALEC` | léky | +| `CENAPAU` | paušál | +| `ODB` | odbornost | +| `ICP` | IČP | + +--- + +### PORTAL – elektronické podání pojišťovně +- **180 záznamů** +- Vazba: `IDFAK` → FAK.ID + +| Sloupec | Popis | +|---|---| +| `ID` | primární klíč | +| `IDFAK` | FK → FAK.ID | +| `ODESLANO` | timestamp odeslání | +| `DATA`, `KDAVKA`, `FDAVKA` | BLOBy – pravděpodobně XML dávky | +| `CHYBA` | příznak chyby (1 znak) | +| `STAV` | stav podání (smallint) | +| `ID_PODANI` | ID podání u pojišťovny (32 znaků, UUID) | +| `IDPODANI` | interní ID podání | +| `IDCERT` | certifikát použitý pro podání | +| `DAVKA_ROK`, `DAVKA_DISK`, `DAVKA_IDICZ` | metadata dávky | +| `BB_DAVKA`, `BB_FAKTURA` | ? | +| `DAVKA_DATUMOD`, `DAVKA_DATUMDO` | období dávky | +| `DAVKA_CASTKA` | částka dávky | + +--- + +## Schéma vazeb + +``` +FAK (faktura) + ├── FAKDET (IDFAK → FAK.ID) – finanční breakdown podle lékaře + ├── FAKDAV (IDFAK → FAK.ID) – seznam dávek ve faktuře + ├── PORTAL (IDFAK → FAK.ID) – viz níže, IDFAK bývá NULL + └── ICZ (IDICZ → ICZ.IDICZ) – ordinace (jen jedna, neřešit) +``` + +--- + +## UZIVATEL – lékaři a uživatelé + +| IDUZI | Příjmení | Jméno | Zkratka | Aktivní | +|---|---|---|---|---| +| 2 | Jourová | Jana | JOU | F (neaktivní) | +| 3 | Sestra | — | SES | F (neaktivní) | +| 4 | Buzalková | Michaela | MBU | T – **lékařka, manželka** | +| 5 | Ševčíková | Ivana | ISE | T | +| 6 | Buzalka | Vladimír | VBU | T – **uživatel (já)** | + +--- + +## Ukázkové záznamy + +### FAK ID=856 (poslední) +- Faktura č. 260026, pojišťovna **205 (ČPZP)**, prosinec 2025 +- Vystavena: 2026-03-12, druh: konečná +- VYKONY: 2 528,99 Kč, KAPITACE: 0, CENA: **2 528,99 Kč** +- ZAPLACENO: NULL, PROPLACENO: NULL + +FAKDET k FAK ID=856: +| ID | IDUZI | CENAVYK | CENALEC | CENAKAP | +|---|---|---|---|---| +| 1034 | 0 (systém) | 0 | 0 | 1 902,54 | +| 1035 | 4 (Buzalková) | 2 528,99 | 0 | 0 | + +### FAK ID=855 (předposlední) +- Faktura č. 260026, pojišťovna **207 (OZP)**, prosinec 2025 +- Vystavena: 2026-03-01, druh: konečná +- VYKONY: 85 Kč, KAPITACE: 0, CENA: **85 Kč** +- ZAPLACENO: NULL, PROPLACENO: NULL + +FAKDET k FAK ID=855: +| ID | IDUZI | CENAVYK | CENALEC | CENAKAP | +|---|---|---|---|---| +| 1033 | 6 (Buzalka Vladimír) | 85 | 0 | 0 | + +--- + +## PORTAL – upřesnění (zjištěno 2026-03-28) + +PORTAL **nesouvisí s fakturací**. Je to samostatná agenda – evidence **registračních dávek** odeslaných pojišťovně. + +### Co PORTAL skutečně je +- Medicus přes PORTAL odesílá pojišťovně dávky s přihlášením/odhlášením pacientů k lékaři (MUDr. Buzalková jako praktický lékař) +- Bez peněz – čistě administrativní agenda registrací +- **IDFAK = NULL** u všech registračních podání (není vazba na fakturu) + +### Klíčové sloupce +| Sloupec | Popis | +|---|---| +| `KDAVKA` | odeslaná dávka – pevný formát (hlavička + řádky I = pacienti, RC, datum) | +| `DATA` | odpověď pojišťovny jako XML (`100` = OK) | +| `ID_PODANI` | ID přidělené pojišťovnou (např. `D01F260118593316.D01`) | +| `DAVKA_DISK` | číslo dávky v roce (sekvenční) | +| `DAVKA_ROK` | rok dávky | +| `DAVKA_DATUMOD/DO` | období registrací v dávce | +| `CHYBA` | F = bez chyby | + +### Ukázka KDAVKA (hlavička dávky) +``` +DP80093050000900202506 15 1 0 0.00180:6.2.46 +H21109305001 179202506001 +I 1Příjmení Jméno RC datum_registrace +I 2... +``` + +### Ukázka DATA (odpověď pojišťovny) +```xml + + + Přijetí registrací proběhlo úspěšně + 100 + D01F260118593316.D01 + + +``` + +--- + +## PORTAL – dva typy dávek + +### Typ 1 – Registrační dávka (DP80) +- KDAVKA začíná `DP80` +- **IDFAK = NULL** – bez vazby na fakturu +- Bez peněz (`DAVKA_CASTKA` = NULL) +- Přihlašuje/odhlašuje pacienty k lékaři (MUDr. Buzalková) +- Řádky `I` = pacient (RC, datum registrace) + +### Typ 2 – Výkonová dávka (DP98) +- KDAVKA začíná `DP98` +- **IDFAK = ID faktury** – napojeno na FAK +- Má peníze (`DAVKA_CASTKA`, např. 15 452,91 Kč) +- `STAV = 10` (registrační mají NULL) +- Obsahuje výkony vykázané pojišťovně za dané období + +**Struktura výkonové dávky (KDAVKA):** +``` +DP98... – hlavička dávky (IČP, rok, měsíc, disk, počet případů, částka) +A ... – ambulantní případ (RC pacienta, diagnóza) +V ... – výkon (datum, kód výkonu, body) +Z ... – ZULP (zvlášť účtovaný léčivý přípravek) +L ... – lékový řádek (kód, množství, cena) +DP05... – druhá část dávky (prevence / jiný typ) +P ... – preventivní prohlídka +``` + +**Odpověď pojišťovny pro výkonovou dávku:** +```xml +Přijetí faktury proběhlo úspěšně +100 +``` + +--- + +## Poznámky +- Faktury jsou vystavovány zvlášť pro každou pojišťovnu +- FAKDET má řádky zvlášť pro každého lékaře (IDUZI) +- IDUZI=0 v FAKDET = systémový záznam pro kapitaci +- Kapitace se v FAK.KAPITACE neukazuje (je 0), ale v FAKDET.CENAKAP ano – nutno ověřit +- PORTAL = registrační dávky, nesouvisí s fakturací, IDFAK bývá NULL + +## Kódování KDAVKA/FDAVKA – důležité! + +Dávkové soubory (KDAVKA, FDAVKA) jsou uloženy v **CP852** (DOS Latin-2, prahistorické kódování). + +fdb je čte přes connection charset win1250 a vrací je jako Python `str` (špatně dekódované). + +**Správný postup dekódování:** +```python +# fdb vrátil string dekódovaný jako win1250 – musíme to zvrátit +raw_bytes = s.encode('cp1250', errors='replace') +spravny_text = raw_bytes.decode('cp852', errors='replace') +``` + +- **KDAVKA, FDAVKA** → cp852 +- **DATA** (XML odpověď pojišťovny) → cp1250 (win1250), fdb dekóduje správně