Files
Vladimir Buzalka a9ef60212d notebookvb
2026-05-31 07:51:29 +02:00

596 lines
27 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
poukaz_dp_gen.py
Generátor Poukazu na vyšetření/ošetření DP (VZP-06dp/2024).
Formulář je kreslen od nuly pomocí reportlab žádné překrývání PDF šablony.
Závislosti:
pip install reportlab
"""
from pathlib import Path
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# ── Registrace fontu s českou podporou ────────────────────────────────────────
def _reg_font():
candidates = [
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
"C:/Windows/Fonts/arial.ttf",
"C:/Windows/Fonts/arialbd.ttf",
]
reg, reg_bold = False, False
for p in candidates:
if Path(p).exists():
if not reg and "Bold" not in p and "bd" not in p:
pdfmetrics.registerFont(TTFont("Czech", p))
reg = True
elif not reg_bold and ("Bold" in p or "bd" in p):
pdfmetrics.registerFont(TTFont("Czech-Bold", p))
reg_bold = True
if not reg:
# fallback Helvetica (funguje pro základní znaky)
return "Helvetica", "Helvetica-Bold"
if not reg_bold:
return "Czech", "Czech"
return "Czech", "Czech-Bold"
FONT, FONT_BOLD = _reg_font()
# ═══════════════════════════════════════════════════════════════════════════════
# DATA FORMULÁŘE sem doplňte hodnoty z Medicusu
# ═══════════════════════════════════════════════════════════════════════════════
DATA = {
# ── Hlavička ──────────────────────────────────────────────────────────────
"kod_pojistovny": "111", # 3 číslice, VZP = 111
"icp": "12345678", # IČP pracoviště (max 8 číslic)
"odbornost": "001", # odbornost (3 číslice)
"datum": "22.05.2026", # datum vystavení
"poradove_cislo": "42", # pořadové číslo / nepřerušené DP
"platnost_do": "22.08.2026", # platnost poukazu
# ── Pacient ───────────────────────────────────────────────────────────────
"pacient": "Novák Jan",
"cislo_pojistence": "7001015432", # rodné číslo / č. pojištěnce
"zkladni_dg": "I10", # MKN kód základní diagnózy
"variabilni_symbol": "123456",
"ost_dg": "E11", # ostatní diagnózy
"kod_nahrady": "",
# ── Adresa a kontakty ─────────────────────────────────────────────────────
"adresa_pacienta": "Dlouhá 12, 110 00 Praha 1, tel: 777 123 456",
"dalsi_prislusnici": "ne", # "ano" / "ne"
"kontaktni_osoba": "Nováková Marie (manželka), tel: 777 654 321",
# ── Klinické údaje ────────────────────────────────────────────────────────
"pecovatelska_sluzba": "ne", # "ano" / "ne"
"mobilita": "b", # "a" = plná / "b" = omezená
"mobilita_detail": "chodí s holí",
"smyslove_omezeni": "zraková vada brýle",
"sebeobsluha": "b", # "a" = plná / "b" = omezená
"sebeobsluha_detail": "potřebuje pomoc při hygieně",
# Každá položka = jeden řádek (max 3)
"medikace": [
"Metformin 1000 mg 1-0-1, Amlodipine 5 mg 1-0-0",
"Inzulín Lantus 20j večer",
],
"dalsi_informace": [
"alergie: penicilin; inkontinence moči",
"byt 2. patro bez výtahu",
],
"cil_dp": [
"Edukace v aplikaci inzulínu, kontrola glykémie, péče o DM nohu",
],
# ── Požadované výkony (max 5) ─────────────────────────────────────────────
# kod … kód výkonu (max 5 číslic)
# popis … text na prvním řádku
# popis2 … pokračování na druhém řádku (nepovinné)
"pozadovano": [
{"kod": "06101", "popis": "Komplexní ošetřovatelská péče 1× denně, 5× týdně", "popis2": ""},
{"kod": "06129", "popis": "Aplikace inzulínu 1× denně, 7× týdně", "popis2": ""},
{"kod": "06111", "popis": "Odběr biologického materiálu 1× týdně", "popis2": ""},
{"kod": "", "popis": "", "popis2": ""},
{"kod": "", "popis": "", "popis2": ""},
],
}
# ═══════════════════════════════════════════════════════════════════════════════
# GEOMETRIE (souřadnice od SHORA, konverze na RL přes yt())
# ═══════════════════════════════════════════════════════════════════════════════
PAGE_W, PAGE_H = A4 # 595 × 842 pt
# Vnější zaoblený rámeček
FX1, FX2 = 28, 567 # levý / pravý okraj
FB, FT = 52, 818 # spodní / horní okraj (RL souřadnice od zdola)
IL = FX1 + 7 # inner left (odsazení textu od okraje)
IR = FX2 - 7 # inner right
def yt(from_top: float) -> float:
"""Převede y-od-shora (pt) na reportlab y-od-zdola."""
return PAGE_H - from_top
# ═══════════════════════════════════════════════════════════════════════════════
# POMOCNÉ FUNKCE
# ═══════════════════════════════════════════════════════════════════════════════
def txt(c, x, y_rl, text, size=7.5, bold=False, align="left"):
if not text:
return
c.setFont(FONT_BOLD if bold else FONT, size)
if align == "right":
c.drawRightString(x, y_rl, str(text))
elif align == "center":
c.drawCentredString(x, y_rl, str(text))
else:
c.drawString(x, y_rl, str(text))
def hline(c, x1, y_rl, x2=None, w=0.5):
if x2 is None:
x2 = IR
c.setLineWidth(w)
c.setDash([])
c.line(x1, y_rl, x2, y_rl)
def vline(c, x, y1_rl, y2_rl, w=0.5):
c.setLineWidth(w)
c.setDash([])
c.line(x, y1_rl, x, y2_rl)
def dotline(c, x1, y_rl, x2=None):
if x2 is None:
x2 = IR
c.setLineWidth(0.35)
c.setDash([1.5, 2.5])
c.line(x1, y_rl, x2, y_rl)
c.setDash([])
def chkbox(c, x, y_rl, checked: bool, size=7):
"""Zaškrtávací políčko."""
c.setLineWidth(0.6)
c.setDash([])
c.rect(x, y_rl - 1, size, size, stroke=1, fill=0)
if checked:
c.setFont(FONT_BOLD, size - 0.5)
c.drawString(x + 1, y_rl, "")
def digit_box(c, x, y_rl, width, height, digits, value_text=""):
"""Prostý rámeček pro zadávání hodnot (bez vnitřních oddělovačů)."""
c.setLineWidth(0.7)
c.setDash([])
c.rect(x, y_rl, width, height, stroke=1, fill=0)
if value_text:
c.setFont(FONT, height * 0.65)
c.drawString(x + 3, y_rl + height * 0.2, value_text[:digits])
def wrap(text: str, max_chars: int) -> list[str]:
"""Rozlomí text na řádky po max_chars znacích (na hranici slova)."""
if not text:
return [""]
words = text.split()
lines, cur = [], ""
for w in words:
if cur and len(cur) + 1 + len(w) > max_chars:
lines.append(cur)
cur = w
else:
cur = (cur + " " + w).strip()
if cur:
lines.append(cur)
return lines or [""]
# ═══════════════════════════════════════════════════════════════════════════════
# SEKCE 1: HLAVIČKA
# ═══════════════════════════════════════════════════════════════════════════════
#
# ┌─────────────────┬──────────┬──────────────────────┬──────────────────────┐
# │ Kód pojišťovny │ požaduje │ IČP [________] Datum [________] │ Pořadové číslo…
# │ [___] │ díl A │ Odbornost [___] │ nepřerušené DP:
# └─────────────────┴──────────┴──────────────────────┴──────────────────────┘
# Platnost do:
HDR_TOP = 25 # horní okraj formuláře (od shora)
HDR_MID = 50 # vodorovná čára mezi řádky hlavičky
HDR_BOT = 73 # dolní okraj hlavičky
# Svislé dělicí čáry v hlavičce
HX1 = 130 # po Kód pojišťovny
HX2 = 198 # po požaduje díl A
HX3 = 295 # mezi IČP a Datum
HX4 = 388 # konec IČP+Datum sekce (začátek Pořadové číslo)
def draw_hlavicka(c, d):
# Vnější rámeček hlavičky
hline(c, FX1, yt(HDR_BOT), FX2, w=1.2)
hline(c, FX1, yt(HDR_MID), HX4, w=0.5)
# Svislé čáry
for x in (HX1, HX2, HX4):
vline(c, x, yt(HDR_TOP), yt(HDR_BOT), w=0.8)
vline(c, HX3, yt(HDR_TOP), yt(HDR_MID), w=0.5)
# Kód pojišťovny
txt(c, IL, yt(HDR_TOP + 7), "Kód pojišťovny", size=6.5)
digit_box(c, IL, yt(HDR_MID - 5), 40, 12, 3, d.get("kod_pojistovny", ""))
# požaduje díl A
cx = (HX1 + HX2) / 2
txt(c, cx, yt(HDR_TOP + 12), "požaduje", size=7, bold=True, align="center")
txt(c, cx, yt(HDR_TOP + 21), "díl A", size=7, bold=True, align="center")
# IČP
txt(c, HX2 + 3, yt(HDR_TOP + 7), "IČP", size=6.5)
digit_box(c, HX2 + 22, yt(HDR_MID - 5), HX3 - HX2 - 27, 12, 8, d.get("icp", ""))
# Datum
txt(c, HX3 + 3, yt(HDR_TOP + 7), "Datum", size=6.5)
digit_box(c, HX3 + 28, yt(HDR_MID - 5), HX4 - HX3 - 32, 12, 10, d.get("datum", ""))
# Odbornost
txt(c, HX2 + 3, yt(HDR_MID + 7), "Odbornost", size=6.5)
digit_box(c, HX2 + 48, yt(HDR_BOT - 5), HX3 - HX2 - 52, 12, 3, d.get("odbornost", ""))
# Pořadové číslo (pravý sloupec)
txt(c, HX4 + 4, yt(HDR_TOP + 21), "Pořadové číslo poukazu", size=6.5)
txt(c, HX4 + 4, yt(HDR_TOP + 30), "nepřerušené DP:", size=6.5)
txt(c, HX4 + 80, yt(HDR_TOP + 36), d.get("poradove_cislo", ""), size=8)
# Platnost do
txt(c, HX4 + 4, yt(HDR_MID + 19), "Platnost do:", size=6.5)
hline(c, HX4 + 50, yt(HDR_MID + 13), FX2 - 4, w=0.4)
txt(c, HX4 + 54, yt(HDR_MID + 25), d.get("platnost_do", ""), size=8)
# ═══════════════════════════════════════════════════════════════════════════════
# SEKCE 2: NADPIS
# ═══════════════════════════════════════════════════════════════════════════════
TTL_TOP = HDR_BOT # 73
TTL_BOT = TTL_TOP + 22 # 95
def draw_nadpis(c):
hline(c, FX1, yt(TTL_BOT), FX2, w=0.8)
# "POUKAZ NA VYŠETŘENÍ / OŠETŘENÍ"
c.setFont(FONT_BOLD, 12)
c.drawCentredString(270, yt(TTL_TOP + 15), "POUKAZ NA VYŠETŘENÍ / OŠETŘENÍ")
# "DP" velké
c.setFont(FONT_BOLD, 22)
c.drawString(390, yt(TTL_TOP + 18), "DP")
# ═══════════════════════════════════════════════════════════════════════════════
# SEKCE 3: BLOK PACIENTA
# ═══════════════════════════════════════════════════════════════════════════════
PAC_TOP = TTL_BOT # 95
PAC_ROW = 19 # výška každého řádku
PAC_BOT = PAC_TOP + 4 * PAC_ROW # 171
# Svislé dělicí čáry v bloku pacienta
PX1 = 340 # Č. pojištěnce / Základní diagnóza
PX2 = 340 # (sdílí s PX1 pro 2. a 3. řádek)
PX3 = 410 # Ost. dg. / Kód náhrady
# Šířka bloku pacienta (bez pravého sloupce s razítkem)
PAC_RIGHT = 540 # pravý okraj tabulky pacienta
def draw_pacient(c, d):
# Vnější pravý okraj tabulky pacienta
vline(c, PAC_RIGHT, yt(PAC_TOP), yt(PAC_BOT), w=1.0)
# Řádek 1: Pacient
y1 = yt(PAC_TOP + PAC_ROW)
hline(c, FX1, y1, PAC_RIGHT, w=0.6)
txt(c, IL, y1 + 5, "Pacient", size=7)
txt(c, IL + 50, y1 + 5, d.get("pacient", ""), size=8.5)
# Řádek 2: Č. pojištěnce | Základní diagnóza
y2 = yt(PAC_TOP + 2 * PAC_ROW)
hline(c, FX1, y2, PAC_RIGHT, w=0.6)
vline(c, PX1, yt(PAC_TOP + PAC_ROW), y2, w=0.5)
txt(c, IL, y2 + 5, "Č. pojištěnce", size=7)
digit_box(c, IL + 68, y2 + 3, 130, 13, 10, d.get("cislo_pojistence", ""))
txt(c, PX1 + 4, y2 + 5, "Základní diagnóza", size=7)
digit_box(c, PX1 + 86, y2 + 3, 65, 13, 5, d.get("zkladni_dg", ""))
# Řádek 3: Variabilní symbol | Ost. dg. | Kód náhrady
y3 = yt(PAC_TOP + 3 * PAC_ROW)
hline(c, FX1, y3, PAC_RIGHT, w=0.6)
vline(c, PX2, yt(PAC_TOP + 2 * PAC_ROW), y3, w=0.5)
vline(c, PX3, yt(PAC_TOP + 2 * PAC_ROW), y3, w=0.5)
txt(c, IL, y3 + 5, "Variabilní symbol", size=7)
digit_box(c, IL + 83, y3 + 3, 100, 13, 8, d.get("variabilni_symbol", ""))
txt(c, PX2 + 4, y3 + 5, "Ost. dg.", size=7)
digit_box(c, PX2 + 38, y3 + 3, 60, 13, 5, d.get("ost_dg", ""))
txt(c, PX3 + 4, y3 + 5, "Kód náhrady", size=7)
digit_box(c, PX3 + 54, y3 + 3, 50, 13, 4, d.get("kod_nahrady", ""))
# Řádek 4: Ad zařízení domácí péče + razítko
y4 = yt(PAC_BOT)
hline(c, FX1, y4, PAC_RIGHT, w=0.6)
txt(c, IL, y4 + 5, "Ad zařízení domácí péče:", size=7, bold=True)
# razítko a podpis (pravý sloupec, malé kurzívní)
c.setFont(FONT, 6)
c.drawRightString(FX2 - 4, y4 + 4, "razítko a podpis požadujícího")
hline(c, PAC_RIGHT + 5, y4 + 2, FX2 - 4, w=0.4)
# ═══════════════════════════════════════════════════════════════════════════════
# SEKCE 4: TEXTOVÁ POLE
# ═══════════════════════════════════════════════════════════════════════════════
def draw_textova_pole(c, d) -> float:
"""Vrací cur_top (od shora) po posledním poli."""
top = PAC_BOT + 6 # 177 od shora
LBL = 7.5 # velikost fontu popisků
VAL = 8.0 # velikost fontu hodnot
GAP = 6 # mezera mezi sekcemi
def label_and_value(label_text, value_text, label_width, max_chars=70):
nonlocal top
top += GAP
y_rl = yt(top + 9)
txt(c, IL, y_rl, label_text, size=LBL)
txt(c, IL + label_width, y_rl, value_text[:max_chars] if value_text else "", size=VAL)
dotline(c, IL + label_width, y_rl - 2)
top += 16
def extra_dotline(value_text="", indent=0):
nonlocal top
top += 13
y_rl = yt(top)
dotline(c, IL + indent, y_rl)
if value_text:
txt(c, IL + indent, y_rl + 3, value_text[:80], size=VAL)
def checkbox_row(label_text, field_name, label_width=None):
nonlocal top
top += GAP
y_rl = yt(top + 9)
txt(c, IL, y_rl, label_text, size=LBL)
lw = label_width or (len(label_text) * 4.2)
cx = IL + lw + 5
val = d.get(field_name, "ne").lower()
chkbox(c, cx, y_rl, checked=(val == "ano"), size=7)
txt(c, cx + 9, y_rl, "ano", size=LBL)
chkbox(c, cx + 34, y_rl, checked=(val == "ne"), size=7)
txt(c, cx + 43, y_rl, "ne", size=LBL)
top += 16
# ── Adresa pacienta ───────────────────────────────────────────────────────
adresa_lines = wrap(d.get("adresa_pacienta", ""), 75)
label_and_value("Adresa pacienta (místo poskytování DP) a telefon:", adresa_lines[0], 260)
extra_dotline(adresa_lines[1] if len(adresa_lines) > 1 else "")
# ── Příslušníci domácnosti ────────────────────────────────────────────────
checkbox_row("Další příslušníci domácnosti na této adrese:", "dalsi_prislusnici", label_width=242)
# ── Kontaktní osoba ───────────────────────────────────────────────────────
kont_lines = wrap(d.get("kontaktni_osoba", ""), 55)
label_and_value(
"Kontaktní osoba pro DP (jméno, vztah k pacientovi, adresa a telefon je-li rozdílná od adresy pacienta):",
kont_lines[0], 432, max_chars=55
)
extra_dotline(kont_lines[1] if len(kont_lines) > 1 else "")
# ── Pečovatelská služba ───────────────────────────────────────────────────
checkbox_row("Pacient v péči pečovatelské služby:", "pecovatelska_sluzba", label_width=186)
# ── Mobilita ──────────────────────────────────────────────────────────────
top += GAP
y_mob = yt(top + 9)
txt(c, IL, y_mob, "Mobilita pacienta:", size=LBL)
mob = d.get("mobilita", "a").lower()
chkbox(c, IL + 98, y_mob, checked=(mob == "a"), size=7)
txt(c, IL + 107, y_mob, "a) plná", size=LBL)
top += 16
top += 2
y_mob2 = yt(top + 9)
chkbox(c, IL + 98, y_mob2, checked=(mob == "b"), size=7)
txt(c, IL + 107, y_mob2, "b) omezená:", size=LBL)
mob_detail = d.get("mobilita_detail", "") if mob == "b" else ""
txt(c, IL + 167, y_mob2, mob_detail[:60], size=VAL)
dotline(c, IL + 163, y_mob2 - 2)
top += 16
# ── Smyslové omezení ──────────────────────────────────────────────────────
label_and_value("Smyslové omezení:", d.get("smyslove_omezeni", ""), 95)
# ── Sebeobsluha ───────────────────────────────────────────────────────────
top += GAP
y_sebe = yt(top + 9)
txt(c, IL, y_sebe, "Schopnost základní sebeobsluhy, včetně dodržování léčebného režimu:", size=LBL)
sebe = d.get("sebeobsluha", "a").lower()
chkbox(c, IL + 374, y_sebe, checked=(sebe == "a"), size=7)
txt(c, IL + 383, y_sebe, "a) plná", size=LBL)
top += 16
top += 2
y_sebe2 = yt(top + 9)
chkbox(c, IL + 98, y_sebe2, checked=(sebe == "b"), size=7)
txt(c, IL + 107, y_sebe2, "b) omezená:", size=LBL)
sebe_detail = d.get("sebeobsluha_detail", "") if sebe == "b" else ""
txt(c, IL + 167, y_sebe2, sebe_detail[:60], size=VAL)
dotline(c, IL + 163, y_sebe2 - 2)
top += 16
# ── Medikace ──────────────────────────────────────────────────────────────
med = d.get("medikace", [])
if isinstance(med, str):
med = [med]
med_lines = []
for item in med:
med_lines.extend(wrap(item, 80))
top += GAP
y_med = yt(top + 9)
txt(c, IL, y_med, "Významné údaje o současné medikaci, včetně aplikace inzulínu a diety:", size=LBL)
txt(c, IL + 357, y_med, med_lines[0][:35] if med_lines else "", size=VAL)
dotline(c, IL + 353, y_med - 2)
top += 16
extra_dotline(med_lines[1] if len(med_lines) > 1 else "")
extra_dotline(med_lines[2] if len(med_lines) > 2 else "")
top += 3
# ── Další informace ───────────────────────────────────────────────────────
info = d.get("dalsi_informace", [])
if isinstance(info, str):
info = [info]
info_lines = []
for item in info:
info_lines.extend(wrap(item, 80))
top += GAP
y_info = yt(top + 9)
txt(c, IL, y_info, "Další informace (alergie, kontinence, údaje o bydlišti atd.):", size=LBL)
txt(c, IL + 315, y_info, info_lines[0][:40] if info_lines else "", size=VAL)
dotline(c, IL + 311, y_info - 2)
top += 16
extra_dotline(info_lines[1] if len(info_lines) > 1 else "")
extra_dotline(info_lines[2] if len(info_lines) > 2 else "")
top += 3
# ── Cíl DP ────────────────────────────────────────────────────────────────
cil = d.get("cil_dp", [])
if isinstance(cil, str):
cil = [cil]
cil_lines = []
for item in cil:
cil_lines.extend(wrap(item, 80))
top += GAP
y_cil = yt(top + 9)
txt(c, IL, y_cil, "Cíl předepsané DP, kterého má být dosaženo:", size=LBL)
txt(c, IL + 236, y_cil, cil_lines[0][:50] if cil_lines else "", size=VAL)
dotline(c, IL + 232, y_cil - 2)
top += 16
extra_dotline(cil_lines[1] if len(cil_lines) > 1 else "")
top += 5
return top
# ═══════════════════════════════════════════════════════════════════════════════
# SEKCE 5: POŽADOVÁNO
# ═══════════════════════════════════════════════════════════════════════════════
def draw_pozadovano(c, d, start_top: float):
top = start_top + 5
# Nadpis
top += 8
y_hdr = yt(top + 9)
txt(c, IL, y_hdr, "Požadováno:", size=8, bold=True)
txt(c, IL + 68, y_hdr,
"(Pro úhradu požadované péče zdravotní pojišťovnou je nezbytná jednoznačná specifikace požadavku,",
size=6.5)
top += 12
txt(c, IL + 68, yt(top + 5),
"včetně počtu v jednom dni a frekvence v týdnu)", size=6.5)
top += 10
# Výkony (5 řádků)
KOD_X = IL # x-start kódového rámečku
KOD_W = 108 # šířka kódového rámečku
KOD_H = 22 # výška kódového rámečku
TXT_X = KOD_X + KOD_W + 8 # x-start textové části
ROW_H = 42 # výška jednoho výkonu (rámeček + 2 řádky textu)
for vykon in (d.get("pozadovano", []) + [{}, {}, {}, {}, {}])[:5]:
y_top_row = yt(top)
# Kódový rámeček
c.setLineWidth(0.9)
c.setDash([])
c.rect(KOD_X, y_top_row - KOD_H - 4, KOD_W, KOD_H, stroke=1, fill=0)
# Hodnota kódu
kod_val = vykon.get("kod", "")
if kod_val:
txt(c, KOD_X + 5, y_top_row - KOD_H + 2, kod_val, size=9, bold=True)
# Textový řádek 1
txt(c, TXT_X, y_top_row - 10, vykon.get("popis", "")[:75], size=8)
dotline(c, TXT_X, y_top_row - 13, IR)
# Textový řádek 2 (pokračování)
txt(c, TXT_X, y_top_row - 25, vykon.get("popis2", "")[:75], size=8)
dotline(c, TXT_X, y_top_row - 28, IR)
top += ROW_H
# ═══════════════════════════════════════════════════════════════════════════════
# HLAVNÍ FUNKCE
# ═══════════════════════════════════════════════════════════════════════════════
def generuj_poukaz(data: dict, vystup: Path):
c = canvas.Canvas(str(vystup), pagesize=A4)
# Vnější zaoblený rámeček
c.setLineWidth(1.8)
c.roundRect(FX1, FB, FX2 - FX1, FT - FB, 6, stroke=1, fill=0)
draw_hlavicka(c, data)
draw_nadpis(c)
draw_pacient(c, data)
cur_top = draw_textova_pole(c, data)
draw_pozadovano(c, data, cur_top)
# Zápatí
txt(c, FX1 + 2, FB - 12, "VZP-06dp/2024", size=6)
c.save()
print(f"✓ Uloženo: {vystup}")
# ── Spuštění ──────────────────────────────────────────────────────────────────
if __name__ == "__main__":
folder = Path(__file__).parent
# Najde nejvyšší existující číslo verze a přidá 1
existing = [f for f in folder.glob("Poukaz DP vyplneny_v*.pdf")]
nums = []
for f in existing:
try:
nums.append(int(f.stem.rsplit("_v", 1)[1]))
except (ValueError, IndexError):
pass
next_v = max(nums, default=2) + 1
out = folder / f"Poukaz DP vyplneny_v{next_v}.pdf"
generuj_poukaz(DATA, out)
1
existing = [f for f in folder.glob("Poukaz DP vyplneny_v*.pdf")]
nums = []
for f in existing:
try:
nums.append(int(f.stem.rsplit("_v", 1)[1]))
except (ValueError, IndexError):
pass
next_v = max(nums, default=2) + 1
out = folder / f"Poukaz DP vyplneny_v{next_v}.pdf"
generuj_poukaz(DATA, out)