# -*- coding: utf-8 -*- #!/usr/bin/env python3 import sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') """ Přehled předepsaných ePoukazů na ZP (ORTOPE) Výstup: Přehled_ZP.xlsx se dvěma listy: List 1 "Všechny záznamy" — vše včetně jmen pacientů List 2 "Přehled Medicus" — pouze sloupce z Medicus obrazovky """ import sys sys.path.insert(0, r'U:\OrdinaceProjekt') from Knihovny.najdi_dropbox import get_dropbox_root from Knihovny.medicus_db import get_medicus_connection import openpyxl from openpyxl.styles import Font, PatternFill, Alignment from datetime import datetime, date import os # --- Připojení --- conn = get_medicus_connection() # --- Parsování DATA blobu --- def parse_data(data_text): """Parsuje key=value formát z HISTDOC.DATA""" result = {} if not data_text: return result for line in data_text.replace('\r\n', '\n').replace('\r', '\n').split('\n'): line = line.strip() if '=' not in line: continue key, _, value = line.partition('=') key = key.strip() value = value.strip() if value.startswith('C:'): try: result[key] = float(value[2:].replace(',', '.')) except Exception: result[key] = value[2:] elif value.startswith('I:'): try: result[key] = int(value[2:]) except Exception: result[key] = value[2:] elif value.startswith('D:'): result[key] = value[2:] # DD.MM.YYYY řetězec elif value in ('$:~\b', '$:~\x08', '$:'): result[key] = '' else: result[key] = value return result # --- Načtení dat --- print("Načítám záznamy ORTOPE...") cur = conn.cursor() cur.execute(""" SELECT h.ID, h.DATUM, h.STAV, CAST(h.DATA AS VARCHAR(8000)) AS DATA_TEXT, k.RODCIS, k.PRIJMENI, k.JMENO AS JMENO_PAC, k.POJ AS POJ_KAR, u.TITUL, u.PRIJMENI AS PRIJMENI_LEK, u.JMENO AS JMENO_LEK, e.ID_DOKLADU, e.ID_ZP, e.ODESLANO, e.CHYBA, e.VYDANO FROM HISTDOC h LEFT JOIN KAR k ON h.IDPACI = k.IDPAC LEFT JOIN UZIVATEL u ON h.IDUZIV = u.IDUZI LEFT JOIN HISTDOC_EPOUKAZ e ON e.IDHISTDOC = h.ID WHERE h.TYP = 'ORTOPE' ORDER BY h.DATUM, h.ID """) rows = cur.fetchall() print(f"Načteno {len(rows)} záznamů.") # --- Sestavení řádků --- records = [] for row in rows: (hid, datum, stav, data_text, rodcis, prijmeni_pac, jmeno_pac, poj_kar, titul_lek, prijmeni_lek, jmeno_lek, id_dokladu, id_zp, odeslano, chyba, vydano) = row d = parse_data(data_text) # Pojišťovna — z DATA (POJ=I:111) nebo z KAR poj_raw = d.get('POJ', '') if isinstance(poj_raw, int): poj = str(poj_raw) else: poj = str(poj_raw).replace('I:', '').strip() if poj_raw else (str(poj_kar) if poj_kar else '') vystavil = ' '.join(filter(None, [titul_lek, prijmeni_lek, jmeno_lek])) # Datum jako date objekt pro Excel datum_val = datum if isinstance(datum, (datetime, date)) else datum # Pocet — z DATA pocet_raw = d.get('Pocet', '') try: pocet = float(pocet_raw) if pocet_raw != '' else None except Exception: pocet = pocet_raw # Cena — z DATA (přesnější než HISTDOC.CENA) cena_raw = d.get('Cena', '') try: cena = float(cena_raw) if cena_raw != '' else None except Exception: cena = cena_raw records.append({ 'ID': hid, 'Datum': datum_val, 'Kód': d.get('Kod', ''), 'Název': d.get('Nazev', ''), 'Počet': pocet, 'Cena': cena, 'Pojišťovna': poj, 'IČZ': d.get('ICZ', '09305000'), 'Rodné číslo': rodcis or '', 'Příjmení': prijmeni_pac or '', 'Jméno': jmeno_pac or '', 'Vystavil': vystavil, 'Doklad': id_dokladu or '', 'ID ZP': id_zp or '', 'Odesláno': odeslano, 'Vydáno': vydano, 'Chyba': 'Ano' if chyba == 'T' else '', 'Diagnóza': d.get('Dgn', ''), 'Platnost do': d.get('DatPlat', ''), 'Stav': d.get('Stav', stav or ''), 'Doplněk': d.get('DoplnekNazvu', ''), 'Dopl. cena': d.get('Dopl', ''), 'UHS': d.get('UHS', ''), 'Notifikace': str(d.get('Notifikace', '')), }) # --- Excel --- wb = openpyxl.Workbook() # Styl záhlaví HEADER_FILL = PatternFill("solid", fgColor="1F4E79") HEADER_FONT = Font(bold=True, color="FFFFFF") HEADER_ALIGN = Alignment(horizontal="center", vertical="center", wrap_text=True) def write_sheet(ws, headers, data_rows): """Zapíše záhlaví a data na list.""" ws.append(headers) # Styl záhlaví for cell in ws[1]: cell.fill = HEADER_FILL cell.font = HEADER_FONT cell.alignment = HEADER_ALIGN ws.row_dimensions[1].height = 30 for rec in data_rows: row = [rec.get(h, '') for h in headers] ws.append(row) # Formát sloupce Datum date_cols = [i+1 for i, h in enumerate(headers) if 'Datum' in h or 'datum' in h] for col_idx in date_cols: for row_idx in range(2, ws.max_row + 1): cell = ws.cell(row=row_idx, column=col_idx) if isinstance(cell.value, (datetime, date)): cell.number_format = 'DD.MM.YYYY' # Formát Cena / Počet num_cols = [i+1 for i, h in enumerate(headers) if h in ('Cena', 'Počet', 'Dopl. cena')] for col_idx in num_cols: for row_idx in range(2, ws.max_row + 1): cell = ws.cell(row=row_idx, column=col_idx) if isinstance(cell.value, float): cell.number_format = '#,##0.00' # Šířky sloupců for col in ws.columns: max_len = max((len(str(c.value or '')) for c in col), default=10) ws.column_dimensions[col[0].column_letter].width = min(max_len + 2, 40) # --- List 1: Všechny záznamy --- ws1 = wb.active ws1.title = "Všechny záznamy" headers1 = [ 'Datum', 'Kód', 'Název', 'Doplněk', 'Počet', 'Cena', 'Dopl. cena', 'Pojišťovna', 'IČZ', 'Rodné číslo', 'Příjmení', 'Jméno', 'Diagnóza', 'Platnost do', 'Stav', 'Vystavil', 'Doklad', 'Odesláno', 'Vydáno', 'Chyba', 'ID ZP', 'UHS', 'Notifikace', 'ID' ] write_sheet(ws1, headers1, records) # --- List 2: Přehled Medicus (sloupce jako na obrazovce) --- ws2 = wb.create_sheet("Přehled Medicus") headers2 = [ 'Datum', 'Kód', 'Název', 'Počet', 'Cena', 'Pojišťovna', 'IČZ', 'Rodné číslo', 'Příjmení', 'Jméno', 'Vystavil', 'Doklad' ] write_sheet(ws2, headers2, records) # Zmraž záhlaví na obou listech for ws in [ws1, ws2]: ws.freeze_panes = ws['A2'] # --- Uložení --- DROPBOX_ROOT = get_dropbox_root() OUTPUT_DIR = os.path.join(DROPBOX_ROOT, '!!!Days', 'Downloads Z230') os.makedirs(OUTPUT_DIR, exist_ok=True) output_path = os.path.join(OUTPUT_DIR, 'Přehled_ZP.xlsx') wb.save(output_path) print(f"Uloženo: {output_path}") print(f"Celkem záznamů: {len(records)}") conn.close()