notebookvb

This commit is contained in:
Vladimir Buzalka
2026-05-10 07:29:09 +02:00
parent 0f0e533a9e
commit 38568dc2ca
20 changed files with 41700 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

+176
View File
@@ -0,0 +1,176 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import traceback
from pathlib import Path
from datetime import date
import customtkinter as ctk
from tkinter import messagebox
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent.parent
sys.path.insert(0, str(PROJECT_ROOT))
from Knihovny.vzpb2b_client import VZPB2BClient
from Knihovny.EmailMessagingGraph import send_mail
EMAIL_CHYBY = "vladimir.buzalka@buzalka.cz"
def _zpracuj_chybu(exc: BaseException):
"""Zobrazí chybový dialog a pošle email. Nikdy nevyhodí výjimku."""
detail = traceback.format_exc()
try:
root = ctk.CTk()
root.withdraw()
messagebox.showerror("Chyba — KdoJeLekarApp",
f"Nastala chyba:\n{exc}\n\nByla odeslána na email.")
root.destroy()
except Exception:
pass
try:
send_mail(
to=EMAIL_CHYBY,
subject=f"KdoJeLekarApp — chyba ({date.today().isoformat()})",
body=(f"Pacient: {PRIJMENI} {JMENO} / RC: {RODCIS}\n\n{detail}"),
)
except Exception:
pass
# ── KONFIGURACE ───────────────────────────────────────────────────────────────
PFX_PATH = PROJECT_ROOT / "Insurance" / "Certificates" / "picka.pfx"
PFX_PASS = "Vlado7309208104+"
ODBORNOSTI_NAZVY = {
"001": "Praktický lékař",
"002": "Gynekolog",
"014": "Stomatolog",
}
# Default hodnoty (přepíší argumenty z Medicusu)
JMENO = "Michaela"
PRIJMENI = "Buzalková"
RODCIS = "7155111821"
# ── ARGUMENTY Z MEDICUSU ─────────────────────────────────────────────────────
if len(sys.argv) >= 4:
JMENO = sys.argv[1]
PRIJMENI = sys.argv[2]
RODCIS = sys.argv[3]
elif len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help"):
print("Usage: KdoJeLekarApp.py JMENO PRIJMENI RODCIS")
sys.exit(0)
# ── VZP DOTAZ ────────────────────────────────────────────────────────────────
def zjisti_lekare(rodcis: str) -> list[dict]:
vzp = VZPB2BClient("prod", str(PFX_PATH), PFX_PASS)
xml = vzp.registrace_lekare(rc=rodcis, k_datu=date.today().isoformat())
return vzp.parse_registrace_lekare(xml)
# ── GUI ───────────────────────────────────────────────────────────────────────
class KdoJeLekarApp(ctk.CTk):
def __init__(self, zaznamy: list[dict]):
super().__init__()
self.title("Registrující lékař — VZP B2B")
self.geometry("560x560")
self.minsize(480, 380)
self.resizable(True, True)
ctk.set_appearance_mode("light")
ctk.set_default_color_theme("blue")
outer = ctk.CTkFrame(self, corner_radius=10)
outer.pack(expand=True, fill="both", padx=20, pady=20)
outer.columnconfigure(0, weight=1)
ctk.CTkLabel(outer, text="Registrující lékaři",
font=("Arial", 20, "bold")).grid(row=0, column=0, pady=(10, 8))
# Pacient
poj = zaznamy[0].get("poj_zkratka", "") if zaznamy else ""
pac = ctk.CTkFrame(outer, corner_radius=8)
pac.grid(row=1, column=0, sticky="ew", padx=10, pady=(0, 8))
ctk.CTkFrame(pac, height=6, fg_color="transparent").pack()
for label, value in [
("Příjmení:", PRIJMENI),
("Jméno:", JMENO),
("Rodné číslo:", RODCIS),
("Pojišťovna:", poj),
]:
row = ctk.CTkFrame(pac, fg_color="transparent")
row.pack(fill="x", padx=12, pady=0)
ctk.CTkLabel(row, text=label, font=("Arial", 12, "bold"),
width=100, anchor="w", height=20).pack(side="left", pady=0)
ctk.CTkLabel(row, text=value, font=("Arial", 12),
anchor="w", height=20).pack(side="left", pady=0)
ctk.CTkFrame(pac, height=4, fg_color="transparent").pack()
# Karty lékařů
cards = ctk.CTkFrame(outer, corner_radius=0, fg_color="transparent")
cards.grid(row=2, column=0, sticky="ew", padx=10)
if not zaznamy:
ctk.CTkLabel(cards, text="VZP neeviduje žádného registrujícího lékaře.",
font=("Arial", 13), text_color="#c0392b").pack(pady=20)
else:
for z in zaznamy:
self._render_zaznam(cards, z)
ctk.CTkLabel(outer,
text=f"Dotaz k datu: {date.today().isoformat()} | © Ordinace MUDr. Buzalková",
font=("Arial", 10), text_color="#888").grid(row=3, column=0, pady=(4, 6))
self._autosize()
def _render_zaznam(self, parent, z: dict):
kod = z.get("kod_odbornosti", "")
nazev_odb = ODBORNOSTI_NAZVY.get(kod, f"Odbornost {kod}")
lekar = z.get("nazev_zzz") or ""
pracoviste = z.get("nazev_lekare") or ""
od = z.get("datum_zahajeni") or "?"
do = z.get("datum_ukonceni") or "?"
card = ctk.CTkFrame(parent, corner_radius=8, fg_color="#eaf4fb")
card.pack(fill="x", pady=4)
ctk.CTkLabel(card, text=f" {nazev_odb} ({kod})",
font=("Arial", 13, "bold"), text_color="#1a5276").pack(anchor="w", padx=10, pady=(6, 1))
for label, value in [
("Lékař:", lekar),
("Pracoviště:", pracoviste),
("ICZ / ICP:", f"{z.get('ICZ') or ''} / {z.get('ICP') or ''}"),
("Registrace:", z.get("datum_registrace") or "?"),
("Platí od:", od),
("Platí do:", "bez omezení" if do == "3000-01-01" else do),
]:
row = ctk.CTkFrame(card, fg_color="transparent")
row.pack(fill="x", padx=14, pady=0)
ctk.CTkLabel(row, text=label, font=("Arial", 11, "bold"),
width=90, anchor="w", height=20).pack(side="left", pady=0)
ctk.CTkLabel(row, text=value, font=("Arial", 11),
anchor="w", height=20).pack(side="left", pady=0)
ctk.CTkFrame(card, height=4, fg_color="transparent").pack()
def _autosize(self):
self.update_idletasks()
w = 560
h = self.winfo_reqheight()
sw, sh = self.winfo_screenwidth(), self.winfo_screenheight()
self.geometry(f"{w}x{h}+{(sw-w)//2}+{(sh-h)//2}")
# ── MAIN ─────────────────────────────────────────────────────────────────────
if __name__ == "__main__":
try:
zaznamy = zjisti_lekare(RODCIS)
app = KdoJeLekarApp(zaznamy)
app.mainloop()
except Exception as exc:
_zpracuj_chybu(exc)
sys.exit(1)
@@ -0,0 +1,38 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['KdoJeLekarApp.py'],
pathex=[r'U:\OrdinaceProjekt'],
binaries=[],
datas=[],
hiddenimports=['customtkinter', 'msal', 'requests_pkcs12'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='KdoJeLekarApp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['KdoJeLekarApp.ico'],
)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,260 @@
This file lists modules PyInstaller was not able to find. This does not
necessarily mean these modules are required for running your program. Both
Python's standard library and 3rd-party Python packages often conditionally
import optional modules, some of which may be available only on certain
platforms.
Types of import:
* top-level: imported at the top-level - look at these first
* conditional: imported within an if-statement
* delayed: imported within a function
* optional: imported within a try-except-statement
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), http.server (delayed, optional), netrc (delayed, conditional), getpass (delayed)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
missing module named _posixsubprocess - imported by subprocess (conditional), multiprocessing.util (delayed)
missing module named fcntl - imported by subprocess (optional)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
missing module named urllib.quote_plus - imported by urllib (optional), msal.oauth2cli.oauth2 (optional)
missing module named urllib.urlencode - imported by urllib (optional), msal.oauth2cli.oauth2 (optional), msal.oauth2cli.authcode (optional)
missing module named posix - imported by os (conditional, optional), shutil (conditional), importlib._bootstrap_external (conditional), posixpath (optional)
missing module named resource - imported by posix (top-level)
missing module named _posixshmem - imported by multiprocessing.resource_tracker (conditional), multiprocessing.shared_memory (conditional)
missing module named _scproxy - imported by urllib.request (conditional)
missing module named termios - imported by tty (top-level), getpass (optional)
missing module named multiprocessing.BufferTooShort - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named multiprocessing.AuthenticationError - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named multiprocessing.get_context - imported by multiprocessing (top-level), multiprocessing.pool (top-level), multiprocessing.managers (top-level), multiprocessing.sharedctypes (top-level)
missing module named multiprocessing.TimeoutError - imported by multiprocessing (top-level), multiprocessing.pool (top-level)
missing module named multiprocessing.set_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named multiprocessing.get_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named pyimod02_importers - imported by C:\Python312\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
missing module named cryptography.x509.UnsupportedExtension - imported by cryptography.x509 (optional), urllib3.contrib.pyopenssl (optional)
missing module named bcrypt - imported by cryptography.hazmat.primitives.serialization.ssh (optional)
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl (delayed, conditional)
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl (top-level)
missing module named chardet - imported by requests (optional)
missing module named asyncio.DefaultEventLoopPolicy - imported by asyncio (delayed, conditional), asyncio.events (delayed, conditional)
missing module named annotationlib - imported by typing_extensions (conditional)
missing module named 'pyodide.ffi' - imported by urllib3.contrib.emscripten.fetch (delayed, optional)
missing module named pyodide - imported by urllib3.contrib.emscripten.fetch (top-level)
missing module named js - imported by urllib3.contrib.emscripten.fetch (top-level)
missing module named 'h2.events' - imported by urllib3.http2.connection (top-level)
missing module named 'h2.connection' - imported by urllib3.http2.connection (top-level)
missing module named h2 - imported by urllib3.http2.connection (top-level)
missing module named zstandard - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named compression - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named brotli - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named socks - imported by urllib3.contrib.socks (optional)
missing module named dummy_threading - imported by requests.cookies (optional)
missing module named simplejson - imported by requests.compat (conditional, optional)
missing module named vms_lib - imported by platform (delayed, optional)
missing module named 'java.lang' - imported by platform (delayed, optional)
missing module named java - imported by platform (delayed)
missing module named _winreg - imported by platform (delayed, optional)
missing module named BaseHTTPServer - imported by msal.oauth2cli.authcode (optional)
missing module named urlparse - imported by msal.oauth2cli.oauth2 (optional), msal.oauth2cli.authcode (optional), msal.authority (optional), msal.mex (optional), msal.cloudshell (optional), msal.auth_scheme (optional)
missing module named collections.MutableMapping - imported by collections (optional), msal.individual_cache (optional)
missing module named pymsalruntime - imported by msal.broker (optional), msal.application (delayed, conditional)
missing module named msal_extensions - imported by msal.application (delayed, optional)
missing module named _dummy_thread - imported by numpy._core.arrayprint (optional)
missing module named 'numpy_distutils.cpuinfo' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
missing module named 'numpy_distutils.fcompiler' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
missing module named 'numpy_distutils.command' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
missing module named numpy_distutils - imported by numpy.f2py.diagnose (delayed, optional)
missing module named psutil - imported by numpy.testing._private.utils (delayed, optional)
missing module named readline - imported by cmd (delayed, conditional, optional), code (delayed, conditional, optional), pdb (delayed, optional)
missing module named win32pdh - imported by numpy.testing._private.utils (delayed, conditional)
missing module named _typeshed - imported by numpy.random.bit_generator (top-level)
missing module named numpy.random.RandomState - imported by numpy.random (top-level), numpy.random._generator (top-level)
missing module named threadpoolctl - imported by numpy.lib._utils_impl (delayed, optional)
missing module named numpy._core.zeros - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.vstack - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
missing module named numpy._core.void - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.vecmat - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.vecdot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.ushort - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.unsignedinteger - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ulonglong - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ulong - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.uintp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.uintc - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.uint64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.uint32 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.uint16 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.uint - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ubyte - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.trunc - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.true_divide - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.transpose - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._function_base_impl (top-level), numpy (conditional)
missing module named numpy._core.trace - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.timedelta64 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.tensordot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.tanh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.tan - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.swapaxes - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.sum - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.subtract - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.str_ - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.square - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.sqrt - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.spacing - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.sort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.sinh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.single - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.signedinteger - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.signbit - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.sign - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.short - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.rint - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.right_shift - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.result_type - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.remainder - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.reciprocal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.radians - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.rad2deg - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.prod - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.power - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.positive - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.pi - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.outer - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.ones - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.object_ - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.number - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.not_equal - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.newaxis - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.negative - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ndarray - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy.lib._utils_impl (top-level), numpy (conditional)
missing module named numpy._core.multiply - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.moveaxis - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.modf - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.mod - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.minimum - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.maximum - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.max - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.matvec - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.matrix_transpose - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.matmul - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.longlong - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.longdouble - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.long - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logical_xor - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logical_or - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logical_not - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logical_and - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logaddexp2 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.logaddexp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.log2 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.log1p - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.log - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.linspace - imported by numpy._core (top-level), numpy.lib._index_tricks_impl (top-level), numpy (conditional)
missing module named numpy._core.less_equal - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.less - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.left_shift - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ldexp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.lcm - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.isscalar - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.isnat - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
missing module named numpy._core.isnan - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.isfinite - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.intp - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.integer - imported by numpy._core (conditional), numpy (conditional), numpy.fft._helper (top-level)
missing module named numpy._core.intc - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.int64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.int32 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.int16 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.int8 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.inf - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.inexact - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.iinfo - imported by numpy._core (top-level), numpy.lib._twodim_base_impl (top-level), numpy (conditional)
missing module named numpy._core.hypot - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.hstack - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.heaviside - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.half - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.greater_equal - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.greater - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.gcd - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.frompyfunc - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.frexp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.fmod - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.fmin - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.fmax - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.floor_divide - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.floor - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.floating - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.float_power - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.float32 - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.float16 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.finfo - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.fabs - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.expm1 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.exp - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.euler_gamma - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.errstate - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.equal - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.empty_like - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.empty - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy.fft._helper (top-level)
missing module named numpy._core.e - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.double - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.dot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.divmod - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.divide - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.diagonal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.degrees - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.deg2rad - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.datetime64 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.csingle - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.cross - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.count_nonzero - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.cosh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.cos - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.copysign - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.conjugate - imported by numpy._core (conditional), numpy (conditional), numpy.fft._pocketfft (top-level)
missing module named numpy._core.conj - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.complexfloating - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.complex64 - imported by numpy._core (conditional), numpy (conditional), numpy._array_api_info (top-level)
missing module named numpy._core.clongdouble - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.character - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.ceil - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.cdouble - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.cbrt - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bytes_ - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.byte - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bool_ - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bitwise_xor - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bitwise_or - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bitwise_count - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.bitwise_and - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.atleast_3d - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
missing module named numpy._core.atleast_2d - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.atleast_1d - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.asarray - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._array_utils_impl (top-level), numpy (conditional), numpy.fft._helper (top-level), numpy.fft._pocketfft (top-level)
missing module named numpy._core.asanyarray - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.array_repr - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
missing module named numpy._core.array2string - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.array - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
missing module named numpy._core.argsort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.arctanh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arctan2 - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arctan - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arcsinh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arcsin - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arccosh - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arccos - imported by numpy._core (conditional), numpy (conditional)
missing module named numpy._core.arange - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy.fft._helper (top-level)
missing module named numpy._core.amin - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.amax - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named numpy._core.all - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
missing module named numpy._core.add - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
missing module named yaml - imported by numpy.__config__ (delayed)
missing module named numpy._distributor_init_local - imported by numpy (optional), numpy._distributor_init (optional)
missing module named olefile - imported by PIL.FpxImagePlugin (top-level), PIL.MicImagePlugin (top-level)
missing module named defusedxml - imported by PIL.Image (optional)
missing module named PyObjCTools - imported by darkdetect._mac_detect (optional)
missing module named Foundation - imported by darkdetect._mac_detect (optional)
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

+141
View File
@@ -0,0 +1,141 @@
# QRPlatbaApp QR kód pro platby
## Přehled
Aplikace **QRPlatbaApp** generuje QR kódy pro platby pacientů v ordinaci. Údaje o pacientovi jsou předávány z Medicusu, aplikace zobrazí okno s výběrem položky k úhradě a generuje QR kód ve formátu **SPAYD** (Czech Payment Standard).
## Soubory
- `QRPlatbaApp.py` — hlavní Python skript (customtkinter GUI)
- `dist/QRPlatbaApp.exe` — kompilovaný spustitelný soubor (bez CMD okna)
## Technologie
- **Python 3.x** (nutný pouze pro vývoj, EXE běží bez Pythonu)
- **customtkinter** — moderní GUI
- **qrcode** — generování QR kódů
- **pillow (PIL)** — manipulace s obrázky
- **fdb** — připojení na Firebird DB (Medicus)
## Jak to funguje
### 1. Spouštění z Medicusu
Medicus předá údaje pacienta přes příkazový řádek do EXE:
```
QRPlatbaApp.exe %JMENO% %PRIJMENI% %RODCIS%
```
### 2. Načtení ceníku
Skript se připojí na Medicus DB a načte ceník ze stored procedure `VLV_SEL`:
```python
cur.execute("SELECT V.KOD, V.NAZEV, V.CENA FROM VLV_SEL(NULL, NULL, NULL) V ORDER BY V.KOD")
```
### 3. GUI okno
Zobrazí se okno s:
- Údaji pacienta (jméno, příjmení, rodné číslo)
- Výběrem položky k úhradě (dropdown)
- Výběrem bankovního účtu (2 možnosti: Fio 2100046291/2010 nebo 2800046620/2010)
- Tlačítko "Uložit QR kód"
- QR kód (200x200px, SPAYD formát)
### 4. SPAYD formát
QR kód obsahuje:
```
SPD*1.0*ACC:CZ7520100000002800046620*AM:500.00*CC:CZK*X-VS:7309281045*MSG:Buzalka%20Vladimír%20%20Poplatek
```
- `ACC` — IBAN bankovního účtu
- `AM` — částka (Kč)
- `CC` — měna (CZK)
- `X-VS` — variabilní symbol (rodné číslo pacienta)
- `MSG` — zpráva (jméno + položka)
### 5. Uložení QR
Po kliknutí na "Uložit QR kód" se PNG vygeneruje do adresáře:
```
U:\OrdinaceProjekt\Medicus\QRCode\QRPlatby\Buzalka_Vladimír_20260510_143025.png
```
## Konfigurace v Medicusu
V menu **Konfigurace > Externí programy** přidej nový záznam:
| Položka | Hodnota |
|---------|---------|
| **Kategorie** | Ostatní |
| **Typ programu** | Externí program |
| **Program** | `U:\OrdinaceProjekt\Medicus\QRCode\dist\QRPlatbaApp.exe` |
| **Příkazový řádek** | `"U:\OrdinaceProjekt\Medicus\QRCode\dist\QRPlatbaApp.exe" %JMENO% %PRIJMENI% %RODCIS%` |
| **Pacient** | ✓ (vyžaduje vybraného pacienta) |
| **Menu** | QR Platba |
## Firebird DB připojení
```python
DB_DSN = r'localhost:c:\medicus 3\data\medicus.fdb'
DB_USER = 'SYSDBA'
DB_PASSWORD = 'masterkey'
DB_CHARSET = 'win1250'
```
## Bankovní účty
```python
ACCOUNTS = {
"2100046291/2010": "CZ1720100000002100046291",
"2800046620/2010": "CZ7520100000002800046620",
}
```
Oba účty jsou u Fio banky.
## Spouštění bez CMD okna
EXE soubor se zkompiloval pomocí PyInstalleru s parametrem `--windowed`, což zajistí spuštění bez zobrazení CMD okna. GUI se zobrazí přímo bez blikání.
## Příjmání argumentů
Python skript přijímá argumenty přesně z příkazového řádku:
```python
if len(sys.argv) >= 4:
JMENO = sys.argv[1] # arg 1 z Medicusu (%JMENO%)
PRIJMENI = sys.argv[2] # arg 2 z Medicusu (%PRIJMENI%)
RODCIS = sys.argv[3] # arg 3 z Medicusu (%RODCIS%)
```
## Ladění a opravy
Při chybách se informace vypíší v GUI (messagebox).
Pokud potřebuješ upravit zdrojový kód, edituj `QRPlatbaApp.py` a znovu zkompiluj EXE.
## Výstup
Generované QR kódy PNG se ukládají do:
```
U:\OrdinaceProjekt\Medicus\QRCode\QRPlatby\
├── Buzalka_Vladimír_20260510_143025.png
├── Buzalka_Vladimír_20260510_144030.png
└── ...
```
## PyInstaller kompilace
EXE soubor byl zkompilován příkazem:
```bash
pyinstaller --onefile --windowed --icon=qrcode.ico QRPlatbaApp.py
```
Výsledný EXE se nachází v `dist/QRPlatbaApp.exe` a je schopen běžet na počítačích bez Pythonu.
Při potřebě znovu kompilovat po změně kódu:
```bash
cd U:\OrdinaceProjekt\Medicus\QRCode
C:\Python312\Scripts\pyinstaller.exe --onefile --windowed --icon=qrcode.ico --clean QRPlatbaApp.py
```
+208
View File
@@ -0,0 +1,208 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import urllib.parse
import qrcode
import fdb
from pathlib import Path
from datetime import datetime
from PIL import Image, ImageTk
import customtkinter as ctk
from tkinter import messagebox
# ================================
# ⚙️ Default Configuration
# ================================
ACCOUNTS = {
"2100046291/2010": "CZ1720100000002100046291",
"2800046620/2010": "CZ7520100000002800046620",
}
CURRENCY = "CZK"
OUTPUT_DIR = Path(r"U:\OrdinaceProjekt\Medicus\Externi\QRCode\QRPlatby")
OUTPUT_DIR.mkdir(exist_ok=True)
# Firebird připojení
DB_DSN = r'localhost:c:\medicus 3\data\medicus.fdb'
DB_USER = 'SYSDBA'
DB_PASSWORD = 'masterkey'
DB_CHARSET = 'win1250'
# Default values (can be overridden by arguments)
PRIJMENI = "Buzalka"
JMENO = "Vladimír"
RODCIS = "730928104"
# ================================
# 💬 Argument Handling
# ================================
if len(sys.argv) >= 4:
JMENO = sys.argv[1]
PRIJMENI = sys.argv[2]
RODCIS = sys.argv[3]
elif len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help"):
print("Usage: QRPlatbaApp.py JMENO PRIJMENI RODCIS")
sys.exit(0)
# ================================
# 💉 Items to Pay načteno z Medicusu
# ================================
def nacti_polozky():
"""Načte ceník z Medicusu seřazený podle KOD (pořadového čísla)."""
try:
conn = fdb.connect(dsn=DB_DSN, user=DB_USER, password=DB_PASSWORD, charset=DB_CHARSET)
cur = conn.cursor()
cur.execute("SELECT V.KOD, V.NAZEV, V.CENA FROM VLV_SEL(NULL, NULL, NULL) V ORDER BY V.KOD")
rows = cur.fetchall()
conn.close()
# Vrátí OrderedDict: název -> cena (float)
return {row[1].strip(): float(row[2]) for row in rows if row[2] is not None}
except Exception as e:
messagebox.showerror("Chyba databáze", f"Nepodařilo se načíst ceník z Medicusu:\n{e}")
return {}
ITEMS = nacti_polozky()
# ================================
# 🧩 Helper
# ================================
def create_spayd(iban, amount, vs, msg, currency="CZK"):
msg_encoded = urllib.parse.quote(msg, safe="$%*+-.:/")
return f"SPD*1.0*ACC:{iban}*AM:{amount:.2f}*CC:{currency}*X-VS:{vs}*MSG:{msg_encoded}"
# ================================
# 🪟 GUI Class
# ================================
class QRPlatbaApp(ctk.CTk):
def __init__(self):
super().__init__()
self.title("QR Platba Ordinace MUDr. Buzalková")
self.geometry("520x680")
self.minsize(480, 480)
self.resizable(True, True)
ctk.set_appearance_mode("light")
ctk.set_default_color_theme("blue")
frame = ctk.CTkFrame(self, corner_radius=10)
frame.pack(expand=True, fill="both", padx=20, pady=20)
ctk.CTkLabel(frame, text="Generátor QR Platby",
font=("Arial", 20, "bold")).pack(pady=(8, 10))
# 👤 Patient Info
patient = ctk.CTkFrame(frame, corner_radius=8)
patient.pack(fill="x", pady=(0, 8), padx=10)
for text in [f"Příjmení: {PRIJMENI}",
f"Jméno: {JMENO}",
f"Rodné číslo: {RODCIS}"]:
ctk.CTkLabel(patient, text=text, font=("Arial", 12)).pack(anchor="w", padx=10, pady=1)
# 💰 Payment Section
pay = ctk.CTkFrame(frame, corner_radius=8)
pay.pack(fill="x", pady=(0, 8), padx=10)
ctk.CTkLabel(pay, text="Vyberte položku k úhradě:",
font=("Arial", 12, "bold")).pack(anchor="w", padx=10, pady=(6, 3))
self.display_items = [f"{name} ({price:.0f} Kč)" for name, price in ITEMS.items()]
self.item_map = {f"{name} ({price:.0f} Kč)": name for name, price in ITEMS.items()}
self.selected_item = ctk.StringVar(value=self.display_items[0])
self.combo = ctk.CTkOptionMenu(
pay,
variable=self.selected_item,
values=self.display_items,
font=("Arial", 12),
command=self.on_change
)
self.combo.pack(fill="x", padx=10)
self.amount_label = ctk.CTkLabel(pay, text="", font=("Arial", 12, "italic"))
self.amount_label.pack(anchor="e", padx=10, pady=(3, 6))
# 🏦 Account Selection
acc = ctk.CTkFrame(frame, corner_radius=8)
acc.pack(fill="x", pady=(0, 8), padx=10)
ctk.CTkLabel(acc, text="Číslo účtu:", font=("Arial", 12, "bold")).pack(anchor="w", padx=10, pady=(6, 3))
self.selected_account = ctk.StringVar(value=list(ACCOUNTS.keys())[0])
ctk.CTkOptionMenu(
acc,
variable=self.selected_account,
values=list(ACCOUNTS.keys()),
font=("Arial", 12),
command=self.on_change
).pack(fill="x", padx=10, pady=(0, 6))
ctk.CTkButton(frame, text="Uložit QR kód",
font=("Arial", 13, "bold"),
height=40,
command=self.ulozit_qr).pack(pady=6)
self.qr_label = ctk.CTkLabel(frame, text="")
self.qr_label.pack(pady=6)
ctk.CTkLabel(frame,
text="© Ordinace MUDr. Buzalková | QR Platba dle ČBA v1.2",
font=("Arial", 10),
text_color="#666").pack(side="bottom", pady=(10, 0))
self.center_window()
# QR automaticky při startu
self.after(100, self.refresh_qr)
# ================================
# 🪟 Center Window
# ================================
def center_window(self):
self.update_idletasks()
width = self.winfo_width()
height = self.winfo_height()
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
x = int((screen_width / 2) - (width / 2))
y = int((screen_height / 2) - (height / 2))
self.geometry(f"{width}x{height}+{x}+{y}")
# ================================
# 💸 Update and Generate
# ================================
def _get_current(self):
"""Vrátí (item, iban, spayd) pro aktuální výběr."""
display_item = self.selected_item.get()
item = self.item_map[display_item]
iban = ACCOUNTS[self.selected_account.get()]
spayd = create_spayd(iban, ITEMS[item], RODCIS, f"{PRIJMENI} {JMENO} {item}", CURRENCY)
return item, iban, spayd
def on_change(self, _=None):
"""Při změně dropdownu aktualizuj částku i QR."""
self.refresh_qr()
def refresh_qr(self):
"""Zobrazí QR kód pro aktuální výběr (bez uložení)."""
item, _, spayd = self._get_current()
self.amount_label.configure(text=f"Částka: {ITEMS[item]:.2f}")
img = qrcode.make(spayd)
img_resized = img.resize((200, 200), Image.LANCZOS)
qr_tk = ImageTk.PhotoImage(img_resized)
self.qr_label.configure(image=qr_tk)
self.qr_label.image = qr_tk
def ulozit_qr(self):
"""Uloží QR kód do souboru a informuje uživatele."""
item, _, spayd = self._get_current()
img = qrcode.make(spayd)
filename = f"{PRIJMENI}_{JMENO}_{datetime.now():%Y%m%d_%H%M%S}.png"
out_path = OUTPUT_DIR / filename
img.save(out_path)
messagebox.showinfo("Uloženo", f"QR kód uložen:\n{out_path}")
# ================================
# 🚀 Main
# ================================
if __name__ == "__main__":
app = QRPlatbaApp()
app.mainloop()
+39
View File
@@ -0,0 +1,39 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['QRPlatbaApp.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='QRPlatbaApp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['qrcode.ico'],
)
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB