238 lines
6.6 KiB
Python
238 lines
6.6 KiB
Python
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') + '_Přehled posudků řidičák.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('_Přehled posudků řidičák.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')
|
||
ZEBRA_FILL = PatternFill('solid', fgColor='DCE6F1')
|
||
GREEN_FILL = PatternFill('solid', fgColor='C6EFCE')
|
||
GREEN_FONT = Font(bold=True, color='276221')
|
||
|
||
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, 50)
|
||
|
||
def fmt(val):
|
||
if val is None:
|
||
return ''
|
||
return val
|
||
|
||
def parse_data(data_str):
|
||
"""Parsuje key=value text z HISTDOC.DATA do slovníku."""
|
||
result = {}
|
||
if not data_str:
|
||
return result
|
||
for line in data_str.splitlines():
|
||
if '=' in line:
|
||
key, _, val = line.partition('=')
|
||
result[key.strip()] = val.strip()
|
||
return result
|
||
|
||
def parse_date(val):
|
||
"""Převede 'D:DD.MM.YYYY' na datetime.date, nebo vrátí původní hodnotu."""
|
||
if val and val.startswith('D:'):
|
||
try:
|
||
return datetime.strptime(val[2:], '%d.%m.%Y').date()
|
||
except ValueError:
|
||
return val
|
||
return val
|
||
|
||
# =====================
|
||
# List 1 – MOTORVO (ruční posudky k řízení)
|
||
# =====================
|
||
|
||
ws1 = wb.active
|
||
ws1.title = 'MOTORVO'
|
||
|
||
# Množina (IDPACI, DATUM) kde existuje EPOSMRO
|
||
cur.execute("""
|
||
SELECT IDPACI, DATUM FROM HISTDOC WHERE TYP = 'EPOSMRO'
|
||
""")
|
||
eposmro_keys = set((r[0], r[1]) for r in cur.fetchall())
|
||
|
||
cur.execute("""
|
||
SELECT h.ID, h.DATUM, h.IDPACI,
|
||
k.PRIJMENI, k.JMENO, k.RODCIS,
|
||
h.DATA, h.PORCISLO, h.STAV, h.PRINTED, h.IDUZIV, h.CREATED
|
||
FROM HISTDOC h
|
||
JOIN KAR k ON k.IDPAC = h.IDPACI
|
||
WHERE h.TYP = 'MOTORVO'
|
||
ORDER BY h.ID DESC
|
||
""")
|
||
raw_rows = cur.fetchall()
|
||
|
||
headers = [
|
||
'ID', 'DATUM', 'IDPACI', 'PRIJMENI', 'JMENO', 'RODCIS',
|
||
'PorCislo', 'DatumVyd', 'DatKonec', 'DruhProh',
|
||
'Posouzeni', 'ZpusobPodminka', 'SkupinaPodminka',
|
||
'Skupiny',
|
||
'ePosudek',
|
||
'STAV', 'PRINTED', 'IDUZIV', 'CREATED'
|
||
]
|
||
ws1.append(headers)
|
||
|
||
for i, row in enumerate(raw_rows, start=2):
|
||
(hid, datum, idpac, prijmeni, jmeno, rodcis,
|
||
data_blob, porcislo, stav, printed, iduziv, created) = row
|
||
|
||
data = parse_data(data_blob)
|
||
|
||
posouzeni = ''
|
||
if data.get('Posouzeni') == 'T':
|
||
if data.get('Posouzeni2') == 'T':
|
||
posouzeni = 'nezpůsobilý'
|
||
elif data.get('ZpusobPodminka') == 'B:1':
|
||
posouzeni = 'způsobilý s podmínkou'
|
||
else:
|
||
posouzeni = 'způsobilý'
|
||
|
||
skupiny = data.get('SkupinyRidicskehoOpravneniSeznam', '')
|
||
if not skupiny:
|
||
# MOTORVO nemá SkupinyRidicskehoOpravneniSeznam, zkusíme ZpusobJe
|
||
skupiny = data.get('ZpusobJe', '')
|
||
|
||
ws1.append([
|
||
hid,
|
||
fmt(datum),
|
||
idpac,
|
||
fmt(prijmeni),
|
||
fmt(jmeno),
|
||
fmt(rodcis),
|
||
fmt(porcislo or data.get('PorCislo', '')),
|
||
parse_date(data.get('DatumVyd', '')),
|
||
parse_date(data.get('DatKonec', '')),
|
||
fmt(data.get('DruhProh', '')),
|
||
posouzeni,
|
||
fmt(data.get('ZpusobPodminka', '')),
|
||
fmt(data.get('SkupinaPodminka', '')),
|
||
fmt(skupiny),
|
||
'ANO' if (idpac, datum) in eposmro_keys else 'NE',
|
||
fmt(stav),
|
||
fmt(printed),
|
||
fmt(iduziv),
|
||
fmt(created),
|
||
])
|
||
|
||
if i % 2 == 0:
|
||
for cell in ws1[i]:
|
||
cell.fill = ZEBRA_FILL
|
||
|
||
# Sloupec ePosudek – zvýraznit ANO zeleně
|
||
epos_col = headers.index('ePosudek') + 1
|
||
cell = ws1.cell(row=i, column=epos_col)
|
||
if cell.value == 'ANO':
|
||
cell.fill = GREEN_FILL
|
||
cell.font = GREEN_FONT
|
||
|
||
style_header(ws1)
|
||
ws1.freeze_panes = 'A2'
|
||
autofit(ws1)
|
||
|
||
# =====================
|
||
# List 2 – EPOSMRO (elektronická podání do registru)
|
||
# =====================
|
||
|
||
ws2 = wb.create_sheet('EPOSMRO')
|
||
|
||
cur.execute("""
|
||
SELECT h.ID, h.DATUM, h.IDPACI,
|
||
k.PRIJMENI, k.JMENO, k.RODCIS,
|
||
h.DATA, h.STAV, h.CREATED,
|
||
e.ID_PODANI, e.ODESLANO, e.STATUS
|
||
FROM HISTDOC h
|
||
JOIN KAR k ON k.IDPAC = h.IDPACI
|
||
LEFT JOIN HISTDOC_EPOSUDEK e ON e.ID_HISTDOC = h.ID
|
||
WHERE h.TYP = 'EPOSMRO'
|
||
ORDER BY h.ID DESC
|
||
""")
|
||
epos_rows = cur.fetchall()
|
||
|
||
headers2 = [
|
||
'ID', 'DATUM', 'IDPACI', 'PRIJMENI', 'JMENO', 'RODCIS',
|
||
'DatumVyd', 'DatKonec', 'DruhProhlidky', 'DruhPosudku',
|
||
'Vysledek', 'StavPosudku', 'TypAkce',
|
||
'STAV', 'CREATED',
|
||
'ID_PODANI', 'ODESLANO', 'STATUS_ODESL'
|
||
]
|
||
ws2.append(headers2)
|
||
|
||
for i, row in enumerate(epos_rows, start=2):
|
||
(hid, datum, idpac, prijmeni, jmeno, rodcis,
|
||
data_blob, stav, created,
|
||
id_podani, odeslano, status_odesl) = row
|
||
|
||
data = parse_data(data_blob)
|
||
|
||
ws2.append([
|
||
hid,
|
||
fmt(datum),
|
||
idpac,
|
||
fmt(prijmeni),
|
||
fmt(jmeno),
|
||
fmt(rodcis),
|
||
parse_date(data.get('DatumVystaveni', '')),
|
||
parse_date(data.get('PlatnostDo', '')),
|
||
fmt(data.get('DruhProhlidkyNazev', '')),
|
||
fmt(data.get('DruhPosudkuNazev', '')),
|
||
fmt(data.get('VysledekNazev', '')),
|
||
fmt(data.get('StavPosudkuNazev', '')),
|
||
fmt(data.get('TypAkceNazev', '')),
|
||
fmt(stav),
|
||
fmt(created),
|
||
fmt(id_podani),
|
||
fmt(odeslano),
|
||
fmt(status_odesl),
|
||
])
|
||
|
||
if i % 2 == 0:
|
||
for cell in ws2[i]:
|
||
cell.fill = ZEBRA_FILL
|
||
|
||
style_header(ws2)
|
||
ws2.freeze_panes = 'A2'
|
||
autofit(ws2)
|
||
|
||
# =====================
|
||
# 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'MOTORVO: {len(raw_rows)} radku, EPOSMRO: {len(epos_rows)} radku\n'.encode('utf-8'))
|