166 lines
5.5 KiB
Python
166 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
|
||
import sys
|
||
import urllib.parse
|
||
import qrcode
|
||
from pathlib import Path
|
||
from datetime import datetime
|
||
from PIL import Image, ImageTk
|
||
import customtkinter as ctk
|
||
from tkinter import messagebox
|
||
|
||
|
||
# ================================
|
||
# ⚙️ Default Configuration
|
||
# ================================
|
||
IBAN = "CZ7520100000002800046620"
|
||
CURRENCY = "CZK"
|
||
OUTPUT_DIR = Path("QRPlatby")
|
||
OUTPUT_DIR.mkdir(exist_ok=True)
|
||
|
||
# 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
|
||
# ================================
|
||
ITEMS = {
|
||
"Očkování chřipka Vaxigrip": 600.00,
|
||
"Očkování chřipka Efluelda": 1300.00,
|
||
}
|
||
|
||
# ================================
|
||
# 🧩 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("520x520")
|
||
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=(10, 20))
|
||
|
||
# 👤 Patient Info
|
||
patient = ctk.CTkFrame(frame, corner_radius=8)
|
||
patient.pack(fill="x", pady=(0, 20), 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=2)
|
||
|
||
# 💰 Payment Section
|
||
pay = ctk.CTkFrame(frame, corner_radius=8)
|
||
pay.pack(fill="x", pady=(0, 20), padx=10)
|
||
ctk.CTkLabel(pay, text="Vyberte položku k úhradě:",
|
||
font=("Arial", 12, "bold")).pack(anchor="w", padx=10, pady=(10, 5))
|
||
|
||
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.update_amount
|
||
)
|
||
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=(5, 10))
|
||
self.update_amount()
|
||
|
||
ctk.CTkButton(frame, text="Vytvořit QR Platbu",
|
||
font=("Arial", 13, "bold"),
|
||
height=40,
|
||
command=self.generate_qr).pack(pady=10)
|
||
|
||
self.qr_label = ctk.CTkLabel(frame, text="")
|
||
self.qr_label.pack(pady=15)
|
||
|
||
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()
|
||
|
||
# ================================
|
||
# 🪟 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 update_amount(self, _=None):
|
||
display_item = self.selected_item.get()
|
||
item = self.item_map[display_item]
|
||
self.amount_label.configure(text=f"Částka: {ITEMS[item]:.2f} Kč")
|
||
|
||
def generate_qr(self):
|
||
display_item = self.selected_item.get()
|
||
item = self.item_map[display_item]
|
||
spayd = create_spayd(IBAN, ITEMS[item], RODCIS, f"{PRIJMENI} {JMENO} – {item}", CURRENCY)
|
||
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)
|
||
|
||
img_resized = img.resize((300, 300))
|
||
qr_tk = ImageTk.PhotoImage(img_resized)
|
||
self.qr_label.configure(image=qr_tk)
|
||
self.qr_label.image = qr_tk
|
||
|
||
self.update_idletasks()
|
||
self.geometry(f"{self.winfo_reqwidth()}x{self.winfo_reqheight()}")
|
||
self.center_window()
|
||
|
||
|
||
# ================================
|
||
# 🚀 Main
|
||
# ================================
|
||
if __name__ == "__main__":
|
||
app = QRPlatbaApp()
|
||
app.mainloop()
|