228 lines
7.2 KiB
Python
228 lines
7.2 KiB
Python
# -*- 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()
|