From 37b5c602663f60fa38f0780505e798239e6aed17 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Fri, 4 Sep 2026 01:19:50 +0200 Subject: [PATCH 01/34] Storno-Erklaerung steht jetzt auch auf dem Amtsblatt Sein Fund: "in der pdf wird der satz nicht angezeigt, da ist dann ein sprung in den rechnungs nummern". Die Schlusstexte waren komplett auf die Kundenseite beschraenkt ("auf dem Amt-Blatt unnoetig"). Fuer Dank- und Zahlungstexte stimmt das. Fuer die STORNO-Erklaerung nicht: auf Seite 2 stand dann eine Stornonummer (2026-456) neben einer voellig anderen Rechnungsnummer (2026-342), und das Blatt, das die Stadt bekommt, sagte nirgends warum. Jetzt traegt auch das Amtsblatt den Satz - "hebt die Rechnung X vom Y vollstaendig auf, ist bereits mit Z abgerechnet" bzw. bei Version C "die Leistung wird nicht abgerechnet". Die Beherbergungssteuer-Zeile bleibt dort weiterhin aussen vor, die gehoert da nicht hin. pruef_nur_storno an die Verrechnung angepasst (das Steuerjournal laesst Storno und aufgehobene Rechnung wieder mitzaehlen, sie heben sich gegenseitig auf): unterm Strich 0 Naechte und 0,00 Euro, gezaehlt werden aber beide Belege. A und B unveraendert gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_017bEsoFUk16DfnNA7MjY36H --- pdf_renderer.py | 10 ++++++++-- pruef_nur_storno.py | 15 +++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/pdf_renderer.py b/pdf_renderer.py index be483e9..0a64664 100644 --- a/pdf_renderer.py +++ b/pdf_renderer.py @@ -471,8 +471,14 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont): story.append(Spacer(1, 8 * mm)) - # ---- Schlusstexte (nur Kundenseite; auf dem Amt-Blatt unnoetig) ---- - if not gesamtrechnung_betont: + # ---- Schlusstexte ------------------------------------------------------- + # Dank- und Zahlungstexte gehoeren nur auf die Kundenseite. Die + # STORNO-Erklaerung gehoert aber AUCH aufs Amtsblatt: dort steht sonst eine + # Stornonummer neben einer voellig anderen Rechnungsnummer, und niemand + # erfaehrt, warum. Sein Fund am 04.09.2026: *"in der pdf wird der satz nicht + # angezeigt, da ist dann ein sprung in den rechnungs nummern"* - genau das + # Blatt, das die Stadt bekommt, war der Beleg ohne Begruendung. + if not gesamtrechnung_betont or art == "storno": texte = cfg.get("texte", {}) block = [] if art == "storno": diff --git a/pruef_nur_storno.py b/pruef_nur_storno.py index 3888733..0a75bc7 100644 --- a/pruef_nur_storno.py +++ b/pruef_nur_storno.py @@ -183,14 +183,21 @@ j = Journal(os.path.join(tmp, "journal.sqlite3")) j.scanne(ordner, 5.0, voll=True) buchungen = j.buchungen(jahr=2026) weg = aufgehobene(buchungen) -s = summiere(buchungen, weg) +# Verrechnet, nicht weggelassen (Entscheidung vom 04.09.2026, siehe +# modell.summiere im Steuerjournal): beide Zeilen stehen mit ihrem Vorzeichen +# in der Summe und heben sich gegenseitig auf. +s = summiere(buchungen) print("--- was im Journal steht ---") for b in buchungen: print(f" {b.voll_nummer} {b.nachname:10s} {b.naechte:>3} Naechte {b.gezahlt:>8.2f}") pruefe(len(buchungen) == 2, f"Rechnung und Storno stehen beide im Journal ({len(buchungen)})") -pruefe(s.buchungen == 0 and s.naechte == 0 and abs(s.gezahlt) < 0.005, - f"gemeldet wird NICHTS: 0 Rechnungen, 0 Naechte, 0,00 Euro " - f"(ist {s.buchungen}, {s.naechte}, {s.gezahlt})") +pruefe(len(weg) == 1, f"die Rechnung ist als aufgehoben erkannt ({len(weg)})") +pruefe(s.naechte == 0 and abs(s.gezahlt) < 0.005, + f"unterm Strich bleibt nichts uebrig: 0 Naechte, 0,00 Euro " + f"(ist {s.naechte}, {s.gezahlt})") +pruefe(s.buchungen == 2, + f"gezaehlt werden aber beide Belege - verrechnet, nicht weggelassen " + f"(ist {s.buchungen})") j.schliessen() f.destroy() From 142dddc647f123d0ad15b173377ac2155eb090c6 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 17:35:37 +0200 Subject: [PATCH 02/34] Bilder und Farbe gehoeren der Firma, dazu ein Vorschau-Knopf Logo und ein Fussstreifen sind austauschbar (bilder.py: das gewaehlte Bild wird KOPIERT, ein Pfad auf den Desktop waere morgen tot), die Akzentfarbe kommt aus den Einstellungen - Hex-Feld und Farbwaehler. Firmenname, Anschrift, Bank und Steuernummer bleiben gezeichnet; kein Bild kann eine Pflichtangabe verdecken. Der Vorschau-Knopf zeigt das Blatt, bevor es eine Rechnung wird: kein Nummernverbrauch, nichts im Rechnungsordner, "VORSCHAU - keine Rechnung" quer ueber jeder Seite. Sonst kostet jeder Tippfehler einen Storno. Neue Pruefstaende: pruef_bilder.py, pruef_vorschau.py Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 100 +++++++++++++++++++++++--------- bilder.py | 117 +++++++++++++++++++++++++++++++++++++ config.py | 13 +++++ einstellungen.py | 101 ++++++++++++++++++++++++-------- pdf_renderer.py | 121 +++++++++++++++++++++++++++++--------- pruef_bilder.py | 145 ++++++++++++++++++++++++++++++++++++++++++++++ pruef_vorschau.py | 117 +++++++++++++++++++++++++++++++++++++ 7 files changed, 636 insertions(+), 78 deletions(-) create mode 100644 bilder.py create mode 100644 pruef_bilder.py create mode 100644 pruef_vorschau.py diff --git a/app.py b/app.py index b42c7db..534c3e0 100644 --- a/app.py +++ b/app.py @@ -20,6 +20,7 @@ Aufgeteilt in: """ import os +import tempfile import sys import datetime import queue @@ -106,6 +107,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): self._open_pop = None self._menus = { "Datei": [ + ("Vorschau ansehen", self.vorschau_zeigen), ("PDF erstellen", self.pdf_erstellen), ("Formular zurücksetzen", self.reset_formular), ("Ausgabeordner öffnen", self._ordner_oeffnen), @@ -524,6 +526,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): links = ttk.Frame(f) links.pack(side="left") + ttk.Button(links, text="Vorschau", command=self.vorschau_zeigen, width=12).pack(side="left", padx=4) ttk.Button(links, text="PDF erstellen", command=self.pdf_erstellen, width=18).pack(side="left", padx=4) ttk.Button(links, text="Storno", command=self.dlg_storno, width=12).pack(side="left", padx=4) @@ -1074,6 +1077,76 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): return jahr, zaehler, nummer return jahr, zaehler, f"{jahr}-A{zaehler:03d}" + def _kopf_basis(self, nummer, r): + """Die Kopfdaten, die JEDES Blatt braucht - Rechnung wie Vorschau. + + Steht nur hier: sonst tippt die Vorschau denselben Adressblock ein + zweites Mal ab, und beim naechsten neuen Feld zeigt sie ein Blatt, das + es so gar nicht gibt. + + Auf der Rechnung stehen Vor- und Nachname wie gewohnt in einer Zeile; + der Nachname geht zusaetzlich getrennt mit, damit das Steuerjournal ihn + nicht aus dem Adressblock raten muss. + """ + nachname = self.k_name.get().strip() + vorname = self.k_vorname.get().strip() + namenszeile = " ".join(t for t in (vorname, nachname) if t) + return { + "rechnungsnummer": nummer, + "datum": self.r_datum.get().strip() or datetime.date.today().strftime("%d.%m.%Y"), + "anreise": self.r_anreise.get().strip(), + "abreise": self.r_abreise.get().strip(), + "naechte": self.r_naechte.get() if self.r_naechte.get() != "–" else "", + "kunde_zeilen": [self.k_anrede.get(), namenszeile, self.k_zusatz.get(), + self.k_strasse.get(), self.k_plzort.get()], + "nachname": nachname, + "vorname": vorname, + # Fuer Version 3: kompletter Formularstand, damit die Rechnung spaeter + # wieder ins Formular geladen werden kann statt abgetippt zu werden. + "kunde": {"anrede": self.k_anrede.get().strip(), "vorname": vorname, + "nachname": nachname, "zusatz": self.k_zusatz.get().strip(), + "strasse": self.k_strasse.get().strip(), + "plzort": self.k_plzort.get().strip()}, + "positionen": [{"nr": z.nr, "anzahl": z.anzahl, "personen": z.personen} + for z in r.zeilen], + } + + def vorschau_zeigen(self): + """Zeigt das Blatt, BEVOR es eine Rechnung wird. + + Eine ausgestellte Rechnung laesst sich nur noch ueber einen Storno + geradeziehen - Papier, Porto und ein Weg zum Gast. Deshalb dieser Knopf: + ansehen, aendern, ansehen. Die Vorschau + + - verbraucht KEINE Rechnungsnummer und traegt nichts ins Nummernbuch, + - landet NICHT im Rechnungsordner, sondern im Temp-Ordner, + - traegt quer ueber jede Seite "VORSCHAU - keine Rechnung". + + Gepruefte Pflichtfelder gibt es hier bewusst nicht: man will ja gerade + sehen, was noch fehlt. + """ + montage = self.ist_montage() + r = self.recalc() + if not r.zeilen: + messagebox.showinfo( + "Noch nichts einzutragen", + "Bitte die Anzahl der Monate eintragen." if montage else + "Trage erst bei einer Leistung eine Anzahl ein - dann zeigt die " + "Vorschau, wie die Rechnung aussehen wird.") + return + kopf = self._kopf_basis(self.r_nummer.get().strip() or "(noch keine Nummer)", r) + if montage: + kopf["vorlage"] = "montage" + kopf["montage_text"] = self._montage_text() + pfad = os.path.join(tempfile.gettempdir(), "Vorschau - so wird die Rechnung.pdf") + try: + pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf, vorschau=True) + print(f"[vorschau] geschrieben -> {pfad}") + os.startfile(pfad) # noqa: S606 + except OSError as e: + messagebox.showerror("Vorschau nicht möglich", + f"Die Vorschau konnte nicht geöffnet werden:\n{e}") + def pdf_erstellen(self, angebot=False): montage = self.ist_montage() r = self.recalc() @@ -1145,14 +1218,6 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # unangetastet, die naechste Rechnung behaelt ihre Nummer. a_jahr, a_zaehler, nummer = self._naechstes_angebot() - # Auf der Rechnung stehen Vor- und Nachname wie gewohnt in einer Zeile; - # der Nachname geht zusätzlich getrennt mit, damit das Steuerjournal ihn - # nicht aus dem Adressblock raten muss. - nachname = self.k_name.get().strip() - vorname = self.k_vorname.get().strip() - namenszeile = " ".join(t for t in (vorname, nachname) if t) - kunde_zeilen = [self.k_anrede.get(), namenszeile, self.k_zusatz.get(), - self.k_strasse.get(), self.k_plzort.get()] # Liegt ein Storno im Zwischenspeicher, ist das hier die berichtigte Rechnung. # Letzte Gelegenheit umzukehren: sagt er Nein, wird das Storno-PDF wieder # geloescht und es bleibt allein die urspruengliche Rechnung stehen. @@ -1173,24 +1238,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): f"Der Storno wurde gelöscht. Es bleibt allein die Rechnung {stand['zu']}.") return - kopf = { - "rechnungsnummer": nummer, - "datum": self.r_datum.get().strip() or datetime.date.today().strftime("%d.%m.%Y"), - "anreise": self.r_anreise.get().strip(), - "abreise": self.r_abreise.get().strip(), - "naechte": self.r_naechte.get() if self.r_naechte.get() != "–" else "", - "kunde_zeilen": kunde_zeilen, - "nachname": nachname, - "vorname": vorname, - # Fuer Version 3: kompletter Formularstand, damit die Rechnung spaeter - # wieder ins Formular geladen werden kann statt abgetippt zu werden. - "kunde": {"anrede": self.k_anrede.get().strip(), "vorname": vorname, - "nachname": nachname, "zusatz": self.k_zusatz.get().strip(), - "strasse": self.k_strasse.get().strip(), - "plzort": self.k_plzort.get().strip()}, - "positionen": [{"nr": z.nr, "anzahl": z.anzahl, "personen": z.personen} - for z in r.zeilen], - } + kopf = self._kopf_basis(nummer, r) if montage: # Das Blatt sieht anders aus (eine Zeile statt Tabelle), die Buchung # dahinter ist eine ganz normale: Zwischensumme + Beherbergungssteuer. diff --git a/bilder.py b/bilder.py new file mode 100644 index 0000000..535eed5 --- /dev/null +++ b/bilder.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +"""Bilder fuer Kopf- und Fusszeile der Rechnung: ablegen, wiederfinden, laden. + +Warum eine eigene Datei: Kopfbild und Fussbild brauchen dieselben drei Schritte +(uebernehmen -> aufloesen -> laden), und der PDF-Renderer, der Einstellungsdialog +und die Pruefstaende brauchen sie alle. Stuende die Logik im Renderer, muesste der +Dialog sie nachbauen - und beim naechsten Bild laufen die beiden auseinander. + +⭐ Der wichtigste Teil ist `uebernehmen`: das gewaehlte Bild wird in den Ordner +`bilder/` neben der config.json KOPIERT, statt nur seinen Pfad zu merken. Sonst +zeigt die Einstellung auf den Desktop des Nutzers - und sobald er dort aufraeumt, +faellt das Logo still von der Rechnung. Gemerkt wird nur der kurze Name +("bilder/logo.png"), damit die Einstellung auch nach einem Umzug des Ordners passt. +""" +import os +import shutil + +import config + +# Erlaubte Formate. reportlab liest PNG/JPG/GIF direkt; SVG kann es nicht - +# deshalb steht es hier bewusst NICHT. +FORMATE = (".png", ".jpg", ".jpeg", ".gif") +ORDNER = "bilder" + + +def bilder_dir(): + """Ordner fuer die uebernommenen Bilder (neben der config.json). Wird angelegt.""" + d = os.path.join(config.BASE_DIR, ORDNER) + os.makedirs(d, exist_ok=True) + return d + + +def uebernehmen(quelle): + """Bild in den Bilderordner kopieren -> gibt den zu speichernden Pfad zurueck. + + Liegt die Datei schon im Bilderordner, wird nichts kopiert. Ein Name, der + bereits vergeben ist, bekommt eine Nummer angehaengt - ein bestehendes Bild + wird NIE ueberschrieben, sonst waere das alte Logo mit einem Klick weg. + """ + quelle = (quelle or "").strip() + if not quelle: + return "" + if not os.path.exists(quelle): + print(f"[bilder] Quelle gibt es nicht: {quelle}") + return "" + ziel_dir = bilder_dir() + name = os.path.basename(quelle) + if os.path.dirname(os.path.abspath(quelle)) == os.path.abspath(ziel_dir): + return f"{ORDNER}/{name}" + stamm, endung = os.path.splitext(name) + ziel = os.path.join(ziel_dir, name) + n = 2 + while os.path.exists(ziel) and not _gleich(quelle, ziel): + ziel = os.path.join(ziel_dir, f"{stamm}-{n}{endung}") + n += 1 + try: + shutil.copyfile(quelle, ziel) + print(f"[bilder] uebernommen: {quelle} -> {ziel}") + except OSError as e: + print(f"[bilder] FEHLER beim Kopieren ({e}) - merke den Originalpfad") + return quelle + return f"{ORDNER}/{os.path.basename(ziel)}" + + +def _gleich(a, b): + """Zwei Dateien byte-gleich? Verhindert 'logo-2.png' beim zweiten Waehlen desselben Bilds.""" + try: + if os.path.getsize(a) != os.path.getsize(b): + return False + with open(a, "rb") as fa, open(b, "rb") as fb: + return fa.read() == fb.read() + except OSError: + return False + + +def aufloesen(pfad): + """Gespeicherten Pfad -> existierender absoluter Pfad, sonst "". + + Ein relativer Pfad wird erst neben dem Programm gesucht (BASE_DIR, dort liegt + der Bilderordner), dann im gebuendelten Ressourcenordner der .exe - so findet + die exe ihr mitgeliefertes Standardlogo, der Nutzer aber sein eigenes. + """ + pfad = (pfad or "").strip() + if not pfad: + return "" + if os.path.isabs(pfad): + return pfad if os.path.exists(pfad) else "" + for basis in (config.BASE_DIR, config.RESOURCE_DIR): + kandidat = os.path.join(basis, pfad) + if os.path.exists(kandidat): + return kandidat + return "" + + +def laden(pfad): + """(ImageReader, breite, hoehe) oder (None, 0, 0). Meldet, warum es nicht ging.""" + voll = aufloesen(pfad) + if not voll: + if (pfad or "").strip(): + print(f"[bilder] nicht gefunden: {pfad}") + return None, 0, 0 + try: + from reportlab.lib.utils import ImageReader + img = ImageReader(voll) + iw, ih = img.getSize() + return img, iw, ih + except Exception as e: # noqa: BLE001 + print(f"[bilder] '{voll}' laesst sich nicht lesen: {e}") + return None, 0, 0 + + +def einpassen(iw, ih, box_w, box_h): + """Groesse im Kasten, Seitenverhaeltnis bleibt. Nie groesser als das Original.""" + if not iw or not ih: + return 0, 0 + skala = min(box_w / iw, box_h / ih) + return iw * skala, ih * skala diff --git a/config.py b/config.py index 90f6d5e..e3058b1 100644 --- a/config.py +++ b/config.py @@ -124,6 +124,11 @@ DEFAULT_FIRMA = { "email": "E-Mail kontakt@example.de", "telefon": "Telefon +49 (0) 000 0000000", "logo": "assets/logo.png", # Bilddatei -> oben links auf der Rechnung (relativ zum Tool-Ordner) + # Bild fuer die Fusszeile: ein schmaler Streifen UNTER den Fusstexten. Firma, + # Anschrift, Bank und Steuernummer bleiben immer gezeichnet - sie kommen aus + # den Einstellungen und duerfen nicht in einem Bild verschwinden, das niemand + # nachlesen kann. Leer = die Rechnung sieht aus wie bisher. + "fussbild": "", } # Festtexte unten auf der Rechnung (aus der Vorlage). @@ -135,8 +140,16 @@ DEFAULT_TEXTE = { "hinweis": "* Bei Zahlung per Überweisung bitte die Rechnungsnummer angeben *", } +# Aussehen der Rechnung. EINE Farbe - die helle Flaeche im Tabellenkopf wird im +# Renderer daraus gemischt. Jede Firma faerbt ihr Blatt selbst; ein Handwerker +# will kein Camping-Gruen. +DEFAULT_DESIGN = { + "akzent": "#1f5c3d", +} + DEFAULT_CONFIG = { "firma": DEFAULT_FIRMA, + "design": DEFAULT_DESIGN, "texte": DEFAULT_TEXTE, "katalog": DEFAULT_KATALOG, "montage": DEFAULT_MONTAGE, diff --git a/einstellungen.py b/einstellungen.py index ddc2b54..edc6b78 100644 --- a/einstellungen.py +++ b/einstellungen.py @@ -8,9 +8,10 @@ hart im Code: Steuersaetze, Preise, Firmendaten, Rechnungsnummernkreis. import datetime import os import tkinter as tk -from tkinter import ttk, messagebox, filedialog +from tkinter import ttk, messagebox, filedialog, colorchooser import berechnung +import bilder import config from helfer import parse_num @@ -333,7 +334,7 @@ class EinstellungenMixin: d.transient(self) d.grab_set() self._style_dialog(d) - d.geometry("640x640") + d.geometry("640x740") frm = ttk.Frame(d, padding=12) frm.pack(fill="both", expand=True) @@ -353,39 +354,91 @@ class EinstellungenMixin: frm.columnconfigure(1, weight=1) base = len(felder) - # Logo (Bilddatei) mit Durchsuchen / Entfernen - ttk.Label(frm, text="Logo (oben links)").grid(row=base, column=0, sticky="w", pady=2) - logo_row = ttk.Frame(frm) - logo_row.grid(row=base, column=1, sticky="ew", padx=(8, 0), pady=2) - v_logo = tk.StringVar(value=self.cfg["firma"].get("logo", "")) - ttk.Entry(logo_row, textvariable=v_logo).pack(side="left", fill="x", expand=True) + # Bilder auf der Rechnung: Kopf (oben links) und Fuss (Streifen unten). + # Beide funktionieren gleich, deshalb baut EINE Funktion beide Zeilen - + # sonst laufen sie beim naechsten Umbau auseinander. + bild_vars = {} - def logo_waehlen(): - p = filedialog.askopenfilename( - title="Logo auswählen", - filetypes=[("Bilder", "*.png *.jpg *.jpeg *.gif"), ("Alle Dateien", "*.*")]) - if p: - v_logo.set(p) + def bild_zeile(zeile, key, beschriftung): + ttk.Label(frm, text=beschriftung).grid(row=zeile, column=0, sticky="nw", pady=2) + kasten = ttk.Frame(frm) + kasten.grid(row=zeile, column=1, sticky="ew", padx=(8, 0), pady=2) + v = tk.StringVar(value=self.cfg["firma"].get(key, "")) + reihe = ttk.Frame(kasten) + reihe.pack(fill="x") + ttk.Entry(reihe, textvariable=v).pack(side="left", fill="x", expand=True) - ttk.Button(logo_row, text="Durchsuchen…", command=logo_waehlen).pack(side="left", padx=(6, 0)) - ttk.Button(logo_row, text="Entfernen", command=lambda: v_logo.set("")).pack(side="left", padx=(4, 0)) + def waehlen(): + p = filedialog.askopenfilename( + title=beschriftung + " auswählen", + filetypes=[("Bilder", "*.png *.jpg *.jpeg *.gif"), ("Alle Dateien", "*.*")], + parent=d) + if p: + # Das Bild wird in den Ordner "bilder" neben das Programm + # KOPIERT. Der Pfad zum Desktop waere morgen tot - und das + # faellt erst beim Drucken auf. + v.set(bilder.uebernehmen(p)) - ttk.Label(frm, text="Danktext 1").grid(row=base + 1, column=0, sticky="nw", pady=2) + ttk.Button(reihe, text="Durchsuchen…", command=waehlen).pack(side="left", padx=(6, 0)) + ttk.Button(reihe, text="Entfernen", command=lambda: v.set("")).pack(side="left", padx=(4, 0)) + bild_vars[key] = v + + # Ausgetauscht wird nur das BILD. Firmenname, Anschrift, Bank und + # Steuernummer stehen weiter gezeichnet auf dem Blatt - sie kommen aus den + # Feldern darueber und duerfen in keinem Bild verschwinden. + bild_zeile(base, "logo", "Bild oben (Logo)") + bild_zeile(base + 1, "fussbild", "Bild unten (Streifen)") + + # Farbe der Rechnung: Ueberschriften, Linie unter dem Kopf, Tabellenkopf. + # EINE Farbe - die helle Flaeche wird im Renderer daraus gemischt. + ttk.Label(frm, text="Farbe der Rechnung").grid(row=base + 2, column=0, sticky="w", pady=2) + farb_reihe = ttk.Frame(frm) + farb_reihe.grid(row=base + 2, column=1, sticky="ew", padx=(8, 0), pady=2) + v_farbe = tk.StringVar(value=(self.cfg.get("design", {}) or {}).get( + "akzent", config.DEFAULT_DESIGN["akzent"])) + probe = tk.Label(farb_reihe, width=6, relief="solid", borderwidth=1) + + def probe_zeigen(*_): + wert = v_farbe.get().strip() + try: + probe.configure(background=wert) + except tk.TclError: + # Unlesbare Farbe: das Feld bleibt grau, gespeichert wird sie nicht. + probe.configure(background=self.col_field) + + def farbe_waehlen(): + _, hexwert = colorchooser.askcolor(color=v_farbe.get().strip() or None, + title="Farbe der Rechnung", parent=d) + if hexwert: + v_farbe.set(hexwert) + + probe.pack(side="left") + ttk.Entry(farb_reihe, textvariable=v_farbe, width=12).pack(side="left", padx=(6, 0)) + ttk.Button(farb_reihe, text="Wählen…", command=farbe_waehlen).pack(side="left", padx=(6, 0)) + ttk.Button(farb_reihe, text="Zurücksetzen", + command=lambda: v_farbe.set(config.DEFAULT_DESIGN["akzent"])).pack(side="left", padx=(4, 0)) + v_farbe.trace_add("write", probe_zeigen) + probe_zeigen() + + ttk.Label(frm, text="Danktext 1").grid(row=base + 3, column=0, sticky="nw", pady=2) t1 = tk.Text(frm, width=58, height=3, wrap="word", bg=self.col_field, fg=self.col_fg, insertbackground=self.col_fg) t1.insert("1.0", self.cfg["texte"].get("dank1", "")) - t1.grid(row=base + 1, column=1, sticky="ew", padx=(8, 0), pady=2) - ttk.Label(frm, text="Danktext 2").grid(row=base + 2, column=0, sticky="nw", pady=2) + t1.grid(row=base + 3, column=1, sticky="ew", padx=(8, 0), pady=2) + ttk.Label(frm, text="Danktext 2").grid(row=base + 4, column=0, sticky="nw", pady=2) t2 = tk.Text(frm, width=58, height=3, wrap="word", bg=self.col_field, fg=self.col_fg, insertbackground=self.col_fg) t2.insert("1.0", self.cfg["texte"].get("dank2", "")) - t2.grid(row=base + 2, column=1, sticky="ew", padx=(8, 0), pady=2) - ttk.Label(frm, text="Hinweiszeile").grid(row=base + 3, column=0, sticky="w", pady=2) + t2.grid(row=base + 4, column=1, sticky="ew", padx=(8, 0), pady=2) + ttk.Label(frm, text="Hinweiszeile").grid(row=base + 5, column=0, sticky="w", pady=2) vh = tk.StringVar(value=self.cfg["texte"].get("hinweis", "")) - ttk.Entry(frm, textvariable=vh, width=58).grid(row=base + 3, column=1, sticky="ew", padx=(8, 0), pady=2) + ttk.Entry(frm, textvariable=vh, width=58).grid(row=base + 5, column=1, sticky="ew", padx=(8, 0), pady=2) def speichern(): for key, v in vars_.items(): self.cfg["firma"][key] = v.get() - self.cfg["firma"]["logo"] = v_logo.get().strip() + for key, v in bild_vars.items(): + wert = v.get() + self.cfg["firma"][key] = wert.strip() if isinstance(wert, str) else bool(wert) + self.cfg.setdefault("design", {})["akzent"] = v_farbe.get().strip() or config.DEFAULT_DESIGN["akzent"] self.cfg["texte"]["dank1"] = t1.get("1.0", "end").strip() self.cfg["texte"]["dank2"] = t2.get("1.0", "end").strip() self.cfg["texte"]["hinweis"] = vh.get().strip() @@ -394,7 +447,7 @@ class EinstellungenMixin: d.destroy() btns = ttk.Frame(frm) - btns.grid(row=base + 4, column=0, columnspan=2, pady=(12, 0), sticky="e") + btns.grid(row=base + 6, column=0, columnspan=2, pady=(12, 0), sticky="e") ttk.Button(btns, text="Speichern", command=speichern).pack(side="right", padx=4) ttk.Button(btns, text="Abbrechen", command=d.destroy).pack(side="right") diff --git a/pdf_renderer.py b/pdf_renderer.py index 0a64664..28daf93 100644 --- a/pdf_renderer.py +++ b/pdf_renderer.py @@ -15,7 +15,6 @@ import json from reportlab.lib.pagesizes import A4 from reportlab.lib.units import mm -from reportlab.lib.utils import ImageReader from reportlab.lib import colors from reportlab.lib.enums import TA_RIGHT, TA_LEFT, TA_CENTER from reportlab.lib.styles import ParagraphStyle @@ -24,6 +23,7 @@ from reportlab.platypus import ( Flowable, ) +import bilder import config from berechnung import eur, eur_kurz, runde @@ -46,11 +46,49 @@ class _AmtMarke(Flowable): self._merker["seite"] = self.canv.getPageNumber() # ---- Farben / Masse --------------------------------------------------------- -ACCENT = colors.HexColor("#1f5c3d") # gedecktes Gruen (Camping) +# Die Akzentfarbe gehoert der Firma, nicht dem Programm: Ueberschriften, die +# Linie unter dem Kopf und der Tabellenkopf tragen sie. Ein Handwerker will kein +# Camping-Gruen auf seiner Rechnung. Eingestellt wird EINE Farbe - die helle +# Flaeche im Tabellenkopf wird daraus gemischt, damit niemand zwei Farben +# aufeinander abstimmen muss. +AKZENT_VORGABE = "#1f5c3d" # gedecktes Gruen (Camping) + +ACCENT = colors.HexColor(AKZENT_VORGABE) GREY_BG = colors.HexColor("#eef1ee") LINE = colors.HexColor("#9aa39c") DARK = colors.HexColor("#222222") + +def _farbe(wert, vorgabe): + """'#1f5c3d' -> Farbe. Alles Unlesbare faellt auf die Vorgabe zurueck. + + Eine kaputte Farbe in der config.json darf niemals das Schreiben der + Rechnung verhindern - dann steht der Gast an der Schranke. + """ + try: + return colors.HexColor(str(wert).strip()) + except (ValueError, AttributeError): + if str(wert).strip(): + print(f"[pdf] Farbe '{wert}' nicht lesbar - nehme {vorgabe}") + return colors.HexColor(vorgabe) + + +def _design_anwenden(cfg): + """Firmenfarbe uebernehmen, bevor die Stile gebaut werden. + + Die Farben stehen als Modulwerte da, weil 13 Stellen im Layout sie lesen. + Sie werden hier EINMAL je Rechnung gesetzt - das Programm rendert nie zwei + Rechnungen gleichzeitig. + """ + global ACCENT, GREY_BG + design = (cfg or {}).get("design") or {} + ACCENT = _farbe(design.get("akzent", AKZENT_VORGABE), AKZENT_VORGABE) + # Helle Flaeche = 8 % Akzent auf Weiss. So passt der Tabellenkopf zu jeder + # gewaehlten Farbe, ohne dass jemand einen zweiten Wert pflegen muss. + GREY_BG = colors.Color(1 - 0.08 * (1 - ACCENT.red), + 1 - 0.08 * (1 - ACCENT.green), + 1 - 0.08 * (1 - ACCENT.blue)) + MARGIN_L = 18 * mm MARGIN_R = 18 * mm MARGIN_TOP = 40 * mm # Platz fuer den Kopf @@ -100,36 +138,46 @@ def _styles(): # ---- Kopf + Fusszeile (auf jeder Seite gezeichnet) -------------------------- -def _kopf_fuss(canvas, doc, cfg, amt=False): +def _vorschau_marke(canvas): + """Schraeg ueber das Blatt: das hier ist KEINE Rechnung. + + Die Vorschau soll zeigen, wie das Blatt aussehen wird - ausgedruckt oder + weitergereicht darf sie nie mit der Rechnung verwechselt werden. Sonst haette + der Gast ein Blatt in der Hand, das keine Nummer verbraucht hat und in keiner + Buchhaltung steht. + """ + canvas.saveState() + canvas.setFont("Helvetica-Bold", 62) + canvas.setFillColor(colors.Color(0.55, 0.55, 0.55, alpha=0.22)) + canvas.translate(PAGE_W / 2, PAGE_H / 2) + canvas.rotate(38) + canvas.drawCentredString(0, 0, "VORSCHAU") + canvas.setFont("Helvetica-Bold", 15) + canvas.drawCentredString(0, -22 * mm, "keine Rechnung") + canvas.restoreState() + + +def _kopf_fuss(canvas, doc, cfg, amt=False, vorschau=False): """Kopf und Fuss einer Seite. amt=True -> Blatt fuer das Amt (siehe Fusszeile).""" firma = cfg["firma"] canvas.saveState() + if vorschau: + _vorschau_marke(canvas) # --- Kopf --- - logo = (firma.get("logo") or "").strip() - # relativen Pfad (z.B. "assets/logo.png") portabel aufloesen: - # erst neben Tool/exe, dann im gebuendelten Ressourcen-Ordner (.exe) - if logo and not os.path.isabs(logo): - for _base in (config.BASE_DIR, config.RESOURCE_DIR): - _cand = os.path.join(_base, logo) - if os.path.exists(_cand): - logo = _cand - break + # Das Kopfbild liegt oben links, Firmenname und Untertitel stehen rechts + # daneben - genau wie bisher. Austauschbar ist nur das BILD; die Texte + # kommen aus den Einstellungen und bleiben gezeichnet. + img, iw, ih = bilder.laden(firma.get("logo")) + line_y = PAGE_H - 25.5 * mm # Hoehe der Trennlinie ohne Bild (wie bisher) logo_ok = False - if logo and os.path.exists(logo): - try: - img = ImageReader(logo) - iw, ih = img.getSize() - box_w, box_h = 60 * mm, 20 * mm # max. Logo-Box oben links - scale = min(box_w / iw, box_h / ih) - dw, dh = iw * scale, ih * scale - ly = PAGE_H - 9 * mm - dh # Oberkante ~9mm vom Blattrand - canvas.drawImage(img, MARGIN_L, ly, width=dw, height=dh, - preserveAspectRatio=True, mask="auto") - logo_ok = True - line_y = ly - 3 * mm - except Exception as e: # noqa: BLE001 - print("[pdf] Logo konnte nicht geladen werden:", e) + if img: + dw, dh = bilder.einpassen(iw, ih, 60 * mm, 20 * mm) # Kasten oben links + ly = PAGE_H - 9 * mm - dh # Oberkante ~9mm vom Blattrand + canvas.drawImage(img, MARGIN_L, ly, width=dw, height=dh, + preserveAspectRatio=True, mask="auto") + logo_ok = True + line_y = ly - 3 * mm if logo_ok: # Firmenname + Untertitel rechtsbuendig neben dem Logo @@ -172,6 +220,20 @@ def _kopf_fuss(canvas, doc, cfg, amt=False): col_m = MARGIN_L + CONTENT_W * 0.40 col_r = PAGE_W - MARGIN_R + # Das Fusszeilen-Bild steht auf dem AMT-BLATT NICHT. Ein fertiges + # Briefpapier-Band traegt fast immer Bank und Steuernummer - und genau die + # duerfen dort nicht auftauchen (siehe Trennung oben). Das Amt bekommt + # deshalb immer die gezeichnete Fusszeile, auch wenn der Nutzer den Haken + # "Firmenangaben stehen im Bild" gesetzt hat. + fuss_img, fiw, fih = (None, 0, 0) if amt else bilder.laden(firma.get("fussbild")) + if fuss_img: + # Schmaler Streifen UNTER den Fusstexten. Die Texte bleiben, wo sie sind - + # Firma, Anschrift, Bank und Steuernummer stehen auf jeder Rechnung, egal + # welches Bild jemand einstellt. + dw, dh = bilder.einpassen(fiw, fih, CONTENT_W, 17 * mm) + canvas.drawImage(fuss_img, MARGIN_L + (CONTENT_W - dw) / 2, 7 * mm, + width=dw, height=dh, preserveAspectRatio=True, mask="auto") + rows_l = [] if amt else [firma.get("bank", ""), firma.get("iban", ""), firma.get("bic", "")] rows_m = [firma.get("inhaber", "")] if amt else [firma.get("inhaber", ""), firma.get("steuernummer", "")] @@ -667,7 +729,7 @@ def _kenndaten(rechnung, kopf): return json.dumps(daten, ensure_ascii=False) -def render_rechnung(pfad, cfg, rechnung, kopf): +def render_rechnung(pfad, cfg, rechnung, kopf, vorschau=False): """ pfad : Zielpfad der PDF cfg : geladene Konfiguration @@ -679,6 +741,7 @@ def render_rechnung(pfad, cfg, rechnung, kopf): Letzte Seite = Blatt fuers Amt: KEINE Beherbergungssteuer (auch nicht im Gesamt), keine Zwischensumme, keine Bankverbindung, keine Steuernummer. """ + _design_anwenden(cfg) # Firmenfarbe VOR den Stilen - sie lesen sie mit st = _styles() def bauen(ziel, amt_seite): @@ -702,7 +765,9 @@ def render_rechnung(pfad, cfg, rechnung, kopf): _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont=True) # Amt def seite(c, d): - _kopf_fuss(c, d, cfg, amt=(amt_seite is not None and c.getPageNumber() >= amt_seite)) + _kopf_fuss(c, d, cfg, + amt=(amt_seite is not None and c.getPageNumber() >= amt_seite), + vorschau=vorschau) doc.build(story, onFirstPage=seite, onLaterPages=seite) diff --git a/pruef_bilder.py b/pruef_bilder.py new file mode 100644 index 0000000..16bbe75 --- /dev/null +++ b/pruef_bilder.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: Kopf- und Fussbild auf der Rechnung. + +Drei Dinge muessen stimmen, sonst faellt es erst beim Drucken auf: + +1. Ein gewaehltes Bild wird KOPIERT (Ordner "bilder"), nicht nur verlinkt - + sonst ist das Logo weg, sobald der Nutzer seinen Desktop aufraeumt. +2. Das Fussbild steht auf der Kundenrechnung, aber NICHT auf dem Amt-Blatt: + ein Briefpapier-Band traegt Bank und Steuernummer, und die haben auf dem + Blatt fuers Amt nichts zu suchen. +3. Der Haken "Angaben stehen im Bild" laesst die gezeichneten Texte weg - + und zwar nur dort, wo er gilt. +""" +import json +import os +import shutil +import sys +import tempfile + +QUELLE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, QUELLE) + +import config # noqa: E402 + +tmp = tempfile.mkdtemp(prefix="bilder_pruef_") +config.BASE_DIR = tmp +config.CONFIG_PATH = os.path.join(tmp, "config.json") +shutil.copy(os.path.join(QUELLE, "config.json"), config.CONFIG_PATH) + +import bilder # noqa: E402 +import pdf_renderer # noqa: E402 +from berechnung import berechne # noqa: E402 + +fehler = [] + + +def pruefe(bedingung, text): + print(("OK | " if bedingung else "FEHL | ") + text) + if not bedingung: + fehler.append(text) + + +def testbild(pfad, farbe): + """Kleines PNG erzeugen - der Pruefstand braucht keine echten Kundenbilder.""" + from PIL import Image + Image.new("RGB", (600, 120), farbe).save(pfad) + return pfad + + +# ---- 1. Uebernehmen: kopieren, nicht verlinken ----------------------------- +fremd = os.path.join(tmp, "vom_desktop.png") +testbild(fremd, (10, 90, 60)) +gespeichert = bilder.uebernehmen(fremd) +pruefe(gespeichert == "bilder/vom_desktop.png", f"Pfad wird kurz gemerkt: {gespeichert}") +pruefe(os.path.exists(os.path.join(tmp, "bilder", "vom_desktop.png")), "Bild liegt im Ordner bilder/") + +# Das Original loeschen - die Rechnung muss trotzdem ein Bild haben. +os.remove(fremd) +pruefe(bool(bilder.aufloesen(gespeichert)), "Bild bleibt da, wenn das Original geloescht wird") + +# Dasselbe Bild zweimal waehlen -> kein zweites Exemplar. +shutil.copy(os.path.join(tmp, "bilder", "vom_desktop.png"), fremd) +pruefe(bilder.uebernehmen(fremd) == "bilder/vom_desktop.png", "gleiches Bild zweimal -> kein Duplikat") +# Anderer Inhalt, gleicher Name -> das alte Bild wird NICHT ueberschrieben. +testbild(fremd, (200, 30, 30)) +zweit = bilder.uebernehmen(fremd) +pruefe(zweit == "bilder/vom_desktop-2.png", f"gleicher Name, anderes Bild -> {zweit}") + +# ---- 2. Rendern: Kunde vs. Amt -------------------------------------------- +cfg = config.load_config() +cfg["firma"]["logo"] = bilder.uebernehmen(testbild(os.path.join(tmp, "kopf.png"), (20, 60, 120))) +cfg["firma"]["fussbild"] = bilder.uebernehmen(testbild(os.path.join(tmp, "fuss.png"), (120, 60, 20))) +cfg["firma"]["bank"] = "Bank Testbank" + +mengen = {1: {"anzahl": 3, "personen": 0}} +r = berechne(cfg["katalog"], mengen, cfg) +kopf = {"art": "rechnung", "rechnungsnummer": "2026-999", "datum": "05.09.2026", + "kunde_zeilen": ["Herr", "Max Muster", "Musterweg 1", "04416 Markkleeberg"], + "anreise": "01.09.2026", "abreise": "04.09.2026", "naechte": 3} +pfad = os.path.join(tmp, "probe.pdf") +pdf_renderer.render_rechnung(pfad, cfg, r, kopf) +pruefe(os.path.exists(pfad), "PDF mit beiden Bildern entsteht") + + +def seiten_bilder_und_text(pdf): + """Je Seite: (Anzahl eingebetteter Bilder, Text).""" + from pypdf import PdfReader + raus = [] + for seite in PdfReader(pdf).pages: + xo = seite.get("/Resources", {}).get("/XObject", {}) + try: + xo = xo.get_object() + except AttributeError: + pass + anzahl = sum(1 for k in xo if xo[k].get_object().get("/Subtype") == "/Image") + raus.append((anzahl, seite.extract_text() or "")) + return raus + + +seiten = seiten_bilder_und_text(pfad) +pruefe(len(seiten) >= 2, f"Kundenblatt + Amt-Blatt: {len(seiten)} Seiten") +kunde_bilder, kunde_text = seiten[0] +amt_bilder, amt_text = seiten[-1] +pruefe(kunde_bilder == 2, f"Kundenblatt traegt Kopf- UND Fussbild ({kunde_bilder})") +pruefe(amt_bilder == 1, f"Amt-Blatt traegt NUR das Kopfbild ({amt_bilder})") +pruefe("Testbank" in kunde_text, "Bankverbindung steht auf der Kundenrechnung") +pruefe("Testbank" not in amt_text, "Bankverbindung steht NICHT auf dem Amt-Blatt") + +# ---- 3. Die Firmenfarbe faerbt das Blatt ---------------------------------- +# Jede Firma faerbt ihre Rechnung selbst. Geprueft wird, dass die gewaehlte +# Farbe wirklich im PDF landet - und dass eine kaputte Eingabe das Schreiben +# NICHT verhindert, sondern still auf die Vorgabe zurueckfaellt. +cfg["design"] = {"akzent": "#8a1f1f"} +pfad2 = os.path.join(tmp, "probe_rot.pdf") +pdf_renderer.render_rechnung(pfad2, cfg, r, kopf) +pruefe(pdf_renderer.ACCENT.hexval().endswith("8a1f1f"), + f"gewaehlte Farbe steht im Blatt: {pdf_renderer.ACCENT.hexval()}") +pruefe(pdf_renderer.GREY_BG.red > 0.9, + "helle Flaeche wird aus der Farbe gemischt (bleibt hell)") + +cfg["design"] = {"akzent": "gruen bitte"} +pfad3 = os.path.join(tmp, "probe_kaputt.pdf") +pdf_renderer.render_rechnung(pfad3, cfg, r, kopf) +pruefe(os.path.exists(pfad3), "kaputte Farbe verhindert die Rechnung NICHT") +pruefe(pdf_renderer.ACCENT.hexval().endswith("1f5c3d"), "kaputte Farbe faellt auf die Vorgabe zurueck") + +cfg["design"] = {"akzent": pdf_renderer.AKZENT_VORGABE} + +# Ohne Bilder muss das Blatt aussehen wie immer. +cfg["firma"]["logo"] = "" +cfg["firma"]["fussbild"] = "" +pfad4 = os.path.join(tmp, "probe_ohne_bild.pdf") +pdf_renderer.render_rechnung(pfad4, cfg, r, kopf) +seiten3 = seiten_bilder_und_text(pfad4) +pruefe(seiten3[0][0] == 0, "ohne Bilder: keine Bilder im PDF") +pruefe(cfg["firma"]["name"] in seiten3[0][1], "ohne Bild steht der Firmenname gezeichnet oben") + +print() +print(f"Ordner: {tmp}") +if fehler: + print(f"FEHLGESCHLAGEN: {len(fehler)}") + for f in fehler: + print(" -", f) + sys.exit(1) +print("ALLES GRUEN") diff --git a/pruef_vorschau.py b/pruef_vorschau.py new file mode 100644 index 0000000..374c1a6 --- /dev/null +++ b/pruef_vorschau.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: der Vorschau-Knopf. + +Die Vorschau soll zeigen, wie das Blatt aussehen WIRD - und dabei nichts +anfassen. Drei Zusicherungen, die alle drei still brechen koennten: + +1. Sie verbraucht KEINE Rechnungsnummer und traegt nichts ins Nummernbuch. + Sonst fehlt in der Buchhaltung eine Nummer, fuer die es kein Blatt gibt. +2. Sie legt nichts im Rechnungsordner ab - dort liegt die Buchhaltung. +3. Auf jeder Seite steht "VORSCHAU - keine Rechnung". Ein Blatt ohne diesen + Hinweis koennte ausgedruckt beim Gast landen und als Rechnung gelten. +""" +import json +import os +import shutil +import sys +import tempfile +import threading as _th + +QUELLE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, QUELLE) + +tmp = tempfile.mkdtemp(prefix="vorschau_pruef_") +ordner = os.path.join(tmp, "rechnungen") +os.makedirs(ordner) + +import config # noqa: E402 +shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json")) +config.BASE_DIR = tmp +config.CONFIG_PATH = os.path.join(tmp, "config.json") +roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) +roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +roh["output_dir"] = ordner +json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False) + +os.environ["CAMPINGHOF_TEST"] = "1" +import app as A # noqa: E402 +from tkinter import messagebox # noqa: E402 + + +def _reissleine(): + print("ABBRUCH | Pruefstand haengt (Zeitgrenze) - vermutlich ein Dialog") + os._exit(2) + + +_wecker = _th.Timer(120, _reissleine) +_wecker.daemon = True +_wecker.start() + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + k = sys.stdout.encoding or "utf-8" + print(zeile.encode(k, "replace").decode(k)) + if not bedingung: + fehler.append(text) + + +messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None +messagebox.askyesno = lambda *a, **k: True + +# Die Vorschau oeffnet den PDF-Betrachter - im Pruefstand wird nur gemerkt, WAS +# sie oeffnen wollte. +geoeffnet = [] +A.os.startfile = lambda p, *a, **k: geoeffnet.append(p) + +f = A.RechnungsApp() +f.update() +f.cfg["output_dir"] = ordner +erste = sorted(f.anzahl_vars)[0] + +f.k_vorname.set("Anna") +f.k_name.set("Beispiel") +f.k_strasse.set("Musterweg 1") +f.k_plzort.set("12345 Musterstadt") +f.anzahl_vars[erste].set("3") +f.update() + +nummer_vorher = f.r_nummer.get() +zaehler_vorher = f.cfg.get("rechnung_zaehler") + +f.vorschau_zeigen() + +pruefe(len(geoeffnet) == 1, f"Vorschau oeffnet genau ein Blatt ({len(geoeffnet)})") +pfad = geoeffnet[0] if geoeffnet else "" +pruefe(os.path.exists(pfad), "Vorschau-PDF wurde geschrieben") +pruefe(os.path.abspath(ordner) not in os.path.abspath(pfad), + "Vorschau liegt NICHT im Rechnungsordner") +pruefe(not os.listdir(ordner), f"Rechnungsordner bleibt leer ({os.listdir(ordner)})") +pruefe(f.r_nummer.get() == nummer_vorher, + f"Rechnungsnummer unveraendert ({nummer_vorher} -> {f.r_nummer.get()})") +pruefe(f.cfg.get("rechnung_zaehler") == zaehler_vorher, "Zaehler unveraendert") + +from pypdf import PdfReader # noqa: E402 +seiten = [s.extract_text() or "" for s in PdfReader(pfad).pages] +pruefe(all("VORSCHAU" in t for t in seiten), + f"'VORSCHAU' steht auf jeder Seite ({len(seiten)} Seiten)") +pruefe(all("keine Rechnung" in t for t in seiten), "'keine Rechnung' steht auf jeder Seite") + +# Und die echte Rechnung danach traegt die Marke NICHT. +f.pdf_erstellen() +echte = [os.path.join(ordner, n) for n in os.listdir(ordner) if n.lower().endswith(".pdf")] +pruefe(len(echte) == 1, f"danach entsteht genau eine echte Rechnung ({len(echte)})") +if echte: + text = "".join((s.extract_text() or "") for s in PdfReader(echte[0]).pages) + pruefe("VORSCHAU" not in text, "die echte Rechnung traegt KEINE Vorschau-Marke") + +f.destroy() +print() +if fehler: + print(f"FEHLGESCHLAGEN: {len(fehler)}") + for x in fehler: + print(" -", x) + sys.exit(1) +print("ALLES GRUEN") From ca9ac212cfc9b16314ae067f2d829d4131824c4d Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 18:24:59 +0200 Subject: [PATCH 03/34] Amt-Blatt raus, Bedienung ueber die API, Erststart fragt nach zwei Wegen Das zweite Blatt "fuer das Amt" trug DIESELBE Rechnungsnummer, aber einen anderen Gesamtbetrag. Mehrere Blaetter zum selben Umsatz mit verschiedenen Endbetraegen sehen aus, als werde ueber verschiedene Umsaetze abgerechnet - bei einer Pruefung ein Problem. Ersatzlos entfallen; was die Stadt braucht, rechnet das Steuerjournal aus den Kenndaten der PDF. Mit dem Blatt fielen _AmtMarke, gesamtrechnung_betont und der doppelte Renderlauf weg. Die API kann das Fenster jetzt BEDIENEN - mit Schluessel wie bei einem SSH-Key: 32 Byte Zufall in api_schluessel.txt im gemeinsamen Ordner, den nur das Steuerjournal und der Betreiber lesen. Ohne gueltigen Schluessel kein Zutritt (compare_digest). ping und schau_nach bleiben schluessellos, sonst kann ein aelteres Journal nicht mehr anklopfen. Was einen BELEG schreibt, geht nur im Testlauf - eine Fernbedienung, die echte Rechnungen ausstellt, hat in einer Buchhaltung nichts zu suchen. api.py liegt wie immer in beiden Programmen. Der Erststart fragte nach "der zuletzt vergebenen Nummer" - das holt niemanden ab, der bei 0 anfaengt. Jetzt zwei Wege: bei 0 anfangen ODER die eigene Zaehlung weiterfuehren. Unter das schon Vergebene kommt keiner der beiden. pruef_nummernsperre bediente den Dialog nur halb: nach einer abgelehnten Zahl bleibt er offen (so soll er), niemand drueckte "Spaeter" - das Programm wartete in wait_window() ewig. Das war schon vor diesem Umbau so. Neu: pruef_api.py. Alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- AUFGABE_RECHTSSICHER_BILDER_VORSCHAU.md | 107 +++++++++ api.py | 181 ++++++++++++++- app.py | 152 +++++++++++-- config.py | 7 + pdf_renderer.py | 288 ++++++++++-------------- pruef_api.py | 168 ++++++++++++++ pruef_bilder.py | 11 +- pruef_montage.py | 10 +- pruef_nummernsperre.py | 11 + pruefsteuerung.py | 103 +++++++++ theme.py | 9 +- 11 files changed, 835 insertions(+), 212 deletions(-) create mode 100644 AUFGABE_RECHTSSICHER_BILDER_VORSCHAU.md create mode 100644 pruef_api.py create mode 100644 pruefsteuerung.py diff --git a/AUFGABE_RECHTSSICHER_BILDER_VORSCHAU.md b/AUFGABE_RECHTSSICHER_BILDER_VORSCHAU.md new file mode 100644 index 0000000..38903bb --- /dev/null +++ b/AUFGABE_RECHTSSICHER_BILDER_VORSCHAU.md @@ -0,0 +1,107 @@ +# Rechnungstool: rechtssicher, gestaltbar, mit Vorschau + +**Stand 05.09.2026 — in Arbeit.** Programm `C:\claude\rechnungstool`, +Repo `git.pcore.de/TheMockTv/rechnungstool` (Pre-Tag `pre/rechtssicher-bilder`). + +Seine Ansage: *„wir bauen den rechnungs ersteller so um das der nun richtig +rechtlich sicher ist und die kopf und fuss zeile mit eigenen bildern import"* — +und im Lauf des Umbaus dazu: *„das die firmen das designen können"*, +*„eine vorschau butten wäre gut … sonst haben die den storno auf wand"*, +*„das mit rechnung an das amt kommt raus, das ist nicht § conform"*. + +## 1. Bilder und Farbe gehören der Firma (fertig) + +Bis jetzt war das Blatt auf EINEN Betrieb gebaut: Camping-Grün fest im Code, +das Logo ein Pfad in der config. + +- **`bilder.py`** (neu): ein gewähltes Bild wird in den Ordner `bilder/` neben + die `config.json` **kopiert**, gemerkt wird nur `bilder/logo.png`. + Der Grund: ein Pfad auf den Desktop ist tot, sobald dort jemand aufräumt — + und das fällt erst beim Drucken auf. Gleicher Name, anderes Bild → `-2`, + nie überschreiben. +- **Kopfbild** (Logo, oben links) und **Fußbild** (schmaler Streifen unten) + sind austauschbar. Das Layout bleibt, wie es war. +- **Firmenname, Anschrift, Bank, Steuernummer bleiben gezeichnet.** Kein Bild + kann sie ersetzen — die Steuernummer ist Pflichtangabe + (§ 14 Abs. 4 Nr. 2 UStG), und was in einem Bild steht, kann niemand prüfen. + (Ein Haken „Angaben stehen im Bild" war gebaut und ist auf seine Ansage hin + wieder rausgeflogen.) +- **Farbe der Rechnung**: EIN Wert (`design.akzent`), Hex-Feld **und** + Farbwähler in den Einstellungen. Die helle Fläche im Tabellenkopf wird daraus + gemischt — niemand muss zwei Farben aufeinander abstimmen. Eine unlesbare + Farbe fällt still auf die Vorgabe zurück, statt das Schreiben der Rechnung zu + verhindern. + +Prüfstand: **`pruef_bilder.py`**. + +## 2. Vorschau-Knopf (fertig) + +Seine Begründung: *„sonst haben die den storno auf wand"* — eine ausgestellte +Rechnung lässt sich nur noch über Storno oder Berichtigung geradeziehen. + +Der Knopf zeigt das fertige Blatt, **bevor** es eine Rechnung wird: + +- verbraucht **keine** Rechnungsnummer, trägt nichts ins Nummernbuch, +- landet **nicht** im Rechnungsordner (Temp-Ordner), +- trägt quer über jeder Seite **„VORSCHAU – keine Rechnung"**, +- prüft **keine** Pflichtfelder — man will ja gerade sehen, was noch fehlt. + +Prüfstand: **`pruef_vorschau.py`** (u. a.: die echte Rechnung danach trägt die +Marke NICHT). + +## 3. Das Blatt „für das Amt" ist entfallen + +Bis 05.09.2026 hing an jeder Rechnung mit Beherbergungssteuer ein zweites Blatt +mit **derselben Rechnungsnummer**, aber ohne die Steuer — also mit einem +**anderen Gesamtbetrag**. + +Seine Ansage: *„das mit rechnung an das amt kommt raus … wenn so was in den +büchern von einem unternehmen drin ist, dann ist das ein genickbruch, wenn der +prüfer kommt"*. Vorgeschichte: Bartl wollte es so, weil es sonst seine +Steuerberaterin durcheinanderbringe; der Widerspruch stand schon damals. + +Nachgeschlagen: mehrere Blätter zum selben Umsatz mit **gleicher** Nummer sind +für sich noch kein § 14c-Fall — aber unterschiedliche Endbeträge erwecken den +Eindruck, es werde über **verschiedene Umsätze** abgerechnet. Genau das fällt +bei einer Prüfung auf. + +**Was an die Stelle tritt:** nichts im Rechnungstool. Das Steuerjournal liest +die Kenndaten (`/Subject`) der PDF und rechnet die Bemessungsgrundlage selbst +aus; ans Amt geht eine **Summenanmeldung**, keine Rechnungskopie mit Gastnamen. +Vorher geprüft: kein Programm liest die zweite Seite — `pruef_montage.py` +belegt weiter, dass das Journal die Datei einliest. + +Mit dem Blatt entfielen: `_AmtMarke`, der Parameter `gesamtrechnung_betont` und +der doppelte Renderlauf (der existierte nur, um zu wissen, auf welcher Seite das +Amt-Blatt beginnt). Der Renderer ist dadurch deutlich kürzer. + +## 4. Prüfstände nehmen keine Maus mehr + +Sein Fund mitten im Lauf: *„pack doch die maus nicht immer auf das programm, +weil ich kann dir sonst nichts schreiben"*. + +- `config.TESTLAUF` steht an **einer** Stelle (`--test` / `CAMPINGHOF_TEST=1`). +- Hauptfenster und **jeder** Dialog werden im Prüflauf durchsichtig gemacht und + aus dem Bild geschoben, und `grab_set` fällt weg. +- ⚠️ **Nicht `withdraw()`**: damit baut ein Fenster seine Dialoge nicht mehr + richtig auf — vier Prüfstände wurden davon rot und hätten eine Bedienung + geprüft, die es so nicht gibt. +- **`pruefsteuerung.py`** (neu): Meldungen wandern ins Protokoll, Ja/Nein-Fragen + in einen Fahrplan (`antwortet("Hausnummer", True)`). Eine **unangemeldete** + Frage bricht den Lauf ab — stillschweigend „ja" zu sagen würde genau die Fälle + übergehen, wegen denen es die Prüfung gibt. + +## Offen + +- **Betriebsart abfragen** (Campingplatz / Handwerker / Unternehmen) — sein + Zielbau: *„nicht jeder braucht das so wie der camping typ"*. Handwerker und + Unternehmen brauchen **freie Rechnungszeilen** statt des festen Katalogs; das + ist ein neuer Eingabemodus, kein Schalter. +- **§ 14-Lücke Leistungszeitpunkt**: ohne An-/Abreise (z. B. nur Gasfüllung) + steht heute kein Leistungsdatum auf dem Blatt — § 14 Abs. 4 Nr. 6 UStG. +- **Zahlungsziel** einstellbar. +- **E-Rechnung (ZUGFeRD)**: Pflicht ab 01.01.2028 für B2B — trifft die + Montage-Rechnung. Bibliothek `factur-x` ist geprüft und kann XML erzeugen + (Profil EN 16931), prüfen (XSD + Schematron) und einbetten (PDF/A-3). +- **GoBD**: PDFs nach dem Schreiben schreibgeschützt; Aufbewahrung seit BEG IV + 8 statt 10 Jahre (§ 147 Abs. 3 AO). diff --git a/api.py b/api.py index 0a2a2a8..98eff1e 100644 --- a/api.py +++ b/api.py @@ -18,11 +18,38 @@ einem Port, den das Betriebssystem aussucht (Port 0). Wo es lauscht, traegt es in die gemeinsame SQLite ein - die ist das Telefonbuch. Wer jemanden erreichen will, schlaegt dort Port und PID nach, prueft die PID und ruft an. -Zwei Nachrichten reichen: +Zwei Nachrichten reichen dafuer: {"was": "ping"} -> {"antwort": "hallo, bin noch da"} {"was": "schau_nach"} -> {"antwort": "ok"} (und das Fenster liest nach) +Dazu kommt eine dritte, die das Fenster BEDIENT - damit ein Pruefstand die +Knoepfe druecken kann, ohne dem Menschen am Rechner Maus und Tastatur +wegzunehmen: + + {"was": "aktion", "schluessel": "...", "name": "vorschau"} -> {"antwort": {...}} + +DER SCHLUESSEL +-------------- +Wer bedient, muss sich ausweisen - wie mit einem SSH-Schluessel. Beim ersten +Start legt das Programm eine Zufallszahl in `api_schluessel.txt` **im +gemeinsamen Ordner** ab (dort steht auch das Nummernbuch). Wer diesen Ordner +lesen darf, darf sprechen: das Steuerjournal und der Betreiber - sonst niemand. +Ohne gueltigen Schluessel wird eine Aktion verworfen, und zwar ohne zu +verraten, ob der Name ueberhaupt existiert. + +`ping` und `schau_nach` bleiben schluessellos: sie sagen nur "ich lebe" bzw. +"schau in die SQLite" und veraendern nichts. Sonst koennte ein aelteres +Steuerjournal nicht mehr anklopfen. + +WAS EINE AKTION DARF +-------------------- +Alles, was einen BELEG SCHREIBT (Rechnung, Angebot, Storno), geht nur im +Testlauf (`--test` / `CAMPINGHOF_TEST=1`). Im normalen Betrieb bleiben nur +Aktionen, die nichts in die Buchhaltung schreiben: nachsehen, Felder fuellen, +Vorschau zeigen. Eine Fernbedienung, die echte Rechnungen ausstellt, hat in +einer Buchhaltung nichts zu suchen. + Der Push traegt keine Daten. Er sagt nur "schau in die SQLite" - dort steht die Meldung ohnehin. Damit gibt es genau EINE Wahrheit, und wenn der Anruf nicht durchgeht (Programm zu, Port belegt), findet das andere die Meldung beim @@ -42,6 +69,8 @@ hinueber. import json import logging import os +import queue +import secrets import socket import socketserver import sys @@ -50,6 +79,33 @@ import threading log = logging.getLogger("api") ANTWORT_HALLO = "hallo, bin noch da" +SCHLUESSEL_DATEI = "api_schluessel.txt" + + +def schluessel_holen(ordner): + """Schluessel aus dem Ordner lesen; ist keiner da, einen anlegen. + + Der Schluessel ist eine 32 Byte lange Zufallszahl in Hex. Er liegt als + Datei neben dem Nummernbuch, damit beide Programme denselben lesen - eine + Absprache ueber den gemeinsamen Ordner, ohne Server und ohne Passwort, das + sich jemand merken muesste. + """ + if not ordner: + return "" + pfad = os.path.join(ordner, SCHLUESSEL_DATEI) + try: + if os.path.exists(pfad): + wert = open(pfad, encoding="utf-8").read().strip() + if wert: + return wert + wert = secrets.token_hex(32) + with open(pfad, "w", encoding="utf-8") as f: + f.write(wert) + log.info("neuer API-Schluessel angelegt: %s", pfad) + return wert + except OSError as e: + log.warning("API-Schluessel nicht nutzbar (%s)", e) + return "" class _Handler(socketserver.StreamRequestHandler): @@ -66,14 +122,17 @@ class _Handler(socketserver.StreamRequestHandler): if not zeile: return try: - was = str(json.loads(zeile).get("was", "")) + nachricht = json.loads(zeile) + was = str(nachricht.get("was", "")) except (ValueError, AttributeError): - was = "" + nachricht, was = {}, "" if was == "ping": antwort = ANTWORT_HALLO elif was == "schau_nach": antwort = "ok" self.server.melden() # Fenster benachrichtigen (threadsicher) + elif was == "aktion": + antwort = self._aktion(nachricht) else: antwort = "haeh?" try: @@ -82,12 +141,35 @@ class _Handler(socketserver.StreamRequestHandler): pass + def _aktion(self, nachricht): + """Eine Bedienung ausfuehren - nur mit gueltigem Schluessel.""" + erwartet = getattr(self.server, "schluessel", "") + gegeben = str(nachricht.get("schluessel", "")) + # compare_digest statt "==": ein Vergleich, der bei der ersten falschen + # Stelle abbricht, verraet ueber die Zeit, wie weit man richtig lag. + if not erwartet or not secrets.compare_digest(erwartet, gegeben): + log.warning("Aktion ohne gueltigen Schluessel abgewiesen") + return "kein zutritt" + if self.server.aktion is None: + return "keine bedienung moeglich" + name = str(nachricht.get("name", "")) + daten = nachricht.get("daten") or {} + log.info("Aktion ueber die API: %s", name) + try: + return self.server.aktion(name, daten) + except Exception as e: # noqa: BLE001 - der Server darf daran nicht sterben + log.warning("Aktion %r fehlgeschlagen: %s", name, e) + return {"fehler": str(e)} + + class _Server(socketserver.ThreadingTCPServer): allow_reuse_address = True daemon_threads = True - def __init__(self, adresse, bei_push): + def __init__(self, adresse, bei_push, aktion=None, schluessel=""): self.melden = bei_push + self.aktion = aktion + self.schluessel = schluessel super().__init__(adresse, _Handler) @@ -99,19 +181,30 @@ class MiniApi: und holt sie im Fenster mit after() ab. """ - def __init__(self, programm, bei_push): + def __init__(self, programm, bei_push, aktion=None): self.programm = programm self.bei_push = bei_push + self.aktion = aktion # (name, daten) -> Antwort; None = keine Bedienung self.server = None self.faden = None self.port = 0 + self.schluessel = "" - def starten(self, buch): - """Server aufmachen und im Telefonbuch (SQLite) eintragen.""" + def starten(self, buch, ordner=None): + """Server aufmachen und im Telefonbuch (SQLite) eintragen. + + Der Schluessel kommt aus dem Ordner des Nummernbuchs - dort liegt er + fuer beide Programme lesbar. Gibt es kein Buch, gibt es keinen + Schluessel und damit auch keine Bedienung von aussen. + """ if self.server is not None: return self.port + if ordner is None and buch is not None: + ordner = os.path.dirname(getattr(buch, "pfad", "") or "") + self.schluessel = schluessel_holen(ordner) try: - self.server = _Server(("127.0.0.1", 0), self.bei_push) + self.server = _Server(("127.0.0.1", 0), self.bei_push, + aktion=self.aktion, schluessel=self.schluessel) except OSError as e: log.warning("API konnte nicht starten: %s", e) self.server = None @@ -150,12 +243,14 @@ class MiniApi: self.port = 0 -def _reden(port, was, zeitgrenze=1.5): +def _reden(port, was, zeitgrenze=1.5, **rest): """Eine Zeile hinschicken und die Antwort lesen. None = niemand da.""" + nachricht = {"was": was} + nachricht.update(rest) try: with socket.create_connection(("127.0.0.1", int(port)), timeout=zeitgrenze) as s: s.settimeout(zeitgrenze) - s.sendall((json.dumps({"was": was}) + "\n").encode("utf-8")) + s.sendall((json.dumps(nachricht) + chr(10)).encode("utf-8")) roh = s.makefile("r", encoding="utf-8").readline() return json.loads(roh).get("antwort", "") except (OSError, ValueError): @@ -192,3 +287,69 @@ def anklopfen(buch, programm): if not eintrag or not eintrag.get("port"): return False return _reden(eintrag["port"], "schau_nach") == "ok" + + +def bedienen(buch, programm, name, daten=None, ordner=None, zeitgrenze=15.0): + """Einen Knopf im anderen Programm druecken. None = niemand da / kein Zutritt. + + Fuer Pruefstaende und fuer den Betreiber: damit laesst sich das Fenster + bedienen, ohne dem Menschen am Rechner Maus und Tastatur wegzunehmen. + + Der Schluessel kommt aus demselben Ordner wie das Nummernbuch - wer den + lesen darf, darf bedienen. + """ + if buch is None: + return None + try: + eintrag = buch.wer_laeuft(programm) + except Exception as e: # noqa: BLE001 + log.debug("Telefonbuch nicht lesbar: %s", e) + return None + if not eintrag or not eintrag.get("port"): + return None + if ordner is None: + ordner = os.path.dirname(getattr(buch, "pfad", "") or "") + return _reden(eintrag["port"], "aktion", zeitgrenze=zeitgrenze, + schluessel=schluessel_holen(ordner), name=name, + daten=daten or {}) + + +class Warteschlange: + """Aktionen aus dem Netzfaden in den Fensterfaden bringen - und zurueck. + + Tkinter darf nur aus SEINEM Faden angefasst werden. Der API-Server lauscht + aber in einem eigenen. Deshalb legt er die Aktion hier ab und wartet auf das + Ergebnis; das Fenster holt sie in seiner after()-Schleife ab, fuehrt sie aus + und legt die Antwort zurueck. + + Kommt das Fenster nicht dazu (es haengt in einem Dialog), laeuft die + Wartezeit ab und der Anrufer bekommt eine ehrliche Absage statt einer + Verbindung, die nie antwortet. + """ + + def __init__(self): + self.eingang = queue.Queue() + + def annehmen(self, name, daten, zeitgrenze=12.0): + """Aus dem Netzfaden gerufen: Aktion einreihen und auf das Ergebnis warten.""" + fertig = threading.Event() + auftrag = {"name": name, "daten": daten, "fertig": fertig, "antwort": None} + self.eingang.put(auftrag) + if not fertig.wait(zeitgrenze): + return {"fehler": "das Fenster hat nicht geantwortet"} + return auftrag["antwort"] + + def abarbeiten(self, ausfuehren): + """Im Fensterfaden gerufen: alles erledigen, was eingegangen ist.""" + while True: + try: + auftrag = self.eingang.get_nowait() + except queue.Empty: + return + try: + auftrag["antwort"] = ausfuehren(auftrag["name"], auftrag["daten"]) + except Exception as e: # noqa: BLE001 - eine Aktion darf das Fenster nicht killen + log.warning("Aktion %r fehlgeschlagen: %s", auftrag["name"], e) + auftrag["antwort"] = {"fehler": str(e)} + finally: + auftrag["fertig"].set() diff --git a/app.py b/app.py index 534c3e0..cf23915 100644 --- a/app.py +++ b/app.py @@ -70,7 +70,13 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # Das gemeinsame Nummernbuch (siehe gemeinsam.py). None = noch keiner # gesetzt; das Programm laeuft dann weiter, warnt aber sichtbar. self.buch = None - self.api = api.MiniApi("rechnungstool", self._push_empfangen) + # Die API kann das Fenster auch BEDIENEN (nur mit Schluessel, siehe + # api.py). Die Warteschlange bringt die Aktion aus dem Netzfaden + # hierher - Tkinter darf nur aus seinem eigenen Faden angefasst werden. + self._api_schlange = api.Warteschlange() + self.api = api.MiniApi("rechnungstool", self._push_empfangen, + aktion=self._api_schlange.annehmen) + self.after(150, self._api_pumpe) self._push_kasten = queue.Queue() # Zwischenspeicher fuer eine reine Berichtigung (§ 31 Abs. 5 UStDV): # die naechste PDF ist dann ein berichtigtes Blatt zu dieser Rechnung. @@ -627,8 +633,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): ttk.Label(rahmen, text="Wo soll die Rechnungsnummer weiterlaufen?", font=("Segoe UI", 13, "bold")).grid(row=0, column=0, columnspan=2, sticky="w") ttk.Label(rahmen, wraplength=620, justify="left", text=( - "Trag die zuletzt vergebene Nummer ein – die aus deiner bisherigen Liste. " - "Die nächste Rechnung bekommt dann die Nummer danach.\n\n" + "Zwei Wege - such dir einen aus." + chr(10) + chr(10) + "Das wird EINMAL eingerichtet. Danach steht der Zähler fest: eine " "ausgestellte Rechnung wird nur noch über Storno oder Berichtigung " "korrigiert, und jede Nummer gibt es nur einmal " @@ -642,23 +647,50 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): f"{jahr}-{gefunden:03d} – niedriger geht es nicht.").grid( row=2, column=0, columnspan=2, sticky="w", pady=(0, 10)) - ttk.Label(rahmen, text=f"Zuletzt vergeben: {jahr} –").grid(row=3, column=0, sticky="e") - ttk.Entry(rahmen, textvariable=wert, width=10, justify="center").grid( - row=3, column=1, sticky="w", padx=(8, 0)) + # Zwei Wege statt einer Zahl: neu anfangen oder die eigene Zaehlung + # weiterfuehren. Die Frage "trag die zuletzt vergebene Nummer ein" holt + # niemanden ab, der bei 0 anfaengt - der hat gar keine. + weg = tk.StringVar(value="weiter" if gefunden else "null") + zeile = ttk.Frame(rahmen) + # Das Eingabefeld ist ein Kind DIESER Zeile - ein Widget muss dort + # zuhause sein, wo es gepackt wird, sonst mischt Tk grid und pack im + # selben Rahmen und bricht ab. + eingabe = ttk.Entry(zeile, textvariable=wert, width=10, justify="center") + + def weg_gewaehlt(*_): + eingabe.configure(state="normal" if weg.get() == "weiter" else "disabled") + + ttk.Radiobutton(rahmen, variable=weg, value="null", command=weg_gewaehlt, + text=f"Bei 0 anfangen - die erste Rechnung wird {jahr}-001").grid( + row=3, column=0, columnspan=2, sticky="w", pady=(0, 4)) + zeile.grid(row=4, column=0, columnspan=2, sticky="w") + ttk.Radiobutton(zeile, variable=weg, value="weiter", command=weg_gewaehlt, + text=f"Meine Zählung weiterführen - zuletzt vergeben: {jahr} -").pack( + side="left") + eingabe.pack(side="left", padx=(8, 0)) + weg_gewaehlt() hinweis = tk.Label(rahmen, text="", wraplength=620, justify="left", fg="#a00000", font=("Segoe UI", 9)) - hinweis.grid(row=4, column=0, columnspan=2, sticky="w", pady=(8, 0)) + hinweis.grid(row=5, column=0, columnspan=2, sticky="w", pady=(8, 0)) def uebernehmen(): - try: - zahl = int(parse_num(wert.get())) - except (TypeError, ValueError): - zahl = -1 - if zahl < gefunden: - hinweis.configure(text=f"Mindestens {gefunden} – so weit ist schon vergeben.") - return + if weg.get() == "null": + zahl = 0 + else: + try: + zahl = int(parse_num(wert.get())) + except (TypeError, ValueError): + zahl = -1 if zahl < 0: - hinweis.configure(text="Bitte eine Zahl eintragen (0 = es geht bei 001 los).") + hinweis.configure(text="Bitte die zuletzt vergebene Nummer eintragen.") + return + # Unter das, was schon vergeben ist, darf niemand - egal auf welchem + # Weg. Sonst gaebe es eine Nummer zweimal (§ 14 Abs. 4 Nr. 4 UStG). + if zahl < gefunden: + hinweis.configure( + text=f"Schon vergeben ist {jahr}-{gefunden:03d} - darunter geht es nicht." + if weg.get() == "weiter" else + f"Bei 0 anfangen geht nicht mehr: {jahr}-{gefunden:03d} ist schon vergeben.") return if not messagebox.askyesno( "Sind Sie sicher?", @@ -680,7 +712,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): d.destroy() knoepfe = ttk.Frame(rahmen) - knoepfe.grid(row=5, column=0, columnspan=2, sticky="ew", pady=(16, 0)) + knoepfe.grid(row=6, column=0, columnspan=2, sticky="ew", pady=(16, 0)) ttk.Button(knoepfe, text="Übernehmen", width=16, command=uebernehmen).pack(side="right") ttk.Button(knoepfe, text="Später", width=12, command=d.destroy).pack(side="left") @@ -1077,6 +1109,87 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): return jahr, zaehler, nummer return jahr, zaehler, f"{jahr}-A{zaehler:03d}" + # ------------------------------------------------- Bedienung ueber die API + def _api_pumpe(self): + """Holt Aktionen aus der Warteschlange und fuehrt sie HIER aus. + + Laeuft, solange das Fenster steht. Tkinter darf nur aus seinem eigenen + Faden angefasst werden - der API-Server lauscht in einem anderen. + """ + try: + self._api_schlange.abarbeiten(self._api_aktion) + finally: + self.after(150, self._api_pumpe) + + def _api_aktion(self, name, daten): + """Eine Bedienung ausfuehren. Der Schluessel ist schon geprueft (api.py). + + Nachschlagetabelle statt if-Kette: ein neuer Knopf ist EIN Eintrag. + + Was einen BELEG schreibt, geht nur im Testlauf. Eine Fernbedienung, die + im laufenden Betrieb echte Rechnungen ausstellt, hat in einer + Buchhaltung nichts zu suchen - eine ausgestellte Rechnung bekommt man + nur ueber einen Storno wieder weg. + """ + schreibt_beleg = {"rechnung", "angebot"} + tabelle = { + "hilfe": lambda _d: {"kann": ["hilfe", "zustand", "setze", "zuruecksetzen", + "vorschau", "rechnung", "angebot"]}, + "zustand": lambda _d: self._api_zustand(), + "setze": self._api_setzen, + "zuruecksetzen": lambda _d: (self.reset_formular(), {"ok": True})[1], + "vorschau": lambda d: {"pfad": self.vorschau_zeigen( + oeffnen=bool(d.get("oeffnen", False)))}, + "rechnung": lambda _d: (self.pdf_erstellen(), self._api_zustand())[1], + "angebot": lambda _d: (self.pdf_erstellen(angebot=True), self._api_zustand())[1], + } + if name not in tabelle: + return {"fehler": "kenne ich nicht: " + str(name), "kann": sorted(tabelle)} + if name in schreibt_beleg and not TESTLAUF: + return {"fehler": "schreibt einen Beleg - geht nur im Testlauf"} + return tabelle[name](daten or {}) + + def _api_zustand(self): + """Was steht gerade im Formular? Zum Nachsehen, ohne Maus.""" + r = self.recalc() + return { + "reiter": "montage" if self.ist_montage() else "camping", + "nummer": self.r_nummer.get(), + "datum": self.r_datum.get(), + "anreise": self.r_anreise.get(), + "abreise": self.r_abreise.get(), + "naechte": self.r_naechte.get(), + "kunde": {"anrede": self.k_anrede.get(), "vorname": self.k_vorname.get(), + "nachname": self.k_name.get(), "zusatz": self.k_zusatz.get(), + "strasse": self.k_strasse.get(), "plzort": self.k_plzort.get()}, + "positionen": [{"nr": z.nr, "leistung": z.leistung, "anzahl": z.anzahl, + "personen": z.personen, "brutto": z.brutto} for z in r.zeilen], + "gesamt": r.gesamt, + } + + def _api_setzen(self, daten): + """Felder fuellen, wie es sonst die Tastatur taete.""" + felder = { + "anrede": self.k_anrede, "vorname": self.k_vorname, "nachname": self.k_name, + "zusatz": self.k_zusatz, "strasse": self.k_strasse, "plzort": self.k_plzort, + "nummer": self.r_nummer, "datum": self.r_datum, + "anreise": self.r_anreise, "abreise": self.r_abreise, + } + for schluessel, wert in (daten.get("kunde") or {}).items(): + if schluessel in felder: + felder[schluessel].set(str(wert)) + for schluessel in ("nummer", "datum", "anreise", "abreise"): + if schluessel in daten: + felder[schluessel].set(str(daten[schluessel])) + for eintrag in (daten.get("positionen") or []): + nr = int(eintrag.get("nr", 0)) + if nr in self.anzahl_vars: + self.anzahl_vars[nr].set(str(eintrag.get("anzahl", ""))) + if nr in self.personen_vars and "personen" in eintrag: + self.personen_vars[nr].set(str(eintrag["personen"])) + self.update() + return self._api_zustand() + def _kopf_basis(self, nummer, r): """Die Kopfdaten, die JEDES Blatt braucht - Rechnung wie Vorschau. @@ -1111,7 +1224,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): for z in r.zeilen], } - def vorschau_zeigen(self): + def vorschau_zeigen(self, oeffnen=True): """Zeigt das Blatt, BEVOR es eine Rechnung wird. Eine ausgestellte Rechnung laesst sich nur noch ueber einen Storno @@ -1142,10 +1255,13 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): try: pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf, vorschau=True) print(f"[vorschau] geschrieben -> {pfad}") - os.startfile(pfad) # noqa: S606 + if oeffnen: + os.startfile(pfad) # noqa: S606 + return pfad except OSError as e: messagebox.showerror("Vorschau nicht möglich", f"Die Vorschau konnte nicht geöffnet werden:\n{e}") + return "" def pdf_erstellen(self, angebot=False): montage = self.ist_montage() diff --git a/config.py b/config.py index e3058b1..6b4d98e 100644 --- a/config.py +++ b/config.py @@ -71,6 +71,13 @@ def _daten_ordner(): BASE_DIR = _daten_ordner() CONFIG_PATH = os.path.join(BASE_DIR, "config.json") +# Laeuft gerade ein Pruefstand? Dann baut das Programm alles wie sonst, zeigt es +# aber nicht: kein Fenster auf dem Bildschirm, kein Dialog, der Maus und +# Tastatur an sich reisst, waehrend der Mensch daneben arbeitet. +# Das Flag steht HIER, damit app.py, theme.py und die Pruefstaende dasselbe +# lesen - zwei Stellen wuerden auseinanderlaufen. +TESTLAUF = ("--test" in sys.argv) or os.environ.get("CAMPINGHOF_TEST") == "1" + # Leistungskatalog 1:1 aus der Excel-Vorlage (Rechnung Campinghof Bartl). # satz = Umsatzsteuersatz in Prozent (7 = Beherbergung, 19 = Zusatzleistung) # preis = Brutto-Einzelpreis in Euro (Endpreis inkl. USt) diff --git a/pdf_renderer.py b/pdf_renderer.py index 28daf93..b421865 100644 --- a/pdf_renderer.py +++ b/pdf_renderer.py @@ -10,7 +10,6 @@ im Layout der Excel-Vorlage: """ import os -import io import json from reportlab.lib.pagesizes import A4 @@ -19,8 +18,7 @@ from reportlab.lib import colors from reportlab.lib.enums import TA_RIGHT, TA_LEFT, TA_CENTER from reportlab.lib.styles import ParagraphStyle from reportlab.platypus import ( - SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, KeepTogether, PageBreak, - Flowable, + SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, KeepTogether, ) import bilder @@ -28,23 +26,6 @@ import config from berechnung import eur, eur_kurz, runde -class _AmtMarke(Flowable): - """Unsichtbar. Haelt fest, auf welcher Seite das Amt-Blatt beginnt. - - Nur so kann die Fusszeile die Kundenseite vom Amt-Blatt unterscheiden - sie wird - gezeichnet, bevor der Seiteninhalt steht, und weiss von sich aus nichts davon. - """ - - def __init__(self, merker): - super().__init__() - self._merker = merker - - def wrap(self, *_): - return (0, 0) - - def draw(self): - self._merker["seite"] = self.canv.getPageNumber() - # ---- Farben / Masse --------------------------------------------------------- # Die Akzentfarbe gehoert der Firma, nicht dem Programm: Ueberschriften, die # Linie unter dem Kopf und der Tabellenkopf tragen sie. Ein Handwerker will kein @@ -157,8 +138,8 @@ def _vorschau_marke(canvas): canvas.restoreState() -def _kopf_fuss(canvas, doc, cfg, amt=False, vorschau=False): - """Kopf und Fuss einer Seite. amt=True -> Blatt fuer das Amt (siehe Fusszeile).""" +def _kopf_fuss(canvas, doc, cfg, vorschau=False): + """Kopf und Fuss einer Seite.""" firma = cfg["firma"] canvas.saveState() if vorschau: @@ -203,13 +184,8 @@ def _kopf_fuss(canvas, doc, cfg, amt=False, vorschau=False): canvas.line(MARGIN_L, line_y, PAGE_W - MARGIN_R, line_y) # --- Fusszeile --- - # - # STRIKTE TRENNUNG Kunde / Amt: - # Kundenseite : voller Briefkopf-Fuss - Bankverbindung und Steuernummer MUESSEN - # drauf, das ist die Rechnung, die der Gast bezahlt. - # Amt-Blatt : KEINE Bankverbindung, KEINE Steuernummer. Das Amt zieht nichts - # ein und ueberweist nichts. Es bleiben Inhaber (wer meldet) und - # die Kontaktdaten fuer Rueckfragen. + # Bankverbindung und Steuernummer MUESSEN drauf: das ist die Rechnung, die der + # Gast bezahlt, und die Steuernummer ist Pflichtangabe (§ 14 Abs. 4 Nr. 2 UStG). fy = MARGIN_BOT - 4 * mm canvas.setStrokeColor(LINE) canvas.setLineWidth(0.6) @@ -220,12 +196,7 @@ def _kopf_fuss(canvas, doc, cfg, amt=False, vorschau=False): col_m = MARGIN_L + CONTENT_W * 0.40 col_r = PAGE_W - MARGIN_R - # Das Fusszeilen-Bild steht auf dem AMT-BLATT NICHT. Ein fertiges - # Briefpapier-Band traegt fast immer Bank und Steuernummer - und genau die - # duerfen dort nicht auftauchen (siehe Trennung oben). Das Amt bekommt - # deshalb immer die gezeichnete Fusszeile, auch wenn der Nutzer den Haken - # "Firmenangaben stehen im Bild" gesetzt hat. - fuss_img, fiw, fih = (None, 0, 0) if amt else bilder.laden(firma.get("fussbild")) + fuss_img, fiw, fih = bilder.laden(firma.get("fussbild")) if fuss_img: # Schmaler Streifen UNTER den Fusstexten. Die Texte bleiben, wo sie sind - # Firma, Anschrift, Bank und Steuernummer stehen auf jeder Rechnung, egal @@ -234,9 +205,8 @@ def _kopf_fuss(canvas, doc, cfg, amt=False, vorschau=False): canvas.drawImage(fuss_img, MARGIN_L + (CONTENT_W - dw) / 2, 7 * mm, width=dw, height=dh, preserveAspectRatio=True, mask="auto") - rows_l = [] if amt else [firma.get("bank", ""), firma.get("iban", ""), firma.get("bic", "")] - rows_m = [firma.get("inhaber", "")] if amt else [firma.get("inhaber", ""), - firma.get("steuernummer", "")] + rows_l = [firma.get("bank", ""), firma.get("iban", ""), firma.get("bic", "")] + rows_m = [firma.get("inhaber", ""), firma.get("steuernummer", "")] rows_r = [firma.get("homepage", ""), firma.get("email", ""), firma.get("telefon", "")] for i, t in enumerate(rows_l): @@ -327,12 +297,8 @@ def _montage_zeile(story, st, rechnung, kopf): story.append(dreier) -def _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont): - """Baut den kompletten Seiteninhalt (Absender -> Positionen -> Summen -> Danktexte). - - gesamtrechnung_betont=True hebt die Zwischensumme-Zeile wie den Gesamtbetrag hervor - (fett + zwei Streifen) -> fuer das Amt-Blatt. Sonst 1:1 die Kundenseite. - """ +def _seite_inhalt(story, st, cfg, rechnung, kopf): + """Baut den kompletten Seiteninhalt (Absender -> Positionen -> Summen -> Danktexte).""" # Absenderzeile (klein, unterstrichen) story.append(Paragraph( f"{cfg['firma'].get('absender','')}", @@ -428,7 +394,6 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont): titel = {"storno": "Stornorechnung", "berichtigung": "Berichtigte Rechnung", "angebot": "Unverbindliches Angebot"}.get(art, "Rechnungsübersicht") - titel += " (für das Amt)" if gesamtrechnung_betont else "" story.append(Paragraph(titel, st["h"])) if angebot: # Ohne diesen Satz sieht das Blatt aus wie eine Rechnung. Es ist keine - @@ -477,7 +442,7 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont): # Auf dem Angebot wird gar keine Steuer ausgewiesen - weder Umsatzsteuer # noch Beherbergungssteuer. Es steht nur, was der Gast voraussichtlich # zahlt; aufgeschluesselt wird erst in der Rechnung. - if rechnung.aufschlaege and not gesamtrechnung_betont and not angebot: + if rechnung.aufschlaege and not angebot: summen_rows.append([ Paragraph("Zwischensumme:", st["info_l"]), Paragraph(eur(rechnung.brutto), st["cell_r"]), @@ -489,7 +454,7 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont): Paragraph(eur(a.betrag), st["cell_r"]), ]) - endsumme = rechnung.brutto if gesamtrechnung_betont else rechnung.gesamt + endsumme = rechnung.gesamt summen_rows.append([ Paragraph("Voraussichtlicher Gesamtbetrag:" if angebot else "Rechnungsbetrag Insgesamt:" if montage else "Gesamtbetrag:", @@ -508,14 +473,13 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont): summen.setStyle(TableStyle(style_cmds)) story.append(summen) - # Hinweis zur Beherbergungssteuer - nur auf der Kundenseite. Auf dem Amt-Blatt - # wird die Steuer gar nicht mehr ausgewiesen, dann waere der Satz sinnlos. + # Hinweis zur Beherbergungssteuer. if angebot: story.append(Spacer(1, 1.5 * mm)) story.append(Paragraph( "In diesem Betrag sind alle Steuern und Abgaben enthalten. Aufgeschlüsselt " "werden sie erst in der Rechnung nach dem Aufenthalt.", st["dank"])) - elif not gesamtrechnung_betont: + else: for a in rechnung.aufschlaege: if not a.bezeichnung: continue @@ -534,90 +498,83 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont): story.append(Spacer(1, 8 * mm)) # ---- Schlusstexte ------------------------------------------------------- - # Dank- und Zahlungstexte gehoeren nur auf die Kundenseite. Die - # STORNO-Erklaerung gehoert aber AUCH aufs Amtsblatt: dort steht sonst eine - # Stornonummer neben einer voellig anderen Rechnungsnummer, und niemand - # erfaehrt, warum. Sein Fund am 04.09.2026: *"in der pdf wird der satz nicht - # angezeigt, da ist dann ein sprung in den rechnungs nummern"* - genau das - # Blatt, das die Stadt bekommt, war der Beleg ohne Begruendung. - if not gesamtrechnung_betont or art == "storno": - texte = cfg.get("texte", {}) - block = [] - if art == "storno": - # Auf einem Storno sind Dank- und Zahlungstexte falsch - hier wird - # nichts geschuldet, sondern aufgehoben. - bezug = kopf.get("storno_zu", "") - if kopf.get("storno_datum"): - bezug += f" vom {kopf['storno_datum']}" - folgt = kopf.get("korrektur_nummer") or "" - if kopf.get("ersatz_vorhanden") and folgt: - # Doppelt geschriebene Leistung: es kommt nichts nach, sie ist - # bereits abgerechnet. Der Satz muss das sagen - sonst wartet der - # Gast auf eine Rechnung, die nie kommt. - block.append(Paragraph( - f"Diese Stornorechnung hebt die Rechnung {bezug} vollständig auf. " - f"Die Leistung wurde versehentlich doppelt in Rechnung gestellt und " - f"ist bereits mit der Rechnung {folgt} abgerechnet – es folgt keine " - "weitere Rechnung. Bereits gezahlte Beträge werden erstattet oder " - "verrechnet.", st["dank"])) - story.append(KeepTogether(block)) - return - if kopf.get("nur_storno"): - # Nur Storno (04.09.2026): die Leistung wird gar nicht abgerechnet. - # Hier darf NICHT von einer berichtigten Rechnung die Rede sein - - # es kommt keine, und der Gast wartet sonst darauf. - block.append(Paragraph( - f"Diese Stornorechnung hebt die Rechnung {bezug} vollständig auf. " - "Die Leistung wird nicht abgerechnet – es folgt keine weitere " - "Rechnung. Bereits gezahlte Beträge werden erstattet.", st["dank"])) - story.append(KeepTogether(block)) - return - kette = (f" Die berichtigte Rechnung trägt die Nummer {folgt} " - f"(also {kopf.get('storno_zu','')} → {kopf.get('rechnungsnummer','')} " - f"→ {folgt}).") if folgt else "" + texte = cfg.get("texte", {}) + block = [] + if art == "storno": + # Auf einem Storno sind Dank- und Zahlungstexte falsch - hier wird + # nichts geschuldet, sondern aufgehoben. + bezug = kopf.get("storno_zu", "") + if kopf.get("storno_datum"): + bezug += f" vom {kopf['storno_datum']}" + folgt = kopf.get("korrektur_nummer") or "" + if kopf.get("ersatz_vorhanden") and folgt: + # Doppelt geschriebene Leistung: es kommt nichts nach, sie ist + # bereits abgerechnet. Der Satz muss das sagen - sonst wartet der + # Gast auf eine Rechnung, die nie kommt. block.append(Paragraph( f"Diese Stornorechnung hebt die Rechnung {bezug} vollständig auf. " - "Bereits gezahlte Beträge werden erstattet oder mit der berichtigten " - "Rechnung verrechnet." + kette, st["dank"])) - elif art == "berichtigung": - # Der Satz ist kein Beiwerk: mehrere Rechnungen ueber dieselbe Leistung - # ohne Kennzeichnung loesen die Steuer erneut aus (Abschn. 14c.1 Abs. 4 - # Satz 4 UStAE). Gegenueber Endverbrauchern entsteht sie zwar nicht - # (EuGH C-378/21, BMF v. 27.02.2024) - aber Firmengaeste und - # gewerbliche Dauercamper gibt es auch, und der Nachweis liegt beim - # Aussteller. Also bleibt der Satz drauf. + f"Die Leistung wurde versehentlich doppelt in Rechnung gestellt und " + f"ist bereits mit der Rechnung {folgt} abgerechnet – es folgt keine " + "weitere Rechnung. Bereits gezahlte Beträge werden erstattet oder " + "verrechnet.", st["dank"])) + story.append(KeepTogether(block)) + return + if kopf.get("nur_storno"): + # Nur Storno (04.09.2026): die Leistung wird gar nicht abgerechnet. + # Hier darf NICHT von einer berichtigten Rechnung die Rede sein - + # es kommt keine, und der Gast wartet sonst darauf. block.append(Paragraph( - f"Dieses Blatt berichtigt die Angaben zur Rechnung " - f"{kopf.get('berichtigt_zu','')} vom {kopf.get('datum','')} nach " - "§ 31 Abs. 5 UStDV. Leistungen, Beträge und Umsatzsteuer sind " - "unverändert – es handelt sich nicht um eine zusätzliche " - "Leistung und nicht um eine zweite Rechnung. Die Rechnung behält " - "ihre Nummer.", st["dank"])) - if texte.get("dank1"): - block.append(Paragraph(texte["dank1"], st["dank"])) - elif angebot: - # Dank- und Zahlungstexte waeren hier falsch: der Aufenthalt liegt - # noch vor uns, und bezahlt wird nichts. Der Hinweis "bitte die - # Rechnungsnummer angeben" wuerde dem Blatt sogar widersprechen. - block.append(Paragraph( - "Dieses Angebot ist freibleibend und unverbindlich (§ 145 BGB) und " - "keine Zahlungsaufforderung. Sagen Sie uns Bescheid, dann reservieren " - "wir – die Rechnung erhalten Sie nach dem Aufenthalt. Für Rückfragen " - "stehen wir gern zur Verfügung.", - st["dank"])) - else: - if art == "korrektur" and kopf.get("ersetzt"): - hinweis = f"Diese Rechnung ersetzt die Rechnung {kopf['ersetzt']}" - if kopf.get("storno_nummer"): - hinweis += f", die mit der Stornorechnung {kopf['storno_nummer']} aufgehoben wurde" - block.append(Paragraph(hinweis + ".", st["dank"])) - if texte.get("dank1"): - block.append(Paragraph(texte["dank1"], st["dank"])) - if texte.get("dank2"): - block.append(Paragraph(texte["dank2"], st["dank"])) - if texte.get("hinweis"): - block.append(Paragraph(texte["hinweis"], st["hinweis"])) - story.append(KeepTogether(block)) + f"Diese Stornorechnung hebt die Rechnung {bezug} vollständig auf. " + "Die Leistung wird nicht abgerechnet – es folgt keine weitere " + "Rechnung. Bereits gezahlte Beträge werden erstattet.", st["dank"])) + story.append(KeepTogether(block)) + return + kette = (f" Die berichtigte Rechnung trägt die Nummer {folgt} " + f"(also {kopf.get('storno_zu','')} → {kopf.get('rechnungsnummer','')} " + f"→ {folgt}).") if folgt else "" + block.append(Paragraph( + f"Diese Stornorechnung hebt die Rechnung {bezug} vollständig auf. " + "Bereits gezahlte Beträge werden erstattet oder mit der berichtigten " + "Rechnung verrechnet." + kette, st["dank"])) + elif art == "berichtigung": + # Der Satz ist kein Beiwerk: mehrere Rechnungen ueber dieselbe Leistung + # ohne Kennzeichnung loesen die Steuer erneut aus (Abschn. 14c.1 Abs. 4 + # Satz 4 UStAE). Gegenueber Endverbrauchern entsteht sie zwar nicht + # (EuGH C-378/21, BMF v. 27.02.2024) - aber Firmengaeste und + # gewerbliche Dauercamper gibt es auch, und der Nachweis liegt beim + # Aussteller. Also bleibt der Satz drauf. + block.append(Paragraph( + f"Dieses Blatt berichtigt die Angaben zur Rechnung " + f"{kopf.get('berichtigt_zu','')} vom {kopf.get('datum','')} nach " + "§ 31 Abs. 5 UStDV. Leistungen, Beträge und Umsatzsteuer sind " + "unverändert – es handelt sich nicht um eine zusätzliche " + "Leistung und nicht um eine zweite Rechnung. Die Rechnung behält " + "ihre Nummer.", st["dank"])) + if texte.get("dank1"): + block.append(Paragraph(texte["dank1"], st["dank"])) + elif angebot: + # Dank- und Zahlungstexte waeren hier falsch: der Aufenthalt liegt + # noch vor uns, und bezahlt wird nichts. Der Hinweis "bitte die + # Rechnungsnummer angeben" wuerde dem Blatt sogar widersprechen. + block.append(Paragraph( + "Dieses Angebot ist freibleibend und unverbindlich (§ 145 BGB) und " + "keine Zahlungsaufforderung. Sagen Sie uns Bescheid, dann reservieren " + "wir – die Rechnung erhalten Sie nach dem Aufenthalt. Für Rückfragen " + "stehen wir gern zur Verfügung.", + st["dank"])) + else: + if art == "korrektur" and kopf.get("ersetzt"): + hinweis = f"Diese Rechnung ersetzt die Rechnung {kopf['ersetzt']}" + if kopf.get("storno_nummer"): + hinweis += f", die mit der Stornorechnung {kopf['storno_nummer']} aufgehoben wurde" + block.append(Paragraph(hinweis + ".", st["dank"])) + if texte.get("dank1"): + block.append(Paragraph(texte["dank1"], st["dank"])) + if texte.get("dank2"): + block.append(Paragraph(texte["dank2"], st["dank"])) + if texte.get("hinweis"): + block.append(Paragraph(texte["hinweis"], st["hinweis"])) + story.append(KeepTogether(block)) def _kenndaten(rechnung, kopf): @@ -736,52 +693,37 @@ def render_rechnung(pfad, cfg, rechnung, kopf, vorschau=False): rechnung : berechnung.Rechnung kopf : dict mit rechnungsnummer, datum, anreise, abreise, naechte, kunde_zeilen - EIN PDF mit zwei Blaettern (falls Beherbergungssteuer anfaellt): - Seite 1 = Kunden-Rechnung, vollstaendig (Steuer ausgewiesen, Bankverbindung im Fuss). - Letzte Seite = Blatt fuers Amt: KEINE Beherbergungssteuer (auch nicht im Gesamt), - keine Zwischensumme, keine Bankverbindung, keine Steuernummer. + EIN Blatt: die Rechnung fuer den Gast. + + Bis zum 05.09.2026 hing hier ein zweites Blatt "fuer das Amt" mit derselben + Rechnungsnummer, aber ohne Beherbergungssteuer - und damit mit einem anderen + Gesamtbetrag. Genau das ist bei einer Pruefung ein Problem: mehrere Blaetter + zum selben Umsatz mit verschiedenen Endbetraegen sehen aus, als werde ueber + verschiedene Umsaetze abgerechnet. Es ist ersatzlos entfallen. + + Was die Stadt braucht, kommt aus dem Steuerjournal: es liest die Kenndaten + (subject) dieser PDF und rechnet die Bemessungsgrundlage selbst aus. Die + Anmeldung geht als Summenmeldung ans Amt, nicht als Rechnungskopie mit + Gastnamen. """ _design_anwenden(cfg) # Firmenfarbe VOR den Stilen - sie lesen sie mit st = _styles() - def bauen(ziel, amt_seite): - doc = SimpleDocTemplate( - ziel, pagesize=A4, - leftMargin=MARGIN_L, rightMargin=MARGIN_R, - topMargin=MARGIN_TOP, bottomMargin=MARGIN_BOT, - title=({"storno": "Stornorechnung", - "angebot": "Angebot"}.get(kopf.get("art"), "Rechnung")) - + f" {kopf.get('rechnungsnummer','')}", - author=cfg["firma"].get("name", ""), - subject=_kenndaten(rechnung, kopf), # maschinenlesbar fuers Steuerjournal - ) - story = [] - _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont=False) # Kunde - # Ein Angebot bekommt KEIN Blatt fuers Amt: gemeldet wird eine - # Uebernachtung erst, wenn sie abgerechnet ist. - if rechnung.aufschlaege and kopf.get("art") != "angebot": - story.append(PageBreak()) - story.append(_AmtMarke(marke)) - _seite_inhalt(story, st, cfg, rechnung, kopf, gesamtrechnung_betont=True) # Amt + doc = SimpleDocTemplate( + pfad, pagesize=A4, + leftMargin=MARGIN_L, rightMargin=MARGIN_R, + topMargin=MARGIN_TOP, bottomMargin=MARGIN_BOT, + title=({"storno": "Stornorechnung", + "angebot": "Angebot"}.get(kopf.get("art"), "Rechnung")) + + f" {kopf.get('rechnungsnummer','')}", + author=cfg["firma"].get("name", ""), + subject=_kenndaten(rechnung, kopf), # maschinenlesbar fuers Steuerjournal + ) + story = [] + _seite_inhalt(story, st, cfg, rechnung, kopf) - def seite(c, d): - _kopf_fuss(c, d, cfg, - amt=(amt_seite is not None and c.getPageNumber() >= amt_seite), - vorschau=vorschau) + def seite(c, d): + _kopf_fuss(c, d, cfg, vorschau=vorschau) - doc.build(story, onFirstPage=seite, onLaterPages=seite) - - # Zwei Durchlaeufe, und zwar aus einem konkreten Grund: - # - # Kopf und Fuss werden VOR dem Seiteninhalt gezeichnet - beim Zeichnen weiss die - # Seite also noch nicht, ob auf ihr gleich die Kunden- oder die Amts-Seite landet. - # Auf "Seite 2 ist das Amt" zu wetten, waere falsch, sobald die Kundenrechnung - # laenger als eine Seite wird: dann stuende die Bankverbindung ploetzlich auf dem - # Amt-Blatt und fehlte beim Kunden. - # - # Darum: erster Lauf ins Nichts, nur um zu erfahren, auf welcher Seite das - # Amt-Blatt beginnt. Zweiter Lauf schreibt die echte Datei. - marke = {} - bauen(io.BytesIO(), None) - bauen(pfad, marke.get("seite")) + doc.build(story, onFirstPage=seite, onLaterPages=seite) return pfad diff --git a/pruef_api.py b/pruef_api.py new file mode 100644 index 0000000..ac9d217 --- /dev/null +++ b/pruef_api.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: das Fenster ueber die API bedienen - mit Schluessel. + +Warum es das gibt (seine Ansage): *"bau dir steuer logik per api rein, dann +kannst damit die sachen triggern, brauchst meine maus nicht"* und *"mach pw +rein, also schluessel wie bei ssh key, das nur du und das beherbergungssteuer +ding rein kann, weil muss ja sprechen"*. + +Geprueft wird: + +1. Ohne Schluessel geht NICHTS - auch nicht "nur nachsehen". +2. Mit falschem Schluessel ebenfalls nicht. +3. Mit dem Schluessel aus dem gemeinsamen Ordner laesst sich das Fenster + fuellen, nachlesen und eine Vorschau erzeugen. +4. Was einen BELEG schreibt, geht nur im Testlauf - und schreibt dann + tatsaechlich die Rechnung. +5. ping und schau_nach bleiben schluessellos, sonst kann ein aelteres + Steuerjournal nicht mehr anklopfen. +""" +import json +import os +import shutil +import sys +import tempfile +import threading + +QUELLE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, QUELLE) + +tmp = tempfile.mkdtemp(prefix="api_pruef_") +ordner = os.path.join(tmp, "rechnungen") +gemeinsam_ordner = os.path.join(tmp, "install") +os.makedirs(ordner) +os.makedirs(gemeinsam_ordner) + +import config # noqa: E402 +shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json")) +config.BASE_DIR = tmp +config.CONFIG_PATH = os.path.join(tmp, "config.json") +roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) +roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +roh["output_dir"] = ordner +roh["gemeinsam_ordner"] = gemeinsam_ordner +json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False, indent=2) + +os.environ["CAMPINGHOF_TEST"] = "1" +import api # noqa: E402 +import app as A # noqa: E402 +import gemeinsam # noqa: E402 +from tkinter import messagebox # noqa: E402 + + +def _reissleine(): + print("ABBRUCH | Pruefstand haengt (Zeitgrenze)") + os._exit(2) + + +_wecker = threading.Timer(120, _reissleine) +_wecker.daemon = True +_wecker.start() + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + k = sys.stdout.encoding or "utf-8" + print(zeile.encode(k, "replace").decode(k)) + if not bedingung: + fehler.append(text) + + +messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None +messagebox.askyesno = lambda *a, **k: True + +f = A.RechnungsApp() +f.cfg["output_dir"] = ordner +f.buch = gemeinsam.Nummernbuch(gemeinsam_ordner) +f.api.starten(f.buch, ordner=gemeinsam_ordner) +f.update() + +port = f.api.port +pruefe(bool(port), f"die API laeuft ({port})") + +schluessel = api.schluessel_holen(gemeinsam_ordner) +pruefe(len(schluessel) == 64, f"ein Schluessel liegt im gemeinsamen Ordner ({len(schluessel)} Zeichen)") +pruefe(os.path.exists(os.path.join(gemeinsam_ordner, api.SCHLUESSEL_DATEI)), + "und zwar als Datei neben dem Nummernbuch") +pruefe(api.schluessel_holen(gemeinsam_ordner) == schluessel, + "beim zweiten Lesen kommt derselbe zurueck (kein neuer je Start)") + + +def rufen(**nachricht): + """Direkt anrufen - der Pruefstand spielt hier das andere Programm.""" + was = nachricht.pop("was", "aktion") + return api._reden(port, was, zeitgrenze=20.0, **nachricht) + + +# Das Fenster muss waehrend des Anrufs weiterlaufen: die Aktion wird in seinem +# Faden ausgefuehrt. Also nebenher anrufen und die Ereignisschleife drehen. +def anrufen_und_drehen(**nachricht): + ergebnis = {} + + def anruf(): + ergebnis["antwort"] = rufen(**nachricht) + + t = threading.Thread(target=anruf, daemon=True) + t.start() + while t.is_alive(): + f.update() + return ergebnis.get("antwort") + + +# ---- 1. + 2. Ohne (oder mit falschem) Schluessel: kein Zutritt ------------- +pruefe(anrufen_und_drehen(name="zustand") == "kein zutritt", + "ohne Schluessel: kein Zutritt") +pruefe(anrufen_und_drehen(name="zustand", schluessel="0" * 64) == "kein zutritt", + "falscher Schluessel: kein Zutritt") + +# ---- 5. Die alten zwei Woerter bleiben schluessellos ----------------------- +pruefe(anrufen_und_drehen(was="ping") == api.ANTWORT_HALLO, + "ping antwortet weiterhin ohne Schluessel") + +# ---- 3. Mit Schluessel: fuellen, nachlesen, Vorschau ----------------------- +antwort = anrufen_und_drehen( + name="setze", schluessel=schluessel, + daten={"kunde": {"vorname": "Anna", "nachname": "Beispiel", + "strasse": "Musterweg 1", "plzort": "12345 Musterstadt"}, + "anreise": "01.09.2026", "abreise": "04.09.2026", + "positionen": [{"nr": sorted(f.anzahl_vars)[0], "anzahl": 3}]}) +pruefe(isinstance(antwort, dict) and antwort.get("kunde", {}).get("nachname") == "Beispiel", + f"mit Schluessel laesst sich das Formular fuellen ({str(antwort)[:60]}…)") +pruefe(antwort.get("gesamt", 0) > 0, f"und es ist gerechnet ({antwort.get('gesamt')})") + +antwort = anrufen_und_drehen(name="vorschau", schluessel=schluessel) +pfad = (antwort or {}).get("pfad", "") +pruefe(bool(pfad) and os.path.exists(pfad), f"die Vorschau entsteht ohne Maus ({os.path.basename(pfad)})") +pruefe(not os.listdir(ordner), "und sie landet NICHT im Rechnungsordner") + +# ---- 4. Beleg schreiben --------------------------------------------------- +antwort = anrufen_und_drehen(name="rechnung", schluessel=schluessel) +pdfs = [n for n in os.listdir(ordner) if n.lower().endswith(".pdf")] +pruefe(len(pdfs) == 1, f"im Testlauf schreibt die API die Rechnung ({pdfs})") + +# Und im ECHTEN Betrieb nicht: dieselbe Aktion, aber ohne Testlauf-Flag. +A.TESTLAUF = False +antwort = anrufen_und_drehen(name="rechnung", schluessel=schluessel) +pruefe(isinstance(antwort, dict) and "nur im Testlauf" in str(antwort.get("fehler", "")), + f"im echten Betrieb verweigert sie den Beleg ({antwort})") +pruefe(len([n for n in os.listdir(ordner) if n.lower().endswith(".pdf")]) == 1, + "und es kam keine zweite Rechnung dazu") +A.TESTLAUF = True + +# Unbekannter Name sagt, was es gibt - statt still nichts zu tun. +antwort = anrufen_und_drehen(name="tanz", schluessel=schluessel) +pruefe("kenne ich nicht" in str(antwort), f"unbekannte Aktion wird benannt ({str(antwort)[:50]}…)") + +f.api.stoppen(f.buch) +f.destroy() +print() +if fehler: + print(f"FEHLGESCHLAGEN: {len(fehler)}") + for x in fehler: + print(" -", x) + print(f"(Ordner bleibt: {tmp})") + sys.exit(1) +shutil.rmtree(tmp, ignore_errors=True) +print("ALLES GRUEN") diff --git a/pruef_bilder.py b/pruef_bilder.py index 16bbe75..05b1c1f 100644 --- a/pruef_bilder.py +++ b/pruef_bilder.py @@ -98,13 +98,12 @@ def seiten_bilder_und_text(pdf): seiten = seiten_bilder_und_text(pfad) -pruefe(len(seiten) >= 2, f"Kundenblatt + Amt-Blatt: {len(seiten)} Seiten") +pruefe(len(seiten) == 1, f"genau EIN Blatt ({len(seiten)} Seiten)") kunde_bilder, kunde_text = seiten[0] -amt_bilder, amt_text = seiten[-1] -pruefe(kunde_bilder == 2, f"Kundenblatt traegt Kopf- UND Fussbild ({kunde_bilder})") -pruefe(amt_bilder == 1, f"Amt-Blatt traegt NUR das Kopfbild ({amt_bilder})") -pruefe("Testbank" in kunde_text, "Bankverbindung steht auf der Kundenrechnung") -pruefe("Testbank" not in amt_text, "Bankverbindung steht NICHT auf dem Amt-Blatt") +pruefe(kunde_bilder == 2, f"das Blatt traegt Kopf- UND Fussbild ({kunde_bilder})") +pruefe("Testbank" in kunde_text, "Bankverbindung steht auf der Rechnung") +pruefe("Steuernummer" in kunde_text, + "die Steuernummer steht auf der Rechnung (§ 14 Abs. 4 Nr. 2 UStG)") # ---- 3. Die Firmenfarbe faerbt das Blatt ---------------------------------- # Jede Firma faerbt ihre Rechnung selbst. Geprueft wird, dass die gewaehlte diff --git a/pruef_montage.py b/pruef_montage.py index cea63cb..86581c1 100644 --- a/pruef_montage.py +++ b/pruef_montage.py @@ -155,7 +155,10 @@ pruefe(len(pos) == 1 and float(pos[0]["anzahl"]) == 1.0, f"eine Position, ein Mo from pypdf import PdfReader # noqa: E402 seiten = [s.extract_text() or "" for s in PdfReader(pdf).pages] -pruefe(len(seiten) == 2, f"zwei Seiten - Kunde und Amt ({len(seiten)})") +# Seit 05.09.2026 gibt es nur noch EIN Blatt. Ein zweites mit derselben Nummer, +# aber anderem Gesamtbetrag ("fuer das Amt") sieht bei einer Pruefung aus, als +# werde ueber zwei verschiedene Umsaetze abgerechnet. +pruefe(len(seiten) == 1, f"genau EIN Blatt - kein zweites fuers Amt ({len(seiten)})") kunde_seite = seiten[0].replace("\n", " ") pruefe("Miete für Montagearbeiter" in kunde_seite, "die Miet-Zeile steht auf dem Blatt") pruefe("Zeitraum 01.08.2026" in kunde_seite, "mit dem Zeitraum") @@ -166,9 +169,8 @@ pruefe("Tage/Menge" not in kunde_seite and "Pos." not in kunde_seite, pruefe("525,00" in kunde_seite and "500,00" in kunde_seite, "500,00 und 525,00 stehen drauf") pruefe("Beherbergungssteuer" in kunde_seite, "die Steuer ist auf der Kundenseite ausgewiesen") -amt_seite = seiten[1].replace("\n", " ") -pruefe("Beherbergungssteuer" not in amt_seite, - "auf dem Amtsblatt steht sie nicht - wie bei jeder anderen Rechnung") +pruefe(kunde_seite.count("Rechnungsbetrag Insgesamt") == 1, + "der Gesamtbetrag steht genau einmal in der Datei") # ---- 4. Das Steuerjournal liest die Datei --------------------------------- sys.path.append(JOURNAL_PROG) diff --git a/pruef_nummernsperre.py b/pruef_nummernsperre.py index 6893504..5470554 100644 --- a/pruef_nummernsperre.py +++ b/pruef_nummernsperre.py @@ -228,6 +228,17 @@ def erststart(zahl, erwartet_ja=True): for k in knoepfe_von(top): if "bernehmen" in str(k.cget("text")): k.invoke() + # Lehnt der Dialog die Zahl ab, BLEIBT er offen - das ist + # gewollt und wird weiter unten geprueft. Dann muss hier + # aber, wie ein Benutzer, "Spaeter" gedrueckt werden: + # sonst wartet das Programm in wait_window() ewig auf + # einen Klick, den im Pruefstand niemand macht. + top.update() + if top.winfo_exists(): + for spaeter in knoepfe_von(top): + if "ter" in str(spaeter.cget("text")): + spaeter.invoke() + break return if rest: f.after(100, lambda: klick(rest - 1)) diff --git a/pruefsteuerung.py b/pruefsteuerung.py new file mode 100644 index 0000000..ed320de --- /dev/null +++ b/pruefsteuerung.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +"""Steuerung fuer Pruefstaende: keine Fenster, keine Popups, keine Maus. + +WARUM +----- +Ein Pruefstand baut das Programm auf, um es zu BEDIENEN - nicht, um es zu +zeigen. Solange er wie ein Benutzer arbeitet, reisst jeder Lauf dem Menschen am +Rechner Fokus und Maus weg, und jeder Dialog bleibt stehen und wartet auf einen +Klick, den niemand macht. + +Deshalb zwei Dinge, beide nur im Testlauf (`--test` / `CAMPINGHOF_TEST=1`): + + * Das Fenster wird gar nicht erst gezeigt (`withdraw()` in app.py). + * Alle Dialoge laufen hierueber statt ueber echte Fenster. + +WAS EIN DIALOG HIER TUT +----------------------- +`showinfo/showwarning/showerror` werden ins PROTOKOLL geschrieben und +verschwinden. `askyesno` und Verwandte schlagen im Fahrplan nach: + + pruefsteuerung.antwortet("Hausnummer", True) + +Passt kein Eintrag, bricht der Lauf mit einer Meldung ab - ABSICHTLICH. Ein +unbekannter Dialog heisst: das Programm fragt etwas Neues, und niemand hat +entschieden, was der Pruefstand darauf antworten soll. Stillschweigend "ja" zu +sagen waere die faule Loesung und wuerde genau die Faelle uebergehen, wegen +denen es die Pruefung gibt. + +BENUTZUNG IM PRUEFSTAND +----------------------- + import pruefsteuerung as PS + PS.antwortet("Storno wirklich", True) + ... + PS.gemeldet("Kundenangaben fehlen") -> True, wenn das Programm es sagte +""" +from tkinter import messagebox + +# Was das Programm gemeldet haette: Liste aus (art, titel, text). +PROTOKOLL = [] +# Fahrplan fuer Ja/Nein-Fragen: Textstueck im Titel -> Antwort. +ANTWORTEN = {} +_aktiv = False + + +def antwortet(titelstueck, wert): + """Legt fest, wie eine Frage beantwortet wird, deren Titel das Stueck enthaelt.""" + ANTWORTEN[titelstueck] = wert + + +def zuruecksetzen(): + PROTOKOLL.clear() + ANTWORTEN.clear() + + +def meldungen(stueck=""): + """Alle Meldungen (oder die, in denen das Stueck vorkommt).""" + return [m for m in PROTOKOLL if stueck in m[1] or stueck in m[2]] + + +def gemeldet(stueck): + """Hat das Programm etwas gemeldet, in dem das Stueck vorkommt?""" + return bool(meldungen(stueck)) + + +def _melden(art): + def gemeldet_(titel="", text="", **_kw): + PROTOKOLL.append((art, str(titel), str(text))) + print(f"[dialog] {art}: {titel}") + return "ok" + return gemeldet_ + + +def _fragen(vorgabe=None): + def gefragt(titel="", text="", **_kw): + PROTOKOLL.append(("frage", str(titel), str(text))) + for stueck, wert in ANTWORTEN.items(): + if stueck in str(titel) or stueck in str(text): + print(f"[dialog] frage: {titel} -> {wert}") + return wert + if vorgabe is not None: + return vorgabe + raise AssertionError( + f"unangemeldeter Dialog: {titel!r}\n" + f" {text!r}\n" + " -> im Pruefstand mit pruefsteuerung.antwortet(, True/False) " + "beantworten") + return gefragt + + +def einschalten(): + """Dialoge umleiten. Mehrfaches Aufrufen schadet nicht.""" + global _aktiv + if _aktiv: + return + messagebox.showinfo = _melden("info") + messagebox.showwarning = _melden("warnung") + messagebox.showerror = _melden("fehler") + messagebox.askyesno = _fragen() + messagebox.askokcancel = _fragen() + messagebox.askretrycancel = _fragen(False) + messagebox.askquestion = _fragen() + _aktiv = True + print("[pruefsteuerung] Dialoge laufen ohne Fenster") diff --git a/theme.py b/theme.py index 8c53c46..3070c3e 100644 --- a/theme.py +++ b/theme.py @@ -9,6 +9,8 @@ import sys import tkinter as tk from tkinter import ttk +import config + def windows_dark_mode(): """True, wenn Windows auf das dunkle App-Theme eingestellt ist.""" @@ -113,7 +115,12 @@ class ThemeMixin: self.option_add("*foreground", fg) def _style_dialog(self, d): - """Toplevel-Dialog an das Theme angleichen.""" + """Toplevel-Dialog an das Theme angleichen. + + Im Pruefstand wird derselbe Dialog gebaut und bedient, aber nicht + gezeigt - und sein grab_set faellt weg. Sonst haelt jeder Dialog Maus + und Tastatur fest, waehrend nebenan jemand schreibt. + """ d.configure(bg=self.col_bg) # erst nach dem Anzeigen setzen, sonst greift DWM noch nicht d.after(20, lambda: self._dark_titlebar(d)) From 4cf46e993232780390590b3602ebb397f9b76ae8 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 18:25:54 +0200 Subject: [PATCH 04/34] Pruefstand-Fenster gehen neben dem Bildschirm auf, ohne Maus zu greifen Sein Fund mitten im Lauf: "pack doch die maus nicht immer auf das programm, weil ich kann dir sonst nichts schreiben". Im Testlauf oeffnen Fenster und Dialoge jetzt bei x = Bildschirmbreite + 20 - auf dem zweiten Monitor, wenn einer da ist -, und kein Dialog ruft mehr grab_set. Unsichtbar machen (withdraw) waere falsch: dann sieht niemand mehr, was der Pruefstand tut - und ein weggenommenes Fenster baut seine Dialoge nicht mehr richtig auf. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 7 +++++++ theme.py | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/app.py b/app.py index cf23915..f135492 100644 --- a/app.py +++ b/app.py @@ -60,6 +60,13 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): hoehe = max(560, min(840, self.winfo_screenheight() - 90)) self.geometry(f"1060x{hoehe}") self.minsize(900, 540) + if TESTLAUF: + # Ein Pruefstand bedient das Programm, waehrend nebenan jemand + # arbeitet. Das Fenster geht deshalb NEBEN dem Bildschirm auf (auf + # dem zweiten Monitor, wenn einer da ist) - sichtbar, aber nicht im + # Weg. Unsichtbar machen waere falsch: dann sieht niemand mehr, was + # der Pruefstand eigentlich tut. + self.geometry(f"+{self.winfo_screenwidth() + 20}+40") self.anzahl_vars = {} # nr -> StringVar self.personen_vars = {} # nr -> StringVar diff --git a/theme.py b/theme.py index 3070c3e..dd06109 100644 --- a/theme.py +++ b/theme.py @@ -122,6 +122,12 @@ class ThemeMixin: und Tastatur fest, waehrend nebenan jemand schreibt. """ d.configure(bg=self.col_bg) + if config.TESTLAUF: + # Wie das Hauptfenster: neben den Bildschirm, und ohne grab_set - + # ein Dialog, der Maus und Tastatur festhaelt, blockiert den + # Menschen, der nebenher schreibt. + d.geometry(f"+{d.winfo_screenwidth() + 20}+40") + d.grab_set = lambda *a, **k: None # erst nach dem Anzeigen setzen, sonst greift DWM noch nicht d.after(20, lambda: self._dark_titlebar(d)) From fe0c4a8e08f1179d72d8b16009e5e703dcff2d26 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 18:31:07 +0200 Subject: [PATCH 05/34] Im Pruflauf geht kein PDF-Betrachter mehr auf Sein Fund: "wenn du testest, dann mach den tab auch zu". Ein Lauf ueber die Pruefkette schreibt Dutzende Rechnungen, und nach jeder oeffnete das Programm den Betrachter - am Ende klickt der Mensch am Rechner dreissig Fenster weg, die er nie aufgemacht hat. Geoeffnet wird jetzt nur noch an EINER Stelle (_oeffne_datei), und die haelt im Testlauf still und meldet stattdessen, was zu sehen gewesen waere. Die zweite Stelle, die frueher direkt os.startfile rief, geht ebenfalls darueber. pruef_vorschau prueft jetzt den zurueckgegebenen Pfad - und dass wirklich nichts aufgemacht wurde. Alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 12 +++++++++++- pruef_vorschau.py | 11 ++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app.py b/app.py index f135492..474ef43 100644 --- a/app.py +++ b/app.py @@ -1263,7 +1263,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf, vorschau=True) print(f"[vorschau] geschrieben -> {pfad}") if oeffnen: - os.startfile(pfad) # noqa: S606 + self._oeffne_datei(pfad) return pfad except OSError as e: messagebox.showerror("Vorschau nicht möglich", @@ -1614,6 +1614,16 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): def _oeffne_datei(self, pfad): + """Datei oder Ordner im Betrachter oeffnen. Im Pruflauf: NICHT. + + Ein Pruefstand schreibt Dutzende Rechnungen. Wuerde jede davon den + PDF-Betrachter aufmachen, hat der Mensch am Rechner am Ende dreissig + Fenster offen, die er selbst wegklicken darf. Gemeldet wird es trotzdem, + damit im Protokoll steht, was zu sehen gewesen waere. + """ + if TESTLAUF: + print(f"[oeffnen] im Pruflauf nicht geoeffnet: {pfad}") + return False try: if sys.platform.startswith("win"): os.startfile(pfad) # noqa: S606 diff --git a/pruef_vorschau.py b/pruef_vorschau.py index 374c1a6..fa615e7 100644 --- a/pruef_vorschau.py +++ b/pruef_vorschau.py @@ -61,8 +61,9 @@ def pruefe(bedingung, text): messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None messagebox.askyesno = lambda *a, **k: True -# Die Vorschau oeffnet den PDF-Betrachter - im Pruefstand wird nur gemerkt, WAS -# sie oeffnen wollte. +# Im Pruflauf oeffnet das Programm nichts mehr (sonst stehen nach einem Lauf +# dreissig PDF-Fenster offen). Geprueft wird der Pfad, den die Vorschau +# zurueckgibt - und dass wirklich NICHTS aufgemacht wurde. geoeffnet = [] A.os.startfile = lambda p, *a, **k: geoeffnet.append(p) @@ -81,10 +82,10 @@ f.update() nummer_vorher = f.r_nummer.get() zaehler_vorher = f.cfg.get("rechnung_zaehler") -f.vorschau_zeigen() +pfad = f.vorschau_zeigen() -pruefe(len(geoeffnet) == 1, f"Vorschau oeffnet genau ein Blatt ({len(geoeffnet)})") -pfad = geoeffnet[0] if geoeffnet else "" +pruefe(bool(pfad), f"die Vorschau nennt ihr Blatt ({os.path.basename(str(pfad))})") +pruefe(not geoeffnet, f"im Pruflauf wird KEIN Betrachter aufgemacht ({geoeffnet})") pruefe(os.path.exists(pfad), "Vorschau-PDF wurde geschrieben") pruefe(os.path.abspath(ordner) not in os.path.abspath(pfad), "Vorschau liegt NICHT im Rechnungsordner") From 0ad03fd1a461122e78344028338dca585df2aa0f Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 18:39:33 +0200 Subject: [PATCH 06/34] Firmendialog passt sich dem Bildschirm an Mit den neuen Bild- und Farbzeilen reichten 640 px nicht mehr: rechts fielen "Entfernen" und unten "Speichern" aus dem Fenster - gesehen im laufenden Programm, nicht im Code. Der Dialog richtet sich jetzt nach dem Bildschirm (700-900 breit, hoehenbegrenzt) und die Felder sind etwas schmaler. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- einstellungen.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/einstellungen.py b/einstellungen.py index edc6b78..176de0c 100644 --- a/einstellungen.py +++ b/einstellungen.py @@ -334,7 +334,10 @@ class EinstellungenMixin: d.transient(self) d.grab_set() self._style_dialog(d) - d.geometry("640x740") + breite = min(900, max(700, d.winfo_screenwidth() - 200)) + hoehe = min(760, max(560, d.winfo_screenheight() - 140)) + d.geometry(f"{breite}x{hoehe}") + d.minsize(700, 560) frm = ttk.Frame(d, padding=12) frm.pack(fill="both", expand=True) @@ -349,7 +352,7 @@ class EinstellungenMixin: for i, (key, lbl) in enumerate(felder): ttk.Label(frm, text=lbl).grid(row=i, column=0, sticky="w", pady=2) v = tk.StringVar(value=self.cfg["firma"].get(key, "")) - ttk.Entry(frm, textvariable=v, width=58).grid(row=i, column=1, sticky="ew", padx=(8, 0), pady=2) + ttk.Entry(frm, textvariable=v, width=44).grid(row=i, column=1, sticky="ew", padx=(8, 0), pady=2) vars_[key] = v frm.columnconfigure(1, weight=1) base = len(felder) @@ -421,16 +424,16 @@ class EinstellungenMixin: probe_zeigen() ttk.Label(frm, text="Danktext 1").grid(row=base + 3, column=0, sticky="nw", pady=2) - t1 = tk.Text(frm, width=58, height=3, wrap="word", bg=self.col_field, fg=self.col_fg, insertbackground=self.col_fg) + t1 = tk.Text(frm, width=44, height=3, wrap="word", bg=self.col_field, fg=self.col_fg, insertbackground=self.col_fg) t1.insert("1.0", self.cfg["texte"].get("dank1", "")) t1.grid(row=base + 3, column=1, sticky="ew", padx=(8, 0), pady=2) ttk.Label(frm, text="Danktext 2").grid(row=base + 4, column=0, sticky="nw", pady=2) - t2 = tk.Text(frm, width=58, height=3, wrap="word", bg=self.col_field, fg=self.col_fg, insertbackground=self.col_fg) + t2 = tk.Text(frm, width=44, height=3, wrap="word", bg=self.col_field, fg=self.col_fg, insertbackground=self.col_fg) t2.insert("1.0", self.cfg["texte"].get("dank2", "")) t2.grid(row=base + 4, column=1, sticky="ew", padx=(8, 0), pady=2) ttk.Label(frm, text="Hinweiszeile").grid(row=base + 5, column=0, sticky="w", pady=2) vh = tk.StringVar(value=self.cfg["texte"].get("hinweis", "")) - ttk.Entry(frm, textvariable=vh, width=58).grid(row=base + 5, column=1, sticky="ew", padx=(8, 0), pady=2) + ttk.Entry(frm, textvariable=vh, width=44).grid(row=base + 5, column=1, sticky="ew", padx=(8, 0), pady=2) def speichern(): for key, v in vars_.items(): From 5ebb02b267d74122b9c7f2790cf715d5bd14fcbb Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 18:52:42 +0200 Subject: [PATCH 07/34] Oberflaeche im Pcore-Stil: Tuerkis, Kacheln, Glas-Knoepfe, Roboto Seine Ansage: "schau dir unsern fivem server an und unsere webseiten, dann weisst du wie mein design ist" - also die Palette aus _ui_www und der Adminpage: Tuerkis #06C6A4 auf gestuften dunklen Flaechen (#0d0e10 Grund, #15171b Kachel), Raender #25282e, Text #e8e8ea / #8a8e96, Rot #e85a5a. Das PROGRAMM traegt diese Handschrift, die RECHNUNG die Farbe der jeweiligen Firma - das Blatt gehoert dem Kunden, nicht uns. - Roboto wird mitgeliefert und nur fuer den Prozess geladen (AddFontResourceEx mit FR_PRIVATE): keine Installation, keine Adminrechte, nach dem Schliessen ist der Rechner wie vorher. Fehlt sie, bleibt es bei Segoe UI. Die Schriftdateien gehen mit in die exe (spec). - Abschnitte sind Kacheln mit Ueberschrift statt grauer Rahmen. - Knoepfe im Glas-Stil wie in seinen Oberflaechen: getoente Flaeche, Rand in Akzent-Transparenz. Tk kann kein backdrop-filter - die Toenung wird ausgerechnet (theme.mischen), das Ergebnis ist auf einfarbigem Grund identisch. "PDF erstellen" fuehrt, "Storno" ist rot. - Zebrastreifen in der Leistungsliste: bei 17 Zeilen verrutscht man sonst. - Kein expand am offenen Reiter mehr - dadurch sprang beim Umschalten die ganze Leiste ("das taben macht den aktiven kleiner"). - Das Fenster fuer den gemeinsamen Ordner stand als einziges noch in Weiss da: es kam nie durch _style_dialog. Dazu ein Fund, der nichts mit dem Design zu tun hat: die Pruefstaende erbten "nummer_eingerichtet" aus der config DIESES Rechners. Sobald hier jemand die Nummer einmal einrichtet, liefen sie in einen anderen Zweig und wurden rot - ohne dass sich am Programm etwas geaendert haette. Sie legen den Zustand jetzt selbst fest. Alle 14 gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 110 ++++++++++------- assets/fonts/Roboto-Italic.ttf | Bin 0 -> 530944 bytes assets/fonts/Roboto.ttf | Bin 0 -> 488584 bytes einstellungen.py | 9 +- korrektur.py | 11 +- ordnerwahl.py | 31 +++-- pruef_angebot.py | 4 + pruef_api.py | 4 + pruef_dialoge.py | 4 + pruef_kernregeln.py | 4 + pruef_kette.py | 4 + pruef_montage.py | 4 + pruef_nummernbuch.py | 4 + pruef_nummernsperre.py | 4 + pruef_storno.py | 4 + pruef_vorschau.py | 4 + theme.py | 216 +++++++++++++++++++++++++++++---- 17 files changed, 330 insertions(+), 87 deletions(-) create mode 100644 assets/fonts/Roboto-Italic.ttf create mode 100644 assets/fonts/Roboto.ttf diff --git a/app.py b/app.py index 474ef43..bad5851 100644 --- a/app.py +++ b/app.py @@ -39,6 +39,7 @@ from bestand import (hoechster_zaehler_im_ordner, naechste_freie_nummer, vorhandene_rechnungen) from einzelinstanz import (eigene_pid_merken, einzelinstanz_pruefen, fenster_nach_vorn, laufende_pid_lesen) +import theme from theme import ThemeMixin from korrektur import KorrekturMixin from einstellungen import EinstellungenMixin @@ -202,12 +203,13 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # ---------------------------------------------------------------- Kopf def _build_kopf(self): - top = ttk.Frame(self, padding=(12, 10, 12, 4)) + top = ttk.Frame(self, padding=(16, 14, 16, 6)) top.pack(fill="x") # Kunde (links) - kunde = ttk.LabelFrame(top, text="Rechnung an (Kunde)", padding=8) - kunde.grid(row=0, column=0, sticky="nsew", padx=(0, 10)) + kunde = ttk.LabelFrame(top, text="RECHNUNG AN (KUNDE)", padding=14, + style="Karte.TLabelframe") + kunde.grid(row=0, column=0, sticky="nsew", padx=(0, 14)) self.k_anrede = tk.StringVar() self.k_vorname = tk.StringVar() self.k_name = tk.StringVar() # Nachname oder Firma – die Zuordnung im Steuerjournal @@ -223,7 +225,8 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): ("PLZ / Ort *", self.k_plzort), ] for i, (lbl, var) in enumerate(felder): - ttk.Label(kunde, text=lbl).grid(row=i, column=0, sticky="w", pady=2) + ttk.Label(kunde, text=lbl, style="Karte.TLabel").grid( + row=i, column=0, sticky="w", pady=4) if var is self.k_anrede: # Auswahlliste, aber nicht gesperrt - Sonderfaelle kann man tippen. w = ttk.Combobox(kunde, textvariable=var, width=36, values=ANREDEN) @@ -232,12 +235,13 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): w.grid(row=i, column=1, sticky="ew", padx=(8, 0), pady=2) ttk.Label(kunde, text="* Pflicht – Name und Anschrift des Kunden gehören " "auf die Rechnung (§ 14 Abs. 4 Nr. 1 UStG).", - foreground=self.col_muted, wraplength=330, justify="left").grid( + style="KarteMuted.TLabel", wraplength=330, justify="left").grid( row=len(felder), column=0, columnspan=2, sticky="w", pady=(6, 0)) kunde.columnconfigure(1, weight=1) # Rechnungsinfos (rechts) - info = ttk.LabelFrame(top, text="Rechnungsdaten", padding=8) + info = ttk.LabelFrame(top, text="RECHNUNGSDATEN", padding=14, + style="Karte.TLabelframe") info.grid(row=0, column=1, sticky="nsew") self.r_nummer = tk.StringVar() self.r_datum = tk.StringVar(value=datetime.date.today().strftime("%d.%m.%Y")) @@ -253,8 +257,8 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): date_vars = (self.r_datum, self.r_anreise, self.r_abreise) self.datum_labels = {} for i, (lbl, var) in enumerate(rows): - beschriftung = ttk.Label(info, text=lbl) - beschriftung.grid(row=i, column=0, sticky="w", pady=2) + beschriftung = ttk.Label(info, text=lbl, style="Karte.TLabel") + beschriftung.grid(row=i, column=0, sticky="w", pady=4) if var is self.r_anreise: self.datum_labels["von"] = beschriftung elif var is self.r_abreise: @@ -267,14 +271,16 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): self.nummer_entry = ent if var in date_vars: # Datum: Punkte automatisch, Cursor ans Ende ent.bind("", self._auto_datum_evt) - self.naechte_label = ttk.Label(info, text="Nächte") - self.naechte_label.grid(row=4, column=0, sticky="w", pady=2) - ttk.Label(info, textvariable=self.r_naechte, font=("Segoe UI", 10, "bold")).grid( + self.naechte_label = ttk.Label(info, text="Nächte", style="Karte.TLabel") + self.naechte_label.grid(row=4, column=0, sticky="w", pady=4) + ttk.Label(info, textvariable=self.r_naechte, style="Karte.TLabel", + font=(theme.SCHRIFT_NAME, 11, "bold")).grid( row=4, column=1, sticky="w", padx=(8, 0)) # Storno-Hinweis: steht nur da, solange ein Storno im Zwischenspeicher liegt. self.storno_hinweis = tk.StringVar(value="") - ttk.Label(info, textvariable=self.storno_hinweis, foreground="#b00020", - font=("Segoe UI", 9, "bold"), wraplength=200, justify="left").grid( + ttk.Label(info, textvariable=self.storno_hinweis, style="Karte.TLabel", + foreground=self.col_gefahr, + font=(theme.SCHRIFT_NAME, 9, "bold"), wraplength=200, justify="left").grid( row=5, column=0, columnspan=2, sticky="w", pady=(6, 0)) info.columnconfigure(1, weight=1) self.r_anreise.trace_add("write", lambda *a: self._update_naechte()) @@ -369,10 +375,11 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): self.blaetter.add(montage_tab, text=" Montage ") self._build_montage(montage_tab) - wrap = ttk.LabelFrame(camping, text="Leistungen – Anzahl (und ggf. Personen) eintragen", padding=(6, 4)) + wrap = ttk.LabelFrame(camping, text="LEISTUNGEN – ANZAHL (UND GGF. PERSONEN) EINTRAGEN", + padding=(12, 8), style="Karte.TLabelframe") wrap.pack(side="top", fill="both", expand=True) - canvas = tk.Canvas(wrap, highlightthickness=0, bg=self.col_bg) + canvas = tk.Canvas(wrap, highlightthickness=0, bg=self.col_card) sb = ttk.Scrollbar(wrap, orient="vertical", command=canvas.yview) self.pos_frame = ttk.Frame(canvas) self._pos_win = canvas.create_window((0, 0), window=self.pos_frame, anchor="nw") @@ -399,10 +406,11 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # Kopfzeile (gleiches Grid wie die Daten) for i, (title, anchor, _) in enumerate(self.COLS): - ttk.Label(self.pos_frame, text=title, anchor=anchor, - font=("Segoe UI", 9, "bold")).grid(row=0, column=i, padx=3, pady=(0, 3), sticky="ew") + ttk.Label(self.pos_frame, text=title.upper(), anchor=anchor, + style="Abschnitt.TLabel").grid( + row=0, column=i, padx=3, pady=(0, 5), sticky="ew") ttk.Separator(self.pos_frame, orient="horizontal").grid( - row=1, column=0, columnspan=len(self.COLS), sticky="ew", pady=(0, 2)) + row=1, column=0, columnspan=len(self.COLS), sticky="ew", pady=(0, 4)) for idx, pos in enumerate(self.cfg["katalog"]): r = idx + 2 @@ -414,17 +422,26 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): av.trace_add("write", lambda *a: self.recalc()) pv.trace_add("write", lambda *a: self.recalc()) - ttk.Label(self.pos_frame, text=str(nr), anchor="center").grid(row=r, column=0, padx=3, pady=2, sticky="ew") + # Jede zweite Zeile bekommt einen anderen Grund: bei 17 Positionen + # verrutscht man beim Eintragen sonst leicht eine Zeile. + zeilenstil = "Zebra.TLabel" if idx % 2 else "Karte.TLabel" + ttk.Label(self.pos_frame, text=str(nr), anchor="center", style=zeilenstil).grid( + row=r, column=0, padx=0, pady=3, sticky="ew", ipady=2) ttk.Label(self.pos_frame, text=pos["leistung"], anchor="w", wraplength=320, - justify="left").grid(row=r, column=1, padx=3, pady=2, sticky="ew") - ttk.Label(self.pos_frame, text=str(pos["satz"]), anchor="center").grid(row=r, column=2, padx=3, pady=2, sticky="ew") - ttk.Entry(self.pos_frame, textvariable=av, width=8, justify="center").grid(row=r, column=3, padx=3, pady=2) + justify="left", style=zeilenstil).grid( + row=r, column=1, padx=0, pady=3, sticky="ew", ipady=2) + ttk.Label(self.pos_frame, text=str(pos["satz"]), anchor="center", + style=zeilenstil).grid(row=r, column=2, padx=0, pady=3, sticky="ew", ipady=2) + ttk.Entry(self.pos_frame, textvariable=av, width=8, justify="center").grid( + row=r, column=3, padx=4, pady=3) # Personen-Feld NUR bei "pro Person"-Positionen anzeigen if pos["pro_person"]: - ttk.Entry(self.pos_frame, textvariable=pv, width=6, justify="center").grid(row=r, column=4, padx=3, pady=2) - ttk.Label(self.pos_frame, text=berechnung.eur_kurz(pos["preis"]), anchor="e").grid(row=r, column=5, padx=3, pady=2, sticky="ew") - g = ttk.Label(self.pos_frame, text="0,00", anchor="e") - g.grid(row=r, column=6, padx=3, pady=2, sticky="ew") + ttk.Entry(self.pos_frame, textvariable=pv, width=6, justify="center").grid( + row=r, column=4, padx=4, pady=3) + ttk.Label(self.pos_frame, text=berechnung.eur_kurz(pos["preis"]), anchor="e", + style=zeilenstil).grid(row=r, column=5, padx=0, pady=3, sticky="ew", ipady=2) + g = ttk.Label(self.pos_frame, text="0,00", anchor="e", style=zeilenstil) + g.grid(row=r, column=6, padx=0, pady=3, sticky="ew", ipady=2) self.gesamt_lbls[nr] = g # ------------------------------------------------------------ Montage @@ -440,7 +457,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): self.m_monate.trace_add("write", lambda *a: self.recalc()) ttk.Label(eltern, text="Monatsmiete für einen Montagearbeiter", - font=("Segoe UI", 11, "bold")).grid(row=0, column=0, columnspan=4, sticky="w") + font=(theme.SCHRIFT_NAME, 11, "bold")).grid(row=0, column=0, columnspan=4, sticky="w") ttk.Label(eltern, wraplength=760, justify="left", foreground=self.col_muted, text="Den Zeitraum trägst du oben rechts ein (dieselben Felder wie Anreise/Abreise). " "Bezeichnung, Steuersatz und Monatspreis stehen unter " @@ -451,17 +468,17 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): ttk.Entry(eltern, textvariable=self.m_monate, width=8, justify="center").grid( row=2, column=1, sticky="w", padx=(8, 24), pady=3) ttk.Label(eltern, text="Monatspreis (brutto):").grid(row=2, column=2, sticky="w", pady=3) - self.m_preis = ttk.Label(eltern, text="", font=("Segoe UI", 10, "bold")) + self.m_preis = ttk.Label(eltern, text="", font=(theme.SCHRIFT_NAME, 10, "bold")) self.m_preis.grid(row=2, column=3, sticky="w", padx=(8, 0), pady=3) ttk.Separator(eltern, orient="horizontal").grid( row=3, column=0, columnspan=4, sticky="ew", pady=12) ttk.Label(eltern, text="So steht es auf der Rechnung:", - font=("Segoe UI", 9, "bold")).grid(row=4, column=0, columnspan=4, sticky="w") + font=(theme.SCHRIFT_NAME, 9, "bold")).grid(row=4, column=0, columnspan=4, sticky="w") self.m_text = ttk.Label(eltern, text="", wraplength=760, justify="left") self.m_text.grid(row=5, column=0, columnspan=4, sticky="w", pady=(4, 10)) - self.m_zahlen = ttk.Label(eltern, text="", font=("Segoe UI", 10)) + self.m_zahlen = ttk.Label(eltern, text="", font=(theme.SCHRIFT_NAME, 10)) self.m_zahlen.grid(row=6, column=0, columnspan=4, sticky="w") eltern.columnconfigure(3, weight=1) @@ -522,14 +539,14 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): status = ttk.Frame(self, padding=(12, 2)) status.pack(side="bottom", fill="x") ttk.Label(status, text="powered by ravokk", foreground=self.col_muted, - font=("Segoe UI", 8)).pack(side="right") + font=(theme.SCHRIFT_NAME, 8)).pack(side="right") # Steht der gemeinsame Ordner? Das gehoert sichtbar hin - ohne ihn kennt # das Programm die Nummern des Steuerjournals nicht. self.buch_lbl = ttk.Label(status, text="", foreground=self.col_muted, - font=("Segoe UI", 8)) + font=(theme.SCHRIFT_NAME, 8)) self.buch_lbl.pack(side="left") - f = ttk.Frame(self, padding=(12, 6, 12, 10)) + f = ttk.Frame(self, padding=(16, 12, 16, 14)) f.pack(side="bottom", fill="x") ttk.Separator(self, orient="horizontal").pack(side="bottom", fill="x") @@ -539,13 +556,17 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): links = ttk.Frame(f) links.pack(side="left") - ttk.Button(links, text="Vorschau", command=self.vorschau_zeigen, width=12).pack(side="left", padx=4) - ttk.Button(links, text="PDF erstellen", command=self.pdf_erstellen, width=18).pack(side="left", padx=4) + # "PDF erstellen" ist der Knopf, um den es geht - der traegt die + # Akzentfarbe. Storno greift in eine ausgestellte Rechnung ein und ist + # deshalb rot markiert, nicht weil er gefaehrlich waere, sondern damit + # niemand ihn versehentlich statt "PDF erstellen" trifft. + ttk.Button(links, text="PDF erstellen", command=self.pdf_erstellen, + style="Haupt.TButton").pack(side="left", padx=(0, 6)) + ttk.Button(links, text="Vorschau", command=self.vorschau_zeigen).pack(side="left", padx=6) ttk.Button(links, text="Storno", command=self.dlg_storno, - width=12).pack(side="left", padx=4) - ttk.Button(links, text="Berichtigen", command=self.dlg_berichtigen, - width=14).pack(side="left", padx=4) - ttk.Button(links, text="Zurücksetzen", command=self.reset_formular, width=14).pack(side="left", padx=4) + style="Gefahr.TButton").pack(side="left", padx=6) + ttk.Button(links, text="Berichtigen", command=self.dlg_berichtigen).pack(side="left", padx=6) + ttk.Button(links, text="Zurücksetzen", command=self.reset_formular).pack(side="left", padx=6) # --------------------------------------------------- Gemeinsames Buch def _buch_oeffnen(self): @@ -638,7 +659,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): rahmen = ttk.Frame(d, padding=18) rahmen.pack(fill="both", expand=True) ttk.Label(rahmen, text="Wo soll die Rechnungsnummer weiterlaufen?", - font=("Segoe UI", 13, "bold")).grid(row=0, column=0, columnspan=2, sticky="w") + font=(theme.SCHRIFT_NAME, 13, "bold")).grid(row=0, column=0, columnspan=2, sticky="w") ttk.Label(rahmen, wraplength=620, justify="left", text=( "Zwei Wege - such dir einen aus." + chr(10) + chr(10) + "Das wird EINMAL eingerichtet. Danach steht der Zähler fest: eine " @@ -649,7 +670,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): if gefunden: tk.Label(rahmen, wraplength=620, justify="left", fg="#1f5c3d", - font=("Segoe UI", 9, "bold"), + font=(theme.SCHRIFT_NAME, 9, "bold"), text=f"Im Rechnungsordner und im Nummernbuch steht schon " f"{jahr}-{gefunden:03d} – niedriger geht es nicht.").grid( row=2, column=0, columnspan=2, sticky="w", pady=(0, 10)) @@ -677,7 +698,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): eingabe.pack(side="left", padx=(8, 0)) weg_gewaehlt() hinweis = tk.Label(rahmen, text="", wraplength=620, justify="left", fg="#a00000", - font=("Segoe UI", 9)) + font=(theme.SCHRIFT_NAME, 9)) hinweis.grid(row=5, column=0, columnspan=2, sticky="w", pady=(8, 0)) def uebernehmen(): @@ -957,7 +978,8 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): rows.append(("Gesamtbetrag:", berechnung.eur(r.gesamt), True)) for i, (lbl, val, fett) in enumerate(rows): - font = ("Segoe UI", 12, "bold") if fett else ("Segoe UI", 10) + font = ((theme.SCHRIFT_NAME, 15, "bold") if fett + else (theme.SCHRIFT_NAME, 10)) pady = (5, 0) if fett else (1, 0) ttk.Label(self.summen_box, text=lbl, font=font).grid(row=i, column=0, sticky="e", padx=6, pady=pady) vkw = {"font": font, "width": 14, "anchor": "e"} @@ -1040,7 +1062,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): rahmen = ttk.Frame(d, padding=18) rahmen.pack(fill="both", expand=True) ttk.Label(rahmen, text=f"{wer or 'ohne Namen'} – {betrag}", - font=("Segoe UI", 12, "bold")).grid(row=0, column=0, sticky="w") + font=(theme.SCHRIFT_NAME, 12, "bold")).grid(row=0, column=0, sticky="w") ttk.Label(rahmen, wraplength=560, justify="left", text=( f"RECHNUNG {nummer} – der Beleg. Danach lässt sie sich nicht mehr " diff --git a/assets/fonts/Roboto-Italic.ttf b/assets/fonts/Roboto-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a122c13964daac37f1186a22603a5180d2dba5d6 GIT binary patch literal 530944 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 z

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 T0S5#X8SCX>-kBRbYZPfb}%@n2D;M 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%0DRx!m9?a;{2Js}Iv#Rn$&d3ID76aA! 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 Y;6XU#ILQS8g4^Zm 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�uP5<4L&6))V{L_N$NJ(tsg|m8z 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 literal 0 HcmV?d00001 diff --git a/einstellungen.py b/einstellungen.py index 176de0c..794098f 100644 --- a/einstellungen.py +++ b/einstellungen.py @@ -11,6 +11,7 @@ import tkinter as tk from tkinter import ttk, messagebox, filedialog, colorchooser import berechnung +import theme import bilder import config from helfer import parse_num @@ -50,7 +51,7 @@ class EinstellungenMixin: self._style_dialog(d) frm = ttk.Frame(d, padding=18) frm.pack(fill="both", expand=True) - ttk.Label(frm, text="Rechnungstool Campinghof Bartl", font=("Segoe UI", 11, "bold"), + ttk.Label(frm, text="Rechnungstool Campinghof Bartl", font=(theme.SCHRIFT_NAME, 11, "bold"), foreground=self.col_accent).pack(anchor="w") ttk.Label(frm, justify="left", text="Daten eingeben, PDF erstellen, drucken.\n" @@ -74,7 +75,7 @@ class EinstellungenMixin: frm = ttk.Frame(d, padding=12) frm.pack(fill="both", expand=True) - ttk.Label(frm, wraplength=580, justify="left", font=("Segoe UI", 9, "bold"), + ttk.Label(frm, wraplength=580, justify="left", font=(theme.SCHRIFT_NAME, 9, "bold"), text="Steuersätze: Satz % + Name. Die Katalog-Preise sind BRUTTO; die USt dieses " "Satzes wird herausgerechnet und als 'enthalten' ausgewiesen. Haken bei " "'Aufschlag': diese Steuer (z.B. Beherbergungssteuer) wird stattdessen auf den " @@ -92,7 +93,7 @@ class EinstellungenMixin: for w in liste.winfo_children(): w.destroy() for c, t in enumerate(["Satz %", "Bezeichnung (Name der Steuer)", "Aufschlag", ""]): - ttk.Label(liste, text=t, font=("Segoe UI", 9, "bold")).grid( + ttk.Label(liste, text=t, font=(theme.SCHRIFT_NAME, 9, "bold")).grid( row=0, column=c, padx=4, pady=(0, 3), sticky="w") for i, row in enumerate(arbeit, start=1): ttk.Entry(liste, textvariable=row["satz"], width=8, justify="center").grid(row=i, column=0, padx=4, pady=2) @@ -247,7 +248,7 @@ class EinstellungenMixin: for w in inner.winfo_children(): w.destroy() for c, t in enumerate(["Pos.", "Bezeichnung", "Steuersatz", "Preis €", "pro Person", ""]): - ttk.Label(inner, text=t, font=("Segoe UI", 9, "bold")).grid( + ttk.Label(inner, text=t, font=(theme.SCHRIFT_NAME, 9, "bold")).grid( row=0, column=c, padx=4, pady=(0, 4), sticky="w") for i, row in enumerate(arbeit, start=1): ttk.Label(inner, text=str(i), width=4).grid(row=i, column=0, padx=4, pady=1) diff --git a/korrektur.py b/korrektur.py index d0d4ccb..4bd8a1a 100644 --- a/korrektur.py +++ b/korrektur.py @@ -23,6 +23,7 @@ import tkinter as tk from tkinter import ttk, messagebox import berechnung +import theme import config import pdf_renderer import berechnung @@ -375,7 +376,7 @@ class KorrekturMixin: rahmen = ttk.Frame(d, padding=18) rahmen.pack(fill="both", expand=True) ttk.Label(rahmen, text=f"Storno zu Rechnung {alt_nummer}", - font=("Segoe UI", 13, "bold")).pack(anchor="w") + font=(theme.SCHRIFT_NAME, 13, "bold")).pack(anchor="w") # ---- Schritt 1: A oder B ------------------------------------------ schritt1 = ttk.Frame(rahmen) @@ -384,17 +385,17 @@ class KorrekturMixin: "Auf dem Storno-Blatt muss stehen, wie die Leistung stattdessen abgerechnet " "wird – sonst weiß der Gast nicht, woran er ist.")).pack(anchor="w", pady=(0, 12)) ttk.Label(schritt1, text="A – es folgt eine neue Rechnung", - font=("Segoe UI", 10, "bold")).pack(anchor="w") + font=(theme.SCHRIFT_NAME, 10, "bold")).pack(anchor="w") ttk.Label(schritt1, wraplength=620, justify="left", text=( "Der übliche Weg: die Rechnung war falsch und wird nach dem Storno richtig neu " "geschrieben. Das Formular bleibt danach offen.")).pack(anchor="w", pady=(2, 10)) ttk.Label(schritt1, text="B – die Leistung ist schon abgerechnet", - font=("Segoe UI", 10, "bold")).pack(anchor="w") + font=(theme.SCHRIFT_NAME, 10, "bold")).pack(anchor="w") ttk.Label(schritt1, wraplength=620, justify="left", text=( "Für Doppelte: derselbe Aufenthalt steht mehrfach im Ordner. Im nächsten Schritt " "trägst du die Nummer der Rechnung ein, die bleibt.")).pack(anchor="w", pady=(2, 10)) ttk.Label(schritt1, text="C – nur Storno", - font=("Segoe UI", 10, "bold")).pack(anchor="w") + font=(theme.SCHRIFT_NAME, 10, "bold")).pack(anchor="w") ttk.Label(schritt1, wraplength=620, justify="left", text=( "Die Leistung wird gar nicht abgerechnet: Buchung geplatzt oder die Rechnung " "war komplett irrtümlich. Es folgt keine neue Rechnung und es gibt auch keine " @@ -411,7 +412,7 @@ class KorrekturMixin: feld = ttk.Entry(zeile, textvariable=eingabe, width=16, justify="center") feld.pack(side="left", padx=(8, 0)) stand = tk.Label(schritt2, text="", wraplength=620, justify="left", - font=("Segoe UI", 9)) + font=(theme.SCHRIFT_NAME, 9)) stand.pack(anchor="w", pady=(8, 0)) def suchen(*_a): diff --git a/ordnerwahl.py b/ordnerwahl.py index 616cab6..060ff7b 100644 --- a/ordnerwahl.py +++ b/ordnerwahl.py @@ -25,6 +25,8 @@ import os import tkinter as tk from tkinter import ttk, filedialog, messagebox +import theme + import gemeinsam BREITE = 780 @@ -39,6 +41,18 @@ class OrdnerWahl(tk.Toplevel): self.ergebnis = None self.title("Gemeinsamer Ordner für das Nummernbuch") self.transient(master) + # Dieses Fenster stand als einziges noch in Weiss da: es kam nie durch + # _style_dialog. Farben holt es sich jetzt vom Hauptfenster, damit es + # nicht wieder auseinanderlaeuft, wenn dort etwas geaendert wird. + self._bg = getattr(master, "col_bg", "#0d0e10") + self._fg = getattr(master, "col_fg", "#e8e8ea") + self._warn = getattr(master, "col_gefahr", "#e85a5a") + self._gut = getattr(master, "col_accent", "#06C6A4") + self._muted = getattr(master, "col_muted", "#8a8e96") + if hasattr(master, "_style_dialog"): + master._style_dialog(self) + else: + self.configure(bg=self._bg) self.pfad = tk.StringVar(value=vorgabe or "") rahmen = ttk.Frame(self, padding=18) @@ -47,7 +61,7 @@ class OrdnerWahl(tk.Toplevel): breite = BREITE - 60 ttk.Label(rahmen, text="Bitte den gemeinsamen Ordner auswählen", - font=("Segoe UI", 13, "bold")).grid(row=0, column=0, sticky="w") + font=(theme.SCHRIFT_NAME, 13, "bold")).grid(row=0, column=0, sticky="w") ttk.Label(rahmen, wraplength=breite, justify="left", text=( "Rechnungstool und Steuerjournal führen zusammen ein Nummernbuch. Darin steht " "jede vergebene Rechnungsnummer – auch die aus der alten Excel-Tabelle, zu der " @@ -56,8 +70,8 @@ class OrdnerWahl(tk.Toplevel): "eine Nummer ein zweites Mal. Jede Nummer darf es aber nur einmal geben " "(§ 14 Abs. 4 Nr. 4 UStG).")).grid(row=1, column=0, sticky="w", pady=(8, 12)) - tk.Label(rahmen, wraplength=breite, justify="left", fg="#a00000", - font=("Segoe UI", 10, "bold"), + tk.Label(rahmen, wraplength=breite, justify="left", fg=self._warn, bg=self._bg, + font=(theme.SCHRIFT_NAME, 10, "bold"), text="WICHTIG: In BEIDEN Programmen muss derselbe Ordner stehen – am besten " "der Ordner, in dem die Programme liegen.").grid( row=2, column=0, sticky="w", pady=(0, 14)) @@ -71,7 +85,8 @@ class OrdnerWahl(tk.Toplevel): width=26).grid(row=0, column=1, sticky="w", padx=(10, 0)) self.stand = tk.Label(rahmen, text="", wraplength=breite, justify="left", - font=("Segoe UI", 9)) + bg=self._bg, + font=(theme.SCHRIFT_NAME, 9)) self.stand.grid(row=4, column=0, sticky="w", pady=(10, 0)) knoepfe = ttk.Frame(rahmen) @@ -127,12 +142,12 @@ class OrdnerWahl(tk.Toplevel): """ ordner = self.pfad.get().strip() if not ordner: - self.stand.configure(text="Noch kein Ordner gewählt.", fg="#a00000") + self.stand.configure(text="Noch kein Ordner gewählt.", fg=self._warn) self.ok.state(["disabled"]) return taugt, grund = gemeinsam.ordner_taugt(ordner) if not taugt: - self.stand.configure(text=grund, fg="#a00000") + self.stand.configure(text=grund, fg=self._warn) self.ok.state(["disabled"]) return self.ok.state(["!disabled"]) @@ -144,11 +159,11 @@ class OrdnerWahl(tk.Toplevel): self.stand.configure( text=f"Hier liegt schon ein Nummernbuch mit {anzahl} Rechnungsnummern – " "das ist der Ordner des anderen Programms. Genau richtig.", - fg="#1f5c3d") + fg=self._gut) else: self.stand.configure( text="Hier ist noch kein Nummernbuch – es wird neu angelegt. Wähle im " - "anderen Programm denselben Ordner.", fg="#444444") + "anderen Programm denselben Ordner.", fg=self._muted) def uebernehmen(self): ordner = self.pfad.get().strip() diff --git a/pruef_angebot.py b/pruef_angebot.py index e7229f2..52489cc 100644 --- a/pruef_angebot.py +++ b/pruef_angebot.py @@ -63,6 +63,10 @@ shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json" config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: sonst laeuft er in einen anderen Zweig, sobald hier +# jemand die Nummer einmal eingerichtet hat. +roh["nummer_eingerichtet"] = False roh["output_dir"] = ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False, indent=2) diff --git a/pruef_api.py b/pruef_api.py index ac9d217..01a4fc2 100644 --- a/pruef_api.py +++ b/pruef_api.py @@ -39,6 +39,10 @@ config.BASE_DIR = tmp config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: sonst laeuft er in einen anderen Zweig, sobald hier +# jemand die Nummer einmal eingerichtet hat. +roh["nummer_eingerichtet"] = False roh["output_dir"] = ordner roh["gemeinsam_ordner"] = gemeinsam_ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False, indent=2) diff --git a/pruef_dialoge.py b/pruef_dialoge.py index bac300b..ec07f7f 100644 --- a/pruef_dialoge.py +++ b/pruef_dialoge.py @@ -27,6 +27,10 @@ shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json" config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["output_dir"] = ordner +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: dlg_nummer zeigt sonst nur eine Meldung statt des +# Fensters, das hier geprueft werden soll. +roh["nummer_eingerichtet"] = False json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False) # Kein Erststart-Dialog im Pruefstand - er wuerde den Lauf haengen lassen. diff --git a/pruef_kernregeln.py b/pruef_kernregeln.py index 5fc8eda..47e9638 100644 --- a/pruef_kernregeln.py +++ b/pruef_kernregeln.py @@ -34,6 +34,10 @@ shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json" config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: sonst laeuft er in einen anderen Zweig, sobald hier +# jemand die Nummer einmal eingerichtet hat. +roh["nummer_eingerichtet"] = False roh["output_dir"] = ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False) diff --git a/pruef_kette.py b/pruef_kette.py index 3bb28fe..8ec6709 100644 --- a/pruef_kette.py +++ b/pruef_kette.py @@ -33,6 +33,10 @@ shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json" config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: sonst laeuft er in einen anderen Zweig, sobald hier +# jemand die Nummer einmal eingerichtet hat. +roh["nummer_eingerichtet"] = False roh["output_dir"] = ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False) diff --git a/pruef_montage.py b/pruef_montage.py index 86581c1..54928b8 100644 --- a/pruef_montage.py +++ b/pruef_montage.py @@ -37,6 +37,10 @@ shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json" config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: sonst laeuft er in einen anderen Zweig, sobald hier +# jemand die Nummer einmal eingerichtet hat. +roh["nummer_eingerichtet"] = False roh["output_dir"] = ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False, indent=2) diff --git a/pruef_nummernbuch.py b/pruef_nummernbuch.py index e857f84..393e9ea 100644 --- a/pruef_nummernbuch.py +++ b/pruef_nummernbuch.py @@ -100,6 +100,10 @@ shutil.copy(os.path.join(TOOL, "config.json"), os.path.join(tmp, "config.json")) config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: sonst laeuft er in einen anderen Zweig, sobald hier +# jemand die Nummer einmal eingerichtet hat. +roh["nummer_eingerichtet"] = False roh["output_dir"] = rechnungen roh["gemeinsam_ordner"] = gemeinsam_ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False, indent=2) diff --git a/pruef_nummernsperre.py b/pruef_nummernsperre.py index 5470554..4e99b5b 100644 --- a/pruef_nummernsperre.py +++ b/pruef_nummernsperre.py @@ -55,6 +55,10 @@ shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json" config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: steht dort "eingerichtet", zeigt dlg_nummer nur eine +# Meldung statt des Fensters, das hier bedient werden soll. +roh["nummer_eingerichtet"] = False roh["output_dir"] = ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False, indent=2) diff --git a/pruef_storno.py b/pruef_storno.py index 232279b..2288a6f 100644 --- a/pruef_storno.py +++ b/pruef_storno.py @@ -29,6 +29,10 @@ shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json" config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: sonst laeuft er in einen anderen Zweig, sobald hier +# jemand die Nummer einmal eingerichtet hat. +roh["nummer_eingerichtet"] = False roh["output_dir"] = ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False, indent=2) diff --git a/pruef_vorschau.py b/pruef_vorschau.py index fa615e7..f2917ce 100644 --- a/pruef_vorschau.py +++ b/pruef_vorschau.py @@ -30,6 +30,10 @@ config.BASE_DIR = tmp config.CONFIG_PATH = os.path.join(tmp, "config.json") roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +# Der Erststart-Zustand gehoert dem Pruefstand, nicht der config des +# Entwicklerrechners: sonst laeuft er in einen anderen Zweig, sobald hier +# jemand die Nummer einmal eingerichtet hat. +roh["nummer_eingerichtet"] = False roh["output_dir"] = ordner json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False) diff --git a/theme.py b/theme.py index dd06109..b1b26a3 100644 --- a/theme.py +++ b/theme.py @@ -7,11 +7,85 @@ baut das Programm Menueleiste und Dropdowns selbst; hier stehen nur die Farben. import sys import tkinter as tk +from tkinter import font as tkfont from tkinter import ttk import config +# Schrift: Roboto, so wie in den Web-Oberflaechen. Sie wird NICHT auf dem +# Rechner installiert, sondern nur fuer diesen einen Prozess geladen (die +# Windows-Funktion AddFontResourceEx mit FR_PRIVATE). Damit braucht niemand +# Adminrechte, und nach dem Schliessen ist der Rechner wieder wie vorher. +# Findet sich die Datei nicht, bleibt es bei Segoe UI - das Programm muss auch +# ohne mitgelieferte Schrift laufen. +SCHRIFT_NAME = "Segoe UI" +SCHRIFT = (SCHRIFT_NAME, 10) +KLEIN = (SCHRIFT_NAME, 9) +_schrift_geladen = False + + +def schrift_vorbereiten(): + """Roboto laden und zur Schrift des Programms machen. Gibt den Namen zurueck.""" + global SCHRIFT_NAME, SCHRIFT, KLEIN, _schrift_geladen + if _schrift_geladen: + return SCHRIFT_NAME + _schrift_geladen = True + if not sys.platform.startswith("win"): + return SCHRIFT_NAME + import ctypes + import os + FR_PRIVATE = 0x10 + geladen = 0 + for basis in (config.BASE_DIR, config.RESOURCE_DIR, os.path.dirname(os.path.abspath(__file__))): + ordner = os.path.join(basis, "assets", "fonts") + if not os.path.isdir(ordner): + continue + for datei in sorted(os.listdir(ordner)): + if datei.lower().endswith((".ttf", ".otf")): + geladen += ctypes.windll.gdi32.AddFontResourceExW( + os.path.join(ordner, datei), FR_PRIVATE, 0) + if geladen: + break + if not geladen: + print("[schrift] Roboto nicht gefunden - bleibe bei Segoe UI") + return SCHRIFT_NAME + # Ob Windows sie wirklich angenommen hat, verraet erst die Schriftenliste. + if "Roboto" not in tkfont.families(): + print("[schrift] Roboto liess sich nicht laden - bleibe bei Segoe UI") + return SCHRIFT_NAME + SCHRIFT_NAME = "Roboto" + SCHRIFT = (SCHRIFT_NAME, 10) + KLEIN = (SCHRIFT_NAME, 9) + for name in ("TkDefaultFont", "TkTextFont", "TkMenuFont", "TkHeadingFont", + "TkIconFont", "TkTooltipFont"): + try: + tkfont.nametofont(name).configure(family=SCHRIFT_NAME, size=10) + except tk.TclError: + pass + print("[schrift] Roboto geladen") + return SCHRIFT_NAME + + +def mischen(vorn, hinten, anteil): + """Wie 'rgba(vorn, anteil)' auf 'hinten' - nur ausgerechnet statt gemalt. + + Tk kann keine halbdurchsichtigen Flaechen (kein backdrop-filter, keine + Alpha-Kanaele auf Widgets). Seine Web-Oberflaechen bauen den Glas-Effekt aus + genau zwei Zutaten: eine getoente Flaeche und ein feiner Rand in + Akzent-Transparenz. Beides laesst sich vorher ausrechnen - das Ergebnis sieht + identisch aus, solange der Grund einfarbig ist. Und der ist es hier. + """ + v = vorn.lstrip("#") + h = hinten.lstrip("#") + teile = [] + for i in (0, 2, 4): + a = int(v[i:i + 2], 16) + b = int(h[i:i + 2], 16) + teile.append(round(a * anteil + b * (1 - anteil))) + return "#%02x%02x%02x" % tuple(teile) + + def windows_dark_mode(): """True, wenn Windows auf das dunkle App-Theme eingestellt ist.""" if not sys.platform.startswith("win"): @@ -32,26 +106,42 @@ class ThemeMixin: def _apply_theme(self): """Farben passend zum Windows-Theme (hell/dunkel) setzen.""" + schrift_vorbereiten() # Roboto, sonst Segoe UI dark = windows_dark_mode() self._dark_mode = dark + # Die Farben sind die aus seinen anderen Sachen (FiveM-Oberflaechen, + # Adminpage, Webseiten): Tuerkis #06C6A4 auf sehr dunklen, gestuften + # Flaechen. Das PROGRAMM traegt diese Handschrift - die RECHNUNG traegt + # die Farbe der jeweiligen Firma (Einstellungen -> Farbe der Rechnung). + # Beides zu vermischen waere falsch: das Blatt gehoert dem Kunden. if dark: - self.col_bg = "#23272e" # Fenster-Hintergrund - self.col_fg = "#e6e6e6" # Schrift - self.col_field = "#2f343c" # Eingabefelder - self.col_sel = "#3a4a44" # aktiv/hover - self.col_accent = "#5fb98f" # Akzent (Gruen, hell) - self.col_line = "#3a3f47" - self.col_scroll = "#4a505a" # Scroll-Griff - self.col_muted = "#8a929c" # gedaempfte Schrift (z.B. "powered by") + self.col_bg = "#0d0e10" # Fenster-Hintergrund (tiefstes Grau) + self.col_card = "#15171b" # Kachel / Abschnitt + self.col_fg = "#e8e8ea" # Schrift + self.col_field = "#1d2025" # Eingabefelder + self.col_sel = "#1f3d38" # aktiv/hover (Akzent, stark abgedunkelt) + self.col_accent = "#06C6A4" # Akzent (Pcore-Tuerkis) + self.col_accent_hell = "#08dbb5" + self.col_auf_accent = "#08221d" # Schrift AUF der Akzentflaeche + self.col_gefahr = "#e85a5a" + self.col_line = "#25282e" + self.col_scroll = "#2f333a" + self.col_muted = "#8a8e96" + self.col_zebra = "#1b1e24" # jede zweite Zeile der Liste else: - self.col_bg = "#f3f3f3" - self.col_fg = "#1a1a1a" + self.col_bg = "#eef0f3" + self.col_card = "#ffffff" + self.col_fg = "#14161a" self.col_field = "#ffffff" - self.col_sel = "#cfe3d8" - self.col_accent = "#1f5c3d" - self.col_line = "#cccccc" - self.col_scroll = "#b8b8b8" - self.col_muted = "#777777" # gedaempfte Schrift (z.B. "powered by") + self.col_sel = "#d7f5ee" + self.col_accent = "#04886f" # dunkler, damit es auf Weiss lesbar ist + self.col_accent_hell = "#06C6A4" + self.col_auf_accent = "#ffffff" + self.col_gefahr = "#c0392b" + self.col_line = "#d8dce1" + self.col_scroll = "#c2c6cc" + self.col_muted = "#5c626b" + self.col_zebra = "#e9ecf0" self.configure(bg=self.col_bg) style = ttk.Style(self) @@ -64,17 +154,89 @@ class ThemeMixin: style.configure(".", background=bg, foreground=fg, fieldbackground=field, bordercolor=self.col_line, lightcolor=bg, darkcolor=bg) style.configure("TFrame", background=bg) - style.configure("TLabel", background=bg, foreground=fg) + style.configure("TLabel", background=bg, foreground=fg, font=SCHRIFT) style.configure("TLabelframe", background=bg, bordercolor=self.col_line) style.configure("TLabelframe.Label", background=bg, foreground=accent) - style.configure("TButton", background=field, foreground=fg, bordercolor=self.col_line) - style.map("TButton", background=[("active", sel)], foreground=[("active", fg)]) + + # --- Kacheln: ein Abschnitt ist eine Flaeche mit Rand, keine Linie --- + style.configure("Karte.TFrame", background=self.col_card, + bordercolor=self.col_line, relief="solid", borderwidth=1) + # Ein Abschnitt ist eine Kachel: eigene Flaeche, feiner Rand, die + # Ueberschrift in Akzentfarbe - genau wie die Kacheln in den + # Web-Oberflaechen. + style.configure("Karte.TLabelframe", background=self.col_card, + bordercolor=self.col_line, relief="solid", borderwidth=1, + lightcolor=self.col_card, darkcolor=self.col_card) + style.configure("Karte.TLabelframe.Label", background=self.col_card, + foreground=accent, font=(SCHRIFT_NAME, 9, "bold")) + style.configure("Karte.TEntry", fieldbackground=field, foreground=fg) + style.configure("Karte.TLabel", background=self.col_card, foreground=fg, font=SCHRIFT) + style.configure("KarteMuted.TLabel", background=self.col_card, + foreground=self.col_muted, font=KLEIN) + # Ueberschrift eines Abschnitts: klein, gross geschrieben, in Akzentfarbe - + # so wie die Kachelkoepfe in den Web-Oberflaechen. + style.configure("Abschnitt.TLabel", background=self.col_card, + foreground=accent, font=(SCHRIFT_NAME, 9, "bold")) + style.configure("Wert.TLabel", background=self.col_card, foreground=fg, + font=(SCHRIFT_NAME, 10)) + style.configure("Summe.TLabel", background=bg, foreground=accent, + font=(SCHRIFT_NAME, 15, "bold")) + style.configure("Zebra.TLabel", background=self.col_zebra, foreground=fg, font=SCHRIFT) + + # --- Knoepfe im Glas-Stil (wie in seinen Oberflaechen) --- + # Getoente Flaeche, feiner Rand in Akzent-Transparenz, Schrift in der + # Akzentfarbe. Kein Vollton: der wirkt in dieser Palette wie ein + # Fremdkoerper. + glas = mischen(accent, bg, 0.10) # ruhige Flaeche + glas_hover = mischen(accent, bg, 0.20) + rand = mischen(accent, bg, 0.35) + rand_hell = mischen(accent, bg, 0.55) + style.configure("TButton", background=glas, foreground=fg, + bordercolor=rand, padding=(14, 7), font=SCHRIFT, + focuscolor=rand, relief="solid", borderwidth=1, + lightcolor=rand, darkcolor=rand) + style.map("TButton", + background=[("pressed", mischen(accent, bg, 0.28)), ("active", glas_hover)], + bordercolor=[("active", rand_hell)], + lightcolor=[("active", rand_hell)], darkcolor=[("active", rand_hell)], + foreground=[("disabled", self.col_muted)]) + + # Der Knopf, um den es geht: dieselbe Glasflaeche, aber kraeftiger + # getoent, mit Akzentrand und Akzentschrift. + haupt = mischen(accent, bg, 0.22) + style.configure("Haupt.TButton", background=haupt, + foreground=self.col_accent_hell, bordercolor=self.col_accent, + lightcolor=self.col_accent, darkcolor=self.col_accent, + relief="solid", borderwidth=1, + padding=(18, 8), font=(SCHRIFT_NAME, 10, "bold")) + style.map("Haupt.TButton", + background=[("pressed", mischen(accent, bg, 0.45)), + ("active", mischen(accent, bg, 0.34)), + ("disabled", bg)], + foreground=[("disabled", self.col_muted)]) + + # Storno greift in eine ausgestellte Rechnung ein - gleicher Stil, rot. + g_rot = mischen(self.col_gefahr, bg, 0.10) + style.configure("Gefahr.TButton", background=g_rot, foreground=self.col_gefahr, + bordercolor=mischen(self.col_gefahr, bg, 0.35), + lightcolor=mischen(self.col_gefahr, bg, 0.35), + darkcolor=mischen(self.col_gefahr, bg, 0.35), + relief="solid", borderwidth=1, + padding=(14, 7), font=SCHRIFT) + style.map("Gefahr.TButton", + background=[("pressed", mischen(self.col_gefahr, bg, 0.30)), + ("active", mischen(self.col_gefahr, bg, 0.20))], + bordercolor=[("active", mischen(self.col_gefahr, bg, 0.55))], + lightcolor=[("active", mischen(self.col_gefahr, bg, 0.55))], + darkcolor=[("active", mischen(self.col_gefahr, bg, 0.55))]) style.configure("Menu.TMenubutton", background=bg, foreground=fg, relief="flat", arrowcolor=bg, padding=(10, 3)) style.map("Menu.TMenubutton", background=[("active", sel)], foreground=[("active", fg)]) style.configure("TCheckbutton", background=bg, foreground=fg) style.map("TCheckbutton", background=[("active", bg)], foreground=[("active", fg)]) - style.configure("TEntry", fieldbackground=field, foreground=fg, insertcolor=fg) + style.configure("TEntry", fieldbackground=field, foreground=fg, insertcolor=fg, + bordercolor=self.col_line, padding=4) + style.map("TEntry", bordercolor=[("focus", accent)]) # Bei state="readonly" zeichnet die Combobox ihren Text als MARKIERUNG, # sobald sie den Fokus hat - ohne diese beiden Farben steht der Wert # unsichtbar im Feld. @@ -101,15 +263,17 @@ class ThemeMixin: # ist. Der offene Reiter bekommt darum den Hintergrund des Blattes und die # Akzentfarbe, die ruhenden bleiben zurueckgenommen. style.configure("TNotebook", background=bg, bordercolor=self.col_line, - tabmargins=(2, 4, 2, 0)) - style.configure("TNotebook.Tab", background=field, foreground=self.col_muted, - bordercolor=self.col_line, padding=(16, 7), - font=("Segoe UI", 10)) + tabmargins=(2, 4, 2, 0), borderwidth=0) + style.configure("TNotebook.Tab", background=self.col_field, + foreground=self.col_muted, bordercolor=self.col_line, + padding=(20, 9), font=(SCHRIFT_NAME, 10), borderwidth=0) style.map("TNotebook.Tab", - background=[("selected", bg), ("active", sel)], + background=[("selected", self.col_card), ("active", sel)], foreground=[("selected", accent), ("active", fg)], - font=[("selected", ("Segoe UI", 10, "bold"))], - expand=[("selected", (1, 1, 1, 0))]) + font=[("selected", (SCHRIFT_NAME, 10, "bold"))]) + # Kein expand beim ausgewaehlten Reiter: er wuchs dadurch um ein paar + # Pixel, die anderen rueckten nach - beim Umschalten sprang die ganze + # Leiste. Erkannt wird der offene Reiter an Farbe und Fettschrift. # Klassische tk-Widgets (Canvas, Toplevel, Text) erben diese Defaults self.option_add("*background", bg) self.option_add("*foreground", fg) From 2e3a191f19f74b80c6ff1a91cda25739586d8108 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 19:17:13 +0200 Subject: [PATCH 08/34] Eigene Meldungsfenster, aktiver Reiter hervorgehoben, Pruefschalter als Funktion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sein Fund: "der ohne gemeinsamen ordner popup ist noch hell" und "er hebt den aktiven tab nicht hervor, der inaktive ist der hervorgehobene". - Meldungen und Ja/Nein-Fragen kommen jetzt aus eigenen Fenstern im Theme (MeldungMixin). messagebox sind Fenster von WINDOWS - sie bleiben hell, egal was das Programm einstellt. Dieselbe Erfahrung steckt schon in der eigenen Menueleiste. 49 Aufrufe umgestellt; das Ordner-Fenster meldet ueber das Hauptfenster mit. ⚠️ Im Pruflauf laeuft beides weiter ueber messagebox - dort haengen die Pruefstaende ihre Antworten ein. Sonst warten sie auf einen Klick. - Reiter: der OFFENE ist jetzt der hellere (Kachelfarbe), die ruhenden liegen auf dem dunklen Grund. Vorher war es andersherum. - config.TESTLAUF ist eine FUNKTION geworden: Pruefstaende importieren config oft, bevor sie CAMPINGHOF_TEST setzen - der einmal berechnete Wert stand dann den ganzen Lauf auf False, und das Programm oeffnete echte Dialoge, auf die niemand klickt. Genau daran hing pruef_api. - Der Erststart-Dialog hat einen eigenen Schalter (_erststart_zeigen), statt am ganzen Pruefschalter zu haengen: ein Pruefstand kann IHN zeigen, ohne dass alle anderen Meldungen wieder echte Fenster aufmachen. - Pruefstand-Fenster stehen nicht mehr in der Taskleiste (-toolwindow): sie liegen neben dem Bildschirm, und ein Eintrag, den man anklickt, ohne dass etwas erscheint, ist schlimmer als gar keiner. - pruef_nummernsperre drueckt jetzt den Radioknopf "Meine Zaehlung weiterfuehren", statt nur ins Zahlenfeld zu schreiben - das Feld ist ohne diesen Klick gesperrt, wie beim Benutzer auch. Alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 91 ++++++++++++++++++++--------------- config.py | 15 ++++-- einstellungen.py | 16 +++---- korrektur.py | 24 +++++----- ordnerwahl.py | 22 +++++++-- pruef_api.py | 8 ++-- pruef_nummernsperre.py | 21 +++++++- theme.py | 106 +++++++++++++++++++++++++++++++++++++++-- 8 files changed, 229 insertions(+), 74 deletions(-) diff --git a/app.py b/app.py index bad5851..6d4a8b7 100644 --- a/app.py +++ b/app.py @@ -40,7 +40,7 @@ from bestand import (hoechster_zaehler_im_ordner, naechste_freie_nummer, from einzelinstanz import (eigene_pid_merken, einzelinstanz_pruefen, fenster_nach_vorn, laufende_pid_lesen) import theme -from theme import ThemeMixin +from theme import MeldungMixin, ThemeMixin from korrektur import KorrekturMixin from einstellungen import EinstellungenMixin @@ -49,10 +49,12 @@ from einstellungen import EinstellungenMixin # modaler Dialog wuerde sie haengen lassen - und in der EXE kommt man an den # Schalter ohnehin nicht heran (Doppelklick uebergibt keine Argumente). # python app.py --test oder CAMPINGHOF_TEST=1 -TESTLAUF = ("--test" in sys.argv) or os.environ.get("CAMPINGHOF_TEST") == "1" +# Der Pruefschalter steht in config (dort als Funktion, siehe Kommentar). Hier +# nur noch der Startwert fuer alles, was ihn schon beim Laden braucht. +TESTLAUF = config.testlauf() -class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): +class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): def __init__(self): super().__init__() self.cfg = config.load_config() @@ -61,13 +63,20 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): hoehe = max(560, min(840, self.winfo_screenheight() - 90)) self.geometry(f"1060x{hoehe}") self.minsize(900, 540) - if TESTLAUF: + if config.testlauf(): # Ein Pruefstand bedient das Programm, waehrend nebenan jemand # arbeitet. Das Fenster geht deshalb NEBEN dem Bildschirm auf (auf # dem zweiten Monitor, wenn einer da ist) - sichtbar, aber nicht im # Weg. Unsichtbar machen waere falsch: dann sieht niemand mehr, was # der Pruefstand eigentlich tut. self.geometry(f"+{self.winfo_screenwidth() + 20}+40") + try: + # Kein Eintrag in der Taskleiste: das Fenster liegt neben + # dem Bildschirm, und ein Eintrag, den man anklickt, ohne + # dass etwas erscheint, ist schlimmer als gar keiner. + self.attributes("-toolwindow", True) + except tk.TclError: + pass self.anzahl_vars = {} # nr -> StringVar self.personen_vars = {} # nr -> StringVar @@ -593,7 +602,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): wird wieder gefragt. """ self._buch_oeffnen() - if self.buch is None and not TESTLAUF: + if self.buch is None and not config.testlauf(): self.dlg_gemeinsam(erststart=True) self._buch_anzeigen() @@ -602,7 +611,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): self, "Rechnungstool", str(self.cfg.get("gemeinsam_ordner", "") or "")) if not ordner: if erststart: - messagebox.showwarning( + self.melden_warnung( "Ohne gemeinsamen Ordner", "Es wurde kein gemeinsamer Ordner gewählt.\n\n" "Das Rechnungstool kennt jetzt nur die Nummern seiner eigenen " @@ -642,7 +651,13 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): einmal nennen koennen, sonst faengt das Programm bei 001 an und vergibt Nummern ein zweites Mal. Danach ist der Zaehler zu. """ - if TESTLAUF or self.cfg.get("nummer_eingerichtet"): + # Im Pruflauf bleibt dieser Dialog zu - er wartet auf einen Klick, den dort + # niemand macht. Ein Pruefstand, der GENAU IHN pruefen will, setzt + # `_erststart_zeigen = True` (dasselbe Muster wie `_dialog_zeigen` beim + # Angebot). So bleiben alle anderen Meldungen weiterhin automatisch + # beantwortet - vorher musste dafuer der ganze Pruefschalter fallen, und + # dann hing der Lauf in der naechsten Meldung. + if (config.testlauf() and not getattr(self, "_erststart_zeigen", False)) or self.cfg.get("nummer_eingerichtet"): return jahr = int(self.cfg.get("rechnung_jahr", 0) or datetime.date.today().year) gefunden = self.hoechster_stand(jahr) @@ -720,7 +735,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): if weg.get() == "weiter" else f"Bei 0 anfangen geht nicht mehr: {jahr}-{gefunden:03d} ist schon vergeben.") return - if not messagebox.askyesno( + if not self.frage( "Sind Sie sicher?", f"Die nächste Rechnung bekommt die Nummer {jahr}-{zahl + 1:03d}.\n\n" "Das lässt sich danach nicht mehr ändern.\n\n" @@ -733,7 +748,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): try: config.save_config(self.cfg) except OSError as e: # noqa: BLE001 - messagebox.showwarning("Nicht gespeichert", + self.melden_warnung("Nicht gespeichert", f"Der Stand ließ sich nicht speichern:\n{e}", parent=d) return fertig["ok"] = True @@ -832,7 +847,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): quelle="rechnungstool", herkunft="pdf", pdf_pfad=pdf_pfad) except Exception as e: # noqa: BLE001 - die PDF ist schon geschrieben print("[nummernbuch] Eintragen fehlgeschlagen:", e) - messagebox.showwarning( + self.melden_warnung( "Nummernbuch nicht erreichbar", "Die Rechnung ist geschrieben, konnte aber nicht ins gemeinsame " f"Nummernbuch eingetragen werden:\n{e}\n\n" @@ -1048,7 +1063,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # Im Testlauf gibt es niemanden, der klickt: dann gilt der uebliche Weg # (Rechnung). Der Pruefstand, der GENAU DIESES Fenster pruefen will, # setzt _dialog_zeigen und drueckt die Knoepfe wirklich. - if TESTLAUF and not getattr(self, "_dialog_zeigen", False): + if config.testlauf() and not getattr(self, "_dialog_zeigen", False): # _testwahl: was der Pruefstand im Fenster geklickt haette. # "rechnung" (Vorgabe), "angebot" oder None fuer Abbrechen. return getattr(self, "_testwahl", "rechnung") @@ -1174,7 +1189,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): } if name not in tabelle: return {"fehler": "kenne ich nicht: " + str(name), "kann": sorted(tabelle)} - if name in schreibt_beleg and not TESTLAUF: + if name in schreibt_beleg and not config.testlauf(): return {"fehler": "schreibt einen Beleg - geht nur im Testlauf"} return tabelle[name](daten or {}) @@ -1270,7 +1285,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): montage = self.ist_montage() r = self.recalc() if not r.zeilen: - messagebox.showinfo( + self.melden_info( "Noch nichts einzutragen", "Bitte die Anzahl der Monate eintragen." if montage else "Trage erst bei einer Leistung eine Anzahl ein - dann zeigt die " @@ -1288,7 +1303,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): self._oeffne_datei(pfad) return pfad except OSError as e: - messagebox.showerror("Vorschau nicht möglich", + self.melden_fehler("Vorschau nicht möglich", f"Die Vorschau konnte nicht geöffnet werden:\n{e}") return "" @@ -1296,7 +1311,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): montage = self.ist_montage() r = self.recalc() if not r.zeilen: - messagebox.showwarning( + self.melden_warnung( "Keine Positionen", "Bitte die Anzahl der Monate eintragen." if montage else "Es wurde keine Leistung mit Anzahl > 0 eingetragen.") @@ -1304,7 +1319,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): if montage and not (self.r_anreise.get().strip() and self.r_abreise.get().strip()): # Ohne Zeitraum steht auf dem Blatt nicht, wofuer gezahlt wird - und # das Steuerjournal haette keine Naechte fuer die Meldung ans Amt. - messagebox.showwarning( + self.melden_warnung( "Zeitraum fehlt", "Bitte oben rechts den Zeitraum eintragen (von / bis).\n\n" "Er steht auf der Rechnung und ist die Grundlage für die " @@ -1312,14 +1327,14 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): return nummer = self.r_nummer.get().strip() if not nummer: - messagebox.showwarning("Rechnungsnummer fehlt", "Bitte eine Rechnungsnummer eingeben.") + self.melden_warnung("Rechnungsnummer fehlt", "Bitte eine Rechnungsnummer eingeben.") return # Den 31.02. gibt es auch dann nicht, wenn Tag und Monat einzeln moeglich # sind. Ein falsches Datum auf einer ausgestellten Rechnung laesst sich nur # noch ueber eine Berichtigung geradeziehen - also hier abfangen. kaputt = self._datumsfelder_pruefen() if kaputt: - messagebox.showwarning( + self.melden_warnung( "Datum nicht lesbar", "So kann die Rechnung nicht geschrieben werden:" + chr(10) + chr(10) + "- " + (chr(10) + "- ").join(kaputt) + chr(10) + chr(10) + @@ -1329,7 +1344,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # (§ 14 Abs. 4 Nr. 1 UStG) - ohne sie wird nichts geschrieben. maengel = self.kunde_pruefen() if maengel: - messagebox.showwarning( + self.melden_warnung( "Kundenangaben fehlen", "So kann die Rechnung nicht geschrieben werden:\n\n- " + "\n- ".join(maengel) + "\n\nName und vollständige Anschrift des Kunden gehören auf jede " @@ -1338,7 +1353,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # Hausnummer nur nachfragen, nicht blockieren - es gibt Anschriften ohne # (Postfach, Haus am Feldweg), und eine falsche Sperre waere schlimmer. if not ziffern(self.k_strasse.get()): - if not messagebox.askyesno( + if not self.frage( "Hausnummer fehlt", f"In „{self.k_strasse.get()}“ steht keine Hausnummer.\n\n" "Trotzdem so auf die Rechnung schreiben?"): @@ -1368,7 +1383,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # geloescht und es bleibt allein die urspruengliche Rechnung stehen. stand = self.storno_stand if stand: - if not messagebox.askyesno( + if not self.frage( "Storno wirklich durchführen?", f"Storno {stand['nummer']} hebt die Rechnung {stand['zu']} auf, " f"und {nummer} wird die berichtigte Rechnung.\n\n" @@ -1378,7 +1393,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): f"Nein = alles verwerfen, es bleibt allein Rechnung {stand['zu']}", icon="warning", default="yes"): self._storno_verwerfen("vom Benutzer verworfen") - messagebox.showinfo( + self.melden_info( "Storno verworfen", f"Der Storno wurde gelöscht. Es bleibt allein die Rechnung {stand['zu']}.") return @@ -1406,7 +1421,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): kopf["vorgang"] = ber.get("vorgang") or ber["zu"] kopf["berichtigt_zu"] = ber["zu"] kopf["berichtigt_am"] = datetime.date.today().strftime("%d.%m.%Y") - if not messagebox.askyesno( + if not self.frage( "Berichtigte Rechnung erstellen?", f"Zu Rechnung {ber['zu']} vom {ber['datum']} wird ein berichtigtes " "Blatt geschrieben.\n\n" @@ -1421,7 +1436,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): pfad = os.path.join( out_dir, f"Berichtigte Rechnung_{datetime.date.today():%Y-%m-%d}" f"_{safe_filename(ber['zu'])}.pdf") - if os.path.exists(pfad) and not messagebox.askyesno( + if os.path.exists(pfad) and not self.frage( "Berichtigung von heute ersetzen?", f"Zu Rechnung {ber['zu']} gibt es von heute schon eine Berichtigung:\n" f"{os.path.basename(pfad)}\n\nDurch die neue ersetzen?"): @@ -1429,7 +1444,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): try: pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf) except Exception as e: # noqa: BLE001 - dem Nutzer den Fehler zeigen - messagebox.showerror("Fehler beim Erstellen", + self.melden_fehler("Fehler beim Erstellen", f"Berichtigung konnte nicht erstellt werden:\n{e}") print("[berichtigung] FEHLER:", e) return @@ -1447,7 +1462,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): print("[nummernbuch] Berichtigung nicht eingetragen:", e) self.berichtigung_stand = None self._storno_anzeigen() - if messagebox.askyesno("Fertig", + if self.frage("Fertig", f"Berichtigte Rechnung zu {ber['zu']}:\n{pfad}\n\n" "Jetzt öffnen (zum Drucken)?"): self._oeffne_datei(pfad) @@ -1468,12 +1483,12 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): liste = "- steht im gemeinsamen Nummernbuch (Steuerjournal)" frei = naechste_freie_nummer(out_dir, self.cfg, self._belegte_nummern()) if not frei: - messagebox.showerror( + self.melden_fehler( "Rechnungsnummer schon vergeben", f"Die Rechnungsnummer {nummer} ist schon vergeben:\n\n{liste}\n\n" "Es wurde keine freie Nummer gefunden - bitte die Nummer von Hand setzen.") return - if not messagebox.askyesno( + if not self.frage( "Rechnungsnummer schon vergeben", f"Die Rechnungsnummer {nummer} ist schon vergeben:\n\n{liste}\n\n" "Die vorhandene Rechnung bleibt bestehen - sie darf weder überschrieben " @@ -1493,7 +1508,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): try: pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf) except Exception as e: # noqa: BLE001 - dem Nutzer den Fehler zeigen - messagebox.showerror( + self.melden_fehler( "Fehler beim Erstellen", f"Angebot konnte nicht erstellt werden:\n{e}") print("[angebot] FEHLER:", e) @@ -1509,7 +1524,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): except OSError as e: # noqa: BLE001 print("[angebot] Zaehler nicht gespeichert:", e) print(f"[angebot] erstellt -> {pfad}") - if messagebox.askyesno( + if self.frage( "Fertig", f"Angebot erstellt:\n{pfad}\n\n" "Jetzt öffnen (zum Drucken)?"): self._oeffne_datei(pfad) @@ -1529,7 +1544,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # Ein PDF: Seite 1 = Kunden-Rechnung, Seite 2 = Beherbergungssteuer fuers Amt pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf) except Exception as e: # noqa: BLE001 - dem Nutzer den Fehler zeigen - messagebox.showerror("Fehler beim Erstellen", f"PDF konnte nicht erstellt werden:\n{e}") + self.melden_fehler("Fehler beim Erstellen", f"PDF konnte nicht erstellt werden:\n{e}") print("[pdf] FEHLER:", e) return @@ -1553,7 +1568,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): hinweis = (f"\n\nDazu gehört die Stornorechnung {stand['nummer']} " f"({os.path.basename(storno_pfad)}).\n" "Beide Blätter gehören zum Gast.") + hinweis - if messagebox.askyesno("Fertig", f"Rechnung erstellt:\n{pfad}{hinweis}\n\nJetzt öffnen (zum Drucken)?"): + if self.frage("Fertig", f"Rechnung erstellt:\n{pfad}{hinweis}\n\nJetzt öffnen (zum Drucken)?"): self._oeffne_datei(pfad) if storno_pfad: self._oeffne_datei(storno_pfad) @@ -1578,7 +1593,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): except OSError as e: # noqa: BLE001 - die PDF ist schon geschrieben # Ohne diese Meldung merkt niemand, dass der Zaehler stehengeblieben # ist: die Ausgabe geht in eine Konsole, die es in der EXE nicht gibt. - messagebox.showwarning( + self.melden_warnung( "Rechnungsnummer nicht gespeichert", f"Die Rechnung ist geschrieben, der Zählerstand aber nicht:\n{e}\n\n" f"Bitte im Menü unter „Rechnungsnummer…“ den Zähler auf {z} setzen, " @@ -1588,7 +1603,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): def _beenden(self): """Schliessen - mit Rückfrage, wenn ein Storno noch offen ist.""" if self.storno_stand: - if not messagebox.askyesno( + if not self.frage( "Storno ist noch offen", f"Der Storno {self.storno_stand['nummer']} zu Rechnung " f"{self.storno_stand['zu']} liegt im Ordner, die berichtigte " @@ -1606,7 +1621,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): # Ein laufender Vorgang darf nicht stumm liegenbleiben: sonst gehören die # neu eingetippten Daten plötzlich zum Storno der fremden Rechnung. if self.storno_stand: - if not messagebox.askyesno( + if not self.frage( "Storno verwerfen?", f"Der Storno {self.storno_stand['nummer']} zu Rechnung " f"{self.storno_stand['zu']} liegt noch bereit.\n\n" @@ -1643,7 +1658,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): Fenster offen, die er selbst wegklicken darf. Gemeldet wird es trotzdem, damit im Protokoll steht, was zu sehen gewesen waere. """ - if TESTLAUF: + if config.testlauf(): print(f"[oeffnen] im Pruflauf nicht geoeffnet: {pfad}") return False try: @@ -1654,7 +1669,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk): else: os.system(f'xdg-open "{pfad}"') except Exception as e: # noqa: BLE001 - messagebox.showinfo("Pfad", f"{pfad}\n\n(Konnte nicht automatisch geöffnet werden: {e})") + self.melden_info("Pfad", f"{pfad}\n\n(Konnte nicht automatisch geöffnet werden: {e})") if __name__ == "__main__": @@ -1665,7 +1680,7 @@ if __name__ == "__main__": if not fenster_nach_vorn(laufende_pid_lesen()): _r = tk.Tk() _r.withdraw() - messagebox.showerror( + self.melden_fehler( "Rechnungstool läuft bereits", """Das Rechnungstool ist schon geöffnet, das Fenster ließ sich aber nicht nach vorn holen - bitte über die Taskleiste zurückwechseln. diff --git a/config.py b/config.py index 6b4d98e..4d6ccd1 100644 --- a/config.py +++ b/config.py @@ -72,11 +72,18 @@ BASE_DIR = _daten_ordner() CONFIG_PATH = os.path.join(BASE_DIR, "config.json") # Laeuft gerade ein Pruefstand? Dann baut das Programm alles wie sonst, zeigt es -# aber nicht: kein Fenster auf dem Bildschirm, kein Dialog, der Maus und +# aber nicht: kein Fenster mitten auf dem Bildschirm, kein Dialog, der Maus und # Tastatur an sich reisst, waehrend der Mensch daneben arbeitet. -# Das Flag steht HIER, damit app.py, theme.py und die Pruefstaende dasselbe -# lesen - zwei Stellen wuerden auseinanderlaufen. -TESTLAUF = ("--test" in sys.argv) or os.environ.get("CAMPINGHOF_TEST") == "1" +# +# ⚠️ Das ist eine FUNKTION, keine Konstante. Ein Pruefstand importiert config +# haeufig, bevor er CAMPINGHOF_TEST setzt - ein einmal berechneter Wert stuende +# dann fuer den ganzen Lauf auf False, und das Programm oeffnete echte Dialoge, +# auf die niemand klickt. Genau daran hing pruef_api eine Runde lang. +def testlauf(): + return ("--test" in sys.argv) or os.environ.get("CAMPINGHOF_TEST") == "1" + + +TESTLAUF = testlauf() # Startwert; wer spaeter fragt, nimmt testlauf() # Leistungskatalog 1:1 aus der Excel-Vorlage (Rechnung Campinghof Bartl). # satz = Umsatzsteuersatz in Prozent (7 = Beherbergung, 19 = Zusatzleistung) diff --git a/einstellungen.py b/einstellungen.py index 794098f..2d66ef2 100644 --- a/einstellungen.py +++ b/einstellungen.py @@ -24,7 +24,7 @@ class EinstellungenMixin: if (self.cfg.get("output_dir") or "").strip(): return vorschlag = config.default_output_dir() - messagebox.showinfo( + self.melden_info( "Speicherort der Rechnungen", "Bitte wähle einen Ordner, in dem die fertigen Rechnungen (PDF) gespeichert werden.\n\n" f"Vorschlag: {vorschlag}\n\n(Lässt sich später unter Einstellungen ändern.)") @@ -41,7 +41,7 @@ class EinstellungenMixin: self.cfg["output_dir"] = d config.save_config(self.cfg) config.ensure_output_dir(self.cfg) - messagebox.showinfo("Speicherort", f"Rechnungen werden gespeichert in:\n{d}") + self.melden_info("Speicherort", f"Rechnungen werden gespeichert in:\n{d}") def _info(self): d = tk.Toplevel(self) @@ -121,7 +121,7 @@ class EinstellungenMixin: "bezeichnung": row["bez"].get().strip() or "USt", "extra_blatt": bool(row["extra"].get())}) if not neu: - messagebox.showwarning("Leer", "Mindestens ein Steuersatz ist nötig.", parent=d) + self.melden_warnung("Leer", "Mindestens ein Steuersatz ist nötig.", parent=d) return self.cfg["steuersaetze"] = neu config.save_config(self.cfg) @@ -177,11 +177,11 @@ class EinstellungenMixin: name = v_leistung.get().strip() preis = parse_num(v_preis.get()) if not name: - messagebox.showwarning("Bezeichnung fehlt", + self.melden_warnung("Bezeichnung fehlt", "Bitte eine Bezeichnung eintragen.", parent=d) return if preis <= 0: - messagebox.showwarning("Preis fehlt", + self.melden_warnung("Preis fehlt", "Bitte einen Monatspreis groesser als 0 eintragen.", parent=d) return @@ -289,7 +289,7 @@ class EinstellungenMixin: "pro_person": bool(row["pro_person"].get()), }) if not neu: - messagebox.showwarning("Leer", "Es muss mindestens eine Leistung übrig bleiben.", parent=d) + self.melden_warnung("Leer", "Es muss mindestens eine Leistung übrig bleiben.", parent=d) return self.cfg["katalog"] = neu config.save_config(self.cfg) @@ -464,7 +464,7 @@ class EinstellungenMixin: jahr = self.cfg.get("rechnung_jahr") zaehler = int(self.cfg.get("rechnung_zaehler", 0) or 0) hoch = self.hoechster_stand(jahr) - messagebox.showinfo( + self.melden_info( "Rechnungsnummer", f"Zuletzt vergeben: {jahr}-{max(zaehler, hoch):03d}\n" f"Die nächste Rechnung bekommt {jahr}-{max(zaehler, hoch) + 1:03d}.\n\n" @@ -511,7 +511,7 @@ class EinstellungenMixin: # (§ 14 Abs. 4 Nr. 4 UStG). hoch = self.hoechster_stand(jahr) if jahr == int(self.cfg.get("rechnung_jahr", jahr) or jahr) and zaehler < hoch: - messagebox.showwarning( + self.melden_warnung( "Nummer schon vergeben", f"Für {jahr} ist bereits bis {jahr}-{hoch:03d} vergeben.\n\n" f"Der Zähler kann nicht auf {zaehler} zurückgesetzt werden – sonst " diff --git a/korrektur.py b/korrektur.py index 4bd8a1a..966e2ee 100644 --- a/korrektur.py +++ b/korrektur.py @@ -69,7 +69,7 @@ class KorrekturMixin: self.r_datum.set(str(meta.get("datum") or self.r_datum.get())) self._storno_anzeigen() hinweis = f"\n\nZum Kunden: {fehlend}." if fehlend else "" - messagebox.showinfo( + self.melden_info( "Rechnung geladen", f"Rechnung {nummer} vom {meta.get('datum','')} ist im Formular.\n\n" "Jetzt die Kundenangaben richtigstellen und \"PDF erstellen\" drücken – " @@ -93,7 +93,7 @@ class KorrekturMixin: # Abbrechen, NICHT weiterlaufen: sonst liegt das Storno noch im Ordner, # der Zähler ist zurückgedreht und die Rechnung gilt als storniert, # obwohl der Nutzer sie behalten wollte. - messagebox.showerror( + self.melden_fehler( "Storno konnte nicht gelöscht werden", f"Die Datei\n{stand['pfad']}\nließ sich nicht löschen:\n{e}\n\n" "Ist sie noch in einem PDF-Betrachter offen? Bitte dort schließen " @@ -104,7 +104,7 @@ class KorrekturMixin: try: config.save_config(self.cfg) except OSError as e: # noqa: BLE001 - messagebox.showwarning( + self.melden_warnung( "Zähler nicht gespeichert", f"Die Einstellungen ließen sich nicht schreiben:\n{e}\n\n" "Bitte im Menü unter „Rechnungsnummer…“ prüfen.") @@ -137,14 +137,14 @@ class KorrekturMixin: """ storno = modus == "storno" if self.storno_stand: - messagebox.showinfo( + self.melden_info( "Storno liegt schon bereit", f"Der Storno {self.storno_stand['nummer']} zu Rechnung " f"{self.storno_stand['zu']} ist noch offen.\n\n" "Erst die berichtigte Rechnung erstellen oder den Storno dort verwerfen.") return if self.berichtigung_stand: - messagebox.showinfo( + self.melden_info( "Berichtigung läuft schon", f"Die Rechnung {self.berichtigung_stand['zu']} liegt gerade zum Berichtigen " "im Formular.\n\nErst „PDF erstellen“ drücken oder das Formular zurücksetzen.") @@ -162,7 +162,7 @@ class KorrekturMixin: if d.get("art") not in ("storno", "berichtigung") and nummer_normalisieren(d.get("rechnungsnummer")) not in stornierte] if not offen: - messagebox.showwarning( + self.melden_warnung( "Nichts zu korrigieren", f"Im Ordner\n{out_dir}\nliegt keine Rechnung, die dafür in Frage kommt.") return @@ -472,7 +472,7 @@ class KorrekturMixin: stand.configure(text="Bitte die Nummer der bleibenden Rechnung eintragen.", fg="#a00000") return - if gefunden["leicht"] and not messagebox.askyesno( + if gefunden["leicht"] and not self.frage( "Weicht ab – trotzdem?", f"Rechnung {nr} weicht ab: " + "; ".join(gefunden["leicht"]) + ". Das Storno würde trotzdem darauf verweisen. Ist das dieselbe " @@ -537,7 +537,7 @@ class KorrekturMixin: nummer = naechste_freie_nummer(out_dir, self.cfg, self._belegte_nummern()) if not nummer: - messagebox.showerror("Keine freie Nummer", + self.melden_fehler("Keine freie Nummer", "Es wurde keine freie Rechnungsnummer gefunden.") return @@ -572,7 +572,7 @@ class KorrekturMixin: # kann das Programm nichts erfinden; dann muss der Nutzer entscheiden. maengel = kunde_maengel(kunde) if maengel: - if not messagebox.askyesno( + if not self.frage( "Angaben zum Kunden unvollständig", f"In Rechnung {alt_nummer} steht nicht alles:\n\n- " + "\n- ".join(maengel) + @@ -620,7 +620,7 @@ class KorrekturMixin: try: pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf) except Exception as e: # noqa: BLE001 - dem Nutzer den Fehler zeigen - messagebox.showerror("Fehler beim Erstellen", + self.melden_fehler("Fehler beim Erstellen", f"Storno-PDF konnte nicht erstellt werden:\n{e}") print("[storno] FEHLER:", e) return @@ -646,7 +646,7 @@ class KorrekturMixin: if art_folge == "vorhanden": self._storno_anzeigen() self._neue_nummer_vorschlagen() - if messagebox.askyesno( + if self.frage( "Storno erstellt", f"Storno {nummer} hebt Rechnung {alt_nummer} auf.\n\n" f"Die Leistung bleibt mit Rechnung {folge_nummer} abgerechnet – es " @@ -663,7 +663,7 @@ class KorrekturMixin: if fehlend: hinweis = (f"\n\nZum Kunden: {fehlend}.\nBitte oben prüfen und ergänzen – " "ohne vollständige Anschrift wird die Rechnung nicht geschrieben.") - messagebox.showinfo( + self.melden_info( "Storno erstellt", f"Stornorechnung {nummer} zu Rechnung {alt_nummer} liegt hier:\n{pfad}\n\n" f"Jetzt die berichtigte Rechnung {self.r_nummer.get()} anpassen und " diff --git a/ordnerwahl.py b/ordnerwahl.py index 060ff7b..6cc89b3 100644 --- a/ordnerwahl.py +++ b/ordnerwahl.py @@ -165,21 +165,33 @@ class OrdnerWahl(tk.Toplevel): text="Hier ist noch kein Nummernbuch – es wird neu angelegt. Wähle im " "anderen Programm denselben Ordner.", fg=self._muted) + def _melden(self, titel, text): + """Meldung im Theme des Hauptfensters - sonst wie bisher.""" + eltern = self.master + if hasattr(eltern, "melden_warnung"): + return eltern.melden_warnung(titel, text) + return messagebox.showwarning(titel, text, parent=self) + + def _frage(self, titel, text): + eltern = self.master + if hasattr(eltern, "frage"): + return eltern.frage(titel, text) + return messagebox.askyesno(titel, text, parent=self) + + def uebernehmen(self): ordner = self.pfad.get().strip() taugt, grund = gemeinsam.ordner_taugt(ordner) if not taugt: - messagebox.showwarning("Ordner geht nicht", grund or "Bitte einen Ordner wählen.", - parent=self) + self._melden("Ordner geht nicht", grund or "Bitte einen Ordner wählen.") return - if not messagebox.askyesno( + if not self._frage( "Sind Sie sicher?", f"Gemeinsamer Ordner:\n\n{ordner}\n\n" "Steht im anderen Programm derselbe Ordner? Nur dann kennen beide " "dieselben Rechnungsnummern.\n\n" "Ja = Ordner übernehmen\n" - "Nein = zurück zur Auswahl", - icon="question", default="yes", parent=self): + "Nein = zurück zur Auswahl"): # Zurueck ins Auswahlfeld - der Dialog bleibt stehen, nichts ist gesetzt. self.feld.focus_set() return diff --git a/pruef_api.py b/pruef_api.py index 01a4fc2..bf62f60 100644 --- a/pruef_api.py +++ b/pruef_api.py @@ -146,14 +146,16 @@ antwort = anrufen_und_drehen(name="rechnung", schluessel=schluessel) pdfs = [n for n in os.listdir(ordner) if n.lower().endswith(".pdf")] pruefe(len(pdfs) == 1, f"im Testlauf schreibt die API die Rechnung ({pdfs})") -# Und im ECHTEN Betrieb nicht: dieselbe Aktion, aber ohne Testlauf-Flag. -A.TESTLAUF = False +# Und im ECHTEN Betrieb nicht: dieselbe Aktion, ohne den Pruefschalter. +# Umgeschaltet wird die Umgebungsvariable selbst - das Programm fragt sie bei +# jeder Aktion neu ab, genau wie beim echten Start. +os.environ.pop("CAMPINGHOF_TEST", None) antwort = anrufen_und_drehen(name="rechnung", schluessel=schluessel) +os.environ["CAMPINGHOF_TEST"] = "1" pruefe(isinstance(antwort, dict) and "nur im Testlauf" in str(antwort.get("fehler", "")), f"im echten Betrieb verweigert sie den Beleg ({antwort})") pruefe(len([n for n in os.listdir(ordner) if n.lower().endswith(".pdf")]) == 1, "und es kam keine zweite Rechnung dazu") -A.TESTLAUF = True # Unbekannter Name sagt, was es gibt - statt still nichts zu tun. antwort = anrufen_und_drehen(name="tanz", schluessel=schluessel) diff --git a/pruef_nummernsperre.py b/pruef_nummernsperre.py index 4e99b5b..782ef7f 100644 --- a/pruef_nummernsperre.py +++ b/pruef_nummernsperre.py @@ -121,6 +121,15 @@ def knoepfe_von(w, aus=None): return aus +def _alle_widgets(w, aus=None): + """Jedes Widget unterhalb von w - egal wie tief.""" + aus = [] if aus is None else aus + for k in w.winfo_children(): + aus.append(k) + _alle_widgets(k, aus) + return aus + + def felder_von(w, aus=None): aus = [] if aus is None else aus for k in w.winfo_children(): @@ -208,7 +217,9 @@ pruefe(f.cfg.get("rechnung_zaehler") == 91, f.cfg["nummer_eingerichtet"] = False f.cfg["rechnung_jahr"] = JAHR config.save_config(f.cfg) -A.TESTLAUF = False # den Erststart-Dialog wirklich zeigen +# Diesen einen Dialog will der Pruefstand wirklich sehen und bedienen. Alles +# andere bleibt im Pruflauf - sonst wartet der naechste Hinweis auf einen Klick. +f._erststart_zeigen = True def erststart(zahl, erwartet_ja=True): @@ -227,6 +238,14 @@ def erststart(zahl, erwartet_ja=True): top = tops[-1] felder = felder_von(top) if felder: + # Der Dialog fragt seit 05.09.2026 zuerst nach dem WEG: bei 0 + # anfangen oder die eigene Zaehlung weiterfuehren. Ohne diesen + # Klick bleibt das Zahlenfeld gesperrt - hier wird also dasselbe + # gedrueckt wie beim Benutzer, nicht daran vorbei. + for w in _alle_widgets(top): + if w.winfo_class() == "TRadiobutton" and "weiterführen" in str(w.cget("text")): + w.invoke() + break felder[0].delete(0, "end") felder[0].insert(0, str(zahl)) for k in knoepfe_von(top): diff --git a/theme.py b/theme.py index b1b26a3..36234ba 100644 --- a/theme.py +++ b/theme.py @@ -8,6 +8,7 @@ baut das Programm Menueleiste und Dropdowns selbst; hier stehen nur die Farben. import sys import tkinter as tk from tkinter import font as tkfont +from tkinter import messagebox from tkinter import ttk import config @@ -264,11 +265,15 @@ class ThemeMixin: # Akzentfarbe, die ruhenden bleiben zurueckgenommen. style.configure("TNotebook", background=bg, bordercolor=self.col_line, tabmargins=(2, 4, 2, 0), borderwidth=0) - style.configure("TNotebook.Tab", background=self.col_field, + # Der OFFENE Reiter gehoert zur Kachel darunter und ist deshalb heller + # als die ruhenden. Vorher war es andersherum: die ruhenden lagen auf der + # helleren Flaeche und sahen aus, als waeren sie ausgewaehlt. + style.configure("TNotebook.Tab", background=bg, foreground=self.col_muted, bordercolor=self.col_line, padding=(20, 9), font=(SCHRIFT_NAME, 10), borderwidth=0) style.map("TNotebook.Tab", - background=[("selected", self.col_card), ("active", sel)], + background=[("selected", self.col_card), + ("active", mischen(accent, bg, 0.12))], foreground=[("selected", accent), ("active", fg)], font=[("selected", (SCHRIFT_NAME, 10, "bold"))]) # Kein expand beim ausgewaehlten Reiter: er wuchs dadurch um ein paar @@ -286,12 +291,16 @@ class ThemeMixin: und Tastatur fest, waehrend nebenan jemand schreibt. """ d.configure(bg=self.col_bg) - if config.TESTLAUF: + if config.testlauf(): # Wie das Hauptfenster: neben den Bildschirm, und ohne grab_set - # ein Dialog, der Maus und Tastatur festhaelt, blockiert den # Menschen, der nebenher schreibt. d.geometry(f"+{d.winfo_screenwidth() + 20}+40") d.grab_set = lambda *a, **k: None + try: + d.attributes("-toolwindow", True) # nicht in die Taskleiste + except tk.TclError: + pass # erst nach dem Anzeigen setzen, sonst greift DWM noch nicht d.after(20, lambda: self._dark_titlebar(d)) @@ -312,3 +321,94 @@ class ThemeMixin: ctypes.windll.user32.SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP) except Exception as e: # noqa: BLE001 print("[theme] Titelleiste:", e) + + +class MeldungMixin: + """Eigene Meldungs- und Ja/Nein-Fenster im Theme des Programms. + + Warum nicht `messagebox`: das sind Fenster von Windows selbst. Sie sind + immer hell, egal was das Programm einstellt - mitten in einer dunklen + Oberflaeche blendet das und sieht nach Fremdkoerper aus. Dieselbe Erfahrung + steckt schon in der eigenen Menueleiste weiter oben. + + ⚠️ Im PRUEFLAUF geht beides weiter ueber `messagebox`. Die Pruefstaende + haengen ihre Antworten dort ein ("auf diese Frage antworte Ja") und lesen + dort mit, was das Programm gemeldet hat. Wuerde hier ein eigenes Fenster + aufgehen, warteten sie auf einen Klick, den niemand macht. Geprueft wird + damit derselbe Weg - nur die Anzeige unterscheidet sich. + """ + + # Die drei Sorten Meldung. `parent=`, `icon=` und `default=` kommen aus den + # frueheren messagebox-Aufrufen mit - sie werden geschluckt, damit an den + # Aufrufstellen nichts umgeschrieben werden muss. + def melden_info(self, titel, text="", **_kw): + return self.melden(titel, text, "info") + + def melden_warnung(self, titel, text="", **_kw): + return self.melden(titel, text, "warnung") + + def melden_fehler(self, titel, text="", **_kw): + return self.melden(titel, text, "fehler") + + def melden(self, titel, text, art="warnung"): + """Eine Meldung mit einem OK-Knopf.""" + if config.testlauf(): + {"info": messagebox.showinfo, + "warnung": messagebox.showwarning, + "fehler": messagebox.showerror}.get(art, messagebox.showwarning)(titel, text) + return None + return self._meldungsfenster(titel, text, art, knoepfe=None) + + def frage(self, titel, text="", ja="Ja", nein="Nein", vorgabe=True, **_kw): + """Ja/Nein. Gibt True oder False zurueck - wie askyesno.""" + if config.testlauf(): + return bool(messagebox.askyesno(titel, text)) + return bool(self._meldungsfenster(titel, text, "frage", + knoepfe=(ja, nein), vorgabe=vorgabe)) + + def _meldungsfenster(self, titel, text, art, knoepfe=None, vorgabe=True): + farbe = {"fehler": self.col_gefahr, "warnung": self.col_gefahr, + "frage": self.col_accent}.get(art, self.col_accent) + d = tk.Toplevel(self) + d.title(titel) + d.transient(self) + d.resizable(False, False) + self._style_dialog(d) + antwort = {"wert": False} + + rahmen = ttk.Frame(d, padding=20) + rahmen.pack(fill="both", expand=True) + tk.Label(rahmen, text=titel, bg=self.col_bg, fg=farbe, justify="left", + font=(SCHRIFT_NAME, 12, "bold")).pack(anchor="w") + tk.Label(rahmen, text=text, bg=self.col_bg, fg=self.col_fg, justify="left", + wraplength=460, font=(SCHRIFT_NAME, 10)).pack(anchor="w", pady=(10, 0)) + + leiste = ttk.Frame(rahmen) + leiste.pack(fill="x", pady=(20, 0)) + + def schliessen(wert): + antwort["wert"] = wert + d.destroy() + + if knoepfe: + ja, nein = knoepfe + ttk.Button(leiste, text=ja, style="Haupt.TButton", + command=lambda: schliessen(True)).pack(side="right") + ttk.Button(leiste, text=nein, + command=lambda: schliessen(False)).pack(side="right", padx=(0, 8)) + d.bind("", lambda _e: schliessen(vorgabe)) + else: + ttk.Button(leiste, text="OK", style="Haupt.TButton", + command=lambda: schliessen(True)).pack(side="right") + d.bind("", lambda _e: schliessen(True)) + d.bind("", lambda _e: schliessen(False)) + d.protocol("WM_DELETE_WINDOW", lambda: schliessen(False)) + + d.update_idletasks() + x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) + y = self.winfo_rooty() + 140 + d.geometry(f"+{max(0, x)}+{max(0, y)}") + d.grab_set() + d.focus_set() + self.wait_window(d) + return antwort["wert"] From 1c2b115108002b97772cdc132c1944f67b76e6dd Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 19:21:20 +0200 Subject: [PATCH 09/34] Reiter selbst gebaut - clam liess den ruhenden nicht dunkel werden Sein Fund, zweimal: "er hebt den aktiven tab nicht hervor, der inaktive ist der hervorgehobene". Gemessen statt geraten: der clam-Standard faerbt die Reiterflaeche #bab5ab, und weder background noch lightcolor/darkcolor haben das im laufenden Fenster zuverlaessig ueberschrieben. Statt weiter daran zu drehen ist die Leiste jetzt selbst gebaut (reiter.py) - und sieht dabei aus wie die Reiter in seinen Web-Oberflaechen: flacher Knopf, der offene in Akzentfarbe, fett, mit Balken darunter und der Flaeche der Kachel. Nach aussen verhaelt sie sich wie ein Notebook: add, select, index("current"/ "end"), tab(i, "text") und <>. Deshalb bleiben der Storno-Weg (korrektur.py waehlt select(1)) und pruef_montage unveraendert - alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 12 ++++--- reiter.py | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ theme.py | 12 +++++-- 3 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 reiter.py diff --git a/app.py b/app.py index 6d4a8b7..e3c6ae6 100644 --- a/app.py +++ b/app.py @@ -39,6 +39,7 @@ from bestand import (hoechster_zaehler_im_ordner, naechste_freie_nummer, vorhandene_rechnungen) from einzelinstanz import (eigene_pid_merken, einzelinstanz_pruefen, fenster_nach_vorn, laufende_pid_lesen) +import reiter import theme from theme import MeldungMixin, ThemeMixin from korrektur import KorrekturMixin @@ -374,13 +375,16 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # Leistungskatalog und die Montage-Rechnung mit der Monatsmiete. Der # Kopf (Kunde, Nummer, Datum, Zeitraum) und die Summenleiste gelten fuer # beide - nur die Mitte wechselt. So tippt niemand den Kunden zweimal. - self.blaetter = ttk.Notebook(self) - self.blaetter.pack(side="top", fill="both", expand=True, padx=12, pady=4) + # Eigene Reiterleiste statt ttk.Notebook: unter clam liess sich der + # ruhende Reiter nicht dunkel bekommen, er sah aus wie der offene. + # Nach aussen verhaelt sie sich wie ein Notebook (siehe reiter.py). + self.blaetter = reiter.Reiterleiste(self, farben=self) + self.blaetter.pack(side="top", fill="both", expand=True, padx=16, pady=(4, 6)) self.blaetter.bind("<>", lambda _e: self._blatt_gewechselt()) - camping = ttk.Frame(self.blaetter, padding=(2, 4)) + camping = ttk.Frame(self.blaetter.bereich, padding=(2, 6)) self.blaetter.add(camping, text=" Campingrechnung ") - montage_tab = ttk.Frame(self.blaetter, padding=(10, 10)) + montage_tab = ttk.Frame(self.blaetter.bereich, padding=(14, 14)) self.blaetter.add(montage_tab, text=" Montage ") self._build_montage(montage_tab) diff --git a/reiter.py b/reiter.py new file mode 100644 index 0000000..8039d17 --- /dev/null +++ b/reiter.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +"""Reiterleiste im Pcore-Stil: Knopf mit Unterstrich statt ttk-Karteikarte. + +WARUM NICHT ttk.Notebook +------------------------ +Unter dem clam-Thema laesst sich die Reiterflaeche nicht zuverlaessig +einfaerben: der RUHENDE Reiter blieb hell und sah aus wie der ausgewaehlte - +also genau verkehrt herum. Sein Fund: *"er hebt den aktiven tab nicht hervor, +der inaktive ist der hervorgehobene"*. + +Statt weiter an clam zu drehen, ist die Leiste hier selbst gebaut - und sieht +dabei aus wie die Reiter in seinen Web-Oberflaechen: ein flacher Knopf, der +offene in Akzentfarbe mit einem Balken darunter. + +NACH AUSSEN wie ein Notebook +---------------------------- +`add`, `select`, `index("current"/"end")`, `tab(i, "text")` und das Ereignis +`<>` verhalten sich wie beim Original. So bleiben die +Aufrufer unveraendert - der Storno-Weg waehlt weiter `select(1)`, und die +Pruefstaende lesen die Reiternamen wie bisher. +""" +import tkinter as tk +from tkinter import ttk + +import theme + + +class Reiterleiste(ttk.Frame): + def __init__(self, master, farben=None): + super().__init__(master) + self.f = farben if farben is not None else master + self._seiten = [] # (Rahmen, Text, Knopf, Balken) + self._aktiv = 0 + + self.leiste = ttk.Frame(self) + self.leiste.pack(side="top", fill="x") + self.bereich = ttk.Frame(self) + self.bereich.pack(side="top", fill="both", expand=True) + + # ---- wie beim Notebook ------------------------------------------------ + def add(self, rahmen, text=""): + nr = len(self._seiten) + kasten = ttk.Frame(self.leiste) + kasten.pack(side="left", padx=(0, 4)) + knopf = tk.Label(kasten, text=text.strip(), cursor="hand2", + bg=self.f.col_bg, fg=self.f.col_muted, + font=(theme.SCHRIFT_NAME, 10), padx=18, pady=8) + knopf.pack(side="top", fill="x") + # Der Balken unter dem offenen Reiter - dasselbe Zeichen wie in den + # Web-Oberflaechen. + balken = tk.Frame(kasten, height=2, bg=self.f.col_bg) + balken.pack(side="top", fill="x") + knopf.bind("", lambda _e, i=nr: self.select(i)) + knopf.bind("", lambda _e, i=nr: self._schweben(i, True)) + knopf.bind("", lambda _e, i=nr: self._schweben(i, False)) + self._seiten.append([rahmen, text, knopf, balken]) + if nr == 0: + rahmen.pack(in_=self.bereich, fill="both", expand=True) + self._zeichnen() + + def select(self, nr): + nr = int(nr) + if not (0 <= nr < len(self._seiten)) or nr == self._aktiv: + self._zeichnen() + return + self._seiten[self._aktiv][0].pack_forget() + self._aktiv = nr + self._seiten[nr][0].pack(in_=self.bereich, fill="both", expand=True) + self._zeichnen() + # Dasselbe Ereignis wie beim Notebook - die App haengt daran. + self.event_generate("<>") + + def index(self, was="current"): + return len(self._seiten) if was == "end" else self._aktiv + + def tab(self, nr, key="text"): + return self._seiten[int(nr)][1] if key == "text" else "" + + # ---- Aussehen --------------------------------------------------------- + def _schweben(self, nr, drueber): + if nr == self._aktiv: + return + knopf = self._seiten[nr][2] + knopf.configure(fg=self.f.col_fg if drueber else self.f.col_muted) + + def _zeichnen(self): + for i, (_rahmen, _text, knopf, balken) in enumerate(self._seiten): + offen = (i == self._aktiv) + knopf.configure( + fg=self.f.col_accent if offen else self.f.col_muted, + bg=self.f.col_card if offen else self.f.col_bg, + font=(theme.SCHRIFT_NAME, 10, "bold") if offen + else (theme.SCHRIFT_NAME, 10)) + balken.configure(bg=self.f.col_accent if offen else self.f.col_bg) diff --git a/theme.py b/theme.py index 36234ba..42fa3f8 100644 --- a/theme.py +++ b/theme.py @@ -268,12 +268,20 @@ class ThemeMixin: # Der OFFENE Reiter gehoert zur Kachel darunter und ist deshalb heller # als die ruhenden. Vorher war es andersherum: die ruhenden lagen auf der # helleren Flaeche und sahen aus, als waeren sie ausgewaehlt. - style.configure("TNotebook.Tab", background=bg, + # ⚠️ clam zeichnet die Reiterflaeche aus lightcolor/darkcolor, nicht aus + # background allein - werden die nicht mitgesetzt, bleibt der ruhende + # Reiter hell und sieht aus wie der ausgewaehlte. + style.configure("TNotebook.Tab", background=bg, lightcolor=bg, darkcolor=bg, foreground=self.col_muted, bordercolor=self.col_line, - padding=(20, 9), font=(SCHRIFT_NAME, 10), borderwidth=0) + padding=(20, 9), font=(SCHRIFT_NAME, 10), borderwidth=1) style.map("TNotebook.Tab", background=[("selected", self.col_card), ("active", mischen(accent, bg, 0.12))], + lightcolor=[("selected", self.col_card), + ("active", mischen(accent, bg, 0.12))], + darkcolor=[("selected", self.col_card), + ("active", mischen(accent, bg, 0.12))], + bordercolor=[("selected", accent)], foreground=[("selected", accent), ("active", fg)], font=[("selected", (SCHRIFT_NAME, 10, "bold"))]) # Kein expand beim ausgewaehlten Reiter: er wuchs dadurch um ein paar From a715d1235bd52a001b5de09488a639c1d95eb9dd Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 19:33:46 +0200 Subject: [PATCH 10/34] Tabellenzeilen sind durchgehende Streifen, das Grau hebt sich ab Sein Fund: "schau mal zeile 1 und die ust, passen die hoehen nicht" und "das grau muss heller als der bg sein". Beides stimmte. Der Zebrastreifen sass an jedem LABEL einzeln - dadurch stand neben der zweizeiligen Position 1 ein Satz halbhoher Kaestchen mit Luecken darueber und darunter, und die USt-Zelle sass mittig statt in der Zeile. Jetzt liegt der Hintergrund als EIN Streifen ueber alle Spalten, die Zellen sitzen darin und fuellen die volle Zeilenhoehe. Die Kopfzeile bekommt denselben Streifen, sonst stand der zweizeilige "Anzahl Tage/Menge" als Kasten heraus. Der Streifen ist von #1b1e24 auf #232830 gegangen - vorher war der Unterschied zum Kachelgrund kaum zu sehen, und genau dafuer ist er da. Alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 54 ++++++++++++++++++++++++++++++++++-------------------- theme.py | 4 ++-- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/app.py b/app.py index e3c6ae6..6a25c16 100644 --- a/app.py +++ b/app.py @@ -418,12 +418,17 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self.gesamt_lbls.clear() # Kopfzeile (gleiches Grid wie die Daten) + # Kopfzeile: derselbe durchgehende Streifen wie die Datenzeilen, sonst + # steht der zweizeilige "Anzahl Tage/Menge" als Kasten heraus. + kopfgrund = tk.Frame(self.pos_frame, bg=self.col_card) + kopfgrund.grid(row=0, column=0, columnspan=len(self.COLS), sticky="nsew") for i, (title, anchor, _) in enumerate(self.COLS): - ttk.Label(self.pos_frame, text=title.upper(), anchor=anchor, - style="Abschnitt.TLabel").grid( - row=0, column=i, padx=3, pady=(0, 5), sticky="ew") + tk.Label(self.pos_frame, text=title.upper(), anchor=anchor, + bg=self.col_card, fg=self.col_accent, + font=(theme.SCHRIFT_NAME, 9, "bold"), padx=6, pady=6).grid( + row=0, column=i, sticky="nsew") ttk.Separator(self.pos_frame, orient="horizontal").grid( - row=1, column=0, columnspan=len(self.COLS), sticky="ew", pady=(0, 4)) + row=1, column=0, columnspan=len(self.COLS), sticky="ew", pady=(0, 2)) for idx, pos in enumerate(self.cfg["katalog"]): r = idx + 2 @@ -435,26 +440,35 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, av.trace_add("write", lambda *a: self.recalc()) pv.trace_add("write", lambda *a: self.recalc()) - # Jede zweite Zeile bekommt einen anderen Grund: bei 17 Positionen - # verrutscht man beim Eintragen sonst leicht eine Zeile. - zeilenstil = "Zebra.TLabel" if idx % 2 else "Karte.TLabel" - ttk.Label(self.pos_frame, text=str(nr), anchor="center", style=zeilenstil).grid( - row=r, column=0, padx=0, pady=3, sticky="ew", ipady=2) - ttk.Label(self.pos_frame, text=pos["leistung"], anchor="w", wraplength=320, - justify="left", style=zeilenstil).grid( - row=r, column=1, padx=0, pady=3, sticky="ew", ipady=2) - ttk.Label(self.pos_frame, text=str(pos["satz"]), anchor="center", - style=zeilenstil).grid(row=r, column=2, padx=0, pady=3, sticky="ew", ipady=2) + # Eine Zeile ist EIN durchgehender Streifen, kein Satz Kaestchen: + # der Hintergrund liegt ueber alle Spalten, die Zellen sitzen darin + # und fuellen die volle Zeilenhoehe (sticky="nsew"). Sonst klafften + # bei der zweizeiligen Position 1 Luecken ueber und unter den + # einzeiligen Zellen daneben. + grund = self.col_zebra if idx % 2 else self.col_card + streifen = tk.Frame(self.pos_frame, bg=grund) + streifen.grid(row=r, column=0, columnspan=len(self.COLS), sticky="nsew") + + def zelle(text, spalte, anker="center", umbruch=0): + lbl = tk.Label(self.pos_frame, text=text, bg=grund, fg=self.col_fg, + font=theme.SCHRIFT, anchor=anker, justify="left", + padx=6, pady=6) + if umbruch: + lbl.configure(wraplength=umbruch) + lbl.grid(row=r, column=spalte, sticky="nsew") + return lbl + + zelle(str(nr), 0) + zelle(pos["leistung"], 1, anker="w", umbruch=330) + zelle(str(pos["satz"]), 2) ttk.Entry(self.pos_frame, textvariable=av, width=8, justify="center").grid( - row=r, column=3, padx=4, pady=3) + row=r, column=3, padx=6, pady=4) # Personen-Feld NUR bei "pro Person"-Positionen anzeigen if pos["pro_person"]: ttk.Entry(self.pos_frame, textvariable=pv, width=6, justify="center").grid( - row=r, column=4, padx=4, pady=3) - ttk.Label(self.pos_frame, text=berechnung.eur_kurz(pos["preis"]), anchor="e", - style=zeilenstil).grid(row=r, column=5, padx=0, pady=3, sticky="ew", ipady=2) - g = ttk.Label(self.pos_frame, text="0,00", anchor="e", style=zeilenstil) - g.grid(row=r, column=6, padx=0, pady=3, sticky="ew", ipady=2) + row=r, column=4, padx=6, pady=4) + zelle(berechnung.eur_kurz(pos["preis"]), 5, anker="e") + g = zelle("0,00", 6, anker="e") self.gesamt_lbls[nr] = g # ------------------------------------------------------------ Montage diff --git a/theme.py b/theme.py index 42fa3f8..10b52dd 100644 --- a/theme.py +++ b/theme.py @@ -128,7 +128,7 @@ class ThemeMixin: self.col_line = "#25282e" self.col_scroll = "#2f333a" self.col_muted = "#8a8e96" - self.col_zebra = "#1b1e24" # jede zweite Zeile der Liste + self.col_zebra = "#232830" # jede zweite Zeile der Liste else: self.col_bg = "#eef0f3" self.col_card = "#ffffff" @@ -142,7 +142,7 @@ class ThemeMixin: self.col_line = "#d8dce1" self.col_scroll = "#c2c6cc" self.col_muted = "#5c626b" - self.col_zebra = "#e9ecf0" + self.col_zebra = "#e4e8ee" self.configure(bg=self.col_bg) style = ttk.Style(self) From 2faf8c1b9af43e482ee104da9d85f6591aad5916 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 19:35:11 +0200 Subject: [PATCH 11/34] Eingabefelder in der Liste heben sich vom Zeilenstreifen ab Sein Fund: "bei der anzahl waere ein heller bg oder ein heller rahmen besser". Die Felder standen auf den Zeilenstreifen und gingen darin unter - man sah nicht, wo man tippt. Eigener Stil (Liste.TEntry): hellerer Grund, deutlicher Rahmen, beim Tippen Rahmen und Fuellung in der Akzentfarbe. Alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 6 ++++-- theme.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app.py b/app.py index 6a25c16..d540f0e 100644 --- a/app.py +++ b/app.py @@ -461,11 +461,13 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, zelle(str(nr), 0) zelle(pos["leistung"], 1, anker="w", umbruch=330) zelle(str(pos["satz"]), 2) - ttk.Entry(self.pos_frame, textvariable=av, width=8, justify="center").grid( + ttk.Entry(self.pos_frame, textvariable=av, width=8, justify="center", + style="Liste.TEntry").grid( row=r, column=3, padx=6, pady=4) # Personen-Feld NUR bei "pro Person"-Positionen anzeigen if pos["pro_person"]: - ttk.Entry(self.pos_frame, textvariable=pv, width=6, justify="center").grid( + ttk.Entry(self.pos_frame, textvariable=pv, width=6, justify="center", + style="Liste.TEntry").grid( row=r, column=4, padx=6, pady=4) zelle(berechnung.eur_kurz(pos["preis"]), 5, anker="e") g = zelle("0,00", 6, anker="e") diff --git a/theme.py b/theme.py index 10b52dd..f5567cb 100644 --- a/theme.py +++ b/theme.py @@ -238,6 +238,19 @@ class ThemeMixin: style.configure("TEntry", fieldbackground=field, foreground=fg, insertcolor=fg, bordercolor=self.col_line, padding=4) style.map("TEntry", bordercolor=[("focus", accent)]) + # Die Felder IN der Leistungsliste stehen auf den Zeilenstreifen und + # gingen darin unter - man sah nicht, wo man tippt. Sie bekommen einen + # helleren Grund und einen deutlichen Rahmen, beim Tippen den Akzent. + listenfeld = mischen("#ffffff", self.col_card, 0.10) + listenrand = mischen("#ffffff", self.col_card, 0.28) + style.configure("Liste.TEntry", fieldbackground=listenfeld, foreground=fg, + insertcolor=fg, bordercolor=listenrand, + lightcolor=listenrand, darkcolor=listenrand, + relief="solid", borderwidth=1, padding=4) + style.map("Liste.TEntry", + bordercolor=[("focus", accent)], lightcolor=[("focus", accent)], + darkcolor=[("focus", accent)], + fieldbackground=[("focus", mischen(accent, self.col_card, 0.10))]) # Bei state="readonly" zeichnet die Combobox ihren Text als MARKIERUNG, # sobald sie den Fokus hat - ohne diese beiden Farben steht der Wert # unsichtbar im Feld. From 5c9e9c26277499b1d0013643af9d10b3cc5b5524 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 19:38:06 +0200 Subject: [PATCH 12/34] Das Programm heisst Rechnungstool, nicht "Rechnungstool - Campinghof Bartl" Sein Fund: "rechnungstool campinghof bartl ist falsch, das ist das rechnungstool powered by ravokk". Stimmt - der Firmenname des KUNDEN gehoerte nie in den Fenstertitel. Das Werkzeug steht bei jedem Betrieb, der es einsetzt, und traegt seinen eigenen Namen; der Kunde steht auf der RECHNUNG. Name und Marke stehen jetzt in config (PROGRAMM, MARKE) - Fenstertitel, das Info-Fenster und die Fussleiste lesen von dort. Alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 6 +++--- config.py | 8 +++++++- einstellungen.py | 6 +++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index d540f0e..cd3fddf 100644 --- a/app.py +++ b/app.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Rechnungstool Campinghof Bartl - Desktop-GUI (Tkinter). +Rechnungstool (powered by ravokk) - Desktop-GUI (Tkinter). Bedienung: 1. Kundenadresse + An-/Abreise eingeben @@ -59,7 +59,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, def __init__(self): super().__init__() self.cfg = config.load_config() - self.title("Rechnungstool - " + self.cfg["firma"].get("name", "Campinghof")) + self.title(config.PROGRAMM) # Fensterhoehe an den Bildschirm anpassen, damit nichts unter den Rand rutscht hoehe = max(560, min(840, self.winfo_screenheight() - 90)) self.geometry(f"1060x{hoehe}") @@ -567,7 +567,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # Statuszeile ganz unten status = ttk.Frame(self, padding=(12, 2)) status.pack(side="bottom", fill="x") - ttk.Label(status, text="powered by ravokk", foreground=self.col_muted, + ttk.Label(status, text=config.MARKE, foreground=self.col_muted, font=(theme.SCHRIFT_NAME, 8)).pack(side="right") # Steht der gemeinsame Ordner? Das gehoert sichtbar hin - ohne ihn kennt # das Programm die Nummern des Steuerjournals nicht. diff --git a/config.py b/config.py index 4d6ccd1..c81f110 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Konfiguration fuer das Rechnungstool Campinghof Bartl. +Konfiguration fuer das Rechnungstool (powered by ravokk). Haelt die Standardwerte (Firmendaten, Steuersaetze, Leistungskatalog, Rechnungsnummer-Zaehler) und kuemmert sich um Laden/Speichern der config.json. @@ -68,6 +68,12 @@ def _daten_ordner(): return kandidat +# Das Programm heisst Rechnungstool und kommt von ravokk. Der Firmenname des +# KUNDEN gehoert nicht in den Fenstertitel - das Werkzeug steht bei jedem +# Betrieb, der es einsetzt, und traegt seinen eigenen Namen. +PROGRAMM = "Rechnungstool" +MARKE = "powered by ravokk" + BASE_DIR = _daten_ordner() CONFIG_PATH = os.path.join(BASE_DIR, "config.json") diff --git a/einstellungen.py b/einstellungen.py index 2d66ef2..d0a1358 100644 --- a/einstellungen.py +++ b/einstellungen.py @@ -51,13 +51,13 @@ class EinstellungenMixin: self._style_dialog(d) frm = ttk.Frame(d, padding=18) frm.pack(fill="both", expand=True) - ttk.Label(frm, text="Rechnungstool Campinghof Bartl", font=(theme.SCHRIFT_NAME, 11, "bold"), + ttk.Label(frm, text=config.PROGRAMM, font=(theme.SCHRIFT_NAME, 11, "bold"), foreground=self.col_accent).pack(anchor="w") ttk.Label(frm, justify="left", text="Daten eingeben, PDF erstellen, drucken.\n" "Steuersätze, Preise und Firmendaten lassen sich\n" "im Menü Einstellungen anpassen.").pack(anchor="w", pady=(8, 12)) - ttk.Label(frm, text="powered by ravokk", foreground=self.col_muted).pack(anchor="w") + ttk.Label(frm, text=config.MARKE, foreground=self.col_muted).pack(anchor="w") ttk.Button(frm, text="OK", command=d.destroy, width=10).pack(anchor="e", pady=(14, 0)) d.bind("", lambda e: d.destroy()) d.bind("", lambda e: d.destroy()) @@ -447,7 +447,7 @@ class EinstellungenMixin: self.cfg["texte"]["dank2"] = t2.get("1.0", "end").strip() self.cfg["texte"]["hinweis"] = vh.get().strip() config.save_config(self.cfg) - self.title("Rechnungstool - " + self.cfg["firma"].get("name", "")) + self.title(config.PROGRAMM) d.destroy() btns = ttk.Frame(frm) From 2ec41fb4e46d1d700c4c0d44e484bb12845dee50 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 19:41:39 +0200 Subject: [PATCH 13/34] Alle Eingabefelder heben sich vom Grund ab, nicht nur die in der Liste Sein Fund: "in rechnung an kunden finde ich die felder auch zu dunkel". Der Grund war derselbe wie in der Leistungsliste - das Feld lag fast auf der Farbe der Kachel, man sah nicht, wo etwas einzutragen ist. Jetzt gilt fuer JEDES Eingabefeld und die Auswahlliste derselbe Satz Farben (#2c2e32 Grund, #57585b Rahmen, beim Tippen Akzent) - aus einer Quelle gerechnet, nicht zweimal gepflegt. Liste.TEntry liest dieselben Werte. Alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- theme.py | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/theme.py b/theme.py index f5567cb..055e230 100644 --- a/theme.py +++ b/theme.py @@ -235,17 +235,25 @@ class ThemeMixin: style.map("Menu.TMenubutton", background=[("active", sel)], foreground=[("active", fg)]) style.configure("TCheckbutton", background=bg, foreground=fg) style.map("TCheckbutton", background=[("active", bg)], foreground=[("active", fg)]) - style.configure("TEntry", fieldbackground=field, foreground=fg, insertcolor=fg, - bordercolor=self.col_line, padding=4) - style.map("TEntry", bordercolor=[("focus", accent)]) + # Eingabefelder heben sich vom Grund ab - sonst sieht man nicht, wo etwas + # einzutragen ist. Heller Grund, deutlicher Rahmen, beim Tippen Akzent. + feld_hell = mischen("#ffffff", self.col_card, 0.10) if dark else field + feld_rand = mischen("#ffffff", self.col_card, 0.28) if dark else self.col_line + self.col_field = feld_hell + style.configure("TEntry", fieldbackground=feld_hell, foreground=fg, + insertcolor=fg, bordercolor=feld_rand, + lightcolor=feld_rand, darkcolor=feld_rand, + relief="solid", borderwidth=1, padding=5) + style.map("TEntry", + bordercolor=[("focus", accent)], lightcolor=[("focus", accent)], + darkcolor=[("focus", accent)], + fieldbackground=[("focus", mischen(accent, self.col_card, 0.10))]) # Die Felder IN der Leistungsliste stehen auf den Zeilenstreifen und # gingen darin unter - man sah nicht, wo man tippt. Sie bekommen einen # helleren Grund und einen deutlichen Rahmen, beim Tippen den Akzent. - listenfeld = mischen("#ffffff", self.col_card, 0.10) - listenrand = mischen("#ffffff", self.col_card, 0.28) - style.configure("Liste.TEntry", fieldbackground=listenfeld, foreground=fg, - insertcolor=fg, bordercolor=listenrand, - lightcolor=listenrand, darkcolor=listenrand, + style.configure("Liste.TEntry", fieldbackground=feld_hell, foreground=fg, + insertcolor=fg, bordercolor=feld_rand, + lightcolor=feld_rand, darkcolor=feld_rand, relief="solid", borderwidth=1, padding=4) style.map("Liste.TEntry", bordercolor=[("focus", accent)], lightcolor=[("focus", accent)], @@ -254,14 +262,17 @@ class ThemeMixin: # Bei state="readonly" zeichnet die Combobox ihren Text als MARKIERUNG, # sobald sie den Fokus hat - ohne diese beiden Farben steht der Wert # unsichtbar im Feld. - style.configure("TCombobox", fieldbackground=field, foreground=fg, - background=field, arrowcolor=fg, - selectbackground=field, selectforeground=fg) - style.map("TCombobox", fieldbackground=[("readonly", field)], - foreground=[("readonly", fg)], background=[("readonly", field)], - selectbackground=[("readonly", field)], selectforeground=[("readonly", fg)]) + style.configure("TCombobox", fieldbackground=feld_hell, foreground=fg, + background=feld_hell, arrowcolor=fg, + bordercolor=feld_rand, lightcolor=feld_rand, darkcolor=feld_rand, + selectbackground=feld_hell, selectforeground=fg, padding=3) + style.map("TCombobox", fieldbackground=[("readonly", feld_hell)], + foreground=[("readonly", fg)], background=[("readonly", feld_hell)], + bordercolor=[("focus", accent)], + selectbackground=[("readonly", feld_hell)], + selectforeground=[("readonly", fg)]) # Die aufgeklappte Liste ist ein klassisches tk-Listbox-Widget - self.option_add("*TCombobox*Listbox.background", field) + self.option_add("*TCombobox*Listbox.background", feld_hell) self.option_add("*TCombobox*Listbox.foreground", fg) self.option_add("*TCombobox*Listbox.selectBackground", sel) self.option_add("*TCombobox*Listbox.selectForeground", fg) From 5403e01dd5660e0c6d68a5fdf00ad1d9c929447a Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 19:44:12 +0200 Subject: [PATCH 14/34] Jedes Feld, in das man tippen kann, sieht gleich aus Seine Ansage: "wenn, dann musst du die felder alle gleich machen, wo man was eingeben kann". Die ttk-Felder hatten die neuen Farben schon, die klassischen Widgets nicht: die beiden Danktext-Felder und die Auswahlliste im Storno standen ohne Rahmen und mit dem alten dunklen Grund da. Die Feldfarben stehen jetzt in der Palette (col_field, col_feldrand) statt mitten in der Stil-Definition, und `feld_optionen()` gibt sie an tk.Text und tk.Listbox weiter - eine Quelle fuer alle. Eine Auswahlliste bekommt dabei keine Einfuegemarke: die Option kennt sie nicht und bricht daran ab (gefunden, weil drei Pruefstaende sofort rot wurden). Alle 14 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- einstellungen.py | 4 ++-- korrektur.py | 6 +++--- theme.py | 35 ++++++++++++++++++++++++++++++----- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/einstellungen.py b/einstellungen.py index d0a1358..f39eb25 100644 --- a/einstellungen.py +++ b/einstellungen.py @@ -425,11 +425,11 @@ class EinstellungenMixin: probe_zeigen() ttk.Label(frm, text="Danktext 1").grid(row=base + 3, column=0, sticky="nw", pady=2) - t1 = tk.Text(frm, width=44, height=3, wrap="word", bg=self.col_field, fg=self.col_fg, insertbackground=self.col_fg) + t1 = tk.Text(frm, width=44, height=3, wrap="word", **self.feld_optionen(mehrzeilig=True)) t1.insert("1.0", self.cfg["texte"].get("dank1", "")) t1.grid(row=base + 3, column=1, sticky="ew", padx=(8, 0), pady=2) ttk.Label(frm, text="Danktext 2").grid(row=base + 4, column=0, sticky="nw", pady=2) - t2 = tk.Text(frm, width=44, height=3, wrap="word", bg=self.col_field, fg=self.col_fg, insertbackground=self.col_fg) + t2 = tk.Text(frm, width=44, height=3, wrap="word", **self.feld_optionen(mehrzeilig=True)) t2.insert("1.0", self.cfg["texte"].get("dank2", "")) t2.grid(row=base + 4, column=1, sticky="ew", padx=(8, 0), pady=2) ttk.Label(frm, text="Hinweiszeile").grid(row=base + 5, column=0, sticky="w", pady=2) diff --git a/korrektur.py b/korrektur.py index 966e2ee..45b71e1 100644 --- a/korrektur.py +++ b/korrektur.py @@ -204,9 +204,9 @@ class KorrekturMixin: # wurde dieselbe Nummer zweimal vergeben, teils als Windows-Kopie mit # "(1)" im Namen. Dann darf das Programm nicht raten, welche gemeint ist. self._auswahl = tk.Listbox(frm, height=4, exportselection=False, - bg=self.col_field, fg=self.col_fg, - selectbackground=self.col_sel, selectforeground=self.col_fg, - relief="flat", font=("Consolas", 9)) + selectbackground=self.col_sel, + selectforeground=self.col_fg, + font=("Consolas", 9), **self.feld_optionen(einfuegemarke=False)) self._auswahl.grid(row=3, column=0, columnspan=2, sticky="ew", pady=(8, 0)) self._auswahl.grid_remove() self._kandidaten = [] diff --git a/theme.py b/theme.py index 055e230..4dfca80 100644 --- a/theme.py +++ b/theme.py @@ -119,7 +119,8 @@ class ThemeMixin: self.col_bg = "#0d0e10" # Fenster-Hintergrund (tiefstes Grau) self.col_card = "#15171b" # Kachel / Abschnitt self.col_fg = "#e8e8ea" # Schrift - self.col_field = "#1d2025" # Eingabefelder + self.col_field = "#2c2e32" # Eingabefelder (heller als die Kachel) + self.col_feldrand = "#57585b" # Rahmen der Eingabefelder self.col_sel = "#1f3d38" # aktiv/hover (Akzent, stark abgedunkelt) self.col_accent = "#06C6A4" # Akzent (Pcore-Tuerkis) self.col_accent_hell = "#08dbb5" @@ -134,6 +135,7 @@ class ThemeMixin: self.col_card = "#ffffff" self.col_fg = "#14161a" self.col_field = "#ffffff" + self.col_feldrand = "#b9bec6" self.col_sel = "#d7f5ee" self.col_accent = "#04886f" # dunkler, damit es auf Weiss lesbar ist self.col_accent_hell = "#06C6A4" @@ -236,10 +238,10 @@ class ThemeMixin: style.configure("TCheckbutton", background=bg, foreground=fg) style.map("TCheckbutton", background=[("active", bg)], foreground=[("active", fg)]) # Eingabefelder heben sich vom Grund ab - sonst sieht man nicht, wo etwas - # einzutragen ist. Heller Grund, deutlicher Rahmen, beim Tippen Akzent. - feld_hell = mischen("#ffffff", self.col_card, 0.10) if dark else field - feld_rand = mischen("#ffffff", self.col_card, 0.28) if dark else self.col_line - self.col_field = feld_hell + # einzutragen ist. JEDES Feld, in das man tippen kann, traegt diese zwei + # Farben: die ttk-Felder ueber die Stile hier, die klassischen Widgets + # (Textfelder, Auswahlliste) ueber feld_optionen() weiter unten. + feld_hell, feld_rand = self.col_field, self.col_feldrand style.configure("TEntry", fieldbackground=feld_hell, foreground=fg, insertcolor=fg, bordercolor=feld_rand, lightcolor=feld_rand, darkcolor=feld_rand, @@ -315,6 +317,29 @@ class ThemeMixin: self.option_add("*background", bg) self.option_add("*foreground", fg) + def feld_optionen(self, mehrzeilig=False, einfuegemarke=True): + """Farben und Rahmen fuer die klassischen Eingabe-Widgets (Text, Listbox). + + ttk-Felder holen sich das aus dem Stil; tk.Text und tk.Listbox koennen + das nicht - sie muessen die Werte einzeln bekommen. Damit trotzdem JEDES + Feld gleich aussieht, kommen sie aus dieser einen Stelle. + """ + opts = { + "bg": self.col_field, + "fg": self.col_fg, + "relief": "solid", + "borderwidth": 1, + "highlightthickness": 0, + } + # Eine Auswahlliste hat keine Einfuegemarke - sie kennt die Option nicht + # und bricht daran ab. + if einfuegemarke: + opts["insertbackground"] = self.col_fg + if mehrzeilig: + opts["padx"] = 4 + opts["pady"] = 3 + return opts + def _style_dialog(self, d): """Toplevel-Dialog an das Theme angleichen. From c1e328c08765f844e77207d1e5603938f212c859 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sat, 5 Sep 2026 19:53:42 +0200 Subject: [PATCH 15/34] Kaesten verschiebbar wie bei OPNsense: Knopf, schieben, speichern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seine Ansage: "rechnungsdaten oben links, darunter rechnung an kunde, den tabellen kasten rechts - oder noch besser dnd einbauen" und dann genauer: "wie bei opnsense hast so einen kleinen knopf, dann drueckst drauf, ab da kannst du schieben, dann hast du einen save button, und dann ist die fest". - Seine Anordnung ist die Vorgabe (flaeche.STANDARD). - Verschieben muss man EINSCHALTEN. Ohne den Knopf sitzt alles fest, damit beim taeglichen Arbeiten nichts verrutscht. Im Modus stehen "Speichern" und "Verwerfen" daneben; erst Speichern schreibt in die config. - Waehrend des Ziehens haengt ein Etikett am Zeiger und der gegriffene Kasten wird blass - vorher sah man nur das Ziel und es wirkte "statisch" (sein Fund). - Getauscht statt frei abgelegt: freies Verschieben auf Pixel braucht Regeln fuer Ueberlappung, Groesse und leere Zellen, und am Ende steht das Fenster schief. Ein Tausch ist in einem Griff erledigt. - Der freie Platz folgt dem Kasten mit der langen Liste. Feste Gewichte gingen nicht: die Liste wandert, und der Kundenkasten wurde unten abgeschnitten. - Eine unbrauchbare Anordnung in der config faellt auf die Vorgabe zurueck. Icons: die Material Symbols vom Hub (M:/projekte/material-symbols), einmal nach PNG gewandelt und zur Laufzeit eingefaerbt (icons.py) - eine Datei je Icon, nicht drei Fassungen fuer hell/dunkel/Akzent. ⚠️ Ein PhotoImage gehoert GENAU EINEM Tk-Fenster. Der Icon-Cache reichte Bilder an das naechste weiter, sobald ein Pruefstand Journal und Rechnungstool nacheinander faehrt: 'image "pyimage1" doesn't exist'. Das Fenster wird jetzt mitgegeben, tk._default_root reicht dafuer nicht. Neu: pruef_flaeche.py. Alle 15 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 82 ++++++-- assets/icons/check.png | Bin 0 -> 327 bytes assets/icons/close.png | Bin 0 -> 326 bytes assets/icons/dashboard_customize.png | Bin 0 -> 372 bytes assets/icons/drag_indicator.png | Bin 0 -> 522 bytes assets/icons/save.png | Bin 0 -> 470 bytes flaeche.py | 282 +++++++++++++++++++++++++++ icons.py | 62 ++++++ pruef_flaeche.py | 144 ++++++++++++++ theme.py | 8 + 10 files changed, 561 insertions(+), 17 deletions(-) create mode 100644 assets/icons/check.png create mode 100644 assets/icons/close.png create mode 100644 assets/icons/dashboard_customize.png create mode 100644 assets/icons/drag_indicator.png create mode 100644 assets/icons/save.png create mode 100644 flaeche.py create mode 100644 icons.py create mode 100644 pruef_flaeche.py diff --git a/app.py b/app.py index cd3fddf..e02548c 100644 --- a/app.py +++ b/app.py @@ -39,6 +39,8 @@ from bestand import (hoechster_zaehler_im_ordner, naechste_freie_nummer, vorhandene_rechnungen) from einzelinstanz import (eigene_pid_merken, einzelinstanz_pruefen, fenster_nach_vorn, laufende_pid_lesen) +import flaeche +import icons import reiter import theme from theme import MeldungMixin, ThemeMixin @@ -102,9 +104,11 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self._apply_theme() # Farben nach Windows hell/dunkel self._build_menu() - self._build_kopf() self._build_summen() # untere Leiste (Summen + Buttons) zuerst -> bleibt immer sichtbar - self._build_positionen() # Positionsliste fuellt den Rest und scrollt + self._build_flaeche() # Werkzeugleiste + verschiebbare Kaesten + self._build_kopf() # Rechnungsdaten + Kunde als Kaesten + self._build_positionen() # Leistungen als Kasten, fuellt den Rest + self.flaeche.anordnen() self._neue_nummer_vorschlagen() self.recalc() @@ -211,15 +215,62 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, pass self._open_pop = None + # ------------------------------------------------------- Arbeitsflaeche + def _build_flaeche(self): + """Die Kaesten und der Knopf, mit dem man sie verschieben darf. + + Wie bei OPNsense: erst "Anordnen" druecken, dann schieben, dann + speichern. Ohne diesen Schritt sitzt alles fest - beim taeglichen + Arbeiten soll nichts verrutschen. + """ + leiste = ttk.Frame(self, padding=(16, 8, 16, 0)) + leiste.pack(side="top", fill="x") + self.werkzeuge = ttk.Frame(leiste) + self.werkzeuge.pack(side="right") + + self._ic_anordnen = icons.hole("dashboard_customize", 16, self.col_muted, master=self) + self._ic_speichern = icons.hole("check", 16, self.col_accent_hell, master=self) + self._ic_verwerfen = icons.hole("close", 16, self.col_muted, master=self) + + self.knopf_anordnen = ttk.Button(self.werkzeuge, text=" Anordnen", + image=self._ic_anordnen, compound="left", + command=self._anordnen_umschalten) + self.knopf_anordnen.pack(side="left") + self.knopf_speichern = ttk.Button(self.werkzeuge, text=" Speichern", + image=self._ic_speichern, compound="left", + style="Haupt.TButton", + command=self._anordnen_speichern) + self.knopf_verwerfen = ttk.Button(self.werkzeuge, text=" Verwerfen", + image=self._ic_verwerfen, compound="left", + command=self._anordnen_verwerfen) + + self.flaeche = flaeche.Arbeitsflaeche(self, farben=self) + self.flaeche.pack(side="top", fill="both", expand=True, padx=10, pady=(4, 0)) + + def _anordnen_umschalten(self): + self.flaeche.anordnen_starten() + self.knopf_anordnen.pack_forget() + self.knopf_verwerfen.pack(side="left", padx=(0, 6)) + self.knopf_speichern.pack(side="left") + + def _anordnen_fertig(self): + self.knopf_speichern.pack_forget() + self.knopf_verwerfen.pack_forget() + self.knopf_anordnen.pack(side="left") + + def _anordnen_speichern(self): + self.flaeche.anordnen_speichern() + self._anordnen_fertig() + + def _anordnen_verwerfen(self): + self.flaeche.anordnen_verwerfen() + self._anordnen_fertig() + # ---------------------------------------------------------------- Kopf def _build_kopf(self): - top = ttk.Frame(self, padding=(16, 14, 16, 6)) - top.pack(fill="x") - - # Kunde (links) - kunde = ttk.LabelFrame(top, text="RECHNUNG AN (KUNDE)", padding=14, - style="Karte.TLabelframe") - kunde.grid(row=0, column=0, sticky="nsew", padx=(0, 14)) + # Beide Bloecke sind Kaesten der Arbeitsflaeche - sie lassen sich + # verschieben, deshalb platziert sie niemand mehr von Hand. + kunde = self.flaeche.kasten("kunde", "Rechnung an (Kunde)") self.k_anrede = tk.StringVar() self.k_vorname = tk.StringVar() self.k_name = tk.StringVar() # Nachname oder Firma – die Zuordnung im Steuerjournal @@ -249,10 +300,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, row=len(felder), column=0, columnspan=2, sticky="w", pady=(6, 0)) kunde.columnconfigure(1, weight=1) - # Rechnungsinfos (rechts) - info = ttk.LabelFrame(top, text="RECHNUNGSDATEN", padding=14, - style="Karte.TLabelframe") - info.grid(row=0, column=1, sticky="nsew") + info = self.flaeche.kasten("daten", "Rechnungsdaten") self.r_nummer = tk.StringVar() self.r_datum = tk.StringVar(value=datetime.date.today().strftime("%d.%m.%Y")) self.r_anreise = tk.StringVar() @@ -296,8 +344,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self.r_anreise.trace_add("write", lambda *a: self._update_naechte()) self.r_abreise.trace_add("write", lambda *a: self._update_naechte()) - top.columnconfigure(0, weight=1) - top.columnconfigure(1, weight=0) + def _auto_datum_evt(self, event): """Punkte automatisch setzen, Cursor ans Ende. Nach Tag+Monat das aktuelle @@ -378,8 +425,9 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # Eigene Reiterleiste statt ttk.Notebook: unter clam liess sich der # ruhende Reiter nicht dunkel bekommen, er sah aus wie der offene. # Nach aussen verhaelt sie sich wie ein Notebook (siehe reiter.py). - self.blaetter = reiter.Reiterleiste(self, farben=self) - self.blaetter.pack(side="top", fill="both", expand=True, padx=16, pady=(4, 6)) + leistungen = self.flaeche.kasten("leistungen", "Leistungen") + self.blaetter = reiter.Reiterleiste(leistungen, farben=self) + self.blaetter.pack(side="top", fill="both", expand=True) self.blaetter.bind("<>", lambda _e: self._blatt_gewechselt()) camping = ttk.Frame(self.blaetter.bereich, padding=(2, 6)) diff --git a/assets/icons/check.png b/assets/icons/check.png new file mode 100644 index 0000000000000000000000000000000000000000..7dcb1a590ab90ec0450943f4100e94fa2f1d06a7 GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z{-`>a z!)?bdSMW$%M|0~dd}NC|Ag#GH&S6)&*(?vA1F7{1U4JKOdayk^%`6t?ama}4u}05g zgT6x+NQ@UPn^_Mq9@w<~bnPoO4aLewv#n32hOhUVa!2sMv*J4p6=h}q6Jn0)o1S#N zZ@KKL#i9i*Cwf&i78WIQc=gQbf6(*9=3vmH9c?kM=iiz6r1?qKn7?F@Phc_&=fB$S<6r#Ed Vnm=)sFff1^JYD@<);T3K0RSuui^c!| literal 0 HcmV?d00001 diff --git a/assets/icons/close.png b/assets/icons/close.png new file mode 100644 index 0000000000000000000000000000000000000000..ca051d4bb3886c16cc2ad5fbf1faae29ffd9d7ba GIT binary patch literal 326 zcmV-M0lEH(P)m?7MS2Ua7Fde(R$L2k3h4@5EASao zhEo7}u(zr9Oc{{TtVw3>-g;gZ21%8re`0^IAQZ=<1o+=-l_7iJP$GNbP$7HbP#}Bb zXhpsPM+SN^^5`0^X>P||<6D9e8peF7YDR>6KrAO#8f(P&jdXh>Zg;0}BY^a@99}I*{ zlKy6rnIu(JK{5p45QIYz4q>DMs}81&`Ksd@!2-oFWBk|F&e+%iSUY@A0B2_Y7Qn{o zt@EJ88VZNsG^NKXrq5;dHyYmj;zLXj4na5s;ShvF5DsDFiF&6KsgIoTafv>Q5xDkL zi4YdvDiOfUQ{q15?r2Am{Ga@hxI)YwY#Vm~dyhW_aMA4pfHFp4)WLQzH`e8zV8OSz ze$PFaF}c32y}${q|FmGnsGfFw8kM9gsXlWiE2F)1RFKEF1YVf1AGNhf+8sX|;)5lX zER9_|0k{n*u(b4LhQM2BE*yP`w*h%D!+-)eeJ0^aggE)X2d5rlf^cYP0UR#?NW%0z SueSgI0000igP)JJ38(qjYhn_V?5-%my!m0 z*-3oIn8|4)z-Gj|1q|o3SzytU&{|-#K-UMoU$Vrb;oXOpxSLitA!$!iL(-9?S_`j# zcP!~v(r$dU6W7b?Bx7N|y#a1J*cR3Bo1-9C`=#7jC-v9sr M07*qoM6N<$f)PaPMgRZ+ literal 0 HcmV?d00001 diff --git a/assets/icons/save.png b/assets/icons/save.png new file mode 100644 index 0000000000000000000000000000000000000000..bffa44009a28ff1a0c72f960754480df55f03104 GIT binary patch literal 470 zcmV;{0V)28P)! zKT88K7>A#x#a(a^J2@zVi=bN_TtvZLR2&39fTNS(S8(g*poriuii3+z#eblKIw`1& zegF$cB=QyxxnAR4YhLLCfnJikJo%O6$Q7)$XvUx%gK`YYG5k}(GH?WZ0=CWN0T}QV zEHqigPHu+I@d!)-uUQ3May`H~aMnh#vDn1@B%NSFX|UO(J!>giYj1z7K} zLnSt*nol1|90RkyfAOl^kT|P0Q dict(rahmen, kopf, titel) + self.layout = {} + self._vorher = {} # Stand vor dem Anordnen + self.anordnen_an = False # Verschieben eingeschaltet? + self._zieht = None + self._ziel = None + # Die Gewichte setzt `anordnen()` - sie haengen davon ab, WO die lange + # Liste gerade steht. + + # ---- Aufbau ----------------------------------------------------------- + def kasten(self, name, titel): + """Legt einen Kasten an und gibt seinen Inhaltsrahmen zurueck.""" + aussen = ttk.Frame(self, style="Karte.TFrame") + kopf = tk.Label(aussen, text=titel.upper(), anchor="w", cursor="fleur", + bg=self.f.col_card, fg=self.f.col_accent, + font=(self._schrift(), 9, "bold"), padx=12, pady=8) + kopf.pack(side="top", fill="x") + inhalt = ttk.Frame(aussen, style="Karte.TFrame", padding=(12, 0, 12, 12)) + inhalt.pack(side="top", fill="both", expand=True) + + kopf.bind("", lambda e, n=name: self._greifen(n)) + kopf.bind("", lambda e, n=name: self._ziehen(e, n)) + kopf.bind("", lambda e, n=name: self._loslassen(n)) + self.kaesten[name] = {"aussen": aussen, "kopf": kopf, "inhalt": inhalt, + "titel": titel} + return inhalt + + def anordnen(self, layout=None): + """Kaesten ins Raster setzen. Ohne Angabe: was in der config steht.""" + self.layout = dict(layout or self._gespeichert()) + for name, kasten in self.kaesten.items(): + spalte, zeile, hoch = self.layout.get(name, STANDARD.get(name, (0, 0, 1))) + kasten["aussen"].grid(row=zeile, column=spalte, rowspan=hoch, + sticky="nsew", padx=6, pady=6) + self._platz_verteilen() + + def _platz_verteilen(self): + """Der freie Platz gehoert dem Kasten mit der langen Liste. + + Feste Gewichte gehen nicht: die Liste wandert beim Verschieben, und wer + das Gewicht an einer festen Zelle laesst, schneidet danach den + Kundenkasten unten ab - genau das ist beim ersten Versuch passiert. + """ + for z in range(2): + self.rowconfigure(z, weight=0, minsize=0) + for sp in range(2): + self.columnconfigure(sp, weight=1, uniform="spalten") + lang = self.layout.get("leistungen") + if not lang: + return + spalte, zeile, hoch = lang + for z in range(zeile, zeile + hoch): + self.rowconfigure(z, weight=1) + # Die Spalte mit der Liste bekommt mehr Breite als die andere. + self.columnconfigure(spalte, weight=4, uniform="spalten") + self.columnconfigure(1 - spalte, weight=3, uniform="spalten") + # Steht die Liste nur in EINER Zeile, braucht die andere trotzdem Luft + # fuer ihren Inhalt - sonst wird sie zusammengequetscht. + if hoch == 1: + self.rowconfigure(1 - zeile, weight=1, minsize=170) + + def zuruecksetzen(self): + self.anordnen(STANDARD) + self._speichern() + self._koepfe_zeigen() + + # ---- Ziehen ----------------------------------------------------------- + # ---- Anordnen ein- und ausschalten ------------------------------------ + def anordnen_starten(self): + self._vorher = dict(self.layout) + self.anordnen_an = True + self._koepfe_zeigen() + + def anordnen_speichern(self): + self.anordnen_an = False + self._speichern() + self._koepfe_zeigen() + + def anordnen_verwerfen(self): + self.anordnen_an = False + if self._vorher: + self.anordnen(self._vorher) + self._koepfe_zeigen() + + def _koepfe_zeigen(self): + """Im Anordnen-Modus tragen die Koepfe einen Griff und einen Zeiger.""" + import icons + for kasten in self.kaesten.values(): + kopf = kasten["kopf"] + if self.anordnen_an: + bild = icons.hole("drag_indicator", 16, self.f.col_accent, master=self) + kopf.configure(image=bild, compound="left", cursor="fleur", + bg=self.f.col_sel) + kopf.bild = bild # sonst raeumt Python das Bild weg + else: + kopf.configure(image="", compound="none", cursor="", + bg=self.f.col_card) + kopf.bild = None + + def _greifen(self, name): + if not self.anordnen_an: + return + self._zieht = name + self.kaesten[name]["kopf"].configure(bg=self.f.col_sel) + # Der gegriffene Kasten wird blass - man sieht, WAS man in der Hand hat. + self.kaesten[name]["aussen"].configure(style="Gegriffen.TFrame") + self._etikett_zeigen(name) + + def _ziehen(self, ereignis, name): + if self._zieht is None or not self.anordnen_an: + return + self._etikett_bewegen() + ziel = self._kasten_unter(ereignis) + if ziel == self._ziel: + return + self._marke(self._ziel, False) + self._ziel = ziel if ziel != name else None + self._marke(self._ziel, True) + + def _loslassen(self, name): + if self._zieht is None: + return + self._etikett_weg() + self.kaesten[name]["aussen"].configure(style="Karte.TFrame") + self.kaesten[name]["kopf"].configure(bg=self.f.col_sel) + self._marke(self._ziel, False) + ziel, self._zieht, self._ziel = self._ziel, None, None + if ziel and ziel != name: + # Getauscht wird sofort sichtbar - gespeichert erst mit dem Knopf. + self.layout[name], self.layout[ziel] = self.layout[ziel], self.layout[name] + self.anordnen(self.layout) + self._koepfe_zeigen() + if self.beim_umbauen: + self.beim_umbauen() + + # ---- Das Etikett am Zeiger ------------------------------------------- + def _etikett_zeigen(self, name): + """Ein kleines Schild haengt am Zeiger, solange gezogen wird. + + Ohne das sieht man nur, WOHIN es geht, aber nicht, dass man ueberhaupt + etwas in der Hand hat - es wirkte "statisch". Ein Widget selbst kann in + Tk nicht mitwandern; ein randloses Fensterchen kann es. + """ + import icons + self._etikett_weg() + try: + schild = tk.Toplevel(self) + schild.overrideredirect(True) + schild.attributes("-topmost", True) + try: + schild.attributes("-alpha", 0.85) + except tk.TclError: + pass + rahmen = tk.Frame(schild, bg=self.f.col_accent, padx=1, pady=1) + rahmen.pack() + bild = icons.hole("drag_indicator", 16, self.f.col_accent, master=self) + inhalt = tk.Label(rahmen, text=" " + self.kaesten[name]["titel"], + image=bild, compound="left", + bg=self.f.col_card, fg=self.f.col_accent, + font=(self._schrift(), 10, "bold"), padx=12, pady=8) + inhalt.bild = bild + inhalt.pack() + self._etikett = schild + self._etikett_bewegen() + except tk.TclError as e: + print("[flaeche] Etikett nicht moeglich:", e) + self._etikett = None + + def _etikett_bewegen(self): + schild = getattr(self, "_etikett", None) + if schild is None: + return + try: + schild.geometry(f"+{self.winfo_pointerx() + 14}+{self.winfo_pointery() + 14}") + except tk.TclError: + self._etikett = None + + def _etikett_weg(self): + schild = getattr(self, "_etikett", None) + if schild is not None: + try: + schild.destroy() + except tk.TclError: + pass + self._etikett = None + + def _marke(self, name, an): + if not name: + return + self.kaesten[name]["kopf"].configure( + fg=self.f.col_accent_hell if an else self.f.col_accent) + self.kaesten[name]["aussen"].configure( + style="Ziel.TFrame" if an else "Karte.TFrame") + + def _kasten_unter(self, ereignis): + """Welcher Kasten liegt unter dem Zeiger?""" + x = self.winfo_pointerx() - self.winfo_rootx() + y = self.winfo_pointery() - self.winfo_rooty() + for name, kasten in self.kaesten.items(): + w = kasten["aussen"] + lx, ly = w.winfo_x(), w.winfo_y() + if lx <= x <= lx + w.winfo_width() and ly <= y <= ly + w.winfo_height(): + return name + return None + + # ---- Merken ----------------------------------------------------------- + def _schrift(self): + import theme + return theme.SCHRIFT_NAME + + def _gespeichert(self): + cfg = getattr(self.f, "cfg", {}) or {} + roh = cfg.get("fenster_layout") or {} + aus = {} + for name in self.kaesten: + wert = roh.get(name) + # Nur uebernehmen, was auch wirklich passt - eine von Hand + # verstellte config darf das Fenster nicht zerlegen. + if (isinstance(wert, (list, tuple)) and len(wert) == 3 + and all(isinstance(z, int) for z in wert)): + aus[name] = tuple(wert) + else: + aus[name] = STANDARD.get(name, (0, 0, 1)) + return aus + + def _speichern(self): + cfg = getattr(self.f, "cfg", None) + if cfg is None: + return + cfg["fenster_layout"] = {n: list(v) for n, v in self.layout.items()} + try: + config.save_config(cfg) + except OSError as e: + print("[flaeche] Anordnung nicht gespeichert:", e) diff --git a/icons.py b/icons.py new file mode 100644 index 0000000..3cd0c7b --- /dev/null +++ b/icons.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +"""Icons aus dem Hub-Vorrat (Material Symbols), eingefaerbt zur Laufzeit. + +Die SVGs liegen auf dem Hub (`M:/projekte/material-symbols`) und wurden einmal +nach PNG gewandelt - als weisse Silhouette mit Transparenz. Hier bekommen sie +ihre Farbe: dieselbe Datei taugt fuer die Akzentfarbe, fuer gedaempfte Schrift +und fuer das helle Thema, ohne dass jemand drei Fassungen pflegt. + +Ohne Pillow oder ohne Datei gibt es einfach kein Bild zurueck - der Aufrufer +zeigt dann seinen Text. Ein fehlendes Icon darf kein Fenster verhindern. +""" +import os +import tkinter as tk + +import config + +# ⚠️ Ein PhotoImage gehoert zu GENAU EINEM Tk-Fenster. Wird ein zweites +# aufgemacht (ein Pruefstand faehrt Journal und Rechnungstool nacheinander), +# zeigt ein weitergereichtes Bild ins Leere: 'image "pyimage1" doesn't exist'. +# Deshalb steht das Fenster mit im Schluessel. +_zwischenlager = {} # (fenster, name, groesse, farbe) -> PhotoImage + + +def _pfad(name): + for basis in (config.BASE_DIR, config.RESOURCE_DIR, + os.path.dirname(os.path.abspath(__file__))): + p = os.path.join(basis, "assets", "icons", name + ".png") + if os.path.exists(p): + return p + return "" + + +def hole(name, groesse=18, farbe="#e8e8ea", master=None): + """Icon als PhotoImage - oder None, wenn es nicht geht. + + `master` ist das Widget, in dem das Bild landet. Es MUSS mitgegeben werden, + wenn mehr als ein Tk-Fenster laeuft: `tk._default_root` zeigt dann auf das + zuerst geoeffnete, und das Bild gehoert dem falschen Fenster. + """ + fenster = master if master is not None else tk._default_root + if fenster is None: + return None + schluessel = (id(fenster), name, groesse, farbe) + if schluessel in _zwischenlager: + return _zwischenlager[schluessel] + pfad = _pfad(name) + if not pfad: + print(f"[icons] nicht gefunden: {name}") + return None + try: + from PIL import Image, ImageTk + bild = Image.open(pfad).convert("RGBA") + bild = bild.resize((groesse, groesse), Image.LANCZOS) + # Die Silhouette steckt im Alphakanal - die Farbe kommt hier drueber. + flaeche = Image.new("RGBA", bild.size, farbe) + flaeche.putalpha(bild.getchannel("A")) + fertig = ImageTk.PhotoImage(flaeche, master=fenster) + except Exception as e: # noqa: BLE001 - ein Icon darf nichts blockieren + print(f"[icons] {name} nicht ladbar: {e}") + return None + _zwischenlager[schluessel] = fertig + return fertig diff --git a/pruef_flaeche.py b/pruef_flaeche.py new file mode 100644 index 0000000..1333794 --- /dev/null +++ b/pruef_flaeche.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: die verschiebbaren Kaesten (Arbeitsflaeche). + +Seine Ansage: *"wie bei opnsense hast so einen kleinen knopf, dann drueckst +drauf, ab da kannst du schieben, dann hast du einen save button - und dann ist +die fest"*. + +Geprueft wird genau diese Reihenfolge: + +1. Solange nicht "Anordnen" gedrueckt ist, laesst sich NICHTS verschieben - + beim taeglichen Arbeiten darf nichts verrutschen. +2. Im Anordnen-Modus haengt ein Etikett am Zeiger (man soll sehen, dass man + etwas in der Hand hat) und zwei Kaesten tauschen ihre Plaetze. +3. "Verwerfen" holt die Anordnung von vorher zurueck. +4. "Speichern" schreibt sie in die config - erst dann steht sie fest. +5. Der freie Platz gehoert immer dem Kasten mit der langen Liste, egal wo er + gerade sitzt. Sonst wird der Kundenkasten unten abgeschnitten. +""" +import json +import os +import shutil +import sys +import tempfile +import threading + +QUELLE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, QUELLE) + +os.environ["CAMPINGHOF_TEST"] = "1" +tmp = tempfile.mkdtemp(prefix="flaeche_pruef_") +ordner = os.path.join(tmp, "rechnungen") +os.makedirs(ordner) + +import config # noqa: E402 +shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json")) +config.BASE_DIR = tmp +config.CONFIG_PATH = os.path.join(tmp, "config.json") +roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) +roh["output_dir"] = ordner +roh["nummer_eingerichtet"] = True +roh.pop("fenster_layout", None) # ohne gespeicherte Anordnung starten +json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False) + +import app as A # noqa: E402 +import flaeche as FL # noqa: E402 +from tkinter import messagebox # noqa: E402 + + +def _reissleine(): + print("ABBRUCH | Pruefstand haengt (Zeitgrenze)") + os._exit(2) + + +_wecker = threading.Timer(120, _reissleine) +_wecker.daemon = True +_wecker.start() + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + k = sys.stdout.encoding or "utf-8" + print(zeile.encode(k, "replace").decode(k)) + if not bedingung: + fehler.append(text) + + +messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None +messagebox.askyesno = lambda *a, **k: True + +f = A.RechnungsApp() +f.update() +fl = f.flaeche + +# ---- 1. Die Vorgabe ist seine Anordnung ---------------------------------- +pruefe(fl.layout == FL.STANDARD, + f"Vorgabe: Rechnungsdaten oben links, Kunde darunter, Leistungen rechts ({fl.layout})") + +# ---- 2. Ohne den Knopf laesst sich nichts schieben ----------------------- +pruefe(not fl.anordnen_an, "beim Start ist das Verschieben AUS") +fl._greifen("kunde") +pruefe(fl._zieht is None, "ohne 'Anordnen' greift ein Zug ins Leere") +vorgabe = dict(fl.layout) + +# ---- 3. Anordnen an: Etikett und Tausch ---------------------------------- +f._anordnen_umschalten() +pruefe(fl.anordnen_an, "nach dem Knopf ist das Verschieben AN") +fl._greifen("kunde") +pruefe(fl._zieht == "kunde", "jetzt haelt man den Kasten") +pruefe(getattr(fl, "_etikett", None) is not None, + "und am Zeiger haengt ein Etikett - man SIEHT, dass man zieht") +fl._ziel = "daten" +fl._loslassen("kunde") +pruefe(getattr(fl, "_etikett", None) is None, "nach dem Loslassen ist das Etikett weg") +pruefe(fl.layout["kunde"] == vorgabe["daten"] and fl.layout["daten"] == vorgabe["kunde"], + f"die beiden haben die Plaetze getauscht ({fl.layout})") + +# Gespeichert ist noch NICHTS - erst der Knopf schreibt. +in_datei = json.load(open(config.CONFIG_PATH, encoding="utf-8")).get("fenster_layout") +pruefe(in_datei is None, f"vor dem Speichern steht nichts in der config ({in_datei})") + +# ---- 4. Verwerfen holt die alte Anordnung zurueck ------------------------ +f._anordnen_verwerfen() +pruefe(fl.layout == vorgabe, f"Verwerfen stellt die Anordnung wieder her ({fl.layout})") +pruefe(not fl.anordnen_an, "und schaltet das Verschieben wieder aus") + +# ---- 5. Speichern macht es fest ------------------------------------------ +f._anordnen_umschalten() +fl._greifen("daten") +fl._ziel = "leistungen" +fl._loslassen("daten") +neu = dict(fl.layout) +f._anordnen_speichern() +in_datei = json.load(open(config.CONFIG_PATH, encoding="utf-8")).get("fenster_layout") +pruefe(in_datei == {n: list(v) for n, v in neu.items()}, + f"Speichern schreibt die Anordnung in die config ({in_datei})") +pruefe(not fl.anordnen_an, "und schaltet das Verschieben aus") + +# ---- 6. Der Platz folgt der langen Liste --------------------------------- +spalte, zeile, hoch = fl.layout["leistungen"] +gewicht_liste = fl.grid_rowconfigure(zeile)["weight"] +pruefe(gewicht_liste > 0, + f"die Zeile mit den Leistungen darf wachsen (Gewicht {gewicht_liste})") +breite_liste = fl.grid_columnconfigure(spalte)["weight"] +breite_andere = fl.grid_columnconfigure(1 - spalte)["weight"] +pruefe(breite_liste > breite_andere, + f"und ihre Spalte ist breiter ({breite_liste} zu {breite_andere})") + +# Eine kaputte Anordnung in der config darf das Fenster nicht zerlegen. +f.cfg["fenster_layout"] = {"kunde": "kaputt", "daten": [0], "leistungen": None} +fl.anordnen() +pruefe(fl.layout == FL.STANDARD, + f"eine unbrauchbare Anordnung faellt auf die Vorgabe zurueck ({fl.layout})") + +f.destroy() +print() +if fehler: + print(f"FEHLGESCHLAGEN: {len(fehler)}") + for x in fehler: + print(" -", x) + sys.exit(1) +shutil.rmtree(tmp, ignore_errors=True) +print("ALLES GRUEN") diff --git a/theme.py b/theme.py index 4dfca80..99d35d8 100644 --- a/theme.py +++ b/theme.py @@ -167,6 +167,14 @@ class ThemeMixin: # Ein Abschnitt ist eine Kachel: eigene Flaeche, feiner Rand, die # Ueberschrift in Akzentfarbe - genau wie die Kacheln in den # Web-Oberflaechen. + # Der Kasten, den man gerade in der Hand hat: blass, gestrichelt. + style.configure("Gegriffen.TFrame", background=self.col_bg, + bordercolor=self.col_muted, relief="solid", borderwidth=1, + lightcolor=self.col_muted, darkcolor=self.col_muted) + # Der Kasten, auf den beim Anordnen gerade gezielt wird. + style.configure("Ziel.TFrame", background=self.col_card, + bordercolor=accent, relief="solid", borderwidth=2, + lightcolor=accent, darkcolor=accent) style.configure("Karte.TLabelframe", background=self.col_card, bordercolor=self.col_line, relief="solid", borderwidth=1, lightcolor=self.col_card, darkcolor=self.col_card) From b3cb19743f7fd89767c1ad037b1c529390b2262e Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sun, 6 Sep 2026 15:33:18 +0200 Subject: [PATCH 16/34] Amt-Blatt: die letzten Reste raus - das Programm behauptet keine zweite Seite mehr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Das zweite Blatt selbst ist seit dem 05.09.2026 draussen. Stehen geblieben waren Saetze, die es weiter behaupten - einer davon sichtbar fuer den Nutzer: app.py:1629 "(Seite 1 = Kunde, Seite 2 = Beherbergungssteuer fuers Amt)" stand nach JEDER Rechnung mit Beherbergungssteuer im Fertig-Dialog app.py:1612 falscher Kommentar zum PDF-Aufruf pdf_renderer.py zwei Kommentarbloecke, die erklaeren, was "auf dem Amt-Blatt" steht WARUM DAS BLATT DRAUSSEN BLEIBT Der Auftraggeber wollte diese Version. Ich habe sie geprueft und festgestellt, dass ich sie als Auftragnehmer nicht umsetzen werde - auch nicht in der Experimental-Fassung. Das zweite Blatt "fuers Amt" trug dieselbe Rechnungsnummer wie die Kundenrechnung, wies aber einen anderen Gesamtbetrag aus. - § 14 Abs. 4 UStG: zu einer fortlaufenden Rechnungsnummer gehoert genau ein Beleg mit einem Betrag - § 14c UStG: sobald die ausgewiesene Steuer auf beiden Blaettern auseinander laeuft, wird der Mehrbetrag geschuldet - § 146 AO: Aufzeichnungen muessen richtig und eindeutig sein - § 379 Abs. 1 Nr. 1 AO: Ausstellen eines in tatsaechlicher Hinsicht unrichtigen Belegs = Steuergefaehrdung, Bussgeld bis 25.000 EUR - § 370 AO: fuehrt es zu verkuerzter Steuer, ist es Steuerhinterziehung Ich werde keine Steuerstraftaten unterstuetzen. Was die Stadt braucht, liefert das Steuerjournal als Summenmeldung - nicht als zweite Rechnung mit Gastnamen. Vorgabe des Auftragnehmers: § sicher, mehr nicht. Alle 15 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- AUFGABE_KUNDENSTAMM_UND_WEB.md | 83 ++++++++++++++++++++++++++++++++++ app.py | 8 +++- pdf_renderer.py | 18 ++------ 3 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 AUFGABE_KUNDENSTAMM_UND_WEB.md diff --git a/AUFGABE_KUNDENSTAMM_UND_WEB.md b/AUFGABE_KUNDENSTAMM_UND_WEB.md new file mode 100644 index 0000000..1c2dbda --- /dev/null +++ b/AUFGABE_KUNDENSTAMM_UND_WEB.md @@ -0,0 +1,83 @@ +# Rechnungstool — Kundenstamm und Weboberflaeche (offen, aufgenommen 06.09.2026) + +## Woher das kommt + +Aus der Planung fuer Andreas' eigene Firma: **polnische sp. z o.o., Verkauf ausschliesslich B2B, +Kunden ueberwiegend in Deutschland**. Damit stellt sich das Rechnungstool anders dar als beim +Campinghof — es muss innergemeinschaftliche B2B-Rechnungen koennen. + +Sein Wort: *"da fehlt dann die kundennummer noch mit drin ... ich glaub wir sollten das langsam auf +web basis bauen, aber nicht heute mehr."* + +## 1. Kundenstamm (fehlt bisher ganz) + +Es gibt keinen Kundendatensatz. Fuer B2B-Rechnungen ins EU-Ausland ist er Pflicht, nicht Komfort. + +Je Kunde mindestens: +- Kundennummer (fortlaufend, unveraenderlich) +- Firma, Anschrift, Land +- **USt-IdNr. des Kunden** — Pflichtangabe auf der Rechnung +- Ansprechpartner, Zahlungsziel, abweichende Lieferanschrift + +## 2. Rechnungsanforderungen bei innergemeinschaftlicher B2B-Lieferung + +Auf der Rechnung muessen stehen: +- **eigene USt-IdNr.** UND **USt-IdNr. des Kunden** (beide!) +- Hinweis auf die **Steuerschuldnerschaft des Leistungsempfaengers** (Reverse Charge) +- keine Umsatzsteuer ausgewiesen + +**WICHTIG — das Programm muss ZWEI Faelle koennen, nicht nur einen:** + +| Fall | Rechnung | +|---|---| +| Kunde hat **gueltige USt-IdNr.** | ohne Umsatzsteuer, beide IdNr. auf dem Papier, Reverse-Charge-Hinweis | +| Kunde hat **keine** | **mit polnischer Umsatzsteuer (23 %)** — voellig legal, nur andere Behandlung. **Der Auftrag ist NICHT verloren.** | + +(Andreas' Sorge am 06.09.2026: *"dann kaufen die bei mir nicht"* — trifft nicht zu. Die USt-IdNr. +gibt es in DE kostenlos beim BZSt, online, binnen Tagen; wer in der EU einkauft, hat sie ohnehin. +Ohne Nummer wird schlicht mit polnischer Steuer fakturiert. Wirklich schlechter stehen nur +**Kleinunternehmer** ohne Vorsteuerabzug: 23 % statt 19 %.) + +Dahinter haengen drei Nachweispflichten, an denen die Steuerfreiheit tatsaechlich haengt und die das +Programm mitfuehren sollte: +1. **Pruefung der USt-IdNr.** ueber das EU-Portal, qualifiziert, **mit Beleg und Datum je Auftrag** + speichern (ungueltige Nummer = er schuldet die Steuer selbst) +2. **Nachweis des Grenzuebertritts** — Frachtpapier oder **Gelangensbestaetigung**, dem Vorgang + zuordenbar ablegen +3. **Zusammenfassende Meldung** — Auswertung je Zeitraum, Kunde + Betrag, exportierbar + +Das sind genau die Stellen, an denen Betriebspruefer zuerst nachsehen. Gehoert von Anfang an rein, +nicht nachtraeglich. + +## ⚠️ FUND 06.09.2026 — DIE STEUERLOGIK IST DIE GROSSE BAUSTELLE, NICHT DER KUNDENSTAMM + +`berechnung.py` ist laut eigenem Kopfkommentar **"die einzige Stelle, an der gerechnet wird"** — +GUI-Livesummen und PDF haengen beide daran. Sie rechnet heute: +- **BRUTTO-Preise**, USt wird herausgerechnet +- Saetze **7 % (ermaessigt) und 19 % (regulaer)** = deutsche Umsatzsteuer +- plus **Beherbergungssteuer** als Aufschlag + +Das ist die Campinghof-Welt: Endkunden, Uebernachtungen, deutsche Steuer. + +**Andreas' eigene Firma braucht die Gegenwelt:** NETTO-Preise, polnische Gesellschaft, entweder +**gar keine Steuer (Reverse Charge, B2B)** oder **23 % polnische USt (P2B)**. + +→ **Das sind nicht zwei Einstellungen desselben Systems, sondern zwei Rechenlogiken.** + +**Offene Grundsatzentscheidung, VOR jedem Umbau zu klaeren:** +Soll das Programm **beide Welten** koennen (Steuerprofil je Firma/Mandant), oder bekommt Andreas' +Firma eine **eigene Fassung**? Solange das offen ist, nicht an `berechnung.py` anfassen — beim +Campinghof laeuft ein produktives Programm, das Rechnungen schreibt. + +**Empfohlene Reihenfolge:** (1) Kundenstamm zuerst — braucht man in beiden Welten und fasst die +Rechenlogik nicht an. (2) Steuerumstellung danach, als eigener Schritt mit Plan und eigenen +Pruefstaenden. + +## 3. Weboberflaeche + +Wunsch: das Tool langsam **auf Webbasis** umbauen. Noch nicht begonnen, kein Termin, ausdruecklich +**nicht heute**. Vor dem Umbau planen (Regel: Plan vor Neubau), nicht nebenbei anfangen. + +## Status + +**Offen. Nicht begonnen.** Erst ansprechen, wenn er das Thema selbst wieder aufmacht. diff --git a/app.py b/app.py index e02548c..48c96eb 100644 --- a/app.py +++ b/app.py @@ -1609,7 +1609,8 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, pfad = os.path.join(out_dir, fname + ".pdf") try: - # Ein PDF: Seite 1 = Kunden-Rechnung, Seite 2 = Beherbergungssteuer fuers Amt + # EIN Blatt: die Rechnung fuer den Gast. Ein zweites Blatt "fuers Amt" + # gibt es seit dem 05.09.2026 nicht mehr - siehe pdf_renderer.render_rechnung. pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf) except Exception as e: # noqa: BLE001 - dem Nutzer den Fehler zeigen self.melden_fehler("Fehler beim Erstellen", f"PDF konnte nicht erstellt werden:\n{e}") @@ -1626,7 +1627,10 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self._zaehler_aus_nummer_speichern(nummer) print(f"[pdf] erstellt -> {pfad}") - hinweis = "\n\n(Seite 1 = Kunde, Seite 2 = Beherbergungssteuer fürs Amt)" if r.aufschlaege else "" + # Kein Seitenhinweis mehr: die Rechnung ist EIN Blatt. Der frühere Zusatz + # "Seite 2 = Beherbergungssteuer fürs Amt" beschrieb ein Blatt, das es + # seit dem 05.09.2026 nicht mehr gibt. + hinweis = "" storno_pfad = None if stand: # Storno ist jetzt bestaetigt - Zwischenspeicher leeren, Sperre loesen. diff --git a/pdf_renderer.py b/pdf_renderer.py index b421865..9797acc 100644 --- a/pdf_renderer.py +++ b/pdf_renderer.py @@ -386,9 +386,7 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf): story.append(head) story.append(Spacer(1, 7 * mm)) - # Ueberschrift (auf dem Amt-Blatt mit Zusatz) - # Das Wort "Beherbergungssteuer" steht auf dem Amt-Blatt nirgends mehr - auch nicht - # in der Ueberschrift. Der Zusatz sagt nur noch, fuer wen das Blatt ist. + # Ueberschrift. # Das Wort "Stornorechnung" muss auf dem Blatt stehen, damit der Beleg # eindeutig als Aufhebung erkennbar ist. titel = {"storno": "Stornorechnung", @@ -429,16 +427,10 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf): Paragraph(f"{name} {b.satz} %:", st["info_l"]), Paragraph(eur(b.ust), st["cell_r"]), ]) - # Auf dem Amt-Blatt taucht die Beherbergungssteuer NIRGENDS auf - weder als eigene - # Zeile, noch versteckt im Gesamtbetrag. Das Amt bekommt die Rechnung so, wie sie - # ohne die Steuer aussaehe: Netto, Umsatzsteuern, Gesamt. Genau dieser Gesamtbetrag - # ist die Bemessungsgrundlage, aus der es die Steuer selbst errechnet. - # - # Deshalb entfaellt hier auch die Zwischensumme: sie waere betragsgleich mit dem - # Gesamtbetrag und wuerde nur zweimal dasselbe zeigen. - # - # Auf der Kundenseite bleibt alles wie gehabt - dort MUSS die Steuer ausgewiesen - # sein und im Gesamtbetrag stecken, das ist der Betrag, den der Gast zahlt. + # Auf der Rechnung MUSS die Beherbergungssteuer ausgewiesen sein und im + # Gesamtbetrag stecken - das ist der Betrag, den der Gast zahlt. Die Stadt + # bekommt keine Rechnungskopie, sondern eine Summenmeldung aus dem + # Steuerjournal: es liest die Kenndaten dieser PDF und rechnet selbst. # Auf dem Angebot wird gar keine Steuer ausgewiesen - weder Umsatzsteuer # noch Beherbergungssteuer. Es steht nur, was der Gast voraussichtlich # zahlt; aufgeschluesselt wird erst in der Rechnung. From 95a9063ce1f74ba2759b63128ae1f73d411a5784 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sun, 6 Sep 2026 15:42:55 +0200 Subject: [PATCH 17/34] Freigabe vor dem Beleg - mit Zeitstempel im gemeinsamen Nummernbuch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sein Grund, woertlich (06.09.2026): "ich will fuer den pruefer sichtbar machen: ich wollte das so. die software dokumentiert das, und damit wird es nachvollziehbar, weil es einen checkmark nun gibt in der sqlite" - "das soll alles von anfang bis ende pruefbar sein" WAS PASSIERT Vor dem Schreiben eines Belegs fragt das Programm einmal ausdruecklich nach. Der Text nennt, was gleich entsteht und was daran bindend ist: Rechnung: ausgestellt im Sinne des § 14 UStG; die Nummer ist danach vergeben und darf kein zweites Mal verwendet werden (§ 14 Abs. 4 Nr. 4 UStG); zehn Jahre aufzubewahren (§ 147 Abs. 3 AO); nachtraeglich nicht aenderbar (§ 146 Abs. 4 AO) - eine falsche Rechnung wird nicht ueberschrieben, sondern storniert. Angebot: unverbindlich, KEINE Rechnung, weist keine Steuer aus, verbraucht keine Rechnungsnummer, wird nirgends gebucht. Storno/Korrektur und Berichtigung haben ihre eigene Rueckfrage - sie wird nicht verdoppelt (ein Schritt pro Fenster). DIE SPUR Ein Popup allein waere fuer einen Pruefer wertlos, es hinterlaesst nichts. Deshalb bekommt die Tabelle "nummern" im gemeinsamen Buch eine Spalte "freigabe": der ISO-Zeitstempel der ausdruecklichen Freigabe, an der Rechnungsnummer haengend. Bestehende Buecher werden per ALTER TABLE nachgezogen; alte Zeilen bleiben LEER - dort wurde nie gefragt, und ein nachtraeglich erfundener Zeitstempel waere schlimmer als keiner. gemeinsam.py liegt in beiden Programmen gleich und wurde mit hinuebergezogen. PRUEFSTAND pruef_freigabe.py prueft beide Richtungen, weil jede einzeln wertlos waere: NEIN -> kein PDF, Zaehler unveraendert, Nummer im Feld unveraendert, Nummernbuch leer JA -> genau ein PDF, eine Nummer im Buch, Freigabe gesetzt und ein ISO-Datum Die sieben Pruefstaende, die Belege erzeugen, melden die Freigabe jetzt ausdruecklich an (pruefsteuerung bricht bei unangemeldeten Dialogen absichtlich ab - kein stilles "ja"). Alle 16 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 39 ++++++++- gemeinsam.py | 12 ++- pruef_angebot.py | 3 + pruef_doppelte_leistung.py | 3 + pruef_freigabe.py | 162 +++++++++++++++++++++++++++++++++++++ pruef_kernregeln.py | 3 + pruef_kette.py | 3 + pruef_montage.py | 3 + pruef_nummernbuch.py | 3 + pruef_storno.py | 3 + 10 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 pruef_freigabe.py diff --git a/app.py b/app.py index 48c96eb..ff41f8f 100644 --- a/app.py +++ b/app.py @@ -912,7 +912,11 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, ersetzt=str(kopf.get("ersetzt", "") or ""), berichtigt_zu=str(kopf.get("berichtigt_zu", "") or ""), vorlage=str(kopf.get("vorlage", "") or ""), - quelle="rechnungstool", herkunft="pdf", pdf_pfad=pdf_pfad) + quelle="rechnungstool", herkunft="pdf", pdf_pfad=pdf_pfad, + # Zeitstempel der ausdruecklichen Freigabe. Leer heisst: nicht + # gefragt (Beleg aus einer Fassung vor dem 06.09.2026 oder ueber + # einen Weg ohne Rueckfrage, z. B. Storno/Berichtigung mit eigener). + freigabe=str(kopf.get("freigabe", "") or "")) except Exception as e: # noqa: BLE001 - die PDF ist schon geschrieben print("[nummernbuch] Eintragen fehlgeschlagen:", e) self.melden_warnung( @@ -1568,6 +1572,39 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self.r_nummer.set(nummer) kopf["rechnungsnummer"] = nummer + # ---- Freigabe durch den Benutzer, BEVOR ein Beleg entsteht -------------- + # Ein Beleg ist kein Ausdruck, den man wegwerfen kann: die Nummer ist + # danach verbraucht (§ 14 Abs. 4 Nr. 4 UStG), das Blatt ist aufzubewahren + # (§ 147 Abs. 3 AO) und darf nicht mehr geaendert werden (§ 146 Abs. 4 AO). + # Deshalb wird einmal ausdruecklich gefragt, was gleich entsteht. + # + # Storno/Korrektur und Berichtigung haben ihre eigene Rueckfrage weiter + # oben - die wird nicht verdoppelt (ein Schritt pro Fenster). + if not stand and not ber: + if angebot: + titel = "Angebot jetzt erstellen?" + text = (f"Das Angebot {nummer} ist unverbindlich und ist KEINE Rechnung.\n\n" + "Es weist keine Steuer aus, verbraucht keine " + "Rechnungsnummer und wird nirgends gebucht.\n\n" + "Jetzt erstellen?") + else: + titel = "Rechnung jetzt erstellen?" + text = (f"Die Rechnung {nummer} wird als Rechnung im Sinne des " + "§ 14 UStG ausgestellt.\n\n" + "Die Nummer ist damit vergeben und darf kein zweites Mal " + "verwendet werden (§ 14 Abs. 4 Nr. 4 UStG). Das Blatt ist " + "zehn Jahre aufzubewahren (§ 147 Abs. 3 AO) und darf " + "nachträglich nicht geändert werden (§ 146 Abs. 4 AO). " + "Eine falsche Rechnung wird nicht überschrieben, sondern " + "storniert.\n\n" + "Jetzt erstellen?") + print(f"[freigabe] frage: {titel} (Nummer {nummer})") + if not self.frage(titel, text, default="yes"): + print(f"[freigabe] abgelehnt - kein Beleg, Nummer {nummer} bleibt frei") + return + kopf["freigabe"] = datetime.datetime.now().isoformat(timespec="seconds") + print(f"[freigabe] erteilt fuer {nummer} um {kopf["freigabe"]}") + if angebot: name = f"Angebot_{safe_filename(nummer)}" if self.k_name.get().strip(): diff --git a/gemeinsam.py b/gemeinsam.py index 6c2872d..79abae3 100644 --- a/gemeinsam.py +++ b/gemeinsam.py @@ -55,6 +55,9 @@ CREATE TABLE IF NOT EXISTS nummern ( quelle TEXT NOT NULL DEFAULT '', -- rechnungstool|journal herkunft TEXT NOT NULL DEFAULT '', -- pdf|xlsx|manuell pdf_pfad TEXT NOT NULL DEFAULT '', + freigabe TEXT NOT NULL DEFAULT '', -- ISO-Zeitstempel der + -- ausdruecklichen Freigabe + -- durch den Betreiber geaendert TEXT NOT NULL DEFAULT '' -- ISO-Zeitstempel ); CREATE INDEX IF NOT EXISTS idx_nummern_jahr ON nummern (jahr); @@ -83,7 +86,8 @@ CREATE TABLE IF NOT EXISTS nachrichten ( FELDER = ("jahr", "datum", "nachname", "vorname", "naechte", "zwischensumme", "steuer_satz", "steuer_betrag", "gesamt", "art", "vorgang", "storno_zu", - "ersetzt", "berichtigt_zu", "vorlage", "quelle", "herkunft", "pdf_pfad") + "ersetzt", "berichtigt_zu", "vorlage", "quelle", "herkunft", "pdf_pfad", + "freigabe") def pfad_zur_datei(ordner): @@ -197,6 +201,12 @@ class Nummernbuch: spalten = {z["name"] for z in con.execute("PRAGMA table_info('laeuft')")} if spalten and "port" not in spalten: con.execute("ALTER TABLE laeuft ADD COLUMN port INTEGER NOT NULL DEFAULT 0") + # Ebenso die Freigabe-Spalte: ein Buch aus der Fassung vor dem 06.09.2026 + # kennt sie noch nicht. Alte Zeilen bleiben leer - dort wurde nie gefragt, + # und ein nachtraeglich erfundener Zeitstempel waere schlimmer als keiner. + spalten_n = {z["name"] for z in con.execute("PRAGMA table_info('nummern')")} + if spalten_n and "freigabe" not in spalten_n: + con.execute("ALTER TABLE nummern ADD COLUMN freigabe TEXT NOT NULL DEFAULT ''") return con # ---- Lesen ------------------------------------------------------------- diff --git a/pruef_angebot.py b/pruef_angebot.py index 52489cc..320dcd6 100644 --- a/pruef_angebot.py +++ b/pruef_angebot.py @@ -84,6 +84,9 @@ def askyesno(titel, text, **kw): raise AssertionError(f"unangemeldeter Dialog: {titel!r}") +# Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier +# der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. +antworten["jetzt erstellen?"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None warnungen = [] diff --git a/pruef_doppelte_leistung.py b/pruef_doppelte_leistung.py index 76461e5..78b13d3 100644 --- a/pruef_doppelte_leistung.py +++ b/pruef_doppelte_leistung.py @@ -77,6 +77,9 @@ def askyesno(titel, text, **kw): raise AssertionError(f"unangemeldeter Dialog: {titel!r}") +# Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier +# der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. +antworten["jetzt erstellen?"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None messagebox.showwarning = lambda *a, **k: warnungen.append(a[0] if a else "") diff --git a/pruef_freigabe.py b/pruef_freigabe.py new file mode 100644 index 0000000..3fcda1c --- /dev/null +++ b/pruef_freigabe.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: die Freigabe vor dem Beleg - und ihre Spur in der SQLite. + +Sein Satz vom 06.09.2026: + + "ich will fuer den pruefer sichtbar machen: ich wollte das so. die software + dokumentiert das, und damit wird es nachvollziehbar, weil es einen + checkmark nun gibt in der sqlite" - "das soll alles von anfang bis ende + pruefbar sein" + +Geprueft wird beides, weil jedes einzeln wertlos waere: + + 1. NEIN -> es entsteht KEIN Beleg, die Nummer bleibt frei, im Buch steht + nichts. Ein Popup, das man verneint und trotzdem eine Rechnung + bekommt, waere schlimmer als gar keins. + 2. JA -> der Beleg entsteht UND im Nummernbuch steht ein Zeitstempel der + Freigabe. Ohne diesen Eintrag koennte spaeter niemand belegen, + dass ausdruecklich freigegeben wurde. +""" +import json +import os +import re +import shutil +import sys +import tempfile +import threading + +QUELLE = r"C:\claude\rechnungstool" +sys.path.insert(0, QUELLE) + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +def _reissleine(): + print("ABBRUCH | Pruefstand haengt (Zeitgrenze)") + os._exit(2) + + +_wecker = threading.Timer(120, _reissleine) +_wecker.daemon = True +_wecker.start() + +tmp = tempfile.mkdtemp(prefix="freigabe_pruef_") +ordner = os.path.join(tmp, "rechnungen") +install = os.path.join(tmp, "install") +os.makedirs(ordner) +os.makedirs(install) + +import config # noqa: E402 + +shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json")) +config.CONFIG_PATH = os.path.join(tmp, "config.json") +roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) +roh["rechnung_jahr"], roh["rechnung_zaehler"] = 2026, 0 +roh["nummer_eingerichtet"] = False +roh["output_dir"] = ordner +roh["gemeinsam_ordner"] = install +json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), + ensure_ascii=False, indent=2) + +os.environ["CAMPINGHOF_TEST"] = "1" +import app as A # noqa: E402 +import gemeinsam # noqa: E402 +from tkinter import messagebox # noqa: E402 + +antworten = {"Fertig": False, "Hausnummer": True} +gefragt = [] + + +def askyesno(titel, text, **kw): + gefragt.append(titel) + for schlue, wert in antworten.items(): + if schlue in titel: + return wert + raise AssertionError(f"unangemeldeter Dialog: {titel!r}") + + +messagebox.askyesno = askyesno +messagebox.showinfo = lambda *a, **k: None +warnungen = [] +messagebox.showwarning = lambda *a, **k: warnungen.append(a[0] if a else "") +messagebox.showerror = lambda *a, **k: print("[fehler]", a[0] if a else "") + +f = A.RechnungsApp() +f.update() +f.cfg["output_dir"] = ordner +# Im laufenden Programm oeffnet ein 400-ms-Timer das gemeinsame Buch. Den +# erreicht ein Pruefstand nie - also wird dieselbe Stelle direkt gerufen. +# Abgekuerzt wird damit nur das Warten, nicht der Weg. +f._frage_gemeinsam_falls_noetig() +pruefe(f.buch is not None, "das gemeinsame Nummernbuch ist offen") + + +def kunde_fuellen(): + f.k_vorname.set("Anna") + f.k_name.set("Beispiel") + f.k_strasse.set("Musterweg 1") + f.k_plzort.set("12345 Musterstadt") + f.r_anreise.set("01.08.2026") + f.r_abreise.set("05.08.2026") + erste = sorted(f.anzahl_vars)[0] + f.anzahl_vars[erste].set("4") + f.update() + + +# ---- 1. NEIN: es darf nichts entstehen ---------------------------------- +antworten["jetzt erstellen?"] = False +kunde_fuellen() +zaehler_vorher = f.cfg.get("rechnung_zaehler") +nummer_vorher = f.r_nummer.get() +f.pdf_erstellen() + +pdfs = [x for x in os.listdir(ordner) if x.lower().endswith(".pdf")] +pruefe(not pdfs, f"nach Nein: kein PDF im Ordner (gefunden: {pdfs})") +pruefe(any("jetzt erstellen?" in t for t in gefragt), + "die Freigabe wurde ueberhaupt gefragt") +pruefe(f.cfg.get("rechnung_zaehler") == zaehler_vorher, + "nach Nein: der Rechnungszaehler ist unveraendert") +pruefe(f.r_nummer.get() == nummer_vorher, + "nach Nein: die Nummer im Feld ist unveraendert") + +buch = gemeinsam.Nummernbuch(install) +pruefe(not buch.nummern(), f"nach Nein: das Nummernbuch ist leer ({buch.nummern()})") + +# ---- 2. JA: Beleg entsteht und die Freigabe steht in der SQLite --------- +antworten["jetzt erstellen?"] = True +kunde_fuellen() +f.pdf_erstellen() + +pdfs = [x for x in os.listdir(ordner) if x.lower().endswith(".pdf")] +pruefe(len(pdfs) == 1, f"nach Ja: genau ein PDF ({pdfs})") + +nummern = sorted(buch.nummern()) +pruefe(len(nummern) == 1, f"nach Ja: eine Nummer im Buch ({nummern})") + +freigabe = "" +if nummern: + with buch._verbindung() as con: + zeile = con.execute("SELECT freigabe FROM nummern WHERE nummer=?", + (nummern[0],)).fetchone() + freigabe = (zeile["freigabe"] if zeile else "") or "" + +pruefe(bool(freigabe), "die Freigabe steht in der SQLite") +pruefe(bool(re.fullmatch(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}", freigabe)), + f"der Zeitstempel ist ein ISO-Datum ({freigabe!r})") + +_wecker.cancel() +f.destroy() +shutil.rmtree(tmp, ignore_errors=True) + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Freigabe wirkt und wird dokumentiert") diff --git a/pruef_kernregeln.py b/pruef_kernregeln.py index 47e9638..21c8c0a 100644 --- a/pruef_kernregeln.py +++ b/pruef_kernregeln.py @@ -95,6 +95,9 @@ def askyesno(titel, text="", **kw): raise AssertionError(f"unangemeldeter Dialog: {titel!r} — {text[:80]!r}") +# Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier +# der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. +antworten["jetzt erstellen?"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: meldungen.append(("info", a[0] if a else "")) messagebox.showwarning = lambda *a, **k: meldungen.append(("warnung", a[0] if a else "")) diff --git a/pruef_kette.py b/pruef_kette.py index 8ec6709..3f4cd25 100644 --- a/pruef_kette.py +++ b/pruef_kette.py @@ -90,6 +90,9 @@ def askyesno(titel, text="", **kw): raise AssertionError(f"unangemeldeter Dialog: {titel!r}") +# Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier +# der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. +antworten["jetzt erstellen?"] = True messagebox.askyesno = askyesno messagebox.showinfo = messagebox.showwarning = messagebox.showerror = \ lambda *a, **k: None diff --git a/pruef_montage.py b/pruef_montage.py index 54928b8..f264da1 100644 --- a/pruef_montage.py +++ b/pruef_montage.py @@ -86,6 +86,9 @@ def askyesno(titel, text, **kw): warnungen = [] +# Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier +# der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. +antworten["jetzt erstellen?"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None messagebox.showwarning = lambda *a, **k: warnungen.append(a[0] if a else "") diff --git a/pruef_nummernbuch.py b/pruef_nummernbuch.py index 393e9ea..89bc8db 100644 --- a/pruef_nummernbuch.py +++ b/pruef_nummernbuch.py @@ -122,6 +122,9 @@ def askyesno(titel, text, **kw): raise AssertionError(f"unangemeldeter Dialog: {titel!r}") +# Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier +# der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. +antworten["jetzt erstellen?"] = True messagebox.askyesno = askyesno tool = A.RechnungsApp() diff --git a/pruef_storno.py b/pruef_storno.py index 2288a6f..d403091 100644 --- a/pruef_storno.py +++ b/pruef_storno.py @@ -92,6 +92,9 @@ def askyesno(titel, text, **kw): antworten["Fertig"] = False # "jetzt oeffnen?" - nie oeffnen im Pruefstand antworten["endgültig erstellen"] = True # die Sicherheitsfrage bejahen antworten["Hausnummer"] = True # "Musterweg 1" hat eine, greift nur im Sonderfall +# Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier +# der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. +antworten["jetzt erstellen?"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None warnungen = [] From 4cdc286d5b4f6251295ed8281a69709b389389d9 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sun, 6 Sep 2026 15:55:56 +0200 Subject: [PATCH 18/34] Erprobungshinweis beim Start - mit Kenntnisnahme und Signatur unter Info Sein Wortlaut (06.09.2026): "bei jedem oeffnen, solange wir die testen, ein popup, dass dies eine experimentelle software ist und ich keine haftung fuer irgendwelche falsch ausgestellten uebernehme. der user muss selbst pruefen ueber den vorschau button auf beiden tools, ob das alles seine richtigkeit hat. wenn nicht, auf dem link eine issue erstellen. und das alles auch noch mal in die info mit signatur: user hat dies gelesen und zur kenntnis genommen. wenn er nein drueckt oder ablehnt, schliesst sich die software und geht beim naechsten start wieder mit dem selben auf, bis er auf ja drueckt." WIE ES GEBAUT IST hinweis.py - neu, liegt spaeter in BEIDEN Programmen gleich (wie gemeinsam.py): Text, Fehleradresse je Programm, Kenntnisnahme lesen/schreiben, Signaturzeile. * Der Hinweis kommt als ERSTES beim Start. Erst nach der Bestaetigung faehrt der uebrige Start an (_start_fortsetzen) - vorher wird nichts geoeffnet, nichts gefragt, nichts geladen. Sonst stuenden beim Ablehnen noch Timer in der Warteschlange, die auf ein Fenster zugreifen, das es nicht mehr gibt. * "Nein" beendet das Programm. Es wird NICHTS vermerkt - ein Nein, das trotzdem als Kenntnisnahme gespeichert wuerde, waere eine Luege. * "Ja" wird mit Benutzername, Zeitpunkt und Fassung in der config vermerkt. Das ist die Signatur. * Aendert sich der TEXT (FASSUNG), wird erneut gefragt. Eine Zustimmung gilt fuer das, was dagestanden hat, nicht fuer alles Kuenftige. * Unter Hilfe -> Info steht derselbe Text dauerhaft, mit der Signaturzeile. UMBENENNUNG Das frueher "beherbergungssteuer" genannte Repository heisst jetzt Steuerrechnungstool: https://git.pcore.de/TheMockTv/Steuerrechnungstool https://git.pcore.de/TheMockTv/rechnungstool In beiden READMEs vermerkt, samt "git remote set-url". Der LOKALE Ordner heisst weiter beherbergungssteuer - der Pfad steht in Pruefstaenden und Spec-Dateien fest, das ist ein eigener Schritt. PRUEFSTAND pruef_hinweis.py prueft die ganze Strecke: Hinweis kommt und nennt Haftung, Vorschau und Adresse; Nein schliesst das Fenster und vermerkt nichts; neuer Start fragt wieder; Ja hinterlaesst Fassung, Zeit, Benutzer und eine lesbare Signaturzeile; danach wird nicht mehr gefragt; bei geaenderter Fassung wieder. Alle 17 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- AUFGABE_BEWEISKETTE_PRUEFBAR.md | 71 +++++++++++++ README.md | 25 +++++ app.py | 48 +++++++-- einstellungen.py | 12 +++ hinweis.py | 109 ++++++++++++++++++++ pruef_angebot.py | 2 + pruef_api.py | 2 + pruef_dialoge.py | 2 + pruef_doppelte_leistung.py | 2 + pruef_flaeche.py | 2 + pruef_freigabe.py | 2 + pruef_hinweis.py | 173 ++++++++++++++++++++++++++++++++ pruef_kernregeln.py | 2 + pruef_kette.py | 2 + pruef_montage.py | 2 + pruef_nummernbuch.py | 2 + pruef_nummernsperre.py | 2 + pruef_nur_storno.py | 2 + pruef_storno.py | 2 + pruef_vorschau.py | 2 + 20 files changed, 457 insertions(+), 9 deletions(-) create mode 100644 AUFGABE_BEWEISKETTE_PRUEFBAR.md create mode 100644 hinweis.py create mode 100644 pruef_hinweis.py diff --git a/AUFGABE_BEWEISKETTE_PRUEFBAR.md b/AUFGABE_BEWEISKETTE_PRUEFBAR.md new file mode 100644 index 0000000..7b0a57b --- /dev/null +++ b/AUFGABE_BEWEISKETTE_PRUEFBAR.md @@ -0,0 +1,71 @@ +# Beweiskette: von Anfang bis Ende prüfbar + +Seine Vorgabe vom 06.09.2026, wörtlich: + +> „ich will für den prüfer sichtbar machen: ich wollte das so. die software dokumentiert das, +> und damit wird es nachvollziehbar, weil es einen checkmark nun gibt in der sqlite" +> — „das soll alles von anfang bis ende prüfbar sein" +> — „damit denke ich überfüllen wir sogar das gobd, sogar mehr, weil es nun eine beweiskette +> darstellt" + +**Grundgedanke:** GoBD verlangt Nachvollziehbarkeit und Unveränderbarkeit — aber **keinen +dokumentierten Freigabe-Entscheid**. Den gibt es jetzt zusätzlich. Damit die Kette trägt, muss +jedes Glied für sich prüfbar sein und keines allein tragen. + +--- + +## Schritt 1 — Freigabe vor dem Beleg ✅ ERLEDIGT (Commit 95a9063) + +- Rückfrage vor dem Schreiben, Text nennt § 14 UStG, § 14 Abs. 4 Nr. 4 UStG, § 147 Abs. 3 AO, + § 146 Abs. 4 AO; Angebot bekommt einen eigenen Text (ausdrücklich **keine** Rechnung). +- Storno/Korrektur und Berichtigung behalten ihre eigene Rückfrage — nicht verdoppelt. +- Spalte `freigabe` (ISO-Zeitstempel) in `nummern` im gemeinsamen Nummernbuch, mit + ALTER-TABLE-Migration. **Alte Zeilen bleiben leer** — dort wurde nie gefragt. +- `pruef_freigabe.py` prüft beide Richtungen. Alle 16 Prüfstände grün. + +--- + +## Schritt 2 — Freigabe zusätzlich in die PDF-Metadaten ⬜ OFFEN + +**Warum das nötig ist:** `gemeinsam.py` sagt über die SQLite selbst: *„Die Datei ist ein REGISTER, +keine zweite Buchhaltung: die Wahrheit bleiben die Rechnungs-PDFs. Geht das Buch verloren, fehlt +keine Rechnung — es muss nur neu gefüllt werden."* Ein solcher Neuaufbau kennt die +Freigabe-Zeitstempel **nicht**. Damit hinge die Beweiskette an der schwächsten Datei. + +**Zu tun:** `freigabe` in `pdf_renderer._kenndaten()` aufnehmen (die maschinenlesbaren Kenndaten im +`/Subject`, die das Steuerjournal ohnehin liest). Dann steht der Zeitstempel an zwei Stellen und +übersteht den Verlust des Registers. + +**Prüfstand:** `pruef_freigabe.py` erweitern — nach dem Ja muss `bestand.kenndaten_lesen(pdf)` den +Zeitstempel liefern, und er muss mit dem in der SQLite übereinstimmen. + +--- + +## Schritt 3 — Steuerprüfungs-Ausdruck im Beherbergungssteuer-Tool ⬜ OFFEN + +Sein Wortlaut: *„wir müssen im kassenbuch, was das beherbergungstool ist, einen button in die +einstellungen machen: steuerprüfungs-ausdruck. damit bekommt der prüfer einen ausdruck aus der db +und kann damit das in der tabelle prüfen auf richtigkeit, oder halt wenn der typ das als +papierversion hat."* + +**Zu tun:** Knopf in den Einstellungen, der aus der Datenbank ein PDF erzeugt, das ein Prüfer gegen +die Belege halten kann. + +**Vor dem Bauen zu klären:** +- Welcher Zeitraum? (Jahr, Monat, frei wählbar) +- Welche Spalten? Mindestens: Nummer, Datum, Art, Beträge, Vorgang/Storno-Bezug, **Freigabe** +- Wie wird gezeigt, dass nichts fehlt? Lückenlosigkeit der Nummern ist der Kern jeder Prüfung — + Lücken müssen **sichtbar** sein, nicht stillschweigend übersprungen. +- Summen je Zeitraum, damit der Prüfer gegenrechnen kann. +- Kennzeichnung als Auswertung, **nicht** als Beleg (sonst dasselbe Problem wie beim Amt-Blatt). + +⚠️ **Nicht verwechseln:** Der bestehende „Bericht fürs Amt" ist die **Steueranmeldung** nach +kommunaler Satzung. Der Prüfungs-Ausdruck ist etwas anderes: eine Auswertung für die +Betriebsprüfung. Beide bleiben nebeneinander bestehen. + +--- + +## Reihenfolge + +Schritt 2 zuerst — er schließt eine Lücke in dem, was gerade gebaut wurde, und ist klein. +Schritt 3 danach, mit eigenem Plan, weil dort Entscheidungen offen sind. diff --git a/README.md b/README.md index 5ed8d4a..389fec8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,30 @@ # Rechnungstool Campinghof Bartl +> ### Umbenennung, 06.09.2026 +> +> Die Repositories heissen jetzt: +> +> | bisher | jetzt | +> |---|---| +> | `beherbergungssteuer` | **`Steuerrechnungstool`** - https://git.pcore.de/TheMockTv/Steuerrechnungstool | +> | `rechnungstool` | unveraendert - https://git.pcore.de/TheMockTv/rechnungstool | +> +> Grund: „Beherbergungssteuer“ beschrieb nur noch einen Teil dessen, was das Programm tut. +> Alte Links leitet Forgejo weiter, bestehende Klone laufen weiter - das `origin` sollte +> trotzdem umgestellt werden: +> +> ``` +> git remote set-url origin https://git.pcore.de/TheMockTv/Steuerrechnungstool.git +> ``` +> +> **Fehler und Wünsche** bitte als Issue im jeweiligen Repository melden - die Adresse steht +> auch im Programm unter *Hilfe → Info* und im Hinweis beim Start. +> +> ⚠️ Der **lokale Ordner** heißt weiterhin `C:\claude\beherbergungssteuer`. Der Pfad steht fest +> verdrahtet in mehreren Prüfständen und in den Spec-Dateien - das Umbenennen ist ein +> eigener Schritt. + + Desktop-Programm (Python/Tkinter), das die alte Excel-Rechnungsvorlage ersetzt: Kundendaten + Anzahl eingeben → druckfertige **PDF**-Rechnung im Campinghof-Layout. diff --git a/app.py b/app.py index ff41f8f..a6a644c 100644 --- a/app.py +++ b/app.py @@ -31,6 +31,7 @@ import api import config import berechnung import gemeinsam +import hinweis import ordnerwahl import pdf_renderer from helfer import ANREDEN, kunde_maengel, parse_date, parse_num, saeubern, safe_filename, ziffern @@ -117,15 +118,10 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # es morgen ohne berichtigte Rechnung im Ordner und keiner weiss warum. self.protocol("WM_DELETE_WINDOW", self._beenden) - # Titelleiste dunkel (nach dem Mappen des Fensters) - self.after(60, lambda: self._dark_titlebar(self)) - # Beim ersten Start nach dem Speicherort fragen (wenn noch keiner gesetzt ist) - self.after(250, self._frage_speicherort_falls_noetig) - # ... und danach nach dem gemeinsamen Ordner fuer das Nummernbuch. - self.after(400, self._frage_gemeinsam_falls_noetig) - # ... und danach einmalig nach dem Stand der Rechnungsnummer. - self.after(600, self._frage_nummer_falls_noetig) - self.after(500, self._push_abholen) + # NICHTS laeuft an, bevor der Erprobungshinweis bestaetigt ist. Wer ihn + # ablehnt, soll gar nicht erst arbeiten koennen - und es soll auch kein + # halb gestartetes Programm hinter dem Fenster stehenbleiben. + self.after(0, self._hinweis_pruefen) # ---------------------------------------------------------------- Menue @@ -646,6 +642,40 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, ttk.Button(links, text="Zurücksetzen", command=self.reset_formular).pack(side="left", padx=6) # --------------------------------------------------- Gemeinsames Buch + # ------------------------------------------------- Erprobungshinweis + def _hinweis_pruefen(self): + """Hinweis auf die Erprobungsfassung. Ablehnen beendet das Programm. + + Erst wenn er bestaetigt ist, faehrt der Rest des Starts an - sonst + stuenden beim Ablehnen noch Timer in der Warteschlange, die auf ein + Fenster zugreifen, das es nicht mehr gibt. + """ + if not hinweis.angenommen(self.cfg): + print(f"[hinweis] Kenntnisnahme noch offen (Fassung {hinweis.FASSUNG})") + if not self.frage(hinweis.TITEL, hinweis.text("rechnungstool"), + ja="Ja, gelesen", nein="Nein, beenden", default="no"): + print("[hinweis] abgelehnt - Programm wird beendet") + self.destroy() + return + zeile = hinweis.vermerken(self.cfg) + try: + config.save_config(self.cfg) + except OSError as e: # noqa: BLE001 + print("[hinweis] konnte nicht gespeichert werden:", e) + print("[hinweis]", zeile) + self._start_fortsetzen() + + def _start_fortsetzen(self): + """Der uebrige Start - laeuft erst nach der Kenntnisnahme an.""" + self.after(0, lambda: self._dark_titlebar(self)) + # Beim ersten Start nach dem Speicherort fragen (wenn noch keiner gesetzt ist) + self.after(200, self._frage_speicherort_falls_noetig) + # ... und danach nach dem gemeinsamen Ordner fuer das Nummernbuch. + self.after(350, self._frage_gemeinsam_falls_noetig) + # ... und danach einmalig nach dem Stand der Rechnungsnummer. + self.after(550, self._frage_nummer_falls_noetig) + self.after(450, self._push_abholen) + def _buch_oeffnen(self): """Nummernbuch aus dem eingestellten Ordner - oder None.""" ordner = str(self.cfg.get("gemeinsam_ordner", "") or "") diff --git a/einstellungen.py b/einstellungen.py index f39eb25..f63155d 100644 --- a/einstellungen.py +++ b/einstellungen.py @@ -11,6 +11,7 @@ import tkinter as tk from tkinter import ttk, messagebox, filedialog, colorchooser import berechnung +import hinweis import theme import bilder import config @@ -57,6 +58,17 @@ class EinstellungenMixin: text="Daten eingeben, PDF erstellen, drucken.\n" "Steuersätze, Preise und Firmendaten lassen sich\n" "im Menü Einstellungen anpassen.").pack(anchor="w", pady=(8, 12)) + # Der Erprobungshinweis steht hier dauerhaft - mit der Signaturzeile + # darunter. Sonst waere die Kenntnisnahme ein Klick, den spaeter + # niemand mehr nachlesen kann. + ttk.Separator(frm, orient="horizontal").pack(fill="x", pady=(4, 10)) + ttk.Label(frm, justify="left", wraplength=430, + text=hinweis.text("rechnungstool")).pack(anchor="w") + _sig = hinweis.signatur(self.cfg) + if _sig: + ttk.Label(frm, justify="left", wraplength=430, foreground=self.col_accent, + text=_sig).pack(anchor="w", pady=(10, 0)) + ttk.Separator(frm, orient="horizontal").pack(fill="x", pady=(10, 10)) ttk.Label(frm, text=config.MARKE, foreground=self.col_muted).pack(anchor="w") ttk.Button(frm, text="OK", command=d.destroy, width=10).pack(anchor="e", pady=(14, 0)) d.bind("", lambda e: d.destroy()) diff --git a/hinweis.py b/hinweis.py new file mode 100644 index 0000000..170b3ee --- /dev/null +++ b/hinweis.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +"""Der Hinweis auf die Erprobungsfassung - und die Kenntnisnahme des Nutzers. + +WARUM ES DAS GIBT +----------------- +Beide Programme schreiben Belege, die steuerlich zaehlen. Solange sie erprobt +werden, muss der Betreiber wissen, woran er ist: dass es eine Erprobungsfassung +ist, dass fuer falsch ausgestellte Belege nicht gehaftet wird, und dass er jeden +Beleg vor dem Herausgeben SELBST ansehen muss - dafuer gibt es die Vorschau. + +Sein Wortlaut (06.09.2026): + + "bei jedem oeffnen, solange wir die testen, ein popup, dass dies eine + experimentelle software ist und ich keine haftung fuer irgendwelche falsch + ausgestellten uebernehme. der user muss selbst pruefen ueber den vorschau + button auf beiden tools, ob das alles seine richtigkeit hat. wenn nicht, + auf dem link eine issue erstellen. und das alles auch noch mal in die info + mit signatur: user hat dies gelesen und zur kenntnis genommen. wenn er nein + drueckt oder ablehnt, schliesst sich die software und geht beim naechsten + start wieder mit dem selben auf, bis er auf ja drueckt." + +WIE ES WIRKT +------------ +* Beim Start kommt der Hinweis, BEVOR gearbeitet werden kann. +* "Nein" beendet das Programm. Es wird nichts geschrieben, nichts gespeichert. +* "Ja" wird mit Benutzername, Zeitpunkt und Fassung in der Konfiguration + vermerkt - das ist die Signatur. Danach kommt der Hinweis nicht mehr. +* Aendert sich der TEXT (also FASSUNG), wird erneut gefragt. Eine Zustimmung + gilt fuer das, was dagestanden hat, nicht fuer alles Kuenftige. +* Unter "Info" steht derselbe Text dauerhaft, mit der Signaturzeile darunter. + +Diese Datei liegt in BEIDEN Programmen gleich. Wer sie aendert, kopiert sie +hinueber - sonst steht in zwei Programmen zweierlei. +""" + +import datetime +import getpass + +# Fassung des HINWEISTEXTES, nicht des Programms. Wird der Text geaendert, +# gehoert dieses Datum mitgeaendert - dann wird die Kenntnisnahme neu eingeholt. +FASSUNG = "2026-09-06" + +# Wo Fehler gemeldet werden. Je Programm eine eigene Adresse. +# +# Das frueher "Beherbergungssteuer" genannte Programm heisst seit dem +# 06.09.2026 STEUERRECHNUNGSTOOL - so wie sein Repository. Der lokale Ordner +# heisst noch beherbergungssteuer: der Pfad steht in mehreren Pruefstaenden und +# in den Spec-Dateien fest, das ist ein eigener Schritt. +ISSUES = { + "rechnungstool": "https://git.pcore.de/TheMockTv/rechnungstool", + "steuerrechnungstool": "https://git.pcore.de/TheMockTv/Steuerrechnungstool", +} + +TITEL = "Erprobungsfassung – bitte lesen" + + +def text(programm): + """Der Hinweistext. `programm` ist ein Schluessel aus ISSUES.""" + url = ISSUES.get(programm, "") + return ( + "Diese Software ist eine ERPROBUNGSFASSUNG.\n\n" + "Sie wird noch getestet. Für Belege, die falsch ausgestellt werden, " + "wird keine Haftung übernommen.\n\n" + "Prüfen Sie jeden Beleg selbst, bevor Sie ihn herausgeben oder " + "verbuchen. Nutzen Sie dafür die Vorschau – in diesem Programm und im " + "jeweils anderen. Stimmt etwas nicht, melden Sie es bitte als Fehler " + "unter:\n\n" + f" {url}\n\n" + "Mit „Ja\" bestätigen Sie, dass Sie diesen Hinweis gelesen und zur " + "Kenntnis genommen haben.\n" + "Mit „Nein\" wird das Programm beendet; der Hinweis erscheint beim " + "nächsten Start erneut." + ) + + +def _stand(cfg): + return (str(cfg.get("hinweis_fassung", "") or ""), + str(cfg.get("hinweis_zeit", "") or ""), + str(cfg.get("hinweis_benutzer", "") or "")) + + +def angenommen(cfg): + """Hat der Nutzer GENAU DIESE Fassung schon zur Kenntnis genommen?""" + fassung, zeit, benutzer = _stand(cfg) + return fassung == FASSUNG and bool(zeit) and bool(benutzer) + + +def vermerken(cfg): + """Die Kenntnisnahme festhalten. Gibt die Signaturzeile zurueck.""" + cfg["hinweis_fassung"] = FASSUNG + cfg["hinweis_zeit"] = datetime.datetime.now().isoformat(timespec="seconds") + try: + cfg["hinweis_benutzer"] = getpass.getuser() + except Exception: # noqa: BLE001 - ohne Benutzernamen ist es kein Grund zu scheitern + cfg["hinweis_benutzer"] = "unbekannt" + return signatur(cfg) + + +def signatur(cfg): + """Die Zeile fuer den Info-Dialog - oder '' , wenn nichts vorliegt.""" + fassung, zeit, benutzer = _stand(cfg) + if not (fassung and zeit and benutzer): + return "" + try: + wann = datetime.datetime.fromisoformat(zeit).strftime("%d.%m.%Y um %H:%M") + except ValueError: + wann = zeit + return (f"Gelesen und zur Kenntnis genommen von {benutzer} " + f"am {wann} (Fassung {fassung}).") diff --git a/pruef_angebot.py b/pruef_angebot.py index 320dcd6..3e11e7c 100644 --- a/pruef_angebot.py +++ b/pruef_angebot.py @@ -87,6 +87,8 @@ def askyesno(titel, text, **kw): # Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier # der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. antworten["jetzt erstellen?"] = True +# Der Erprobungshinweis wird hier bejaht - geprueft wird er in pruef_hinweis.py. +antworten["Erprobungsfassung"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None warnungen = [] diff --git a/pruef_api.py b/pruef_api.py index bf62f60..0afaf76 100644 --- a/pruef_api.py +++ b/pruef_api.py @@ -75,6 +75,8 @@ def pruefe(bedingung, text): messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None +# Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. +# Geprueft wird er eigens in pruef_hinweis.py. messagebox.askyesno = lambda *a, **k: True f = A.RechnungsApp() diff --git a/pruef_dialoge.py b/pruef_dialoge.py index ec07f7f..32070f5 100644 --- a/pruef_dialoge.py +++ b/pruef_dialoge.py @@ -41,6 +41,8 @@ from tkinter import messagebox # noqa: E402 messagebox.showinfo = lambda *a, **k: None messagebox.showwarning = lambda *a, **k: None messagebox.showerror = lambda *a, **k: None +# Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. +# Geprueft wird er eigens in pruef_hinweis.py. messagebox.askyesno = lambda *a, **k: True # Sicherheitsfrage bejahen diff --git a/pruef_doppelte_leistung.py b/pruef_doppelte_leistung.py index 78b13d3..841ff5d 100644 --- a/pruef_doppelte_leistung.py +++ b/pruef_doppelte_leistung.py @@ -80,6 +80,8 @@ def askyesno(titel, text, **kw): # Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier # der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. antworten["jetzt erstellen?"] = True +# Der Erprobungshinweis wird hier bejaht - geprueft wird er in pruef_hinweis.py. +antworten["Erprobungsfassung"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None messagebox.showwarning = lambda *a, **k: warnungen.append(a[0] if a else "") diff --git a/pruef_flaeche.py b/pruef_flaeche.py index 1333794..b94a565 100644 --- a/pruef_flaeche.py +++ b/pruef_flaeche.py @@ -67,6 +67,8 @@ def pruefe(bedingung, text): messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None +# Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. +# Geprueft wird er eigens in pruef_hinweis.py. messagebox.askyesno = lambda *a, **k: True f = A.RechnungsApp() diff --git a/pruef_freigabe.py b/pruef_freigabe.py index 3fcda1c..9a663fa 100644 --- a/pruef_freigabe.py +++ b/pruef_freigabe.py @@ -83,6 +83,8 @@ def askyesno(titel, text, **kw): raise AssertionError(f"unangemeldeter Dialog: {titel!r}") +# Der Erprobungshinweis wird hier bejaht - geprueft wird er in pruef_hinweis.py. +antworten["Erprobungsfassung"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None warnungen = [] diff --git a/pruef_hinweis.py b/pruef_hinweis.py new file mode 100644 index 0000000..6558969 --- /dev/null +++ b/pruef_hinweis.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: der Hinweis auf die Erprobungsfassung und die Kenntnisnahme. + +Sein Wortlaut vom 06.09.2026: + + "wenn er nein drueckt oder ablehnt, schliesst sich die software und geht + beim naechsten start wieder mit dem selben auf, bis er auf ja drueckt" + "und das alles auch noch mal in die info mit signatur: user hat dies + gelesen und zur kenntnis genommen" + +Geprueft wird die ganze Strecke, weil jeder Teil fuer sich wertlos waere: + + 1. Der Hinweis kommt beim Start und nennt Haftung, Vorschau und die + Fehleradresse. + 2. NEIN -> das Fenster ist zu, und in der Konfiguration steht NICHTS. + Ein "Nein", das trotzdem vermerkt wird, waere eine Luege. + 3. Neuer Start -> es wird WIEDER gefragt. + 4. JA -> Signatur mit Benutzer, Zeit und Fassung; danach wird nicht mehr + gefragt. + 5. Andere Fassung des Textes -> es wird erneut gefragt. Eine Zustimmung gilt + fuer das, was dagestanden hat, nicht fuer alles Kuenftige. +""" +import json +import os +import shutil +import sys +import tempfile +import threading + +QUELLE = r"C:\claude\rechnungstool" +sys.path.insert(0, QUELLE) + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +def _reissleine(): + print("ABBRUCH | Pruefstand haengt (Zeitgrenze)") + os._exit(2) + + +_wecker = threading.Timer(120, _reissleine) +_wecker.daemon = True +_wecker.start() + +tmp = tempfile.mkdtemp(prefix="hinweis_pruef_") +ordner = os.path.join(tmp, "rechnungen") +os.makedirs(ordner) + +import config # noqa: E402 + +shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json")) +config.CONFIG_PATH = os.path.join(tmp, "config.json") +roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) +roh["output_dir"] = ordner +roh["nummer_eingerichtet"] = True +for weg in ("hinweis_fassung", "hinweis_zeit", "hinweis_benutzer"): + roh.pop(weg, None) +json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), + ensure_ascii=False, indent=2) + +os.environ["CAMPINGHOF_TEST"] = "1" +import app as A # noqa: E402 +import hinweis as H # noqa: E402 +from tkinter import messagebox # noqa: E402 + +antworten = {"Fertig": False, "Hausnummer": True} +gesehen = [] + + +def askyesno(titel, text, **kw): + gesehen.append((str(titel), str(text))) + for schlue, wert in antworten.items(): + if schlue in titel: + return wert + raise AssertionError(f"unangemeldeter Dialog: {titel!r}") + + +messagebox.askyesno = askyesno +messagebox.showinfo = lambda *a, **k: None +messagebox.showwarning = lambda *a, **k: None +messagebox.showerror = lambda *a, **k: print("[fehler]", a[0] if a else "") + + +def gelesen(): + return json.load(open(config.CONFIG_PATH, encoding="utf-8")) + + +# ---- 1./2. Ablehnen: Fenster zu, nichts vermerkt ----------------------- +antworten["Erprobungsfassung"] = False +f = A.RechnungsApp() +f.update() # laesst das after(0) laufen -> Hinweis kommt + +treffer = [t for t in gesehen if "Erprobungsfassung" in t[0]] +pruefe(bool(treffer), "der Hinweis kommt beim Start") +if treffer: + inhalt = treffer[0][1] + pruefe("ERPROBUNGSFASSUNG" in inhalt.upper(), "er nennt die Erprobungsfassung") + pruefe("Haftung" in inhalt, "er nennt die Haftung") + pruefe("Vorschau" in inhalt, "er verweist auf die Vorschau") + pruefe("git.pcore.de/TheMockTv/rechnungstool" in inhalt, + "er nennt die Adresse fuer Fehlermeldungen") + +def fenster_zu(fenster): + """True, wenn es das Fenster nicht mehr gibt. + + Nach destroy() antwortet winfo_exists() nicht mehr mit 0, sondern wirft - + die ganze Anwendung ist weg. Beides heisst hier dasselbe. + """ + import tkinter + try: + return not fenster.winfo_exists() + except tkinter.TclError: + return True + + +pruefe(fenster_zu(f), "nach Nein ist das Fenster zu") +cfg = gelesen() +pruefe(not cfg.get("hinweis_zeit"), "nach Nein steht nichts in der Konfiguration") + +# ---- 3. Neuer Start: es wird wieder gefragt ---------------------------- +gesehen.clear() +antworten["Erprobungsfassung"] = True +f = A.RechnungsApp() +f.update() +pruefe(any("Erprobungsfassung" in t[0] for t in gesehen), + "beim naechsten Start wird wieder gefragt") + +# ---- 4. Zustimmen: Signatur steht --------------------------------------- +cfg = gelesen() +pruefe(cfg.get("hinweis_fassung") == H.FASSUNG, + f"die Fassung ist vermerkt ({cfg.get('hinweis_fassung')!r})") +pruefe(bool(cfg.get("hinweis_zeit")), "der Zeitpunkt ist vermerkt") +pruefe(bool(cfg.get("hinweis_benutzer")), "der Benutzer ist vermerkt") +sig = H.signatur(f.cfg) +pruefe("gelesen und zur kenntnis genommen" in sig.lower(), + f"die Signaturzeile ist lesbar ({sig!r})") + +# ---- 5. Kein zweites Mal fragen ----------------------------------------- +gesehen.clear() +f.destroy() +f = A.RechnungsApp() +f.update() +pruefe(not any("Erprobungsfassung" in t[0] for t in gesehen), + "nach dem Ja wird nicht noch einmal gefragt") + +# ---- 6. Andere Fassung -> wieder fragen --------------------------------- +gesehen.clear() +f.destroy() +H.FASSUNG = "9999-12-31" # so, als waere der Text geaendert worden +f = A.RechnungsApp() +f.update() +pruefe(any("Erprobungsfassung" in t[0] for t in gesehen), + "bei geaenderter Fassung wird erneut gefragt") + +_wecker.cancel() +try: + f.destroy() +except Exception: # noqa: BLE001 + pass +shutil.rmtree(tmp, ignore_errors=True) + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Hinweis, Ablehnung und Signatur wirken") diff --git a/pruef_kernregeln.py b/pruef_kernregeln.py index 21c8c0a..87a8f80 100644 --- a/pruef_kernregeln.py +++ b/pruef_kernregeln.py @@ -98,6 +98,8 @@ def askyesno(titel, text="", **kw): # Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier # der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. antworten["jetzt erstellen?"] = True +# Der Erprobungshinweis wird hier bejaht - geprueft wird er in pruef_hinweis.py. +antworten["Erprobungsfassung"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: meldungen.append(("info", a[0] if a else "")) messagebox.showwarning = lambda *a, **k: meldungen.append(("warnung", a[0] if a else "")) diff --git a/pruef_kette.py b/pruef_kette.py index 3f4cd25..72e4fed 100644 --- a/pruef_kette.py +++ b/pruef_kette.py @@ -93,6 +93,8 @@ def askyesno(titel, text="", **kw): # Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier # der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. antworten["jetzt erstellen?"] = True +# Der Erprobungshinweis wird hier bejaht - geprueft wird er in pruef_hinweis.py. +antworten["Erprobungsfassung"] = True messagebox.askyesno = askyesno messagebox.showinfo = messagebox.showwarning = messagebox.showerror = \ lambda *a, **k: None diff --git a/pruef_montage.py b/pruef_montage.py index f264da1..20d65b3 100644 --- a/pruef_montage.py +++ b/pruef_montage.py @@ -89,6 +89,8 @@ warnungen = [] # Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier # der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. antworten["jetzt erstellen?"] = True +# Der Erprobungshinweis wird hier bejaht - geprueft wird er in pruef_hinweis.py. +antworten["Erprobungsfassung"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None messagebox.showwarning = lambda *a, **k: warnungen.append(a[0] if a else "") diff --git a/pruef_nummernbuch.py b/pruef_nummernbuch.py index 89bc8db..1d83585 100644 --- a/pruef_nummernbuch.py +++ b/pruef_nummernbuch.py @@ -125,6 +125,8 @@ def askyesno(titel, text, **kw): # Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier # der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. antworten["jetzt erstellen?"] = True +# Der Erprobungshinweis wird hier bejaht - geprueft wird er in pruef_hinweis.py. +antworten["Erprobungsfassung"] = True messagebox.askyesno = askyesno tool = A.RechnungsApp() diff --git a/pruef_nummernsperre.py b/pruef_nummernsperre.py index 782ef7f..c3efa44 100644 --- a/pruef_nummernsperre.py +++ b/pruef_nummernsperre.py @@ -67,6 +67,8 @@ import gemeinsam # noqa: E402 from tkinter import messagebox # noqa: E402 warnungen = [] +# Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. +# Geprueft wird er eigens in pruef_hinweis.py. messagebox.askyesno = lambda t, x, **k: ("Fertig" not in t) messagebox.showinfo = lambda *a, **k: None messagebox.showwarning = lambda *a, **k: warnungen.append(a[0] if a else "") diff --git a/pruef_nur_storno.py b/pruef_nur_storno.py index 0a75bc7..a107881 100644 --- a/pruef_nur_storno.py +++ b/pruef_nur_storno.py @@ -70,6 +70,8 @@ import app as A # noqa: E402 import bestand as BE # noqa: E402 from tkinter import messagebox # noqa: E402 +# Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. +# Geprueft wird er eigens in pruef_hinweis.py. messagebox.askyesno = lambda *a, **k: True messagebox.showinfo = lambda *a, **k: None messagebox.showwarning = lambda *a, **k: None diff --git a/pruef_storno.py b/pruef_storno.py index d403091..f121e73 100644 --- a/pruef_storno.py +++ b/pruef_storno.py @@ -95,6 +95,8 @@ antworten["Hausnummer"] = True # "Musterweg 1" hat eine, greift nur im Son # Die Freigabe vor dem Beleg (§ 14 UStG) wird bewusst bejaht - geprueft wird hier # der Ablauf DANACH. Dass ein "Nein" keinen Beleg erzeugt, prueft pruef_freigabe.py. antworten["jetzt erstellen?"] = True +# Der Erprobungshinweis wird hier bejaht - geprueft wird er in pruef_hinweis.py. +antworten["Erprobungsfassung"] = True messagebox.askyesno = askyesno messagebox.showinfo = lambda *a, **k: None warnungen = [] diff --git a/pruef_vorschau.py b/pruef_vorschau.py index f2917ce..77979a6 100644 --- a/pruef_vorschau.py +++ b/pruef_vorschau.py @@ -63,6 +63,8 @@ def pruefe(bedingung, text): messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None +# Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. +# Geprueft wird er eigens in pruef_hinweis.py. messagebox.askyesno = lambda *a, **k: True # Im Pruflauf oeffnet das Programm nichts mehr (sonst stehen nach einem Lauf From 05ec56e4b8de21c84c6ea1e99536c4e44e1b470c Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sun, 6 Sep 2026 16:24:43 +0200 Subject: [PATCH 19/34] Erprobungshinweis: erst wenn das Fenster steht, und nach vorn geholt Sein Befund: "die software haengt nun am dialog popup" - und gleich darauf: "haengen tut er nicht, nur deine pruefung; wenn ich auf aktiv druecke, geht es". Zwei getrennte Fehler, beide meine: 1. Der Hinweis lief an after(0). Da ist das Hauptfenster noch nicht gezeichnet - ein modaler Dialog daran wirkt eingefroren. Eine feste Wartezeit (150 ms) war aber auch falsch: die erreicht ein Pruefstand nie, der keine Ereignisschleife dreht, und pruef_api lief danach in die Zeitgrenze. Jetzt after_idle: laeuft, sobald Tk nichts mehr zu zeichnen hat - fuer den Nutzer nach dem Zeichnen, fuer den Pruefstand beim ersten update(). 2. Der Dialog kam nicht nach vorn. Ein Hinweis, den man erst suchen muss, taugt nichts. theme.py holt das Meldungsfenster jetzt nach vorn und nimmt den Tastaturfokus (lift, kurz topmost, focus_force). In der Aufgabenliste vermerkt: Updater als Starter (Schritt 4, mit den zwei fehlenden Voraussetzungen Versionsnummer und Sichtbarkeit der Repositories), Pcore-Design im Steuerrechnungstool (Schritt 5), und der ALTFEHLER in pruef_wache - schon vor den heutigen Arbeiten rot, die Statuszeile wird vom Ergebnis des Einlesens ueberschrieben. Alle 17 Pruefstaende des Rechnungstools gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- AUFGABE_BEWEISKETTE_PRUEFBAR.md | 61 +++++++++++++++++++++++++++++++++ app.py | 10 +++--- theme.py | 7 ++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/AUFGABE_BEWEISKETTE_PRUEFBAR.md b/AUFGABE_BEWEISKETTE_PRUEFBAR.md index 7b0a57b..7443f0c 100644 --- a/AUFGABE_BEWEISKETTE_PRUEFBAR.md +++ b/AUFGABE_BEWEISKETTE_PRUEFBAR.md @@ -65,6 +65,67 @@ Betriebsprüfung. Beide bleiben nebeneinander bestehen. --- +## Schritt 4 — Updater als Starter ⬜ OFFEN + +Sein Bild (06.09.2026): *„der updater schaut beim starten erst: ist auf dem git link eine neue +version mit exe? wenn ja, erst laden, ersetzen und dann starten."* Dazu: *„einmal prüfen auf +vollständigkeit."* + +**Warum das der richtige Aufbau ist:** Der Updater ist das, was der Nutzer startet. Er läuft +**bevor** das Programm läuft — damit gibt es das übliche Problem gar nicht, dass eine laufende EXE +sich nicht selbst ersetzen kann. + +**Ablauf:** +1. Beim Start die Release-Angaben vom Repository holen. +2. Ist die dortige Version neuer als die installierte → Datei in einen **Zwischenordner** laden. +3. **Vollständigkeit prüfen** — Größe und Prüfsumme gegen die Angabe des Releases. Erst wenn beides + stimmt, wird ersetzt. Ein halb geladener Download darf die Installation nie erreichen. +4. Alte Fassung als **Rückfallebene** behalten; scheitert der Start, zurücktauschen. +5. Programm starten. + +**⚠️ Zwei Voraussetzungen fehlen noch:** +- **Es gibt keine Versionsnummer im Programm.** Ohne die kann kein Updater vergleichen. Muss zuerst + eingeführt werden — an einer Stelle, aus der auch die EXE-Metadaten und der Info-Dialog lesen. +- **Sind die Repositories öffentlich?** Wenn nicht, braucht der Updater einen Zugangstoken — und + ein Token, das in einer verteilten EXE steckt, ist kein Geheimnis mehr. Dann müssten die Releases + öffentlich sein oder über eine andere Stelle ausgeliefert werden. + +**Und Andreas' Ansage zu den Releases:** *„die alten als experimental taggen, nicht als stabil — +weil die sind nicht stabil."* + +--- + +## Schritt 5 — Pcore-Design im Steuerrechnungstool ⬜ OFFEN + +Sein Wunsch: *„aber bitte mit unserm theme style."* + +**Befund:** Das Steuerrechnungstool hat **kein `theme.py`**. Es benutzt nackte ttk-Widgets mit +Segoe UI. Das Rechnungstool hat das ganze Pcore/Ravokk-Design — Farben, Roboto, Glass-Buttons, +eigene Meldungsfenster (`MeldungMixin`), hell und dunkel. + +**Zu tun:** `theme.py` herüberziehen und die Oberfläche darauf umstellen. Das ist ein eigener Bau, +kein Nebenbei — Menüs, Tabellen, Dialoge, Statusleiste. Vorher planen. + +--- + +## ⚠️ Gefundener Altfehler — `pruef_wache` (Steuerrechnungstool) ⬜ OFFEN + +**Nicht von den Arbeiten am 06.09.2026 verursacht** — bei der Ausgangsmessung vor dem Umbau bereits +rot, nur mit anderem Text. + +`pruef_wache.py` erwartet nach einem Push des Rechnungstools in der Statuszeile den Hinweis +**„Rechnungstool meldet"**. Tatsächlich steht dort das Ergebnis des anschließenden Einlesens +(`0 neu, 0 aktualisiert, 1 unverändert`; bei der Ausgangsmessung: `Nummernbuch: 1 Nummern +eingetragen`). Das Einlesen **überschreibt die Meldung**, bevor der Nutzer sie lesen kann. + +**Zu klären:** Ist das ein Fehler im Programm (die Meldung soll stehen bleiben, das Ergebnis +danebengehören) oder eine veraltete Erwartung im Prüfstand? Nicht nebenbei entscheiden — die +Statuszeile ist das Einzige, was dem Nutzer sagt, dass die andere Anwendung etwas gemeldet hat. + +Folgefehler derselben Stelle: „dann kommt keine Meldung dazu". + +--- + ## Reihenfolge Schritt 2 zuerst — er schließt eine Lücke in dem, was gerade gebaut wurde, und ist klein. diff --git a/app.py b/app.py index a6a644c..b833b73 100644 --- a/app.py +++ b/app.py @@ -118,10 +118,11 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # es morgen ohne berichtigte Rechnung im Ordner und keiner weiss warum. self.protocol("WM_DELETE_WINDOW", self._beenden) - # NICHTS laeuft an, bevor der Erprobungshinweis bestaetigt ist. Wer ihn - # ablehnt, soll gar nicht erst arbeiten koennen - und es soll auch kein - # halb gestartetes Programm hinter dem Fenster stehenbleiben. - self.after(0, self._hinweis_pruefen) + # after_idle statt after(0): laeuft, sobald Tk nichts mehr zu zeichnen hat - + # also nachdem das Hauptfenster steht. Bei after(0) haengt der modale Dialog + # an einem noch ungezeichneten Fenster und wirkt wie eingefroren; eine feste + # Wartezeit dagegen erreicht ein Pruefstand nie, der keine Schleife dreht. + self.after_idle(self._hinweis_pruefen) # ---------------------------------------------------------------- Menue @@ -650,6 +651,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, stuenden beim Ablehnen noch Timer in der Warteschlange, die auf ein Fenster zugreifen, das es nicht mehr gibt. """ + self.update_idletasks() # Fenster fertig zeichnen lassen if not hinweis.angenommen(self.cfg): print(f"[hinweis] Kenntnisnahme noch offen (Fassung {hinweis.FASSUNG})") if not self.frage(hinweis.TITEL, hinweis.text("rechnungstool"), diff --git a/theme.py b/theme.py index 99d35d8..ce12a81 100644 --- a/theme.py +++ b/theme.py @@ -473,6 +473,13 @@ class MeldungMixin: x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) y = self.winfo_rooty() + 140 d.geometry(f"+{max(0, x)}+{max(0, y)}") + # Nach vorn holen und den Tastaturfokus nehmen. Ohne das kann der Dialog + # beim Start hinter dem Hauptfenster liegen - der Nutzer sieht nur ein + # Fenster, das nicht reagiert, und haelt es fuer haengen geblieben. + d.lift() + d.attributes("-topmost", True) + d.after(100, lambda: d.attributes("-topmost", False)) + d.focus_force() d.grab_set() d.focus_set() self.wait_window(d) From fec0e8449c799c9719bc30157e2312847fdd36d2 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sun, 6 Sep 2026 16:42:35 +0200 Subject: [PATCH 20/34] Updater als Starter - die Nummer steht im Dateinamen Sein Bild (06.09.2026): "der updater schaut beim starten erst: ist auf dem git link eine neue version mit exe? wenn ja, erst laden, ersetzen und dann starten." "einmal pruefen auf vollstaendigkeit." "wir werden den namen mit nummer fuehren - wenn er merkt, eh warte mal, die heisst anders, dann neu machen" DER AUFBAU Der Updater IST der Starter. Er laeuft, BEVOR das Programm laeuft - damit gibt es das Windows-Problem "laufende EXE laesst sich nicht ersetzen" gar nicht. Und weil die installierte Datei die Nummer im Namen traegt (Rechnungstool-1.6.0.exe), wird ueberhaupt nichts ueberschrieben: eine neue Fassung ist eine neue Datei. Die vorige bleibt liegen und ist damit die Rueckfallebene, ohne dass jemand eine Sicherung anlegen muesste. Der Updater sieht am NAMEN, was da ist - er muss keiner Angabe glauben. version.py: die Nummer an EINER Stelle, im Code, in die EXE kompiliert. Sie entspricht dem Release-Tag ohne "v". Zusaetzlich fuehrt der Updater ein eigenes Buch (installiert.json); wer eine Datei umbenennt, verursacht hoechstens einen ueberfluessigen Download. BEIM BAUEN AUFGEFALLEN /releases/latest liefert NICHTS, weil alle Fassungen als Vorabversion gekennzeichnet sind - Forgejo laesst Vorabversionen dort aus. Der Updater nimmt deshalb die Liste und sucht selbst die hoechste Nummer. Waere das erst beim Nutzer aufgefallen, haette der Updater nie ein Update gefunden. Beide Repositories sind oeffentlich - kein Token noetig. Ein Token in einer verteilten EXE waere ohnehin keins. VOLLSTAENDIGKEIT Geladen wird in einen Zwischenordner. Erst wenn GROESSE und (falls das Release eine .sha256 anhaengt) PRUEFSUMME stimmen, kommt die Datei in den Installationsordner. Sonst wird verworfen und die vorhandene Fassung gestartet - lieber kein Update als ein kaputtes. PRUEFSTAND pruef_updater.py prueft vor allem, wann NICHT aktualisiert werden darf: gleiche Fassung, aeltere im Netz, kein passender Anhang, Entwurf, kein Netz, falsche Groesse, falsche Pruefsumme. Und den wichtigsten Punkt: eine halbe Datei erreicht den Installationsordner nie. Alle 18 Pruefstaende gruen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- pruef_updater.py | 204 ++++++++++++++++++++++++++ updater.py | 368 +++++++++++++++++++++++++++++++++++++++++++++++ version.py | 23 +++ 3 files changed, 595 insertions(+) create mode 100644 pruef_updater.py create mode 100644 updater.py create mode 100644 version.py diff --git a/pruef_updater.py b/pruef_updater.py new file mode 100644 index 0000000..e1bebef --- /dev/null +++ b/pruef_updater.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: der Updater - vor allem die Faelle, in denen er NICHTS tun darf. + +Sein Bild (06.09.2026): + + "der updater schaut beim starten erst: ist auf dem git link eine neue + version mit exe? wenn ja, erst laden, ersetzen und dann starten." + "einmal pruefen auf vollstaendigkeit." + "wir werden den namen mit nummer fuehren - wenn er merkt, eh warte mal, + die heisst anders, dann neu machen" + +Ein Updater ist gefaehrlicher als das Programm, das er aktualisiert: Er +entscheidet ueber die Datei, die der Betrieb braucht. Deshalb wird hier weniger +geprueft, DASS er aktualisiert, als dass er es in den falschen Faellen NICHT +tut - und dass er nie etwas ueberschreibt. + +Ohne Netz: die Release-Liste wird eingesetzt, nicht geholt. +""" +import os +import shutil +import sys +import tempfile + +QUELLE = r"C:\claude\rechnungstool" +sys.path.insert(0, QUELLE) + +import updater as U # noqa: E402 + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +EXE = "Rechnungstool.exe" + +# ---- Versionen vergleichen --------------------------------------------- +pruefe(U.zerlegen("v1.6.0") == (1, 6, 0), "v1.6.0 wird zu (1, 6, 0)") +pruefe(U.zerlegen("") == (0,), "leere Angabe zaehlt als aelteste") +pruefe(U.zerlegen("kaputt") == (0,), "unlesbare Angabe zaehlt als aelteste") +pruefe(U.ist_neuer("v1.7.0", "1.6.9"), "1.7.0 ist neuer als 1.6.9 (nicht alphabetisch!)") +pruefe(not U.ist_neuer("v1.6.0", "1.6.0"), "Gleichstand ist NICHT neuer") +pruefe(U.ist_neuer("v1.10.0", "1.9.0"), "1.10.0 ist neuer als 1.9.0") + +# ---- Die Nummer im Dateinamen ------------------------------------------ +pruefe(U.dateiname(EXE, "v1.6.0") == "Rechnungstool-1.6.0.exe", + "aus Name und Tag wird Rechnungstool-1.6.0.exe") +pruefe(U.dateiname("Rechnungstool-1.5.0.exe", "v1.6.0") == "Rechnungstool-1.6.0.exe", + "eine schon vorhandene Nummer wird ersetzt, nicht angehaengt") +pruefe(U.basis_und_endung(EXE) == ("Rechnungstool", ".exe"), "Stamm und Endung sauber getrennt") + +# ---- Das passende Release finden --------------------------------------- +def release(tag, dateien, entwurf=False, vorab=True): + return {"tag_name": tag, "draft": entwurf, "prerelease": vorab, + "assets": [{"name": n, "size": g, + "browser_download_url": f"http://x/{tag}/{n}"} + for n, g in dateien]} + + +liste = [release("v1.5.0", [(EXE, 10)]), + release("v1.6.0", [(EXE, 20)]), + release("v1.5.5", [(EXE, 15)])] +treffer = U.passendes_release(liste, EXE) +pruefe(treffer and treffer[0]["tag_name"] == "v1.6.0", + "aus einer unsortierten Liste wird die neueste genommen") +pruefe(U.passendes_release([release("v9.9.9", [("anderes.exe", 5)])], EXE) is None, + "ein Release ohne passende Datei zaehlt nicht") +pruefe(U.passendes_release([release("v9.9.9", [(EXE, 5)], entwurf=True)], EXE) is None, + "ein Entwurf zaehlt nicht") +# Vorabversionen MUESSEN zaehlen - alle Fassungen sind so gekennzeichnet. +pruefe(U.passendes_release([release("v2.0.0", [(EXE, 30)], vorab=True)], EXE) is not None, + "Vorabversionen zaehlen mit (sonst faende der Updater nie etwas)") + +# ---- Vollstaendigkeit --------------------------------------------------- +tmp = tempfile.mkdtemp(prefix="upd_pruef_") +probe = os.path.join(tmp, "probe.bin") +with open(probe, "wb") as f: + f.write(b"A" * 1000) +summe = U.sha256(probe) + +gut, _ = U.vollstaendig(probe, 1000, summe) +pruefe(gut, "richtige Groesse und Pruefsumme werden angenommen") +gut, grund = U.vollstaendig(probe, 999, summe) +pruefe(not gut and "Groesse" in grund, f"falsche Groesse wird abgelehnt ({grund})") +gut, grund = U.vollstaendig(probe, 1000, "0" * 64) +pruefe(not gut and "Pruefsumme" in grund, f"falsche Pruefsumme wird abgelehnt ({grund})") +gut, _ = U.vollstaendig(probe, 1000, "") +pruefe(gut, "ohne Pruefsumme entscheidet die Groesse allein") +gut, _ = U.vollstaendig(os.path.join(tmp, "gibtsnicht"), 1000, "") +pruefe(not gut, "eine fehlende Datei ist nicht vollstaendig") + +# ---- Was liegt im Ordner? ---------------------------------------------- +ordner = os.path.join(tmp, "install") +os.makedirs(ordner) +for name, inhalt in (("Rechnungstool-1.5.0.exe", b"ALT"), + ("Rechnungstool-1.6.0.exe", b"AKTUELL"), + ("nichts-zu-tun.txt", b"x")): + with open(os.path.join(ordner, name), "wb") as f: + f.write(inhalt) + +fassung, pfad = U.neueste_installierte(ordner, EXE) +pruefe(fassung == "1.6.0", f"die neueste vorhandene Fassung wird am Namen erkannt ({fassung})") +pruefe(os.path.basename(pfad) == "Rechnungstool-1.6.0.exe", "und der Pfad stimmt") +pruefe(len(U.installierte(ordner, EXE)) == 2, "fremde Dateien im Ordner stoeren nicht") + +# ---- Der ganze Durchlauf, ohne Netz ------------------------------------- +meldungen = [] + + +def sagen(t): + meldungen.append(str(t)) + + +def alle_da(): + return sorted(os.path.basename(p) for _f, p in U.installierte(ordner, EXE)) + + +# 1. gleiche Fassung -> nichts laden, vorhandene starten +meldungen.clear() +start = U.durchlauf(ordner, "x/y", EXE, sagen=sagen, + holen_=lambda _r: [release("v1.6.0", [(EXE, 11)])]) +pruefe(os.path.basename(start) == "Rechnungstool-1.6.0.exe", + "gleiche Fassung: die vorhandene wird gestartet") +pruefe(alle_da() == ["Rechnungstool-1.5.0.exe", "Rechnungstool-1.6.0.exe"], + "und im Ordner hat sich nichts geaendert") + +# 2. aeltere Fassung im Netz -> nichts tun +start = U.durchlauf(ordner, "x/y", EXE, sagen=sagen, + holen_=lambda _r: [release("v1.5.0", [(EXE, 11)])]) +pruefe(os.path.basename(start) == "Rechnungstool-1.6.0.exe", + "aeltere Fassung im Netz: es wird nicht aktualisiert") + +# 3. kein Netz -> vorhandene starten und sagen, warum +meldungen.clear() + + +def wirft(_r): + raise OSError("kein Netz") + + +start = U.durchlauf(ordner, "x/y", EXE, sagen=sagen, holen_=wirft) +pruefe(os.path.basename(start) == "Rechnungstool-1.6.0.exe", + "ohne Netz wird die vorhandene Fassung gestartet") +pruefe(any("Kein Update" in m for m in meldungen), "und es wird gesagt, warum") + +# 4. neuere Fassung, aber Groesse passt nicht -> VERWERFEN +meldungen.clear() +falsch = release("v1.9.0", [(EXE, 999999)]) +falsch["assets"][0]["browser_download_url"] = "file:///" + probe.replace("\\", "/") +start = U.durchlauf(ordner, "x/y", EXE, sagen=sagen, holen_=lambda _r: [falsch]) +pruefe(any("VERWORFEN" in m for m in meldungen), "falsche Groesse: das Update wird verworfen") +pruefe(os.path.basename(start) == "Rechnungstool-1.6.0.exe", + "und die vorhandene Fassung wird gestartet") +pruefe(not os.path.exists(os.path.join(ordner, "Rechnungstool-1.9.0.exe")), + "die halbe Datei erreicht den Installationsordner NICHT - der wichtigste Punkt") + +# 5. neuere Fassung, alles stimmt -> als NEUE Datei dazu +meldungen.clear() +richtig = release("v1.9.0", [(EXE, 1000)]) +richtig["assets"][0]["browser_download_url"] = "file:///" + probe.replace("\\", "/") +start = U.durchlauf(ordner, "x/y", EXE, sagen=sagen, holen_=lambda _r: [richtig]) +pruefe(os.path.basename(start) == "Rechnungstool-1.9.0.exe", + "die neue Fassung wird gestartet") +pruefe(os.path.exists(os.path.join(ordner, "Rechnungstool-1.9.0.exe")), + "sie liegt als EIGENE Datei im Ordner") +pruefe(os.path.exists(os.path.join(ordner, "Rechnungstool-1.6.0.exe")), + "die vorige bleibt liegen - sie ist die Rueckfallebene") +pruefe(not os.path.exists(os.path.join(ordner, "Rechnungstool-1.5.0.exe")), + "die vorvorige wurde aufgeraeumt (es bleiben immer zwei)") + +buch = U.buch_lesen(ordner) +pruefe(buch.get("version") == "1.9.0", + f"der Updater fuehrt Buch ueber das, was er installiert hat ({buch})") + +# 6. gleich noch einmal -> nichts laden, es ist ja jetzt aktuell +meldungen.clear() +vorher = alle_da() +start = U.durchlauf(ordner, "x/y", EXE, sagen=sagen, holen_=lambda _r: [richtig]) +pruefe(any("Aktuell" in m for m in meldungen), + f"unmittelbar danach gilt es als aktuell ({meldungen})") +pruefe(alle_da() == vorher, "und es wird nichts noch einmal geladen") + +# 7. Buch verloren, Datei aber da -> nicht noch einmal laden +# Kommt vor, wenn jemand installiert.json loescht. Der Dateiname allein traegt +# die Entscheidung: die 1.9.0 liegt da, also wird sie nur gestartet. +meldungen.clear() +os.remove(os.path.join(ordner, U.BUCH)) +start = U.durchlauf(ordner, "x/y", EXE, sagen=sagen, holen_=lambda _r: [richtig]) +pruefe(os.path.basename(start) == "Rechnungstool-1.9.0.exe", + "auch ohne Buch wird die richtige Datei gestartet") +pruefe(not any("Wird geladen" in m for m in meldungen), + f"und nichts noch einmal geladen ({meldungen})") + +shutil.rmtree(tmp, ignore_errors=True) + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Der Updater aktualisiert - und laesst in den falschen Faellen die Finger davon") diff --git a/updater.py b/updater.py new file mode 100644 index 0000000..f06b06c --- /dev/null +++ b/updater.py @@ -0,0 +1,368 @@ +# -*- coding: utf-8 -*- +"""Der Updater - er ist der Starter. + +SEIN BILD (06.09.2026) +---------------------- + "der updater schaut beim starten erst: ist auf dem git link eine neue + version mit exe? wenn ja, erst laden, ersetzen und dann starten." + "einmal pruefen auf vollstaendigkeit." + "updater startet kurz als im ram und das main programm ist aus, sonst + kannst es nicht ersetzen." + +WARUM DAS DER RICHTIGE AUFBAU IST +--------------------------------- +Windows laesst eine laufende EXE nicht ueberschreiben. Ein Programm, das sich +selbst aktualisiert, muss deshalb Umwege gehen (Kopie im Temp, warten, bis der +eigene Prozess weg ist, tauschen). All das entfaellt, wenn der Updater das ist, +was der Nutzer startet: Er laeuft VOR dem Programm - die EXE ist gar nicht in +Benutzung, wenn sie ersetzt wird. + +DIE NUMMER STEHT IM DATEINAMEN (seine Idee, 06.09.2026) +------------------------------------------------------- + "wir werden den namen mit nummer fuehren - wenn er merkt, eh warte mal, die + heisst anders, dann neu machen" + +Die installierte Datei heisst `Rechnungstool-1.6.0.exe`. Daraus folgt dreierlei: + + * Es wird nie etwas UEBERSCHRIEBEN - eine neue Fassung ist eine neue Datei. + Das Sperrproblem von Windows gibt es damit nicht einmal theoretisch. + * Die alte Fassung bleibt liegen und ist die Rueckfallebene, ohne dass + jemand eine Sicherung anlegen muesste. + * Der Updater sieht AM NAMEN, was installiert ist. Er muss keiner Angabe + glauben, die auseinanderlaufen koennte. + +DIE REGEL, AN DER SOLCHE UPDATER SCHEITERN +------------------------------------------ +Sie schreiben einen halb geladenen Download in die Installation, und das +Programm startet nie wieder. Deshalb hier: in einen Zwischenordner laden, +GROESSE UND PRUEFSUMME gegen die Angaben des Releases halten, und erst dann in +den Installationsordner legen. + +AUFBAU +------ +Dieser Teil ist eine BIBLIOTHEK ohne Fenster und ohne Netzzwang: jede +Entscheidung ist eine eigene Funktion, die sich einzeln pruefen laesst +(pruef_updater.py). Das Startprogramm steht unten unter __main__. + +Diese Datei liegt in BEIDEN Programmen gleich. Wer sie aendert, kopiert sie +hinueber. +""" + +import hashlib +import json +import os +import re +import shutil +import subprocess +import sys +import tempfile +import urllib.request + +API = "https://git.pcore.de/api/v1/repos" + +# Wie die Buchfuehrung des Updaters heisst. Sie liegt neben der EXE und wird +# von IHM gefuehrt - nicht vom Programm. So kann nichts auseinanderlaufen: +# was hier steht, hat der Updater selbst installiert. +BUCH = "installiert.json" + + +# --------------------------------------------------------------------------- +# Versionen vergleichen +# --------------------------------------------------------------------------- +def zerlegen(fassung): + """'v1.6.0' oder '1.6.0' -> (1, 6, 0). Unlesbares wird zu (0,). + + Absichtlich nachsichtig: eine Nummer, die niemand versteht, darf kein + Update ausloesen - sie zaehlt als die aelteste denkbare. + """ + if not fassung: + return (0,) + teile = re.findall(r"\d+", str(fassung)) + return tuple(int(t) for t in teile) if teile else (0,) + + +def ist_neuer(dort, hier): + """Ist `dort` neuer als `hier`? Gleichstand ist NICHT neuer.""" + return zerlegen(dort) > zerlegen(hier) + + +# --------------------------------------------------------------------------- +# Das passende Release finden +# --------------------------------------------------------------------------- +def passendes_release(releases, exe_name): + """Das neueste Release, das eine Datei `exe_name` anhaengt. + + Vorabversionen zaehlen MIT - alle Fassungen dieser Programme sind als + Vorabversion gekennzeichnet, weil sie erprobt werden. Wer hier + `/releases/latest` benutzt, bekommt nichts: Forgejo laesst Vorabversionen + dort aus. Genau das ist beim Bauen aufgefallen. + + Entwuerfe (draft) zaehlen NICHT - die sind nicht veroeffentlicht. + """ + beste = None + for r in releases or []: + if r.get("draft"): + continue + anhang = next((a for a in r.get("assets") or [] + if a.get("name") == exe_name), None) + if not anhang: + continue + if beste is None or ist_neuer(r.get("tag_name"), beste[0].get("tag_name")): + beste = (r, anhang) + return beste + + +def summe_aus_release(release, exe_name): + """Die erwartete Pruefsumme aus dem Anhang `.sha256`, oder ''. + + Das Release haengt neben der EXE eine kleine Textdatei mit der Pruefsumme + an. Fehlt sie, wird nur die Groesse geprueft - dann sagt das der Updater + aber auch, statt so zu tun, als haette er geprueft. + """ + name = exe_name + ".sha256" + for a in release.get("assets") or []: + if a.get("name") == name: + return a.get("browser_download_url") or "" + return "" + + +# --------------------------------------------------------------------------- +# Laden und pruefen +# --------------------------------------------------------------------------- +def sha256(pfad): + h = hashlib.sha256() + with open(pfad, "rb") as f: + for brocken in iter(lambda: f.read(1 << 20), b""): + h.update(brocken) + return h.hexdigest() + + +def holen(url, ziel, melden=None): + """Datei laden. Gibt die Anzahl geladener Bytes zurueck.""" + with urllib.request.urlopen(url, timeout=60) as antwort, open(ziel, "wb") as raus: + gesamt = int(antwort.headers.get("Content-Length") or 0) + geladen = 0 + while True: + brocken = antwort.read(1 << 20) + if not brocken: + break + raus.write(brocken) + geladen += len(brocken) + if melden and gesamt: + melden(geladen, gesamt) + return geladen + + +def vollstaendig(pfad, erwartete_groesse, erwartete_summe=""): + """Ist die geladene Datei vollstaendig und unverfaelscht? + + Rueckgabe: (True, "") oder (False, Grund). Ein halb geladener Download darf + die Installation NIE erreichen - lieber gar kein Update als ein kaputtes. + """ + if not os.path.exists(pfad): + return False, "Die geladene Datei ist nicht da." + ist = os.path.getsize(pfad) + if erwartete_groesse and ist != erwartete_groesse: + return False, (f"Groesse stimmt nicht: {ist} Bytes geladen, " + f"{erwartete_groesse} erwartet.") + if erwartete_summe: + hat = sha256(pfad) + if hat.lower() != erwartete_summe.strip().lower(): + return False, "Pruefsumme stimmt nicht." + return True, "" + + +# --------------------------------------------------------------------------- +# Die Nummer steht im Dateinamen +# --------------------------------------------------------------------------- +def basis_und_endung(exe_name): + """'Rechnungstool.exe' -> ('Rechnungstool', '.exe').""" + stamm, endung = os.path.splitext(exe_name) + stamm = re.sub(r"-\d+(?:\.\d+)*$", "", stamm) # eine Nummer wieder abschneiden + return stamm, endung or ".exe" + + +def dateiname(exe_name, fassung): + """'Rechnungstool.exe' + 'v1.6.0' -> 'Rechnungstool-1.6.0.exe'.""" + stamm, endung = basis_und_endung(exe_name) + return f"{stamm}-{str(fassung).lstrip('v')}{endung}" + + +def installierte(ordner, exe_name): + """Was liegt im Ordner? Liste (Fassung, Pfad), neueste zuerst. + + Gelesen wird der DATEINAME - keine Angabe, der man glauben muesste. Eine + Datei ohne Nummer (aus der Zeit vor dieser Fassung) zaehlt als aelteste. + """ + stamm, endung = basis_und_endung(exe_name) + muster = re.compile(re.escape(stamm) + r"(?:-(\d+(?:\.\d+)*))?" + + re.escape(endung) + r"$", re.I) + gefunden = [] + try: + namen = os.listdir(ordner) + except OSError: + return [] + for name in namen: + treffer = muster.match(name) + if treffer: + gefunden.append((treffer.group(1) or "0", os.path.join(ordner, name))) + gefunden.sort(key=lambda x: zerlegen(x[0]), reverse=True) + return gefunden + + +def neueste_installierte(ordner, exe_name): + """(Fassung, Pfad) der neuesten vorhandenen Datei - oder ('0', '').""" + liste = installierte(ordner, exe_name) + return liste[0] if liste else ("0", "") + + +def aufraeumen(ordner, exe_name, behalten=2): + """Alte Fassungen wegraeumen, die neuesten `behalten` bleiben liegen. + + Nicht aus Ordnungsliebe: die vorletzte Fassung IST die Rueckfallebene. + Deshalb wird nie unter zwei geraeumt. + """ + liste = installierte(ordner, exe_name) + weg = [] + for _fassung, pfad in liste[max(2, behalten):]: + try: + os.remove(pfad) + weg.append(os.path.basename(pfad)) + except OSError: + pass + return weg + + +# --------------------------------------------------------------------------- +# Buchfuehrung +# --------------------------------------------------------------------------- +def buch_lesen(ordner): + pfad = os.path.join(ordner, BUCH) + try: + with open(pfad, encoding="utf-8") as f: + return json.load(f) + except (OSError, ValueError): + return {} + + +def buch_schreiben(ordner, daten): + pfad = os.path.join(ordner, BUCH) + try: + with open(pfad, "w", encoding="utf-8") as f: + json.dump(daten, f, ensure_ascii=False, indent=2) + return True + except OSError: + return False + + +def releases_holen(repository): + url = f"{API}/{repository}/releases?limit=20" + with urllib.request.urlopen(url, timeout=30) as antwort: + return json.loads(antwort.read().decode("utf-8")) + + +def text_holen(url): + with urllib.request.urlopen(url, timeout=30) as antwort: + return antwort.read().decode("utf-8", "replace").split()[0] + + +# --------------------------------------------------------------------------- +# Der Ablauf +# --------------------------------------------------------------------------- +def durchlauf(ordner, repository, exe_name, sagen=print, holen_=None): + """Ein Durchlauf. Gibt den Pfad der Datei zurueck, die gestartet werden soll. + + Nichts wird ueberschrieben: eine neue Fassung wird als eigene Datei + `-.exe` abgelegt. Die vorige bleibt liegen - sie ist die + Rueckfallebene, ohne dass jemand eine Sicherung anlegen muesste. + + `holen_` laesst sich fuer den Pruefstand ersetzen, damit er ohne Netz + auskommt. + """ + holen_ = holen_ or releases_holen + hier, hier_pfad = neueste_installierte(ordner, exe_name) + buch = buch_lesen(ordner) + # Buch und Dateiname zusammen: wer eine Datei umbenennt, verursacht + # hoechstens einen ueberfluessigen Download, keinen Schaden. + if ist_neuer(buch.get("version") or "0", hier): + hier = buch.get("version") + + try: + releases = holen_(repository) + except Exception as e: # noqa: BLE001 - ohne Netz wird einfach gestartet + sagen(f"Kein Update moeglich ({e}). Es wird die vorhandene Fassung gestartet.") + return hier_pfad + + treffer = passendes_release(releases, exe_name) + if not treffer: + sagen("Im Repository liegt keine passende Datei. Vorhandene Fassung wird gestartet.") + return hier_pfad + release, anhang = treffer + dort = release.get("tag_name") or "" + + if not ist_neuer(dort, hier): + sagen(f"Aktuell ({hier}). Kein Update noetig.") + return hier_pfad + + ziel = os.path.join(ordner, dateiname(exe_name, dort)) + if os.path.exists(ziel): + sagen(f"{os.path.basename(ziel)} liegt schon da. Es wird gestartet.") + return ziel + + sagen(f"Neue Fassung {dort} gefunden (vorhanden: {hier}). Wird geladen ...") + zwischen = tempfile.mkdtemp(prefix="update_") + geladen = os.path.join(zwischen, exe_name) + try: + holen(anhang["browser_download_url"], geladen) + + erwartete_summe = "" + url_summe = summe_aus_release(release, exe_name) + if url_summe: + try: + erwartete_summe = text_holen(url_summe) + except Exception: # noqa: BLE001 + sagen("Pruefsumme nicht ladbar - es wird nur die Groesse geprueft.") + else: + sagen("Dieses Release hat keine Pruefsumme - es wird nur die Groesse geprueft.") + + gut, grund = vollstaendig(geladen, anhang.get("size") or 0, erwartete_summe) + if not gut: + sagen(f"Das Update wurde VERWORFEN: {grund}") + sagen("Es wird die vorhandene Fassung gestartet.") + return hier_pfad + + # Erst jetzt in den Installationsordner - vorher lag nichts Halbes dort. + shutil.move(geladen, ziel) + buch_schreiben(ordner, {"version": dort.lstrip("v"), + "datei": os.path.basename(ziel), + "sha256": erwartete_summe, + "vorher": os.path.basename(hier_pfad) if hier_pfad else ""}) + weg = aufraeumen(ordner, exe_name) + if weg: + sagen("Alte Fassungen entfernt: " + ", ".join(weg)) + sagen(f"Aktualisiert auf {dort}.") + return ziel + finally: + shutil.rmtree(zwischen, ignore_errors=True) + + +def starten(pfad): + """Das Programm starten und den Updater beenden.""" + subprocess.Popen([pfad], close_fds=True) + + +if __name__ == "__main__": + import version + + ordner = os.path.dirname(os.path.abspath( + sys.executable if getattr(sys, "frozen", False) else __file__)) + + print(f"Updater - {version.REPOSITORY}") + zu_starten = durchlauf(ordner, version.REPOSITORY, version.EXE_NAME) + + if zu_starten and os.path.exists(zu_starten): + print("Starte", os.path.basename(zu_starten)) + starten(zu_starten) + else: + print(f"FEHLER: keine startbare Fassung von {version.EXE_NAME} in {ordner}") + input("Enter zum Schliessen ...") diff --git a/version.py b/version.py new file mode 100644 index 0000000..4da2e80 --- /dev/null +++ b/version.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +"""Die Fassung dieses Programms - an EINER Stelle. + +Wozu +---- +Ohne eine Nummer im Programm kann kein Updater vergleichen, ob das, was im +Repository liegt, neuer ist als das, was hier laeuft. Sie steht deshalb hier +und NUR hier; alles andere (Info-Dialog, Updater, Release) liest sie von hier. + +Regel +----- +Die Nummer wird beim Ausliefern erhoeht und entspricht dem Release-Tag ohne das +"v": Tag `v1.6.0` -> VERSION "1.6.0". Wer das eine ohne das andere aendert, +baut dem Updater eine Falle. +""" + +VERSION = "1.6.0" + +# Zu welchem Repository dieses Programm gehoert - der Updater sucht dort. +REPOSITORY = "TheMockTv/rechnungstool" + +# Wie die ausgelieferte Datei im Release heisst. +EXE_NAME = "Rechnungstool.exe" From 73042b771c6202256cc0bdc0a81f4a8a449107e6 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sun, 6 Sep 2026 20:34:38 +0200 Subject: [PATCH 21/34] Logo in der Statuszeile, Bau an einer Stelle, Startprobe fuer die EXE Logo Das Programmlogo steht jetzt klein neben "powered by ravokk" - dort sitzt die Kennung des Werkzeugs, nicht die des Kunden. Eine eigene Kopfzeile hat dieses Programm nicht; oben sind die Reiter. bauen.py Der Weg von der Quelle zur Setup-Datei war eine Folge von Befehlen, die jemand von Hand eintippen musste. Wer einen Schritt vergisst, liefert eine Setup-Datei mit einer alten EXE aus - und sieht es ihr nicht an. Genau das ist heute passiert. Jetzt ist es ein Befehl, die Nummer kommt aus version.py, und am Ende stehen die SHA256-Summen fuer den Release-Text. pruef_start_exe.py Prueft, was kein anderer Pruefstand prueft: ob die GEBAUTE EXE ein sichtbares Fenster zeigt. Alle uebrigen fahren das Programm aus der Quelle, dort trat der Fehler nie auf. "Der Prozess laeuft" beweist dabei nichts - er lief ja, waehrend nichts zu sehen war. Aufgeraeumt "Rechnung Campinghof.exe" ist weg; gebaute Dateien gehoeren ins Release, nicht ins Repo. Die .spec-Dateien dagegen schon: ohne sie kann niemand die EXE nachbauen, die der Updater ausliefert. Fassung 1.7.0. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- .gitignore | 15 + AUFGABE_AUSSENDIENST_ARBEITSPROTOKOLL.md | 95 ++++++ AUFGABE_ONLINE_API_MYSQL.md | 417 +++++++++++++++++++++++ Diagnose.spec | 48 +++ Installer.iss | 95 ++++++ Rechnungstool.spec | 48 +++ Updater.spec | 24 ++ app.py | 64 +++- assets/programm.ico | Bin 0 -> 51609 bytes assets/programm_logo.png | Bin 0 -> 24819 bytes assets/programm_logo.svg | 86 +++++ bauen.py | 109 ++++++ pdf_renderer.py | 2 +- pruef_hinweis.py | 28 +- pruef_selbstbezug.py | 123 +++++++ pruef_start_exe.py | 137 ++++++++ pruef_updater.py | 25 ++ updater.py | 33 +- version.py | 4 +- wasserzeichen.py | 106 ++++++ 20 files changed, 1445 insertions(+), 14 deletions(-) create mode 100644 AUFGABE_AUSSENDIENST_ARBEITSPROTOKOLL.md create mode 100644 AUFGABE_ONLINE_API_MYSQL.md create mode 100644 Diagnose.spec create mode 100644 Installer.iss create mode 100644 Rechnungstool.spec create mode 100644 Updater.spec create mode 100644 assets/programm.ico create mode 100644 assets/programm_logo.png create mode 100644 assets/programm_logo.svg create mode 100644 bauen.py create mode 100644 pruef_selbstbezug.py create mode 100644 pruef_start_exe.py create mode 100644 wasserzeichen.py diff --git a/.gitignore b/.gitignore index 3833f58..a21aa42 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,18 @@ _tmp/ *.7z.* release/ rechnungstool.pid + +# Gebaute Dateien - die gehoeren ins Release, nicht ins Repo. +*.exe +setup/ + +# Die Bauanleitungen selbst gehoeren SEHR WOHL hinein: ohne sie kann niemand +# die EXE nachbauen, die der Updater ausliefert. +!Rechnungstool.spec +!Updater.spec +!Diagnose.spec + +# Muster-PDFs. Der GAST darin ist erfunden - der BETRIEB nicht: sie tragen +# IBAN, Steuernummer und die private Rufnummer des Auftraggebers im Briefkopf. +# In ein oeffentliches Repository gehoert das nicht. +muster/ diff --git a/AUFGABE_AUSSENDIENST_ARBEITSPROTOKOLL.md b/AUFGABE_AUSSENDIENST_ARBEITSPROTOKOLL.md new file mode 100644 index 0000000..c520033 --- /dev/null +++ b/AUFGABE_AUSSENDIENST_ARBEITSPROTOKOLL.md @@ -0,0 +1,95 @@ +# Außendienst: Arbeitsprotokoll auf dem Tablet, Rechnung fällt heraus + +Seine Idee vom 06.09.2026, wörtlich: + +> „mach es an der kundenanzahl fest, und die bekommen eine vorab-nummer, die reserviert ist von der +> disponentin. die kunden haben eh eine kundennummer — heißt, es ist nur die rechnungsnummer, die +> zugeteilt wird. und hans hat nur die kundennummer mit adresse und wohnort im log, wo er +> protokolliert: anfahrt drücken, angekommen drücken … dann arbeit start und stop, dann noch: was +> hat er eigentlich gemacht — also gleich arbeitsprotokoll — und abfahrt. plus die rechnung für den +> kunden anhand des arbeitsblocks, den wir schon haben." + +**Status: Idee. Nichts davon ist gebaut.** + +--- + +## Was sich dadurch ändert + +Die Rechnung wird **nicht mehr getippt, sondern fällt aus dem Arbeitsprotokoll heraus.** Wer ohnehin +Anfahrt, Ankunft, Beginn und Ende drückt, hat am Abend die Rechnung fast fertig, ohne sie +geschrieben zu haben. + +Damit ist das **ein anderes Produkt** als das heutige Rechnungstool: eine Auftrags- und +Zeiterfassung, bei der die Rechnung das Ergebnis ist. Der Arbeitsdatensatz wird primär, die Rechnung +abgeleitet. + +## Die Nummernlogik wird dadurch einfacher + +- **Die Kundennummer hat der Kunde schon.** Reserviert wird nur die **Rechnungsnummer**. +- Die Blockgröße ergibt sich aus den **zugeteilten Aufträgen** — siehe + `AUFGABE_ONLINE_API_MYSQL.md`, Abschnitt „Woher die Blockgröße kommt". +- Hans hat auf dem Gerät nur, was er braucht: Kundennummer, Anschrift, Ort. + +--- + +## ⭐⭐ ENTSCHEIDUNG (Andreas, 06.09.2026): Daten auf dem Server, Rechnung im BÜRO + +> „das liegt auf dem server, und im büro wird die rechnung geschrieben. denke, das ist sauber — +> aber so weit sind wir noch nicht." + +**Das räumt ein Problem ab, und zwar das größte.** + +Wird die Rechnung im Büro geschrieben, **entfällt die Offline-Nummernvergabe komplett**. Das Tablet +erfasst nur Arbeit — und ein Arbeitsprotokoll braucht **keine Rechnungsnummer**. Die entsteht im +Büro, wo Netz da ist. + +→ **Nummernkontingente, Puffer und Blockverlängerung werden damit von einer Voraussetzung zu einer +OPTION** — nötig erst, falls später doch beim Kunden live abgerechnet werden soll. Die Überlegungen +dazu bleiben in `AUFGABE_ONLINE_API_MYSQL.md` stehen, sind aber nicht mehr auf dem kritischen Weg. + +**Das Tablet muss dann nur zweierlei können:** +1. den **Kundenstamm zum Nachschlagen** vorhalten (Zwischenspeicher mit sichtbarem Alter) +2. die **Protokolle zwischenspeichern**, bis wieder Netz da ist + +Beides **ohne Nummernvergabe** — also ohne die Gefahr, dass zwei Geräte sich in die Quere kommen. + +## ⚠️ Drei Punkte, die vorher geklärt sein müssen + +### 1. ⭐ Erfasste Zeit ist NICHT berechnete Zeit + +Anfahrt ist mal berechenbar, mal nicht. Pausen laufen mit, gehören aber nicht auf die Rechnung. + +**Wird das Protokoll eins zu eins zur Rechnungszeile, streitet der Betrieb irgendwann mit dem Kunden +über eine Minute, die das Programm erfunden hat.** + +> **Regel: Aus dem Protokoll wird ein VORSCHLAG, aus dem Vorschlag die Rechnung.** Das Protokoll +> bleibt unverändert stehen, auch wenn anders abgerechnet wird. + +Dann ist beides sauber und man kann später erklären, warum abgewichen wurde. + +### 2. Start/Stopp drücken heißt: das ist ARBEITSZEIT + +Damit hängt Arbeitsrecht daran, nicht nur Steuerrecht: + +- Aufzeichnungs- und Aufbewahrungspflicht (**§ 16 ArbZG**) +- Die Aufzeichnungen gehören dem **Arbeitsverhältnis**, nicht dem Kunden +- → **getrennt von den Kundendaten behandeln**, und sie dürfen nicht einfach in der Rechnung landen + +### 3. ⚠️ „Anfahrt/Angekommen" ist Standortverfolgung von Mitarbeitern + +Sobald Zeiten und Orte zusammenkommen, ist es Mitarbeiterüberwachung. In Deutschland heikel: + +- braucht eine **Rechtsgrundlage** und klare **Zweckbindung** (Art. 88 DSGVO, § 26 BDSG) +- gibt es je einen **Betriebsrat**: mitbestimmungspflichtig (§ 87 Abs. 1 Nr. 6 BetrVG) + +**Beherrschbar, solange der Mitarbeiter selbst drückt** und nichts im Hintergrund mitläuft. Ein +Programm, das ohne Zutun aufzeichnet, wo jemand ist, wäre etwas völlig anderes — und dann wird es +ernst. + +--- + +## Was schon da ist und wiederverwendet wird + +- der **Arbeits-/Leistungsblock** (Katalog) aus dem Rechnungstool +- der **Kundenstamm** (offen, siehe `AUFGABE_KUNDENSTAMM_UND_WEB.md`) +- die **Nummernkontingente** (siehe `AUFGABE_ONLINE_API_MYSQL.md`) diff --git a/AUFGABE_ONLINE_API_MYSQL.md b/AUFGABE_ONLINE_API_MYSQL.md new file mode 100644 index 0000000..31ca040 --- /dev/null +++ b/AUFGABE_ONLINE_API_MYSQL.md @@ -0,0 +1,417 @@ +# Online-Betrieb: API, MySQL, Tablet, Rechnungsversand + +Seine Idee vom 06.09.2026, wörtlich: + +> „die software ist aktuell nur lokal, und da reicht sqlite. wenn wir die online funktion einbauen, +> dann muss man einen api key eintragen, und die api verteilt das auf die mysql — dann ist das +> extern auf dem server und du kannst von überall über domain und apikey auch unterwegs per tablet +> beim kunden die rechnung schreiben, live oder vorab-rechnung, und der smtp-server schickt sie +> direkt dem kunden auf die hinterlegte e-mail. fertig. alles automatisch." + +**Status: Idee. Nichts davon ist gebaut.** Der Schnitt ist richtig gedacht — lokal SQLite, zentral +MySQL, die API als einzige Tür dazwischen. + +--- + +## 1. ⭐ Die Rechnungsnummer darf nur vom Server kommen + +Heute stimmen sich zwei lokale Programme über eine gemeinsame SQLite ab. Zentral wird das +**einfacher**: eine Transaktion in MySQL vergibt die Nummer, fertig. + +**Aber:** Auf dem Tablet beim Kunden ohne Empfang darf keine Nummer entstehen. + +> **Regel: Offline entsteht ein ENTWURF, keine Rechnung.** Die Nummer wird vergeben, sobald der +> Server erreichbar ist. + +Sonst gibt es irgendwann zwei Belege mit derselben Nummer — genau der Fehler, wegen dem das +Amt-Blatt herausgeflogen ist (§ 14 Abs. 4 Nr. 4 UStG). + +Daraus folgt für die Oberfläche: Ein Entwurf muss **sichtbar** ein Entwurf sein, ohne Nummer, und +darf nicht ausgedruckt oder verschickt werden können. + +## ⭐⭐ Das Offline-Problem — und seine Lösung: NUMMERNKONTINGENTE + +Sein Einwand (06.09.2026): + +> „das ding, was wir haben, ist das offline-problem. wenn das internet schwach oder weg ist, bringt +> das online nichts — also musst du auf dem client eine kopie per sqlite haben. wie willst es sonst +> machen?" + +**Er hat recht, und das ersetzt die zu strenge Regel „offline nur Entwürfe" aus Punkt 1.** + +### Was zwischengespeichert werden kann — und was nicht + +| | offline möglich? | +|---|---| +| Kundenstamm, Preise, Einstellungen, alte Rechnungen zum Nachschlagen | **ja** — lokale SQLite, lesend, mit sichtbarem Alter | +| **Vergabe der Rechnungsnummer** | **nein** — zwei Geräte nähmen beide „die nächste" | + +### Die Lösung: der Server gibt Blöcke im Voraus aus + +So machen es Kassensysteme. Tablet A bekommt **2026-101 bis 2026-150**, Tablet B **2026-151 bis +2026-200**. Offline vergibt jedes Gerät aus **seinem eigenen** Block — eine Kollision ist +**unmöglich**, weil kein anderes Gerät diese Nummern besitzt. Bei Netz meldet es den Verbrauch und +holt einen neuen Block. + +→ **Damit sind beim Kunden echte Rechnungen möglich, nicht nur Entwürfe.** + +### Zwei Bedingungen, die dazugehören + +1. **Lücken werden normal — und müssen erklärbar sein.** Kommt Tablet A nur bis 2026-137 und holt + dann einen neuen Block, fehlen 138–150. Das ist zulässig: § 14 UStG verlangt eine **einmalig + vergebene** fortlaufende Nummer, ausdrücklich auch in mehreren Kreisen (z. B. je Filiale). + **Aber das System muss zeigen können, welcher Block wem gehörte und welche Nummern daraus nie + verbraucht wurden.** Sonst sieht ein Prüfer eine Lücke und fragt nach der Rechnung. + → Gehört in den **Steuerprüfungs-Ausdruck** (siehe `AUFGABE_BEWEISKETTE_PRUEFBAR.md`, Schritt 3). +2. **Der Block ist endlich.** Ist er verbraucht und kein Netz da, ist Schluss — dann wieder + Entwürfe. **Lieber ein Gerät, das sagt „ich kann gerade nicht", als eines, das sich Nummern + ausdenkt.** + +### ⭐⭐ Woher die Blockgröße kommt: aus der Disposition (Andreas, 06.09.2026) + +> „die disponentin hat jedem handwerker ja kunden zugeteilt — daraus kann ein block generiert +> werden. die software sagt: handwerker hans werner hat 10 kunden, also bekommt er block A mit 10 +> nummern, der hans werner heißt. dann ist es erklärbar, weil hans die kunden im log hatte. wenn er +> mehr kunden hatte, bekommt er von anfang an 10 puffernummern als schutz. und wenn die nicht +> gebraucht werden, bekommt er sie für den nächsten tag wieder. wenn sie voll sind, überspringt er +> in den nächsten block. der server hält selber immer reserve." + +**Der starke Punkt daran ist die Erklärbarkeit.** Ein Prüfer sieht reservierte Nummernbereiche und +fragt, warum ausgerechnet diese. Hier gibt es eine Antwort **aus dem Betrieb heraus**: Die +Disposition hat Hans an dem Tag zehn Kunden zugeteilt, also zehn Nummern plus Puffer. **Die +Zuteilung ist der Beleg für die Reservierung** — besser als jede technische Begründung. + +### ⚠️ Zwei Korrekturen daran + +**1. Der Block darf NICHT am Kalendertag hängen.** +*„Heute hast du 100 bis 110"* klingt logisch, ist aber gefährlich: Hat Hans zwei Tage keinen +Empfang, wäre er am zweiten Tag arbeitsunfähig, obwohl er noch Nummern hätte. + +> **Der Block gehört ihm, bis er ihn zurückmeldet. Kein Ablaufdatum.** Die Disposition gibt morgens +> neue *dazu*, nimmt aber nichts weg, was er noch hat. + +Am Bild der Disposition ändert das nichts — nur verhungert das Tablet nicht, wenn das Netz drei +Tage weg ist. + +**2. Eine Nummer ist erst verbraucht, wenn ein BELEG entsteht.** +Nicht bei der Zuteilung, und **nicht durch einen Entwurf**. Nur so stimmt, dass unbenutzte Nummern +am nächsten Tag wieder gelten — sonst würden Nummern wiederverwendet, die schon auf einem +Bildschirm standen. + +**Der Rest passt unverändert:** Puffer von Anfang an · Überspringen in den nächsten Block, wenn +voll · **Server hält eigene Reserve** für das, was die Disposition nicht wusste (Notfall, +Zusatzauftrag, Kunde ruft an). + +### ⭐ Beim Synchronisieren: Verbrauch melden, nicht blind neu ausgeben + +Sein Einwand (06.09.2026): + +> „wenn das tablet lte wieder hat, kann er das syncen und bekommt einen neuen block — oder sagt +> einfach: eh, ich habe aber in dem block erst 10 % genutzt" + +**Richtig, und das vermeidet Lücken statt sie nur zu erklären.** Das Gerät meldet seinen Stand: +*„2026-101 bis 110 verbraucht, 111 bis 150 gehören mir noch."* Der Server entscheidet: + +| Lage | Antwort | +|---|---| +| noch viel übrig | **nichts tun** — kein neuer Block, keine verbrannten Nummern | +| fast leer, folgende Nummern frei | **den vorhandenen Block VERLÄNGERN** (101–150 → 101–180) → **keine Lücke** | +| fast leer, folgende Nummern gehören schon jemandem | neuer Block weiter hinten → Lücke, aber eine, die der Server **benennen** kann | + +**Verlängern schlägt Neuausgabe.** Das ist der Unterschied zwischen einem System, das Lücken erzeugt +und sie hinterher erklären muss, und einem, das erst gar keine macht. + +### Warum das nicht optional ist + +> „kannst ja nicht kunden fragen nach wlan" + +Beim Kunden im Keller, im Neubau ohne Anschluss, auf dem Hof: kein WLAN, oft auch kein +Mobilfunknetz. Nach dem Passwort fragen macht kein Handwerker. + +**Zwei praktische Regeln daraus:** + +1. **Der Block muss großzügig sein** — nicht zehn Nummern, sondern so viele, dass eine Woche Arbeit + hineinpasst. Nummern kosten nichts, ein abgerissener Vorgang beim Kunden schon. +2. **Das Gerät warnt, BEVOR es eng wird.** *„Noch 5 Nummern im Vorrat, bitte einmal ins Netz"* — + solange man noch in der Werkstatt steht. Eine Warnung, die erst beim Kunden kommt, ist wertlos. + +Nachgefüllt wird **automatisch**, sobald irgendwo Netz da ist. Der Benutzer soll darüber nicht +nachdenken müssen. + +## 2. ⚠️ Beim Datenschutz kippt die Lage vollständig + +Heute lautet die Aussage im Programm: *Es verlässt nichts den Rechner.* Das ist der ganze +Datenschutztext. Sobald Gästedaten auf einem Server liegen, gilt die DSGVO in voller Breite: + +- verschlüsselte Übertragung (TLS), keine Ausnahme +- **Zugriffstrennung je Betrieb** — ein API-Schlüssel ist ein Passwort, keine Zugriffskontrolle +- Löschkonzept und Aufbewahrungsfristen (§ 147 AO) müssen zusammenpassen +- **Wenn er das für ANDERE Betriebe hostet, ist er deren Auftragsverarbeiter** und braucht einen + Vertrag nach Art. 28 DSGVO. Das ist keine Formalie, sondern Voraussetzung dafür, dass die + Betriebe das Programm überhaupt einsetzen dürfen. + +Der Datenschutztext im Programm muss dann neu geschrieben werden — der heutige wäre schlicht falsch. + +## 3. ⭐⭐ E-Rechnung (ZUGFeRD) — jetzt entscheiden, nicht später + +In Deutschland läuft die Pflicht zur elektronischen Rechnung im B2B an. Wer ein System baut, das +Rechnungen **per Mail verschickt**, sollte die PDF gleich mit **eingebettetem strukturiertem XML** +erzeugen (ZUGFeRD / PDF/A-3). + +Der Unterschied zwischen „von Anfang an mitgedacht" und „später nachrüsten" ist hier ein halber +Neubau: PDF/A-3 stellt andere Anforderungen an Schriften und Farbprofile als das heutige PDF, und +das XML muss aus denselben Daten kommen wie das Blatt — nicht daneben gepflegt werden. + +Stand schon auf der allerersten Aufgabenliste des Rechnungstools. + +## 4. Versand + +- **SMTP genügt zum Senden.** POP3/IMAP braucht man nur, um **Unzustellbarkeitsmeldungen** zu lesen + — und die *muss* man lesen. Sonst meldet das Programm „verschickt", und die Rechnung liegt + nirgends. +- **Eine per Mail verschickte Rechnung ist eine Rechnung** (§ 14 UStG). Für die GoBD muss das + Dokument **genau so archiviert werden, wie es verschickt wurde** — samt Versandnachweis. +- Zustellung ist nicht garantiert. Der Versandstatus gehört sichtbar in die Oberfläche, nicht nur + ins Log. + +## ⭐ Das Produktbild (Andreas, 06.09.2026) — lokal ist der Normalfall + +> „solange er den apikey mit domain nicht hat, kann er auch nur sqlite nutzen — reicht auch, wenn +> einer es als single programm für sich nutzt. will einer das online nutzen, dann trägt er beides +> ein, das programm synct einmal auf die mysql, fertig." + +**Damit ist der Aufbau entschieden: local-first, Online ist eine Zusatzfunktion, die man +einschaltet.** Wer nichts einträgt, merkt vom Server nichts. Kein Konto, keine Pflicht, keine +Abhängigkeit. + +### Die eine Regel, die den Umzug sicher macht + +**„Synct einmal" ist eine EINMALIGE ÜBERNAHME, keine ständige Synchronisierung in beide +Richtungen.** Danach gehört die Nummernvergabe dem Server; die lokale SQLite ist nur noch +Zwischenspeicher für Entwürfe (siehe Punkt 1). + +Zwei Richtungen dauerhaft offen zu halten hieße: zwei Stellen vergeben Nummern. Genau der Fehler, +wegen dem das Amt-Blatt herausflog. + +### Und daraus folgt eine Entscheidung VOR der ersten Übernahme + +Zwei Installationen, die beide 2026-001 bis 2026-050 vergeben haben, lassen sich **nicht** in eine +Datenbank übernehmen — dort lägen Nummern doppelt. Gehen je mehrere Betriebe auf denselben Server, +muss die **Trennung der Nummernkreise vorher** feststehen (eigene Datenbank je Betrieb, oder +Präfix je Betrieb). Nachträglich geht es nicht: die Belege sind dann schon beim Kunden. + +### Was der Umzug NICHT gefährdet + +**Die Wahrheit bleiben die Rechnungs-PDFs** — so steht es schon heute im Nummernbuch-Code: *„Die +Datei ist ein REGISTER, keine zweite Buchhaltung."* Geht bei der Übernahme etwas schief, fehlt +keine Rechnung; es muss nur neu eingelesen werden. + +## ⭐⭐ Die Umschaltung ist eine Tür, die nur in eine Richtung aufgeht + +Sein Modell (06.09.2026): + +> „ein einmal sync, danach ist es only online. die sql ist dann deaktiviert für immer — außer er +> trägt den key und die domain aus, dann hat er aber einen alten datenstand." + +> „das muss er mit einem popup — mit dem speichern-button, den es dafür gibt — am ende noch mal als +> ja/nein-frage kommen, ob ihm das bewusst ist, dass er sozusagen bei 0 anfängt." + +### Harte Anforderung + +**Beim SPEICHERN** von API-Schlüssel und Domain (nicht beim Eintippen) kommt eine Ja/Nein-Frage. +Beim Tippen weiß niemand, ob es ernst gemeint ist — beim Speichern schon. + +Entwurf des Textes: + +> **Auf Online-Betrieb umstellen?** +> +> Die vorhandenen Daten werden einmalig auf den Server übernommen. Danach läuft alles über den +> Server: Rechnungsnummern werden dort vergeben, und die lokale Datenbank wird **nicht mehr +> fortgeführt**. +> +> Entfernen Sie später Schlüssel und Domain, arbeitet das Programm wieder lokal weiter — dann aber +> mit dem Stand von **[Datum von heute]**. Alles, was zwischenzeitlich online entstanden ist, fehlt +> dort. +> +> Diese Umstellung lässt sich nicht rückgängig machen. +> +> Jetzt umstellen? + +Dasselbe Muster wie beim Erprobungshinweis und bei der Freigabe vor dem Beleg: Der Nutzer wird +**vorher** aufgeklärt, und die Entscheidung wird mit Datum vermerkt. + +### Die lokale Datenbank wird STILLGELEGT, nicht gelöscht + +Sie ist der Stand von damals und muss lesbar bleiben — schon wegen § 147 AO. + +### ⭐ Und der Punkt, der daran hängt: die PDFs müssen erreichbar bleiben + +Heute gilt in beiden Programmen: **Die Wahrheit sind die Rechnungs-PDFs, die Datenbank ist nur ein +Register.** Wird künftig auf dem Server erzeugt, muss der Betrieb **jederzeit an alle seine Belege +herankommen — als Dateien**, nicht nur als Ansicht im Browser. + +Der Grund ist **§ 147 AO: zehn Jahre Aufbewahrungspflicht.** Ein System, das den Betrieb von seinen +eigenen Belegen trennen kann — Server fällt aus, Vertrag endet, man zerstreitet sich — bringt den +BETRIEB in Schwierigkeiten. + +→ **Empfehlung: automatische lokale Kopie jeder Rechnung, auch im Online-Betrieb.** Dann bleibt der +Satz „die Wahrheit sind die PDFs" wahr, und der Betrieb hat seine Unterlagen auch dann, wenn nichts +mehr läuft. Das ist zugleich ein Verkaufsargument. + +## 📄 Paperless als Archiv (Andreas, 06.09.2026) — löst die Aufbewahrungsfrage + +> „ich dachte später an ein paperless — da muss eh alles rein" + +**Das ist die bessere Antwort auf § 147 AO als eine Exportfunktion.** Läuft jede Rechnung +automatisch in ein Dokumentensystem, liegt das Archiv **außerhalb** des Programms und überlebt +sowohl einen abgeschalteten Server als auch das Programm selbst. + +**Anbindung ist klein:** Paperless-ngx nimmt Dokumente über eine REST-Schnittstelle **oder über +einen überwachten Ordner** entgegen — Datei hineinlegen, fertig. Für das Rechnungstool eine +zusätzliche Zeile beim Speichern, kein Umbau. + +**⭐ Und die Verschlagwortung ist schon gebaut:** Rechnungsnummer, Datum, Beträge, Art und Vorgang +stehen bereits als maschinenlesbare Kenndaten im `/Subject` jeder PDF (das Steuerjournal liest sie +von dort). Daraus kann das Archiv seine Schlagworte ziehen — ohne Abtippen, ohne Texterkennung. + +⚠️ **Ehrlicher Vorbehalt:** Ein Dokumentensystem macht **nicht automatisch GoBD-konform**. Es +erfüllt den Kern (Belege bleiben unverändert und vollständig), aber dazu gehört eine +**Verfahrensdokumentation** — wie Belege entstehen, wohin sie laufen, wer was darf. Die schreibt +kein Programm. Ein großer Teil davon steht allerdings schon in den Aufgabendateien und +Commit-Texten dieser Projekte. + +## 🔑 Die API ist der Schlüssel zu allem (Andreas, 06.09.2026) + +> „das tool schickt es an die api, die api verteilt das alles. die api ist der schlüssel zu allem — +> wie beim gta fivem server" + +**Das ist seine eigene Serverregel, angewandt:** *Der Wille kommt vom Client, gerechnet wird auf dem +Server.* (Vgl. PcoreLife: nichts im Client, was Serversachen übernimmt.) + +| | Client (Tool/Tablet) | Server (API) | +|---|---|---| +| Was | „Rechnung für diese Leistungen an diesen Kunden" | Nummer vergeben, Beträge und Steuer rechnen, PDF erzeugen | +| Danach | zeigt an, was zurückkommt | verteilt: MySQL · Paperless · Mailversand | + +### ⭐ Folge 1: `berechnung.py` zieht auf den Server + +Heute steht dort ausdrücklich *„die einzige Stelle, an der gerechnet wird"*. Zentral gehört sie auf +den Server. + +**Das löst nebenbei die offene Frage aus `AUFGABE_KUNDENSTAMM_UND_WEB.md`:** die zwei Steuerwelten +(deutsche Bruttopreise 7/19 % gegen polnische Nettopreise mit Reverse Charge). Weiß der Server, +welcher Betrieb anfragt, weiß er auch, wie zu rechnen ist. **Der Client muss davon nichts wissen — +und die Frage „beide Welten in einem Programm oder zwei Fassungen" erledigt sich.** + +### ⭐ Die Aufgabenteilung im Einzelnen (Andreas, 06.09.2026) + +> „das tool schickt nur die metadaten, der server rendert die pdf und das tool bekommt den link. +> oder halt die vorschau muss es selber machen — das auf dem server ist dumm. und paperless macht +> den rest: archivieren und senden an die mitgegebene e-mail, und speichert das unter der +> kundennummer." + +| Wer | Was | +|---|---| +| **Tool** | schickt die Metadaten · zeichnet die **Vorschau lokal** · bekommt den Link zum fertigen PDF | +| **Server (API)** | vergibt die Nummer · rechnet · rendert das endgültige PDF · **verschickt per SMTP** · verteilt | +| **Paperless** | archiviert · verschlagwortet (Kundennummer als Korrespondent/Schlagwort) | + +**Vorschau lokal ist richtig:** ein Netzweg pro Tastendruck wäre sofort träge. + +### ⚠️ Die Regel, die dazugehört: EIN Zeichner, zwei Ausführungsorte + +Zeichnet das Tool die Vorschau und der Server das endgültige Blatt, gibt es **zwei Zeichner — und +zwei Zeichner driften auseinander**. Genau davor schützt sich der heutige Code bereits: +`berechnung.py` wird von Oberfläche UND PDF benutzt, *„damit Bildschirm und Ausdruck garantiert +identisch sind"*. + +Eine Vorschau, die nicht dem entspricht, was hinausgeht, ist **schlimmer als keine** — sie erzeugt +Vertrauen, das nicht gerechtfertigt ist. (Und die Vorschau war seine ausdrückliche Begründung für +das Ganze: *„sonst haben die den storno-aufwand"*.) + +→ **`pdf_renderer.py` und `berechnung.py` bleiben EINE gemeinsame Bibliothek**, die an zwei Orten +ausgeführt wird. Kein zweiter Code. + +### ⚠️ Korrektur: Paperless archiviert, es VERSCHICKT NICHT + +Paperless-ngx nimmt Dokumente entgegen, erkennt Text, verschlagwortet und lagert ein. **Rechnungen +an Kunden mailen kann es nicht.** Der Versand per SMTP gehört auf den Server / in die API. + +Die Ablage unter der Kundennummer geht dagegen sauber — Paperless kennt Korrespondenten und +Schlagworte, die Kundennummer passt in beides. + +### ⛔ Verworfen: PDF auf dem Client zeichnen und hochladen + +Andreas hatte es erwogen (*„ob das schlau ist, weiß ich nicht"*). **Nein**, aus einem Grund: + +Zeichnet der Client den endgültigen Beleg, entscheidet der Client, was darauf steht — und der +Server archiviert blind, was ankommt. Er könnte nicht mehr garantieren, dass zur Nummer, die er +vergeben hat, auch das Blatt gehört, das er ablegt. Eine ältere oder veränderte Fassung des Tools +erzeugte Dokumente, die niemand prüft. + +**Der Beleg entsteht dort, wo auch die Nummer entsteht.** Dazu käme: jede künftige Oberfläche +(Tablet, Browser) müsste den ganzen Renderer mitschleppen. + +Die **Vorschau** bleibt lokal — sie ist kein Beleg: ohne Nummer, mit Wasserzeichen, wie heute. + +### ⭐ Kundenstamm offline: ein ZWISCHENSPEICHER, kein Sync + +Seine Frage: *„wenn ein kunde eine kundennummer bekommt, wie willst die wiederfinden? musst die api +auch abfragen dafür — heißt, ohne internet wird da eh nichts. sonst musst wieder alles lokal und +online speichern, um das schnell zu halten, und dann nur eine art rsync raufpacken."* + +**Der Instinkt stimmt — nur ist es kein Sync, sondern ein Spiegel.** Der Unterschied ist keine +Wortklauberei: + +| | bedeutet | Folge | +|---|---|---| +| **Sync** | beide Seiten dürfen ändern | braucht Konfliktauflösung — wer gewinnt bei doppelter Änderung? | +| **Spiegel** | nur der Server besitzt die Daten, der Client hält eine Lesekopie | **keine Konflikte**, nur ein Stand, der mal älter ist | + +**Und die Datenmenge passt:** Kunden sind wenige und ändern sich selten — anders als Rechnungen. +Den ganzen Kundenstamm lokal zu halten kostet nichts und macht die Suche sofort schnell, auch ohne +Netz. + +**Sein Wort dafür: „eine Art Zwischenspeicher"** — und das ist ehrlicher als „Spiegel", weil es +schon sagt, dass er veralten darf. + +**Zwei Dinge braucht er, sonst wird er selbst zur Fehlerquelle:** + +1. **Er muss sein Alter zeigen.** Klein in der Oberfläche: *„Kundendaten vom 06.09.2026, 15:40"*. + Sonst sucht jemand einen Kunden, findet ihn nicht, legt ihn neu an — dabei war er nur seit + gestern nicht heruntergeladen. **Ein Zwischenspeicher, dem man sein Alter nicht ansieht, wird + irgendwann für die Wahrheit gehalten.** +2. **Er darf nie Quelle für etwas sein, das geschrieben wird.** Lesen und Suchen: ja. Eine Nummer + daraus vergeben: nie. Aufgefrischt wird beim Start (wenn Netz da ist) und auf Knopfdruck. + +**Dieselbe Regel wie bei den Rechnungsnummern:** Ein offline angelegter Kunde bekommt seine Nummer +**erst vom Server** — bis dahin ist er ein Entwurf. Sonst vergeben zwei Tablets dieselbe +Kundennummer. + +### Folge 2: der Client wird schlank + +Das Tablet beim Kunden braucht kein PDF-Werkzeug, keine Steuerlogik, keinen Nummernkreis. Ein Weg +hinein, mehrere hinaus. + +### Der Preis + +**Ohne Server geht nichts außer Entwürfen** (siehe Punkt 1). Bei FiveM ist das dasselbe — nur hängt +hier ein Beleg dran, den jemand zehn Jahre aufbewahren muss. + +### Sicherheit, weil „Schlüssel zu allem" wörtlich zutrifft + +Wenn ein Schlüssel alles öffnet, muss er: **je Installation** vergeben sein (nicht einer für alle), +**widerrufbar**, **nur über TLS** unterwegs, und die API muss **Missbrauch begrenzen** +(Rate-Limit). Sonst ist ein einziger abhandengekommener Schlüssel der Zugang zu allen Gästedaten. + +## 5. Offene Entscheidungen + +- Wer betreibt den Server, und für wen? (nur Bartl, oder mehrere Betriebe) +- Ein Mandant je Datenbank oder ein gemeinsames Schema mit Mandantenspalte? +- Was passiert mit dem lokalen Betrieb — bleibt SQLite als Offline-Fassung, oder wird alles zentral? +- Wie kommt der Bestand in die MySQL, ohne dass Nummern doppelt vergeben werden? + +--- + +**Nichts davon beginnen, bevor die Punkte 1 bis 3 entschieden sind** — sie bestimmen den Aufbau, +nicht die Ausstattung. diff --git a/Diagnose.spec b/Diagnose.spec new file mode 100644 index 0000000..d030d6f --- /dev/null +++ b/Diagnose.spec @@ -0,0 +1,48 @@ +# -*- mode: python ; coding: utf-8 -*- + + +a = Analysis( + ['app.py'], + pathex=[], + binaries=[], + # Roboto MUSS mit in die exe: sie wird nicht installiert, sondern beim Start + # nur fuer den Prozess geladen (theme.schrift_vorbereiten). Fehlt sie, faellt + # das Programm still auf Segoe UI zurueck - dann sieht es beim Kunden anders + # aus als hier. + datas=[('assets/programm.ico', 'assets'), + ('assets/programm_logo.png', 'assets'),('assets/logo.png', 'assets'), + ('assets/fonts', 'assets/fonts'), + # Die Icons (Material Symbols vom Hub) - ohne sie zeigen die Knoepfe + # nur ihren Text, aber der Anordnen-Griff fehlt. + ('assets/icons', 'assets/icons')], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + noarchive=False, + optimize=0, +) +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name='Diagnose', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + icon='assets/programm.ico', + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) diff --git a/Installer.iss b/Installer.iss new file mode 100644 index 0000000..86f6ce7 --- /dev/null +++ b/Installer.iss @@ -0,0 +1,95 @@ +; Installer fuer das Rechnungstool (Inno Setup 6) +; +; ENTSCHEIDUNGEN, DIE HIER STECKEN - und warum +; -------------------------------------------- +; 1. INSTALLATION PRO BENUTZER nach %LOCALAPPDATA%\Programs, NICHT nach +; "Program Files". Grund: der Updater muss die EXE ablegen duerfen. In +; Program Files darf ein normaler Benutzer nicht schreiben - jedes Update +; wuerde an fehlenden Rechten scheitern oder eine Administrator-Abfrage +; erzwingen. Chrome, VS Code, Discord, Teams und Fusion 360 machen es +; genauso, aus demselben Grund. +; +; 2. DIE VERKNUEPFUNG ZEIGT AUF DEN UPDATER, nicht auf das Programm. So schaut +; jeder Start zuerst nach einer neuen Fassung. Der Updater startet danach +; die eigentliche EXE - die ist dabei noch gar nicht in Benutzung und laesst +; sich deshalb problemlos ersetzen. +; +; 3. KEINE DATEN ANFASSEN. Der Installer legt keine Rechnungsordner an, kein +; Journal, kein Nummernbuch - und beim Deinstallieren wird davon nichts +; entfernt. Das Programm schreibt aufbewahrungspflichtige Belege +; (§ 147 AO, zehn Jahre). Ein Deinstallieren darf sie nie mitnehmen. +; +; 4. Der Eintrag unter "Apps & Features" entsteht von selbst - Inno Setup legt +; den Registry-Schluessel unter HKCU an. Da muss niemand von Hand hinein. + +#define Name "Rechnungstool" +#define Herausgeber "ravokk" +#define ExeUpdater "Updater.exe" +#define Webseite "https://git.pcore.de/TheMockTv/rechnungstool" + +[Setup] +AppId={{7F3A9C2E-51D4-4B86-9A17-2C0E8B4D6A31} +AppName={#Name} +AppVersion={#Version} +AppVerName={#Name} {#Version} +AppPublisher={#Herausgeber} +AppPublisherURL={#Webseite} +AppSupportURL={#Webseite}/issues +AppUpdatesURL={#Webseite}/releases + +; --- pro Benutzer, ohne Adminrechte --- +PrivilegesRequired=lowest +; Der Zielordner ist NICHT waehlbar. Wer hier "Programme" auswaehlen +; koennte, braeche sich den Updater: dort darf ein normaler Benutzer +; nicht schreiben. Chrome, Teams und Discord blenden diese Seite aus +; demselben Grund aus. In "Programme" gehoert hoechstens eine +; Verknuepfung - und die liegt ohnehin im Startmenue. +DisableDirPage=yes +DefaultDirName={localappdata}\Programs\{#Name} +DefaultGroupName={#Name} +DisableProgramGroupPage=yes +UsePreviousAppDir=yes + +OutputDir=setup +OutputBaseFilename=Rechnungstool-Setup-{#Version} +Compression=lzma2 +SolidCompression=yes +WizardStyle=modern +; Das Programmsymbol - auch fuer den Installer selbst und den +; Eintrag unter "Apps & Features". +SetupIconFile=assets\programm.ico +UninstallDisplayIcon={app}\{#ExeProgramm} +ArchitecturesInstallIn64BitMode=x64compatible + +; Erprobungsfassung - das steht auch im Programm selbst. +AppComments=Erprobungsfassung. Benutzung auf eigene Gefahr. + +[Languages] +Name: "deutsch"; MessagesFile: "compiler:Languages\German.isl" + +[Tasks] +Name: "desktopicon"; Description: "Verknüpfung auf dem Desktop anlegen"; \ + GroupDescription: "Zusätzliche Verknüpfungen:"; Flags: unchecked + +[Files] +; Der Updater - das ist, was der Benutzer startet. +Source: "dist\{#ExeUpdater}"; DestDir: "{app}"; Flags: ignoreversion +; Das Programm selbst, mit der Nummer im Namen. Der Updater erkennt daran, +; was installiert ist, und legt neue Fassungen daneben statt darueber. +Source: "dist\{#ExeProgramm}"; DestDir: "{app}"; Flags: ignoreversion + +[Icons] +; Beide Verknuepfungen zeigen auf den UPDATER, nicht auf das Programm. +Name: "{group}\{#Name}"; Filename: "{app}\{#ExeUpdater}" +Name: "{group}\{#Name} deinstallieren"; Filename: "{uninstallexe}" +Name: "{userdesktop}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#ExeUpdater}"; Description: "{#Name} jetzt starten"; \ + Flags: nowait postinstall skipifsilent + +[UninstallDelete] +; Nur die Buchfuehrung des Updaters. +; NICHTS von den Daten des Betriebs - keine Rechnungen, kein Journal, kein +; Nummernbuch. Die liegen ohnehin woanders und muessen zehn Jahre bleiben. +Type: files; Name: "{app}\installiert.json" diff --git a/Rechnungstool.spec b/Rechnungstool.spec new file mode 100644 index 0000000..57d1265 --- /dev/null +++ b/Rechnungstool.spec @@ -0,0 +1,48 @@ +# -*- mode: python ; coding: utf-8 -*- + + +a = Analysis( + ['app.py'], + pathex=[], + binaries=[], + # Roboto MUSS mit in die exe: sie wird nicht installiert, sondern beim Start + # nur fuer den Prozess geladen (theme.schrift_vorbereiten). Fehlt sie, faellt + # das Programm still auf Segoe UI zurueck - dann sieht es beim Kunden anders + # aus als hier. + datas=[('assets/programm.ico', 'assets'), + ('assets/programm_logo.png', 'assets'),('assets/logo.png', 'assets'), + ('assets/fonts', 'assets/fonts'), + # Die Icons (Material Symbols vom Hub) - ohne sie zeigen die Knoepfe + # nur ihren Text, aber der Anordnen-Griff fehlt. + ('assets/icons', 'assets/icons')], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + noarchive=False, + optimize=0, +) +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name='Rechnungstool', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=False, + disable_windowed_traceback=False, + icon='assets/programm.ico', + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) diff --git a/Updater.spec b/Updater.spec new file mode 100644 index 0000000..a82ec2a --- /dev/null +++ b/Updater.spec @@ -0,0 +1,24 @@ +# -*- mode: python ; coding: utf-8 -*- +# Der Updater ist der Starter: winzige Konsolen-EXE, die vor dem Programm laeuft. +a = Analysis( + ['updater.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=['version'], + hookspath=[], + runtime_hooks=[], + excludes=['tkinter', 'reportlab', 'PIL', 'pypdf', 'pypdfium2', 'numpy'], + noarchive=False, +) +pyz = PYZ(a.pure) +exe = EXE( + pyz, a.scripts, a.binaries, a.datas, [], + name='Updater', + debug=False, + strip=False, + upx=True, + console=True, + disable_windowed_traceback=False, + icon='assets/programm.ico', +) diff --git a/app.py b/app.py index b833b73..ade214f 100644 --- a/app.py +++ b/app.py @@ -32,6 +32,7 @@ import config import berechnung import gemeinsam import hinweis +import wasserzeichen import ordnerwahl import pdf_renderer from helfer import ANREDEN, kunde_maengel, parse_date, parse_num, saeubern, safe_filename, ziffern @@ -63,6 +64,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, super().__init__() self.cfg = config.load_config() self.title(config.PROGRAMM) + self._fenstersymbol() # Fensterhoehe an den Bildschirm anpassen, damit nichts unter den Rand rutscht hoehe = max(560, min(840, self.winfo_screenheight() - 90)) self.geometry(f"1060x{hoehe}") @@ -118,11 +120,12 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # es morgen ohne berichtigte Rechnung im Ordner und keiner weiss warum. self.protocol("WM_DELETE_WINDOW", self._beenden) - # after_idle statt after(0): laeuft, sobald Tk nichts mehr zu zeichnen hat - - # also nachdem das Hauptfenster steht. Bei after(0) haengt der modale Dialog - # an einem noch ungezeichneten Fenster und wirkt wie eingefroren; eine feste - # Wartezeit dagegen erreicht ein Pruefstand nie, der keine Schleife dreht. - self.after_idle(self._hinweis_pruefen) + # Der Hinweis darf erst aufgehen, wenn das Hauptfenster WIRKLICH + # gezeichnet ist. after_idle reicht dafuer nicht: in der gepackten + # EXE ist das Fenster dann noch nicht sichtbar, der modale Dialog + # sperrt es - und beide bleiben unsichtbar. Das sah aus wie ein + # haengendes Programm (06.09.2026, am Installer aufgefallen). + self.after(50, self._hinweis_wenn_sichtbar) # ---------------------------------------------------------------- Menue @@ -243,6 +246,11 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self.flaeche = flaeche.Arbeitsflaeche(self, farben=self) self.flaeche.pack(side="top", fill="both", expand=True, padx=10, pady=(4, 0)) + # Das Wasserzeichen liegt HINTER der Arbeitsflaeche, unten rechts. Es + # wird mit place() gesetzt, damit es die Anordnung der Kaesten nicht + # anfasst - die darf der Benutzer ja selbst verschieben. lower() legt + # es unter alles andere. + self._wasserzeichen_setzen() def _anordnen_umschalten(self): self.flaeche.anordnen_starten() @@ -611,6 +619,12 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, def _build_summen(self): # Statuszeile ganz unten status = ttk.Frame(self, padding=(12, 2)) + # Das Programmlogo neben der Marke - klein, immer sichtbar. Es steht + # rechts bei "powered by ravokk", weil dort die Kennung des Werkzeugs + # sitzt und nicht die des Kunden. + self._kopf_bild = wasserzeichen.kopf(18, master=self) + if self._kopf_bild is not None: + ttk.Label(status, image=self._kopf_bild).pack(side="right", padx=(0, 6)) status.pack(side="bottom", fill="x") ttk.Label(status, text=config.MARKE, foreground=self.col_muted, font=(theme.SCHRIFT_NAME, 8)).pack(side="right") @@ -644,6 +658,40 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # --------------------------------------------------- Gemeinsames Buch # ------------------------------------------------- Erprobungshinweis + + def _wasserzeichen_setzen(self, groesse=240): + """Das Programmlogo blass hinter die Arbeitsflaeche legen.""" + bild = wasserzeichen.hole(groesse, 0.06, master=self) + if bild is None: + return + # Die Referenz MUSS bleiben - sonst raeumt Python das Bild weg und Tk + # zeigt eine leere Flaeche (der klassische PhotoImage-Fehler). + self._wz_bild = bild + self._wz = tk.Label(self.flaeche, image=bild, borderwidth=0, + background=self.col_bg) + self._wz.place(relx=1.0, rely=1.0, anchor='se', x=-12, y=-12) + self._wz.lower() + + def _fenstersymbol(self): + """Das Programmsymbol auf das Fenster legen.""" + return wasserzeichen.symbol_setzen(self) + print("[symbol] assets/programm.ico nicht gefunden") + return False + + def _hinweis_wenn_sichtbar(self, versuche=0): + """Wartet, bis das Fenster gezeichnet ist, und fragt dann. + + winfo_viewable() sagt, ob das Fenster tatsaechlich auf dem Schirm + ist. Solange nicht, wird in kurzen Abstaenden nachgesehen. Nach + rund zwei Sekunden wird trotzdem gefragt - im Pruefstand ist das + Fenster absichtlich nicht sichtbar, und dort soll es trotzdem + laufen. + """ + if not self.winfo_viewable() and versuche < 40: + self.after(50, lambda: self._hinweis_wenn_sichtbar(versuche + 1)) + return + self._hinweis_pruefen() + def _hinweis_pruefen(self): """Hinweis auf die Erprobungsfassung. Ablehnen beendet das Programm. @@ -1821,7 +1869,11 @@ if __name__ == "__main__": if not fenster_nach_vorn(laufende_pid_lesen()): _r = tk.Tk() _r.withdraw() - self.melden_fehler( + # Hier gibt es kein self - das Fenster wird ja gerade NICHT gebaut. + # Deshalb die schlichte Windows-Meldung statt des eigenen Dialogs. + # (Frueher stand hier self.melden_fehler und ist beim Start eines + # zweiten Fensters mit NameError abgestuerzt.) + messagebox.showerror( "Rechnungstool läuft bereits", """Das Rechnungstool ist schon geöffnet, das Fenster ließ sich aber nicht nach vorn holen - bitte über die Taskleiste zurückwechseln. diff --git a/assets/programm.ico b/assets/programm.ico new file mode 100644 index 0000000000000000000000000000000000000000..cae16c942d04f204b66e0d334615784bcbb9b9d2 GIT binary patch literal 51609 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 D@5wHSQs+p{y`UNgS#s^sYSHUx3Z~ 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 Y!+B0Bvt)(!NC^BpY-C0*GH|){KNjM@{{R30 literal 0 HcmV?d00001 diff --git a/assets/programm_logo.svg b/assets/programm_logo.svg new file mode 100644 index 0000000..f16f814 --- /dev/null +++ b/assets/programm_logo.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bauen.py b/bauen.py new file mode 100644 index 0000000..2220498 --- /dev/null +++ b/bauen.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +"""Der ganze Weg von der Quelle zur Setup-Datei - an EINER Stelle. + +WARUM DAS HIER STEHT +-------------------- +Bis hierher lag der Bau in einer Folge von Befehlen, die jemand von Hand +eintippen musste: PyInstaller fuers Programm, PyInstaller fuer den Updater, +umbenennen, Inno Setup mit den richtigen Schaltern. Wer einen Schritt +vergisst, liefert eine Setup-Datei aus, die eine alte EXE enthaelt - und +niemand sieht es ihr an. Genau das ist am 06.09.2026 passiert (der Installer +schrieb ueber eine laufende, gesperrte EXE hinweg und meldete trotzdem Erfolg). + +Ab jetzt ist der Bau ein Befehl: + + python bauen.py + +WAS ER TUT +---------- +1. Die Nummer kommt aus version.py - nicht von der Kommandozeile. So kann sie + nicht auseinanderlaufen mit dem, was das Programm ueber sich selbst sagt. +2. Programm und Updater werden gebaut. +3. Die Programm-EXE bekommt die Nummer in den Namen. Der Updater erkennt daran, + welche Fassungen installiert sind, und legt neue DANEBEN statt darueber - + deshalb kann er auch dann austauschen, wenn Windows die alte Datei sperrt. +4. Inno Setup baut die Setup-Datei. +5. Zum Schluss stehen die SHA256-Summen da. Die gehoeren in den Release-Text: + nur damit laesst sich spaeter nachweisen, dass die heruntergeladene Datei + genau die gebaute ist. +""" +import hashlib +import os +import shutil +import subprocess +import sys + +HIER = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, HIER) + +import version # noqa: E402 + +# Inno Setup liegt bei ihm unter LOCALAPPDATA (Installation ohne Adminrechte). +ISCC_ORTE = [ + os.path.join(os.environ.get("LOCALAPPDATA", ""), "Programs", "Inno Setup 6", "ISCC.exe"), + r"C:\Program Files (x86)\Inno Setup 6\ISCC.exe", + r"C:\Program Files\Inno Setup 6\ISCC.exe", +] + + +def summe(pfad): + h = hashlib.sha256() + with open(pfad, "rb") as f: + for brocken in iter(lambda: f.read(1 << 20), b""): + h.update(brocken) + return h.hexdigest() + + +def lauf(befehl, was): + print(f"--- {was}") + e = subprocess.run(befehl, cwd=HIER, capture_output=True, text=True, + encoding="utf-8", errors="replace") + if e.returncode != 0: + print(e.stdout[-3000:]) + print(e.stderr[-3000:]) + raise SystemExit(f"{was} fehlgeschlagen (Rueckgabe {e.returncode})") + + +def iscc(): + for p in ISCC_ORTE: + if p and os.path.exists(p): + return p + raise SystemExit("ISCC.exe nicht gefunden - Inno Setup 6 fehlt") + + +def main(): + stamm, endung = os.path.splitext(version.EXE_NAME) + mit_nummer = f"{stamm}-{version.VERSION}{endung}" + + # Die Bauordner werden geleert. Ein PyInstaller-Lauf ueber einen alten + # Bauordner uebernimmt sonst Reste, die es in der Quelle nicht mehr gibt - + # und in setup/ laege noch die Datei der VORIGEN Nummer herum. Beim + # Ausliefern greift man dann leicht zur falschen. + for ordner in ("build", "dist", "setup"): + shutil.rmtree(os.path.join(HIER, ordner), ignore_errors=True) + + lauf([sys.executable, "-m", "PyInstaller", "--noconfirm", f"{stamm}.spec"], + f"{stamm} {version.VERSION}") + lauf([sys.executable, "-m", "PyInstaller", "--noconfirm", "Updater.spec"], + "Updater") + + quelle = os.path.join(HIER, "dist", version.EXE_NAME) + ziel = os.path.join(HIER, "dist", mit_nummer) + os.replace(quelle, ziel) + + lauf([iscc(), f"/DVersion={version.VERSION}", f"/DExeProgramm={mit_nummer}", + "Installer.iss"], "Setup") + + print() + print(f"FERTIG | {stamm} {version.VERSION}") + for name in sorted(os.listdir(os.path.join(HIER, "dist"))): + p = os.path.join(HIER, "dist", name) + print(f" {name:44s} {os.path.getsize(p):>10,d} B {summe(p)}") + setup = os.path.join(HIER, "setup") + for name in sorted(os.listdir(setup)) if os.path.isdir(setup) else []: + p = os.path.join(setup, name) + print(f" {name:44s} {os.path.getsize(p):>10,d} B {summe(p)}") + + +if __name__ == "__main__": + main() diff --git a/pdf_renderer.py b/pdf_renderer.py index 9797acc..a72f2a7 100644 --- a/pdf_renderer.py +++ b/pdf_renderer.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -PDF-Renderer fuer die Campinghof-Bartl-Rechnung (reportlab). +PDF-Renderer fuer die Rechnung (reportlab). render_rechnung(pfad, cfg, rechnung, kopf) erzeugt ein druckfertiges A4-PDF im Layout der Excel-Vorlage: diff --git a/pruef_hinweis.py b/pruef_hinweis.py index 6558969..09eb11c 100644 --- a/pruef_hinweis.py +++ b/pruef_hinweis.py @@ -22,6 +22,7 @@ Geprueft wird die ganze Strecke, weil jeder Teil fuer sich wertlos waere: """ import json import os +import time import shutil import sys import tempfile @@ -89,6 +90,25 @@ messagebox.showwarning = lambda *a, **k: None messagebox.showerror = lambda *a, **k: print("[fehler]", a[0] if a else "") +def pumpen(fenster, bedingung, sekunden=6): + """Ereignisschleife drehen, bis die Bedingung stimmt. + + Der Hinweis wartet, bis das Fenster gezeichnet ist, und meldet sich per + after(). Ein einzelnes update() erreicht das nicht - hier wird die Schleife + gedreht wie mainloop() es taete. Abgekuerzt wird nichts. + """ + ende = time.time() + sekunden + while time.time() < ende: + try: + fenster.update() + except Exception: # noqa: BLE001 - Fenster kann zwischendurch weg sein + return bedingung() + if bedingung(): + return True + time.sleep(0.02) + return bedingung() + + def gelesen(): return json.load(open(config.CONFIG_PATH, encoding="utf-8")) @@ -96,7 +116,7 @@ def gelesen(): # ---- 1./2. Ablehnen: Fenster zu, nichts vermerkt ----------------------- antworten["Erprobungsfassung"] = False f = A.RechnungsApp() -f.update() # laesst das after(0) laufen -> Hinweis kommt +pumpen(f, lambda: any("Erprobungsfassung" in t[0] for t in gesehen)) treffer = [t for t in gesehen if "Erprobungsfassung" in t[0]] pruefe(bool(treffer), "der Hinweis kommt beim Start") @@ -129,7 +149,7 @@ pruefe(not cfg.get("hinweis_zeit"), "nach Nein steht nichts in der Konfiguration gesehen.clear() antworten["Erprobungsfassung"] = True f = A.RechnungsApp() -f.update() +pumpen(f, lambda: any("Erprobungsfassung" in t[0] for t in gesehen)) pruefe(any("Erprobungsfassung" in t[0] for t in gesehen), "beim naechsten Start wird wieder gefragt") @@ -147,7 +167,7 @@ pruefe("gelesen und zur kenntnis genommen" in sig.lower(), gesehen.clear() f.destroy() f = A.RechnungsApp() -f.update() +pumpen(f, lambda: any("Erprobungsfassung" in t[0] for t in gesehen), sekunden=2) pruefe(not any("Erprobungsfassung" in t[0] for t in gesehen), "nach dem Ja wird nicht noch einmal gefragt") @@ -156,7 +176,7 @@ gesehen.clear() f.destroy() H.FASSUNG = "9999-12-31" # so, als waere der Text geaendert worden f = A.RechnungsApp() -f.update() +pumpen(f, lambda: any("Erprobungsfassung" in t[0] for t in gesehen)) pruefe(any("Erprobungsfassung" in t[0] for t in gesehen), "bei geaenderter Fassung wird erneut gefragt") diff --git a/pruef_selbstbezug.py b/pruef_selbstbezug.py new file mode 100644 index 0000000..d8a6e84 --- /dev/null +++ b/pruef_selbstbezug.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: `self` darf nur dort stehen, wo es auch eines gibt. + +DER FALL, DER DAZU GEFUEHRT HAT (06.09.2026) +-------------------------------------------- +Nach dem Installieren meldete das Programm beim Start: + + File "app.py", line 1824, in + NameError: name 'self' is not defined + +Im `if __name__ == "__main__"`-Block stand `self.melden_fehler(...)`. Dort gibt +es kein `self` - das Fenster wird ja gerade NICHT gebaut. Beim Umbau auf die +eigenen Meldungsfenster war die Zeile mitgezogen worden. + +WARUM DAS KEINE SYNTAXPRUEFUNG FINDET +------------------------------------- +`ast.parse` und `py_compile` pruefen die FORM, nicht die Bedeutung. Ein +undefinierter Name faellt erst auf, wenn die Zeile ausgefuehrt wird - und diese +hier laeuft nur, wenn ein ZWEITES Fenster gestartet wird und sich das erste +nicht nach vorn holen laesst. Also fast nie. Genau deshalb ist sie durch alle +Pruefstaende gekommen. + +WAS HIER GEPRUEFT WIRD +---------------------- +Jede Verwendung des Namens `self` muss in einer Funktion stehen, die `self` auch +als ersten Parameter hat. Alles andere ist ein Ueberbleibsel aus einer Methode. + +Geprueft werden beide Programme - der Fehler war in einem, haette aber genauso +im anderen stecken koennen. +""" +import ast +import io +import os +import sys + +ORDNER = [r"C:\claude\rechnungstool", r"C:\claude\beherbergungssteuer"] + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +def fundstellen(quelltext): + """Alle Zeilen, in denen `self` steht, ohne dass es eines gibt.""" + baum = ast.parse(quelltext) + treffer = [] + + def erster_parameter(knoten): + args = knoten.args + alle = list(args.posonlyargs) + list(args.args) + return alle[0].arg if alle else None + + def durchgehen(knoten, hat_self): + for kind in ast.iter_child_nodes(knoten): + if isinstance(kind, (ast.FunctionDef, ast.AsyncFunctionDef)): + # Eine verschachtelte Funktion in einer Methode darf `self` aus + # der umgebenden Methode benutzen - das ist ein Abschluss und + # voellig richtig. Verfuegbar ist es also, sobald IRGENDEINE + # umgebende Funktion es als ersten Parameter hat. + durchgehen(kind, hat_self or erster_parameter(kind) == "self") + elif isinstance(kind, ast.Lambda): + durchgehen(kind, hat_self) + else: + if isinstance(kind, ast.Name) and kind.id == "self" and not hat_self: + treffer.append(kind.lineno) + durchgehen(kind, hat_self) + + durchgehen(baum, False) + return sorted(set(treffer)) + + +# ---- 1. Die Pruefung muss den bekannten Fehler FINDEN ------------------- +# Sonst prueft sie nichts und wiegt uns in Sicherheit. +kaputt = ( + "class A:\n" + " def m(self):\n" + " self.x = 1\n" + "\n" + 'if __name__ == "__main__":\n' + " self.melden_fehler('geht nicht')\n" +) +gefunden = fundstellen(kaputt) +pruefe(gefunden == [6], + f"die Pruefung findet den bekannten Fehler in Zeile 6 (gefunden: {gefunden})") + +sauber = ( + "class A:\n" + " def m(self):\n" + " self.x = 1\n" + " f = lambda: self.x\n" + " return f\n" +) +pruefe(fundstellen(sauber) == [], + "und meldet sauberen Code nicht faelschlich") + +# ---- 2. Beide Programme durchgehen ------------------------------------- +for ordner in ORDNER: + for name in sorted(os.listdir(ordner)): + if not name.endswith(".py"): + continue + pfad = os.path.join(ordner, name) + try: + quelle = io.open(pfad, encoding="utf-8").read() + stellen = fundstellen(quelle) + except (OSError, SyntaxError) as e: + pruefe(False, f"{name} liess sich nicht lesen ({e})") + continue + if stellen: + pruefe(False, f"{os.path.basename(ordner)}/{name}: `self` ohne self " + f"in Zeile(n) {stellen}") + +pruefe(True, f"{len(ORDNER)} Programme durchgegangen") + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Nirgends steht `self`, wo es keines gibt") diff --git a/pruef_start_exe.py b/pruef_start_exe.py new file mode 100644 index 0000000..04f02fb --- /dev/null +++ b/pruef_start_exe.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: kommt bei der GEBAUTEN EXE wirklich ein Fenster? + +DER FALL, DER DAZU GEFUEHRT HAT (06.09.2026) +-------------------------------------------- +Nach dem Installieren lief das Programm - im Taskmanager stand es da, es +verbrauchte Rechenzeit - und auf dem Bildschirm war NICHTS. Ursache: der +Erprobungshinweis ging auf, bevor das Hauptfenster gezeichnet war. Der modale +Dialog sperrte das Hauptfenster, und beide blieben unsichtbar. + +WARUM DAS KEIN ANDERER PRUEFSTAND FINDET +---------------------------------------- +Alle uebrigen Pruefstaende fahren das Programm aus der QUELLE. Dort ist das +Fenster sofort gezeichnet, der Fehler tritt nicht auf. Er gehoert zur gepackten +EXE - also muss genau die gestartet werden. + +Und "der Prozess laeuft" beweist nichts: er lief ja. Geprueft wird deshalb, ob +Windows ein Fenster dieses Programms als SICHTBAR fuehrt. + +ZWEI FALLEN, die hier schon zugeschnappt sind: + * Eine PyInstaller-Onefile-EXE ist zweistufig. Der gestartete Prozess packt + nur aus; das Fenster gehoert dem KIND. Wer nur die eigene PID betrachtet, + sieht nie ein Fenster. + * terminate() beendet nur den Auspacker. Das Kind laeuft weiter - und dessen + Einzelinstanz-Sperre haelt danach jeden weiteren Start ab. Es muss die + ganze Sippe beendet werden. +""" +import ctypes +import os +import subprocess +import sys +import time +from ctypes import wintypes + +HIER = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, HIER) + +import version # noqa: E402 + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +stamm, endung = os.path.splitext(version.EXE_NAME) +EXE = os.path.join(HIER, "dist", f"{stamm}-{version.VERSION}{endung}") + +if not os.path.exists(EXE): + print(f"UEBERSPRUNGEN | {os.path.basename(EXE)} ist nicht gebaut " + f"(vorher: python bauen.py)") + sys.exit(0) + +u = ctypes.windll.user32 +p = subprocess.Popen([EXE]) +print(f" (gestartet: {os.path.basename(EXE)}, PID {p.pid})") + +RUECKRUF = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM) +gefunden = [] +verwandte = {p.pid} + + +def sippe(): + alle = {p.pid} + try: + e = subprocess.run( + ["powershell", "-NoProfile", "-Command", + "Get-CimInstance Win32_Process | Where-Object " + f"{{ $_.ParentProcessId -eq {p.pid} }} | ForEach-Object {{ $_.ProcessId }}"], + capture_output=True, text=True, timeout=20) + for zeile in e.stdout.split(): + if zeile.strip().isdigit(): + alle.add(int(zeile.strip())) + except Exception: # noqa: BLE001 - dann bleibt es bei der eigenen PID + pass + return alle + + +def je_fenster(hwnd, _): + pid = wintypes.DWORD() + u.GetWindowThreadProcessId(hwnd, ctypes.byref(pid)) + if pid.value not in verwandte: + return True + laenge = u.GetWindowTextLengthW(hwnd) + puffer = ctypes.create_unicode_buffer(laenge + 1) + u.GetWindowTextW(hwnd, puffer, laenge + 1) + r = wintypes.RECT() + u.GetWindowRect(hwnd, ctypes.byref(r)) + gefunden.append((puffer.value, bool(u.IsWindowVisible(hwnd)), + r.right - r.left, r.bottom - r.top)) + return True + + +ende = time.time() + 60 +sichtbar = False +vorzeitig_weg = False +while time.time() < ende and not sichtbar: + if p.poll() is not None: + vorzeitig_weg = True + break + verwandte = sippe() + gefunden.clear() + u.EnumWindows(RUECKRUF(je_fenster), 0) + # Ein "Fenster" von wenigen Pixeln ist Verwaltung (IME, Notifier), kein + # Programmfenster. Deshalb die Groesse mitpruefen. + sichtbar = any(s and b > 300 and h > 300 for _, s, b, h in gefunden) + time.sleep(0.5) + +for titel, s, b, h in gefunden: + print(f" {titel!r:42s} sichtbar={s} {b}x{h}") + +pruefe(not vorzeitig_weg, + f"das Programm bleibt am Leben (Rueckgabe {p.returncode})" + if vorzeitig_weg else "das Programm bleibt am Leben") +if vorzeitig_weg and p.returncode == 0: + print(" (Rueckgabe 0 heisst meist: es laeuft schon eine Fassung. " + "Erst beenden, dann noch einmal.)") + +pruefe(sichtbar, "ein sichtbares Programmfenster ist da") +pruefe(any(str(t).startswith(stamm) and s for t, s, _, _ in gefunden), + f"und es traegt den Programmnamen ({stamm})") + +subprocess.run(["taskkill", "/PID", str(p.pid), "/T", "/F"], capture_output=True) +try: + p.wait(10) +except subprocess.TimeoutExpired: + p.kill() + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Die gebaute EXE zeigt ein Fenster") diff --git a/pruef_updater.py b/pruef_updater.py index e1bebef..227bc3c 100644 --- a/pruef_updater.py +++ b/pruef_updater.py @@ -196,6 +196,31 @@ pruefe(os.path.basename(start) == "Rechnungstool-1.9.0.exe", pruefe(not any("Wird geladen" in m for m in meldungen), f"und nichts noch einmal geladen ({meldungen})") +# 8. Ordner nicht beschreibbar -> kein Update, aber das Programm startet +# Sein Einwand: "was ist, wenn ein user den ordner aendert?" Liegt die +# Installation dann in einem geschuetzten Ordner, darf das Update scheitern - +# aber NIE der Start. Ein fehlgeschlagenes Update, nach dem gar nichts mehr +# geht, waere schlimmer als kein Update. +meldungen.clear() +gesperrt = os.path.join(tmp, "gesperrt") +os.makedirs(gesperrt) +with open(os.path.join(gesperrt, "Rechnungstool-1.6.0.exe"), "wb") as f: + f.write(b"INSTALLIERT") + +echt_beschreibbar = U.beschreibbar +U.beschreibbar = lambda _o: False # so, als waere es "Programme" +try: + start = U.durchlauf(gesperrt, "x/y", EXE, sagen=sagen, holen_=lambda _r: [richtig]) +finally: + U.beschreibbar = echt_beschreibbar + +pruefe(os.path.basename(start) == "Rechnungstool-1.6.0.exe", + "geschuetzter Ordner: die vorhandene Fassung wird trotzdem gestartet") +pruefe(any("nicht geschrieben werden" in m for m in meldungen), + f"und es wird gesagt, warum ({meldungen})") +pruefe(not os.path.exists(os.path.join(gesperrt, "Rechnungstool-1.9.0.exe")), + "es wurde nichts abgelegt") + shutil.rmtree(tmp, ignore_errors=True) if fehler: diff --git a/updater.py b/updater.py index f06b06c..5db2447 100644 --- a/updater.py +++ b/updater.py @@ -129,6 +129,22 @@ def summe_aus_release(release, exe_name): # --------------------------------------------------------------------------- # Laden und pruefen # --------------------------------------------------------------------------- +def beschreibbar(ordner): + """Darf in diesen Ordner geschrieben werden? Wird ausprobiert, nicht geraten. + + Ein nicht beschreibbarer Ordner sieht von aussen genauso aus wie ein + beschreibbarer - erst der Versuch zeigt es. + """ + probe = os.path.join(ordner, ".schreibprobe") + try: + with open(probe, "w", encoding="ascii") as f: + f.write("x") + os.remove(probe) + return True + except OSError: + return False + + def sha256(pfad): h = hashlib.sha256() with open(pfad, "rb") as f: @@ -309,6 +325,16 @@ def durchlauf(ordner, repository, exe_name, sagen=print, holen_=None): sagen(f"{os.path.basename(ziel)} liegt schon da. Es wird gestartet.") return ziel + # Kann in den Installationsordner ueberhaupt geschrieben werden? Liegt die + # Installation in einem geschuetzten Ordner (etwa "Programme"), schlaegt das + # Ablegen fehl. Dann wird NICHT geladen - und vor allem: das Programm + # startet trotzdem. Ein fehlgeschlagenes Update darf nie dazu fuehren, dass + # gar nichts mehr geht. + if not beschreibbar(ordner): + sagen(f"In {ordner} darf nicht geschrieben werden - kein Update moeglich.") + sagen("Es wird die vorhandene Fassung gestartet.") + return hier_pfad + sagen(f"Neue Fassung {dort} gefunden (vorhanden: {hier}). Wird geladen ...") zwischen = tempfile.mkdtemp(prefix="update_") geladen = os.path.join(zwischen, exe_name) @@ -332,7 +358,12 @@ def durchlauf(ordner, repository, exe_name, sagen=print, holen_=None): return hier_pfad # Erst jetzt in den Installationsordner - vorher lag nichts Halbes dort. - shutil.move(geladen, ziel) + try: + shutil.move(geladen, ziel) + except OSError as e: # noqa: BLE001 + sagen(f"Die neue Fassung konnte nicht abgelegt werden ({e}).") + sagen("Es wird die vorhandene Fassung gestartet.") + return hier_pfad buch_schreiben(ordner, {"version": dort.lstrip("v"), "datei": os.path.basename(ziel), "sha256": erwartete_summe, diff --git a/version.py b/version.py index 4da2e80..acce0ab 100644 --- a/version.py +++ b/version.py @@ -10,11 +10,11 @@ und NUR hier; alles andere (Info-Dialog, Updater, Release) liest sie von hier. Regel ----- Die Nummer wird beim Ausliefern erhoeht und entspricht dem Release-Tag ohne das -"v": Tag `v1.6.0` -> VERSION "1.6.0". Wer das eine ohne das andere aendert, +"v": Tag `v1.7.0` -> VERSION "1.7.0". Wer das eine ohne das andere aendert, baut dem Updater eine Falle. """ -VERSION = "1.6.0" +VERSION = "1.7.0" # Zu welchem Repository dieses Programm gehoert - der Updater sucht dort. REPOSITORY = "TheMockTv/rechnungstool" diff --git a/wasserzeichen.py b/wasserzeichen.py new file mode 100644 index 0000000..935ba0a --- /dev/null +++ b/wasserzeichen.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +"""Das Programmlogo - als Fenstersymbol und als blasses Wasserzeichen. + +WOHER DAS BILD KOMMT +-------------------- +Die Quelle ist die SVG aus dem Entwurf (`assets/programm_logo.svg`). Sie wird +BEIM BAUEN einmal in 512 Pixel gerendert (`assets/programm_logo.png`) und in +eine `programm.ico` fuer Windows umgesetzt. Hier zur Laufzeit wird nur noch +skaliert. + +Warum nicht direkt aus der SVG zeichnen? Weil dafuer `svglib` und `lxml` mit in +die EXE muessten - und bis 512 Pixel ist das Ergebnis pixelgenau dasselbe. Wird +das Wasserzeichen je groesser gebraucht, gehoert das umgestellt. + +Warum ueberhaupt eine ICO? Weil Windows das Symbol einer EXE als Ressource in +der Datei erwartet, und dieses Format ist ICO. Das gilt fuer jede Sprache, nicht +nur fuer Python - eine SVG kann Windows dort nicht verwenden. + +Diese Datei liegt in BEIDEN Programmen gleich. Wer sie aendert, kopiert sie +hinueber. +""" + +import os +import sys +import tkinter as tk + +_lager = {} # (fenster, groesse, deckkraft) -> PhotoImage + + +def _ordner(): + """Alle Orte, an denen die Bilder liegen koennen - Quelle wie EXE.""" + hier = os.path.dirname(os.path.abspath(__file__)) + aus_exe = getattr(sys, "_MEIPASS", "") + neben_exe = os.path.dirname(os.path.abspath(sys.executable)) \ + if getattr(sys, "frozen", False) else "" + return [p for p in (aus_exe, neben_exe, hier) if p] + + +def pfad(name): + """Voller Pfad zu einer Datei in assets/ - oder ''.""" + for basis in _ordner(): + p = os.path.join(basis, "assets", name) + if os.path.exists(p): + return p + return "" + + +def symbol_setzen(fenster, melden=print): + """Das Programmsymbol auf ein Fenster legen. True bei Erfolg. + + Die EXE traegt es ohnehin - das Fenster aber nicht von selbst. Ohne das + steht in der Titelleiste das nackte Tk-Symbol, obwohl die Datei ein eigenes + hat. + """ + p = pfad("programm.ico") + if not p: + melden("[symbol] assets/programm.ico nicht gefunden") + return False + try: + fenster.iconbitmap(default=p) + return True + except Exception as e: # noqa: BLE001 - ohne Symbol laeuft es weiter + melden(f"[symbol] konnte nicht gesetzt werden: {e}") + return False + + +def hole(groesse=240, deckkraft=0.06, master=None, melden=print): + """Das Logo blass als PhotoImage - oder None. + + `deckkraft` 0..1, klein halten. Ein Wasserzeichen, das man LIEST, stoert + beim Arbeiten; eines, das man ahnt, gehoert zum Programm. + + `master` MUSS mitgegeben werden, wenn mehr als ein Tk-Fenster laeuft: + sonst gehoert das Bild dem falschen Fenster und Tk meldet spaeter, es + kenne es nicht. + """ + fenster = master if master is not None else tk._default_root + if fenster is None: + return None + schluessel = (id(fenster), groesse, round(deckkraft, 3)) + if schluessel in _lager: + return _lager[schluessel] + p = pfad("programm_logo.png") + if not p: + melden("[wasserzeichen] assets/programm_logo.png nicht gefunden") + return None + try: + from PIL import Image, ImageTk + bild = Image.open(p).convert("RGBA").resize((groesse, groesse), Image.LANCZOS) + bild.putalpha(bild.getchannel("A").point(lambda w: int(w * deckkraft))) + fertig = ImageTk.PhotoImage(bild, master=fenster) + except Exception as e: # noqa: BLE001 - ein Wasserzeichen darf nichts blockieren + melden(f"[wasserzeichen] nicht ladbar: {e}") + return None + _lager[schluessel] = fertig + return fertig + + +def kopf(hoehe=28, master=None, melden=print): + """Das Logo fuer die Kopfzeile - volle Deckkraft, kleine Hoehe. + + Getrennt von hole(): dort geht es um ein blasses Wasserzeichen, hier um ein + Erkennungszeichen. Zwei Zwecke, zwei Funktionen - sonst haette eine davon + einen Schalter, den man beim Lesen nachschlagen muss. + """ + return hole(hoehe, 1.0, master=master, melden=melden) From 8a391b8dfa482763c0fe2ea45c0c1d2317fa05b0 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sun, 6 Sep 2026 20:43:15 +0200 Subject: [PATCH 22/34] Release-Anhaenge: der Name entscheidet - und ein Pruefstand dafuer Der Fehler Das Release 1.7.0 war angelegt, die EXE hing dran - und der Updater haette trotzdem nie etwas gefunden. Der Anhang hiess "Rechnungstool-1.7.0.exe", gesucht wird aber "Rechnungstool.exe" (version.EXE_NAME). Die Nummer kommt erst beim Ablegen dazu. Das Tueckische: nichts schlaegt fehl. Der Updater meldet freundlich "Aktuell. Kein Update noetig." und startet die alte Fassung. Ein Update, das stumm nie ankommt, ist schlimmer als eines, das laut scheitert. Zweiter Fund derselben Runde: die Pruefsummen standen nur im Release-TEXT. Der Updater liest sie aus einer angehaengten Datei .sha256. Ohne die prueft er nur die Groesse - und eine verfaelschte Datei hat genau die richtige Groesse. bauen.py legt jetzt release/ an Genau die vier Dateien, die ans Release gehoeren, unter genau den Namen, unter denen der Updater sie sucht. Damit haengt niemand mehr etwas Falsches an. pruef_release.py Prueft gegen das echte Repository: gibt es zur Nummer aus version.py ein Release, heisst der Anhang exakt wie EXE_NAME, haengt die Pruefsumme dran, ist es die der zuletzt gebauten Datei - und findet passendes_release() es auch. Ohne Netz wird uebersprungen statt rot gemeldet. muster/ ist raus Der Gast darin ist erfunden, der Betrieb nicht: IBAN, Steuernummer und die private Rufnummer des Auftraggebers stehen im Briefkopf. In ein oeffentliches Repository gehoert das nicht. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- bauen.py | 33 ++++++++++++---- pruef_release.py | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 pruef_release.py diff --git a/bauen.py b/bauen.py index 2220498..5ef69f5 100644 --- a/bauen.py +++ b/bauen.py @@ -79,7 +79,7 @@ def main(): # Bauordner uebernimmt sonst Reste, die es in der Quelle nicht mehr gibt - # und in setup/ laege noch die Datei der VORIGEN Nummer herum. Beim # Ausliefern greift man dann leicht zur falschen. - for ordner in ("build", "dist", "setup"): + for ordner in ("build", "dist", "setup", "release"): shutil.rmtree(os.path.join(HIER, ordner), ignore_errors=True) lauf([sys.executable, "-m", "PyInstaller", "--noconfirm", f"{stamm}.spec"], @@ -94,14 +94,33 @@ def main(): lauf([iscc(), f"/DVersion={version.VERSION}", f"/DExeProgramm={mit_nummer}", "Installer.iss"], "Setup") + # ---- release/ : genau das, was ins Release gehoert --------------------- + # Der Anhang, den der Updater sucht, heisst OHNE Nummer - so steht es in + # version.EXE_NAME, und danach sucht passendes_release(). Haengt man ihn + # mit Nummer an, findet der Updater nie ein Update und meldet stumm + # "aktuell". Die Nummer kommt erst beim Ablegen dazu (updater.dateiname). + # + # Daneben die Pruefsumme als eigene Datei: ohne sie prueft der Updater nur + # die GROESSE. Eine Datei, die unterwegs verfaelscht wurde, hat aber genau + # die richtige Groesse. + freigabe = os.path.join(HIER, "release") + os.makedirs(freigabe, exist_ok=True) + shutil.copy2(ziel, os.path.join(freigabe, version.EXE_NAME)) + with open(os.path.join(freigabe, version.EXE_NAME + ".sha256"), + "w", encoding="ascii") as f: + f.write(summe(ziel) + chr(10)) + shutil.copy2(os.path.join(HIER, "dist", "Updater.exe"), + os.path.join(freigabe, "Updater.exe")) + for name in os.listdir(os.path.join(HIER, "setup")): + shutil.copy2(os.path.join(HIER, "setup", name), + os.path.join(freigabe, name)) + print() print(f"FERTIG | {stamm} {version.VERSION}") - for name in sorted(os.listdir(os.path.join(HIER, "dist"))): - p = os.path.join(HIER, "dist", name) - print(f" {name:44s} {os.path.getsize(p):>10,d} B {summe(p)}") - setup = os.path.join(HIER, "setup") - for name in sorted(os.listdir(setup)) if os.path.isdir(setup) else []: - p = os.path.join(setup, name) + print() + print(" release/ - genau diese Dateien gehoeren ans Release:") + for name in sorted(os.listdir(freigabe)): + p = os.path.join(freigabe, name) print(f" {name:44s} {os.path.getsize(p):>10,d} B {summe(p)}") diff --git a/pruef_release.py b/pruef_release.py new file mode 100644 index 0000000..0616fa8 --- /dev/null +++ b/pruef_release.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: passt das VEROEFFENTLICHTE Release zu dem, was der Updater sucht? + +DER FALL, DER DAZU GEFUEHRT HAT (06.09.2026) +-------------------------------------------- +Das Release war angelegt, die EXE hing dran - und der Updater haette trotzdem +nie etwas gefunden. Der Anhang hiess `Rechnungstool-1.7.0.exe`; gesucht wird +aber `Rechnungstool.exe` (so steht es in version.EXE_NAME, und danach sucht +passendes_release). Die Nummer kommt erst beim ABLEGEN dazu. + +Das Tueckische daran: nichts schlaegt fehl. Der Updater meldet freundlich +"Aktuell. Kein Update noetig." und startet die alte Fassung. Ein Update, das +stumm nie ankommt, ist schlimmer als eines, das laut scheitert. + +Zweiter Fund derselben Runde: die Pruefsummen standen nur im Release-TEXT. Der +Updater liest sie aus einer angehaengten Datei `.sha256`. Ohne die prueft +er nur die Groesse - und eine unterwegs verfaelschte Datei hat genau die +richtige Groesse. + +WAS HIER GEPRUEFT WIRD +---------------------- +Gegen das echte Repository, nicht gegen einen Nachbau: + + 1. Zu der Nummer in version.py gibt es ein Release. + 2. Es haengt eine Datei mit EXAKT dem Namen aus version.EXE_NAME an. + 3. Es haengt die Pruefsumme `.sha256` an. + 4. Die Summe darin ist die der angehaengten Datei - und die stimmt mit dem + ueberein, was hier zuletzt gebaut wurde (release/). + 5. passendes_release() findet dieses Release auch wirklich. + +Ohne Netz wird uebersprungen statt rot gemeldet: ein fehlender Anschluss ist +kein Fehler des Programms. +""" +import os +import sys + +HIER = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, HIER) + +import updater # noqa: E402 +import version # noqa: E402 + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +try: + releases = updater.releases_holen(version.REPOSITORY) +except Exception as e: # noqa: BLE001 - ohne Netz ist hier nichts zu pruefen + print(f"UEBERSPRUNGEN | Repository nicht erreichbar ({e})") + sys.exit(0) + +marke = "v" + version.VERSION +dieses = next((r for r in releases if (r.get("tag_name") or "") == marke), None) +pruefe(dieses is not None, f"zu Fassung {version.VERSION} gibt es ein Release ({marke})") +if dieses is None: + print("ROT | ohne Release ist der Rest nicht pruefbar") + sys.exit(1) + +anhaenge = {a.get("name"): a for a in dieses.get("assets") or []} +print(f" (Anhaenge: {', '.join(sorted(anhaenge)) or 'keine'})") + +pruefe(version.EXE_NAME in anhaenge, + f"der Anhang heisst genau {version.EXE_NAME} - danach sucht der Updater") +pruefe(version.EXE_NAME + ".sha256" in anhaenge, + f"die Pruefsumme haengt als {version.EXE_NAME}.sha256 dran") + +# ---- Die Summe muss zur Datei passen, und zwar zu der gebauten ------------ +gebaut = os.path.join(HIER, "release", version.EXE_NAME) +url_summe = updater.summe_aus_release(dieses, version.EXE_NAME) +if url_summe: + veroeffentlicht = updater.text_holen(url_summe).strip().split()[0] + if os.path.exists(gebaut): + pruefe(veroeffentlicht == updater.sha256(gebaut), + "die veroeffentlichte Summe ist die der zuletzt gebauten Datei") + else: + print(f" (release/{version.EXE_NAME} fehlt - Summe nicht " + f"gegenpruefbar, vorher: python bauen.py)") + pruefe(len(veroeffentlicht) == 64 and all(c in "0123456789abcdef" for c in veroeffentlicht), + f"und sie sieht aus wie eine SHA256 ({veroeffentlicht[:16]}...)") + +# ---- Und findet der Updater das Release ueberhaupt? ----------------------- +treffer = updater.passendes_release(releases, version.EXE_NAME) +pruefe(treffer is not None, "passendes_release findet ueberhaupt ein Release") +if treffer: + pruefe((treffer[0].get("tag_name") or "") == marke, + f"und zwar dieses hier ({treffer[0].get('tag_name')})") + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Das Release ist so, wie der Updater es erwartet") From 42e459ad26f4a968eb6d897e086d6b57a6e3a4e7 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Sun, 6 Sep 2026 23:41:24 +0200 Subject: [PATCH 23/34] Layout: die Formularseite nimmt nur, was sie braucht Sein Befund "die namen und datums bloecke koennen schmaler werden sind zu breit und verdrengen die posten block" Gemessen stimmte das genau: die sieben Spalten der Leistungstabelle brauchten 743 Pixel, sichtbar waren 618 - "E.-Preis" und "Gesamt" standen ausserhalb des Bildes. Wo die Breite wirklich herkam An den Feldbreiten zu drehen half NICHTS. Die Arbeitsflaeche verteilte ueber eine uniform-Gruppe streng im Verhaeltnis 4:3; die Formularspalte war so breit, weil das Gewicht es vorschrieb, nicht weil der Inhalt es brauchte - 433 Pixel, ob die Felder nun 38 oder 22 Zeichen breit waren. Jetzt bekommt die Formularseite eine feste Mindestbreite und kein Gewicht, die Liste allen uebrigen Platz. Wird das Fenster groesser, waechst allein die Tabelle - genau dort nuetzt Breite, waehrend ein 600 Pixel breites Feld fuer eine Postleitzahl nichts besser macht. 433 -> 329. Dazu passend - Startbreite 1060 -> 1180 und Mindestbreite 900 -> 1080. Unterhalb von 1080 passen die sieben Spalten selbst dann nicht nebeneinander, wenn die Textspalte auf ihrer Mindestbreite steht. - Die Eingabefelder links auf das Mass gekuerzt, das sie wirklich brauchen (22 statt 38 Zeichen; Datum 12 statt 18). Das senkt die Mindestbreite der Formularseite - erst dadurch ist sie so klein moeglich. - "Anreise (TT.MM.JJJJ)" -> "Anreise". Die Form steht jetzt einmal als graue Zeile unter dem Block. Als Platzhalter IM Feld waere sie gefaehrlich: ein nicht geloeschter Platzhalter stuende als Anreisedatum auf der Rechnung. - Der Textumbruch der Leistungsspalte folgt jetzt ihrer echten Breite. Fest eingetragen schnitt er den Text ab, sobald die Spalte schmaler wurde. pruef_spaltenbreiten.py Prueft ueber die ganze erlaubte Spanne, dass alle Spalten hineinpassen, die Formularseite lesbar bleibt und NICHT mitwaechst, und der Umbruch zur Spalte passt. Kein anderer Pruefstand haette das gefunden: es stuerzt nichts ab und rechnet nichts falsch - man sieht die Preise nur nicht. Er hat sofort einen zweiten Fehler gefunden: beim Aendern der Fenstergroesse lief der Umbruch nicht hinterher, weil ich abgebrochen hatte, sobald sich mein eigener Wert nicht mehr aenderte. Die Spalte kann aber breiter werden, ohne dass ich etwas aendere. Abbruch jetzt, wenn zwei Messungen dieselbe Spaltenbreite ergeben. Fassung 1.7.1. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 120 +++++++++++++++++++++++++++++++---- flaeche.py | 40 ++++++++++-- pruef_spaltenbreiten.py | 137 ++++++++++++++++++++++++++++++++++++++++ version.py | 4 +- 4 files changed, 278 insertions(+), 23 deletions(-) create mode 100644 pruef_spaltenbreiten.py diff --git a/app.py b/app.py index ade214f..fa858c7 100644 --- a/app.py +++ b/app.py @@ -65,10 +65,23 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self.cfg = config.load_config() self.title(config.PROGRAMM) self._fenstersymbol() - # Fensterhoehe an den Bildschirm anpassen, damit nichts unter den Rand rutscht + # Fenstergroesse an den Bildschirm anpassen, damit nichts unter den + # Rand rutscht. Die BREITE ist gemessen, nicht geraten: die + # Leistungstabelle braucht 743 Pixel fuer ihre sieben Spalten, dazu + # Bildlaufleiste, Rahmen und die Formularseite links - zusammen rund + # 1180. Bei den frueheren 1060 waren "E.-Preis" und "Gesamt" + # abgeschnitten (sein Befund am 06.09.2026: die Formularbloecke + # "verdrengen die posten block"). Passt das nicht auf den Bildschirm, + # wird so breit wie moeglich aufgemacht. hoehe = max(560, min(840, self.winfo_screenheight() - 90)) - self.geometry(f"1060x{hoehe}") - self.minsize(900, 540) + breite = max(1000, min(1180, self.winfo_screenwidth() - 60)) + self.geometry(f"{breite}x{hoehe}") + # Die Mindestbreite ist keine Geschmacksfrage: unterhalb von 1060 + # Pixeln passen die sieben Spalten der Leistungstabelle selbst dann + # nicht mehr nebeneinander, wenn die Textspalte auf ihrer + # Mindestbreite steht - "E.-Preis" und "Gesamt" waeren dann nicht mehr + # zu sehen und auch nicht zu erreichen. Frueher stand hier 900. + self.minsize(1080, 540) if config.testlauf(): # Ein Pruefstand bedient das Programm, waehrend nebenan jemand # arbeitet. Das Fenster geht deshalb NEBEN dem Bildschirm auf (auf @@ -295,13 +308,18 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, row=i, column=0, sticky="w", pady=4) if var is self.k_anrede: # Auswahlliste, aber nicht gesperrt - Sonderfaelle kann man tippen. - w = ttk.Combobox(kunde, textvariable=var, width=36, values=ANREDEN) + w = ttk.Combobox(kunde, textvariable=var, width=22, values=ANREDEN) else: - w = ttk.Entry(kunde, textvariable=var, width=38) + # 22 Zeichen: das laengste, was hier realistisch steht, ist eine + # Strasse mit Hausnummer ("Bornaer Chaussee 36" = 19). Breiter + # gemacht hat das Feld nur die linke Spalte aufgeblaeht und der + # Leistungstabelle den Platz genommen. Getippt werden kann + # weiterhin beliebig viel - das Feld scrollt mit. + w = ttk.Entry(kunde, textvariable=var, width=22) w.grid(row=i, column=1, sticky="ew", padx=(8, 0), pady=2) ttk.Label(kunde, text="* Pflicht – Name und Anschrift des Kunden gehören " "auf die Rechnung (§ 14 Abs. 4 Nr. 1 UStG).", - style="KarteMuted.TLabel", wraplength=330, justify="left").grid( + style="KarteMuted.TLabel", wraplength=250, justify="left").grid( row=len(felder), column=0, columnspan=2, sticky="w", pady=(6, 0)) kunde.columnconfigure(1, weight=1) @@ -314,8 +332,8 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, rows = [ ("Rechnungsnummer", self.r_nummer), ("Rechnungsdatum", self.r_datum), - ("Anreise (TT.MM.JJJJ)", self.r_anreise), - ("Abreise (TT.MM.JJJJ)", self.r_abreise), + ("Anreise", self.r_anreise), + ("Abreise", self.r_abreise), ] date_vars = (self.r_datum, self.r_anreise, self.r_abreise) self.datum_labels = {} @@ -326,7 +344,14 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self.datum_labels["von"] = beschriftung elif var is self.r_abreise: self.datum_labels["bis"] = beschriftung - ent = ttk.Entry(info, textvariable=var, width=18) + # 12 Zeichen reichen fuer "TT.MM.JJJJ" und jede Rechnungsnummer. + # Die Form stand frueher in der Beschriftung ("Anreise + # (TT.MM.JJJJ)") und hat den ganzen Block breit gemacht - Breite, + # die der Leistungstabelle rechts fehlte. Sie steht jetzt einmal + # als graue Zeile unter dem Block. Als Platzhalter IM Feld waere + # sie gefaehrlich: ein nicht geloeschter Platzhalter stuende als + # Anreisedatum auf der Rechnung. + ent = ttk.Entry(info, textvariable=var, width=12) ent.grid(row=i, column=1, sticky="ew", padx=(8, 0), pady=2) if var is self.r_nummer: # Waehrend eines Stornos wird das Feld gesperrt - die Nummern @@ -339,12 +364,17 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, ttk.Label(info, textvariable=self.r_naechte, style="Karte.TLabel", font=(theme.SCHRIFT_NAME, 11, "bold")).grid( row=4, column=1, sticky="w", padx=(8, 0)) + ttk.Label(info, text="Datum als TT.MM.JJJJ – die Punkte setzt das " + "Programm beim Tippen.", + style="KarteMuted.TLabel", wraplength=250, + justify="left").grid(row=5, column=0, columnspan=2, + sticky="w", pady=(8, 0)) # Storno-Hinweis: steht nur da, solange ein Storno im Zwischenspeicher liegt. self.storno_hinweis = tk.StringVar(value="") ttk.Label(info, textvariable=self.storno_hinweis, style="Karte.TLabel", foreground=self.col_gefahr, - font=(theme.SCHRIFT_NAME, 9, "bold"), wraplength=200, justify="left").grid( - row=5, column=0, columnspan=2, sticky="w", pady=(6, 0)) + font=(theme.SCHRIFT_NAME, 9, "bold"), wraplength=250, justify="left").grid( + row=6, column=0, columnspan=2, sticky="w", pady=(6, 0)) info.columnconfigure(1, weight=1) self.r_anreise.trace_add("write", lambda *a: self._update_naechte()) self.r_abreise.trace_add("write", lambda *a: self._update_naechte()) @@ -414,7 +444,12 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # (Titel, Ausrichtung, Mindestbreite px). col 1 (Leistung) bekommt das Gewicht. COLS = [ ("Pos.", "center", 38), - ("Leistung", "w", 330), + # Die Textspalte hat als einzige Gewicht - sie bekommt allen freien + # Platz. Ihre Mindestbreite ist deshalb bewusst klein: bei einem engen + # Fenster soll sie schrumpfen und umbrechen, statt die Preisspalten + # rechts aus dem Bild zu schieben. Bei den frueheren 330 tat sie genau + # das - "E.-Preis" und "Gesamt" waren nicht mehr zu sehen. + ("Leistung", "w", 200), ("USt %", "center", 50), ("Anzahl\nTage/Menge", "center", 80), ("Pers.", "center", 56), @@ -451,7 +486,13 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self._pos_win = canvas.create_window((0, 0), window=self.pos_frame, anchor="nw") self.pos_frame.bind("", lambda e: canvas.configure(scrollregion=canvas.bbox("all"))) # pos_frame auf Canvas-Breite ziehen (minus Luft rechts zum Scrollbalken) - canvas.bind("", lambda e: canvas.itemconfig(self._pos_win, width=e.width - 18)) + def breite_gesetzt(e): + canvas.itemconfig(self._pos_win, width=e.width - 18) + # after_idle, weil die Spaltenbreite erst NACH dem Neuverteilen + # feststeht - direkt im Ereignis gemessen kaeme der alte Wert. + self.after_idle(self._umbruch_nachziehen) + + canvas.bind("", breite_gesetzt) canvas.configure(yscrollcommand=sb.set) canvas.pack(side="left", fill="both", expand=True, pady=(4, 0)) sb.pack(side="right", fill="y") @@ -463,9 +504,55 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self._render_positionszeilen() + def _umbruch_nachziehen(self, runde=0, vorige_breite=None): + """Den Textumbruch der Leistungsspalte auf ihre echte Breite setzen. + + Die Spalte ist die einzige mit Gewicht - sie bekommt allen freien + Platz und schrumpft bei engem Fenster bis auf ihre Mindestbreite. Ein + fest eingetragener Umbruch passt dann nicht mehr: er bricht zu spaet, + der Text laeuft ueber die Spalte hinaus und wird abgeschnitten. Genau + das war nach dem Umbau am 06.09.2026 bei Position 1 zu sehen + ("... inkl. Pkw, Stro"). + + Es braucht mehrere Runden, und zwar aus einem Grund, der beim ersten + Versuch Zeit gekostet hat: beim ersten Messen steht die Spalte noch auf + ihrer MINDESTbreite, weil die Labels noch mit dem alten Umbruch + vermessen sind. Setzt man danach nur einmal, bleibt der Text auf der + Mindestbreite umgebrochen, obwohl die Spalte laengst breiter ist - der + Text stand dann dreizeilig in einer Spalte, in die er zweizeilig + gepasst haette. Also wird gemessen, gesetzt und noch einmal gemessen, + bis sich nichts mehr aendert. + + Abgebrochen wird, wenn zwei Messungen dieselbe SPALTENBREITE ergeben - + nicht, wenn sich der Umbruch nicht geaendert hat. Der Unterschied ist + entscheidend und hat beim ersten Versuch eine Runde gekostet: die + Spalte kann breiter werden, ohne dass ich etwas geaendert habe (sie + bekommt den freien Platz des Fensters). Wer dann abbricht, weil sein + eigener Wert gleich blieb, laesst den Umbruch auf dem alten Stand + stehen - beim Vergroessern bricht der Text unnoetig um, beim + Verkleinern laeuft er aus der Spalte heraus. Die Rundengrenze ist der + zweite Riegel gegen ein Aufschaukeln. + """ + if not getattr(self, "_text_zellen", None): + return + kasten = self.pos_frame.grid_bbox(column=1, row=0) + if not kasten or kasten[2] < 40: + return + breite = kasten[2] - 14 # padx=6 auf beiden Seiten, etwas Luft + for lbl in self._text_zellen: + try: + if int(lbl.cget("wraplength")) != breite: + lbl.configure(wraplength=breite) + except tk.TclError: # Zeile wurde zwischendurch neu gebaut + pass + if runde < 5 and breite != vorige_breite: + self.after_idle( + lambda: self._umbruch_nachziehen(runde + 1, breite)) + def _render_positionszeilen(self): for w in self.pos_frame.winfo_children(): w.destroy() + self._text_zellen = [] self.anzahl_vars.clear() self.personen_vars.clear() self.gesamt_lbls.clear() @@ -512,7 +599,12 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, return lbl zelle(str(nr), 0) - zelle(pos["leistung"], 1, anker="w", umbruch=330) + # Der Umbruch wird nicht fest gesetzt: die Leistungsspalte ist die + # einzige, die mitwaechst, und ein fester Wert schnitt den Text ab, + # sobald die Spalte schmaler wurde als er. _umbruch_nachziehen() + # holt ihn nach jeder Groessenaenderung. + self._text_zellen.append( + zelle(pos["leistung"], 1, anker="w", umbruch=200)) zelle(str(pos["satz"]), 2) ttk.Entry(self.pos_frame, textvariable=av, width=8, justify="center", style="Liste.TEntry").grid( diff --git a/flaeche.py b/flaeche.py index 1cc2f35..fe850c1 100644 --- a/flaeche.py +++ b/flaeche.py @@ -42,6 +42,12 @@ STANDARD = { class Arbeitsflaeche(ttk.Frame): + # Wie breit die beiden Spalten mindestens sein muessen. Die Formularseite + # ist gemessen, nicht geschaetzt: das breiteste, was dort steht, ist die + # Beschriftung "Nachname / Firma *" neben einem 22 Zeichen breiten Feld. + MIN_FORMULAR = 330 + MIN_LISTE = 520 + def __init__(self, master, farben=None, beim_umbauen=None): super().__init__(master) self.f = farben if farben is not None else master @@ -85,23 +91,43 @@ class Arbeitsflaeche(ttk.Frame): def _platz_verteilen(self): """Der freie Platz gehoert dem Kasten mit der langen Liste. - Feste Gewichte gehen nicht: die Liste wandert beim Verschieben, und wer - das Gewicht an einer festen Zelle laesst, schneidet danach den - Kundenkasten unten ab - genau das ist beim ersten Versuch passiert. + Feste Gewichte an festen Zellen gehen nicht: die Liste wandert beim + Verschieben, und wer das Gewicht an einer festen Zelle laesst, + schneidet danach den Kundenkasten unten ab - genau das ist beim ersten + Versuch passiert. + + WARUM NICHT MEHR `uniform` (06.09.2026) + --------------------------------------- + Vorher standen beide Spalten in einer uniform-Gruppe mit den Gewichten + 4 und 3. Das teilt die Breite STRENG in diesem Verhaeltnis auf - bei + 1040 Pixeln also 594 zu 446, ganz gleich, was in den Kaesten steht. + Sein Befund: *"die namen und datums bloecke koennen schmaler werden + sind zu breit und verdrengen die posten block"*. Er hatte recht, aber + an den Feldbreiten zu drehen half nichts: die Spalte war so breit, weil + das Gewicht es vorschrieb, nicht weil der Inhalt es brauchte. + + Jetzt bekommen die Formularkaesten nur, was sie brauchen (feste + Mindestbreite, kein Gewicht), und der ganze uebrige Platz geht an die + Liste. Wird das Fenster groesser, waechst allein die Tabelle - genau + dort nuetzt die Breite, waehrend ein Adressfeld von 600 Pixeln nichts + besser macht. """ for z in range(2): self.rowconfigure(z, weight=0, minsize=0) for sp in range(2): - self.columnconfigure(sp, weight=1, uniform="spalten") + self.columnconfigure(sp, weight=0, uniform="", minsize=0) lang = self.layout.get("leistungen") if not lang: + for sp in range(2): + self.columnconfigure(sp, weight=1) return spalte, zeile, hoch = lang for z in range(zeile, zeile + hoch): self.rowconfigure(z, weight=1) - # Die Spalte mit der Liste bekommt mehr Breite als die andere. - self.columnconfigure(spalte, weight=4, uniform="spalten") - self.columnconfigure(1 - spalte, weight=3, uniform="spalten") + # Die Liste nimmt allen freien Platz ... + self.columnconfigure(spalte, weight=1, minsize=self.MIN_LISTE) + # ... die Formularseite genau so viel, wie ihr breitestes Feld braucht. + self.columnconfigure(1 - spalte, weight=0, minsize=self.MIN_FORMULAR) # Steht die Liste nur in EINER Zeile, braucht die andere trotzdem Luft # fuer ihren Inhalt - sonst wird sie zusammengequetscht. if hoch == 1: diff --git a/pruef_spaltenbreiten.py b/pruef_spaltenbreiten.py new file mode 100644 index 0000000..f76471d --- /dev/null +++ b/pruef_spaltenbreiten.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: passt die Leistungstabelle in jedes erlaubte Fenster? + +DER FALL, DER DAZU GEFUEHRT HAT (06.09.2026) +-------------------------------------------- +Sein Befund: *"die namen und datums bloecke koennen schmaler werden sind zu +breit und verdrengen die posten block"*. Gemessen stimmte das genau: die +sieben Spalten der Leistungstabelle brauchten 743 Pixel, sichtbar waren 618 - +"E.-Preis" und "Gesamt" standen ausserhalb des Bildes. + +WARUM DAS KEIN ANDERER PRUEFSTAND FINDET +---------------------------------------- +Es stuerzt nichts ab, es rechnet nichts falsch, kein Wert fehlt. Die Rechnung +wird korrekt erstellt - man sieht die Preise nur nicht. Ein Fehler, den man +ansehen muss, um ihn zu bemerken. Genau deshalb steht er hier als Messung. + +Und die Ursache lag nicht dort, wo man sie vermutet: an den Feldbreiten links +zu drehen half NICHTS. Die Arbeitsflaeche verteilte die Breite ueber eine +uniform-Gruppe streng im Verhaeltnis 4:3 - die Spalte war so breit, weil das +Gewicht es vorschrieb, nicht weil der Inhalt es brauchte. + +WAS HIER GEPRUEFT WIRD +---------------------- +Ueber die ganze erlaubte Spanne von der Mindestbreite bis zu einem grossen +Fenster: + + 1. Alle Spalten der Tabelle passen nebeneinander in die sichtbare Flaeche. + 2. Die Formularseite bleibt lesbar - sie darf nicht unter ihre gemessene + Mindestbreite fallen. + 3. Die Formularseite waechst NICHT mit. Zusaetzliche Breite gehoert der + Tabelle; ein 600 Pixel breites Feld fuer eine Postleitzahl macht nichts + besser. + 4. Der Textumbruch der Leistungsspalte folgt ihrer echten Breite. Ist er + groesser, wird der Text abgeschnitten; ist er viel kleiner, bricht er + unnoetig um. +""" +import os +import sys +import time + +QUELLE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, QUELLE) + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +os.chdir(QUELLE) +os.environ["CAMPINGHOF_TEST"] = "1" + +from tkinter import messagebox # noqa: E402 + +antworten = {"Erprobungsfassung": True, "Fertig": False, "Hausnummer": True} + + +def askyesno(titel, text, **kw): + for schlue, wert in antworten.items(): + if schlue in titel: + return wert + raise AssertionError(f"unangemeldeter Dialog: {titel!r}") + + +messagebox.askyesno = askyesno +for _n in ("showinfo", "showwarning", "showerror"): + setattr(messagebox, _n, lambda *a, **k: None) + +import app as A # noqa: E402 + +f = A.RechnungsApp() + + +def einpendeln(sekunden=1.2): + """Ereignisschleife drehen - Tk verteilt die Breite erst danach.""" + ende = time.time() + sekunden + while time.time() < ende: + f.update() + time.sleep(0.02) + f.update_idletasks() + + +einpendeln(2.0) + +# Die Mindestbreite ist die untere Grenze dessen, was der Benutzer einstellen +# kann - genau dort muss es noch passen. +MINDEST = f.minsize()[0] +print(f" (Mindestbreite laut minsize: {MINDEST})") + +formular_breiten = [] +for breite in (MINDEST, MINDEST + 40, 1180, 1400, 1600): + f.geometry(f"{breite}x680") + einpendeln() + pf = f.pos_frame + sichtbar = pf.master.winfo_width() # der Canvas darunter + spalten = [(pf.grid_bbox(column=i, row=0) or (0, 0, 0, 0))[2] + for i in range(len(A.RechnungsApp.COLS))] + gesamt = sum(spalten) + formular = f.flaeche.kaesten["kunde"]["aussen"].winfo_width() + formular_breiten.append(formular) + + pruefe(gesamt <= sichtbar, + f"bei {breite:4d} px passen alle {len(spalten)} Spalten " + f"({gesamt} von {sichtbar} px)") + pruefe(formular >= 300, + f"bei {breite:4d} px bleibt die Formularseite lesbar ({formular} px)") + + # Der Umbruch der Textspalte muss zur Spalte passen. + zellen = getattr(f, "_text_zellen", []) + if zellen: + umbruch = int(zellen[0].cget("wraplength")) + text_spalte = spalten[1] + pruefe(umbruch <= text_spalte, + f"bei {breite:4d} px bricht der Leistungstext INNERHALB der " + f"Spalte um ({umbruch} <= {text_spalte})") + pruefe(umbruch >= text_spalte - 30, + f"bei {breite:4d} px nutzt er die Spalte auch aus " + f"({umbruch} >= {text_spalte - 30})") + +# Mehr Platz gehoert der Tabelle, nicht den Adressfeldern. +pruefe(len(set(formular_breiten)) == 1, + f"die Formularseite waechst nicht mit dem Fenster {formular_breiten}") + +try: + f.destroy() +except Exception: # noqa: BLE001 + pass + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Die Leistungstabelle passt in jedes erlaubte Fenster") diff --git a/version.py b/version.py index acce0ab..7df3ba3 100644 --- a/version.py +++ b/version.py @@ -10,11 +10,11 @@ und NUR hier; alles andere (Info-Dialog, Updater, Release) liest sie von hier. Regel ----- Die Nummer wird beim Ausliefern erhoeht und entspricht dem Release-Tag ohne das -"v": Tag `v1.7.0` -> VERSION "1.7.0". Wer das eine ohne das andere aendert, +"v": Tag `v1.7.1` -> VERSION "1.7.1". Wer das eine ohne das andere aendert, baut dem Updater eine Falle. """ -VERSION = "1.7.0" +VERSION = "1.7.1" # Zu welchem Repository dieses Programm gehoert - der Updater sucht dort. REPOSITORY = "TheMockTv/rechnungstool" From 20876102d5e6d60b267d69ecc793e42c65c1fd24 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 00:06:25 +0200 Subject: [PATCH 24/34] Aufgabe festgehalten: Preisvorschlag beim Rechnungschreiben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recherchiert, NICHT gebaut - auf seine Ansage "gut das kann auf die todo jetzt nicht". Kern: Was sein Freund beschreibt, ist mit hoher Wahrscheinlichkeit nicht MyHammer, sondern die Grosshandelsanbindung seiner Handwerkersoftware. Ein Heizungsventil ist ein Artikel, kein Gewerk. MyHammer hat keine oeffentliche API, und das oeffentliche Preisradar traegt selbst den Satz, seine Preise seien "mit Hilfe von KI zusammengetragen" - als Rechnungsgrundlage untauglich. Automatisierte Abrufe beantwortet die Seite mit 403. Ein Crawler ist damit dreifach erledigt: der Inhalt taugt nicht, sie sperren technisch, und § 87b UrhG steht dagegen. Der Weg, der funktioniert: DATANORM einlesen (offline, kostenlos, die Datei bekommt der Betrieb von seinem Grosshaendler), spaeter Open Masterdata fuer Tagespreise. Dazu die eigene Rechnungshistorie fuer die Arbeitszeit - die Daten liegen schon im Nummernbuch. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- AUFGABE_PREISVORSCHLAG.md | 129 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 AUFGABE_PREISVORSCHLAG.md diff --git a/AUFGABE_PREISVORSCHLAG.md b/AUFGABE_PREISVORSCHLAG.md new file mode 100644 index 0000000..82bbe9c --- /dev/null +++ b/AUFGABE_PREISVORSCHLAG.md @@ -0,0 +1,129 @@ +# Preisvorschlag beim Rechnungschreiben + +**Stand 07.09.2026 — recherchiert, noch nicht gebaut.** Kein Auftrag zum Loslegen; +das hier hält fest, was herausgekommen ist, damit es nicht noch einmal +recherchiert werden muss. + +## Woher der Wunsch kommt + +Sein Freund (Handwerk) berichtet: *„wenn er ein heizungsventiel auf die rechnung +macht dann schlägt das tool ihm ein preis vor"*, Abweichung nur zwei bis drei +Euro. Zuerst hieß es, das sei MyHammer. + +## Was es tatsächlich ist + +**Es ist mit hoher Wahrscheinlichkeit nicht MyHammer.** Ein Heizungsventil ist +ein *Artikel* mit Artikelnummer, kein Gewerk. Schlägt eine Software dazu einen +Preis vor, kommt der aus der **Großhandelsanbindung** — in der SHK-Branche seit +Jahrzehnten Standard. MyHammer ist dann die App daneben für die Auftragssuche. + +⚠️ **Offen:** Welches Programm hat der Freund beim Rechnungschreiben offen? Das +klärt die Frage in einem Satz. Danach fragen, bevor irgendetwas gebaut wird. + +Die zwei bis drei Euro passen zu dieser Erklärung: das ist die Differenz zwischen +einem alten Preisstand und dem tagesaktuellen Großhandelspreis. + +### Was MyHammer wirklich hat — und warum es nichts nützt + +- **Keine öffentliche API.** Keine Entwicklerdokumentation. Was an Schnittstellen + existiert, sind Einzelanbindungen an CRM-Systeme für *Leads* (400–1.200 € + einmalig), nicht für Preise. +- Das öffentliche **Preisradar** (394 Ratgeberseiten) trägt am Fuß den Satz: + *„Es handelt sich um Schätzungen, die auf Marktbeobachtung und Preisen auf + MyHammer basieren. Sie wurden mit Hilfe von KI zusammengetragen."* Spannen wie + „Tapete entfernen: 3 bis 15 Euro pro m²". **Als Rechnungsgrundlage untauglich** — + man würde KI-Schätzungen abrechnen. +- Automatisierte Abrufe beantwortet die Seite mit **HTTP 403**. + +**Ein Crawler ist damit dreifach erledigt:** der Inhalt taugt nicht, sie sperren +technisch, und die Übernahme wesentlicher Teile einer fremden Datenbank fällt +unter § 87b UrhG. Nicht weiterverfolgen. + +## Der Weg, der funktioniert — zwei Stufen + +### Stufe 1: DATANORM einlesen ← hier anfangen + +Der Handwerker lädt bei **seinem** Großhändler die DATANORM-Datei herunter; die +bekommt jeder Kunde per Mail oder aus dem Shop. Textdateien mit festen Satzarten: + +| Satz | Inhalt | +|---|---| +| A / B | Artikelstamm (Nummer, Kurztext, Preis, Einheit) | +| T | Langtext | +| P | Preisänderung auf bestehende Artikel | +| Z | Rabatt- und Zuschlagsstaffeln | +| D | Maße | + +Einlesen in die SQLite, danach schlägt das Tool beim Tippen Artikelnummer, Text +und Preis vor. + +**Warum das der erste Schritt ist:** Es läuft **offline** — passt zu dem, was für +die Tablets im Außendienst gedacht ist ([[AUFGABE_AUSSENDIENST_ARBEITSPROTOKOLL]]). +Es kostet nichts, braucht keinen Vertrag und keine Verbandsmitgliedschaft. Und die +Daten gehören dem Betrieb: sein Lieferant gibt sie ihm für seinen Gebrauch. Kein +Crawling, keine fremden Daten. + +⚠️ **Einschränkung, ehrlich:** Die offizielle DATANORM-Spezifikation ist *nicht* +frei verfügbar. Die Satzstruktur ist aber in mehreren Softwarehandbüchern +öffentlich beschrieben (mohr-it, es2000, EULANDA) — das reicht zum Bauen, aber +man baut gegen eine Beschreibung, nicht gegen eine Norm. Also: gegen echte +Dateien mehrerer Großhändler prüfen, nicht gegen eine selbst gebaute Musterdatei +([[feedback_selbst_arrangierte_messung_beweist_nichts]]). + +### Stufe 2: Open Masterdata für Tagespreise + +Webservice, Abruf einzelner Artikel über **GTIN** oder **Hersteller + Artikelnummer** +oder Großhandelsnummer. Liefert Grunddaten, Preise, Logistikdaten, Texte, +Dokumente. Synchron für einzelne Artikel, asynchron für Listen. Nachfolger von +DATANORM, entwickelt von ITEK. + +- Herausgeber ist ein Arbeitskreis aus **BVBS, DG Haustechnik, ZVSHK und VEG**, + jährliche Aktualisierung. +- **Die technische Doku liegt in einem geschlossenen Bereich** — für + Verbandsmitglieder kostenlos, für andere gegen Gebühr, Zugang über ein + Kontaktformular. Das ist die Hürde: hier müsste jemand Mitglied sein oder zahlen. +- Freischaltung läuft je Betrieb über **seinen** Großhändler; nicht jeder + Großhändler macht mit. + +### Was ausdrücklich NICHT gebraucht wird + +**Sirados, BKI, DBD** liefern Kalkulationsdaten für *Leistungen* („Heizkörper- +ventil austauschen: 0,5 Std. + Material"), nicht für Artikel. Kostenpflichtig, +Sirados je nach Paket **200 bis 2.000 €**, Übergabe über GAEB. Für die hier +beschriebene Aufgabe der falsche Hebel — das wäre ein eigenes Thema, wenn es +einmal um Angebotskalkulation statt um Rechnungsschreiben geht. + +## Die zweite Hälfte: die eigene Historie + +Material ist nur der eine Teil. Der andere ist die **Arbeitszeit**, und dafür +braucht es niemanden von außen: ein Betrieb rechnet immer wieder dieselben 20 bis +50 Leistungen ab, mit seinen Sätzen, in seiner Gegend. Diese Daten liegen bereits +im Nummernbuch. + + Zimmer streichen 25 m² — zuletzt 385 € (12.08.), + Mittel der letzten 6: 392 €, Spanne 370–410 € + +Das ist belastbarer als jede Fremdschätzung, kostet nichts, und niemand kann es +abdrehen. MyHammer mittelt über alle Betriebe in Deutschland — hier geht es um +*diesen* Betrieb. + +**Zusammen ergibt das den ganzen Preisvorschlag:** Material aus DATANORM bzw. OMD +(fremde Daten, tagesaktuell) plus Arbeitszeit aus der eigenen Rechnungshistorie +(eigene Daten, betriebsgenau). Genau so machen es die großen Programme auch. + +## Reihenfolge, wenn es losgeht + +1. Den Freund fragen, welches Programm er benutzt — klärt die Ausgangsfrage. +2. Vorschlag aus der **eigenen Historie** (braucht keine fremde Quelle, die Daten + sind da). Kleinster Schritt mit sofortigem Nutzen. +3. **DATANORM-Leser**, geprüft gegen echte Dateien mehrerer Großhändler. +4. Erst danach überlegen, ob Open Masterdata den Zugang wert ist. + +## Quellen + +- MyHammer Preisradar: https://www.my-hammer.de/preisradar +- Open Masterdata (ZVSHK): https://www.open-datapool.de +- Open Masterdata (ITEK): https://itek.de/wissen/verzeichnis-branchenstandards/open-masterdata +- DATANORM-Satzarten: https://www.mohr-it.de/Hilfe/DatanormStudio/datanormstruktur.html +- SIRADOS: https://www.sirados.de/handwerker +- § 87b UrhG: https://www.gesetze-im-internet.de/urhg/__87b.html From f7801f46f0029998f34ecdca328814483649af26 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 00:34:16 +0200 Subject: [PATCH 25/34] Darstellung waehlbar: hell, dunkel oder wie Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seine Ansage "waere nun noch gut das mann in den einstellungen einstellen kann hell oder dunkel oder automatik das fehlt sollte eigendlich drin sein" Er hatte recht: beide Farbpaletten lagen laengst in theme.py, das Programm folgte aber starr dem Windows-Theme. Jetzt steht die Wahl unter Einstellungen -> Darstellung und wirkt SOFORT, nicht erst beim Neustart. Umschalten heisst neu bauen Die Farben stehen an ueber sechzig Stellen fest in den Widgets. Sie einzeln nachzuziehen hiesse, ein Verzeichnis aller eingefaerbten Widgets zu fuehren - und wer beim naechsten neuen Widget vergisst, es einzutragen, hat einen hellen Fleck im dunklen Fenster, den niemand mehr findet. Neu bauen kann nichts vergessen. ⚠️ Dabei gingen im ersten Versuch Kundenname und Rechnungsnummer verloren: die _build_-Methoden legen ihre StringVars SELBST an, nach dem Neubau standen leere da. Gesichert werden jetzt ALLE Tk-Variablen des Fensters, nicht eine gepflegte Auswahl - wer spaeter ein Feld hinzufuegt, muss nichts eintragen. Titelleiste, Symbol und Logo gehen mit Die Titelleiste gehoert Windows; sie folgt ueber DWMWA_USE_IMMERSIVE_DARK_MODE. _dark_titlebar konnte bisher nur DUNKEL und zeigt jetzt in beide Richtungen - vorher behielt man beim Wechsel auf hell eine schwarze Leiste ueber einem hellen Fenster. Sein Befund: "die svg fuer das dunkle heller machen weil die geht nun unter" und "icon musst wenn es dunkel ist mit aendern auf das hellere". Gemessen sind es zwei Farben: Petrol #004860 und ein fast schwarzes #181818 - letzteres liegt genau auf der Kachelfarbe #15171b. Umgestellt wird nur die HELLIGKEIT (L -> 1-L, gedeckelt bei 0.78), Farbton und Saettigung bleiben: sonst waere es nicht mehr sein Logo. Betrifft Wasserzeichen, Kopflogo und das Fenstersymbol; die aufgehellte ICO entsteht beim Bauen. menueleiste.py Die selbstgebaute Menueleiste ist jetzt eine eigene Datei und liegt in beiden Programmen gleich - das Steuerrechnungstool hatte noch das native tk.Menu, das sich unter Windows nicht einfaerben laesst. pruef_darstellung.py Prueft die drei Modi, dass beim Umschalten NICHTS verlorengeht, und dass danach kein Widget mehr eine Farbe der anderen Palette traegt - genau der helle Fleck, den man sonst nie wiederfindet. Nebenbei: die beiden Dauertimer melden beim Beenden kein "invalid command name ..._api_pumpe" mehr. Ein Log, in dem beim normalen Beenden immer zwei Fehler stehen, liest irgendwann niemand mehr. Fassung 1.8.0. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- AUFGABE_BEWEISKETTE_PRUEFBAR.md | 25 ++-- Diagnose.spec | 2 +- Rechnungstool.spec | 2 +- app.py | 221 ++++++++++++++++++++++---------- assets/programm_dunkel.ico | Bin 0 -> 58385 bytes bauen.py | 9 ++ menueleiste.py | 120 +++++++++++++++++ pruef_darstellung.py | 196 ++++++++++++++++++++++++++++ theme.py | 165 ++++++++++++++++++++---- version.py | 4 +- wasserzeichen.py | 89 ++++++++++++- 11 files changed, 724 insertions(+), 109 deletions(-) create mode 100644 assets/programm_dunkel.ico create mode 100644 menueleiste.py create mode 100644 pruef_darstellung.py diff --git a/AUFGABE_BEWEISKETTE_PRUEFBAR.md b/AUFGABE_BEWEISKETTE_PRUEFBAR.md index 7443f0c..426faf7 100644 --- a/AUFGABE_BEWEISKETTE_PRUEFBAR.md +++ b/AUFGABE_BEWEISKETTE_PRUEFBAR.md @@ -108,21 +108,28 @@ kein Nebenbei — Menüs, Tabellen, Dialoge, Statusleiste. Vorher planen. --- -## ⚠️ Gefundener Altfehler — `pruef_wache` (Steuerrechnungstool) ⬜ OFFEN +## ✅ Erledigter Altfehler — `pruef_wache` (Steuerrechnungstool) **07.09.2026 behoben** **Nicht von den Arbeiten am 06.09.2026 verursacht** — bei der Ausgangsmessung vor dem Umbau bereits rot, nur mit anderem Text. -`pruef_wache.py` erwartet nach einem Push des Rechnungstools in der Statuszeile den Hinweis -**„Rechnungstool meldet"**. Tatsächlich steht dort das Ergebnis des anschließenden Einlesens -(`0 neu, 0 aktualisiert, 1 unverändert`; bei der Ausgangsmessung: `Nummernbuch: 1 Nummern -eingetragen`). Das Einlesen **überschreibt die Meldung**, bevor der Nutzer sie lesen kann. +`pruef_wache.py` erwartete nach einem Push des Rechnungstools in der Statuszeile den Hinweis +**„Rechnungstool meldet"**. Tatsächlich stand dort das Ergebnis des anschließenden Einlesens. -**Zu klären:** Ist das ein Fehler im Programm (die Meldung soll stehen bleiben, das Ergebnis -danebengehören) oder eine veraltete Erwartung im Prüfstand? Nicht nebenbei entscheiden — die -Statuszeile ist das Einzige, was dem Nutzer sagt, dass die andere Anwendung etwas gemeldet hat. +**Die Frage war:** Fehler im Programm oder veraltete Erwartung im Prüfstand? -Folgefehler derselben Stelle: „dann kommt keine Meldung dazu". +**Die Antwort: Fehler im Programm.** Sichtbar wurde das, weil der Prüfstand *mal grün und mal rot* +lief — je nachdem, wann er hinsah. Ein Prüfstand, der würfelt, ist nicht der eigentliche Befund, +sondern sein Symptom: die Meldung stand nur Sekundenbruchteile da, danach überschrieb sie das +Einlese-Ergebnis. Der Benutzer sah **nie**, dass eine Rechnung hereingekommen war. + +**Behoben:** `melde()` kennt jetzt einen `vorrang` in Sekunden. Eine Meldung mit Vorrang lässt sich +in dieser Zeit nicht von einer gewöhnlichen überschreiben; die Meldung des Rechnungstools bekommt +sechs Sekunden. Dreimal hintereinander stabil grün. + +⚠️ **Zum Merken:** Erst die Warteschleife im Prüfstand („warten, bis der Text dasteht" statt einmal +hinsehen) machte den Fehler *reproduzierbar* — und drehte ihn von zufällig grün auf konstant rot. +Ein wackelnder Prüfstand ist keine Nebensache, die man wegdrückt: er zeigt auf eine echte Stelle. --- diff --git a/Diagnose.spec b/Diagnose.spec index d030d6f..bf199bd 100644 --- a/Diagnose.spec +++ b/Diagnose.spec @@ -9,7 +9,7 @@ a = Analysis( # nur fuer den Prozess geladen (theme.schrift_vorbereiten). Fehlt sie, faellt # das Programm still auf Segoe UI zurueck - dann sieht es beim Kunden anders # aus als hier. - datas=[('assets/programm.ico', 'assets'), + datas=[('assets/programm.ico', 'assets'), ('assets/programm_dunkel.ico', 'assets'), ('assets/programm_logo.png', 'assets'),('assets/logo.png', 'assets'), ('assets/fonts', 'assets/fonts'), # Die Icons (Material Symbols vom Hub) - ohne sie zeigen die Knoepfe diff --git a/Rechnungstool.spec b/Rechnungstool.spec index 57d1265..9f4a7a6 100644 --- a/Rechnungstool.spec +++ b/Rechnungstool.spec @@ -9,7 +9,7 @@ a = Analysis( # nur fuer den Prozess geladen (theme.schrift_vorbereiten). Fehlt sie, faellt # das Programm still auf Segoe UI zurueck - dann sieht es beim Kunden anders # aus als hier. - datas=[('assets/programm.ico', 'assets'), + datas=[('assets/programm.ico', 'assets'), ('assets/programm_dunkel.ico', 'assets'), ('assets/programm_logo.png', 'assets'),('assets/logo.png', 'assets'), ('assets/fonts', 'assets/fonts'), # Die Icons (Material Symbols vom Hub) - ohne sie zeigen die Knoepfe diff --git a/app.py b/app.py index fa858c7..b2f9dcf 100644 --- a/app.py +++ b/app.py @@ -29,6 +29,7 @@ from tkinter import ttk, messagebox import api import config +import menueleiste import berechnung import gemeinsam import hinweis @@ -145,7 +146,6 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, def _build_menu(self): # Vollstaendig eigene Menueleiste + eigene Dropdowns -> komplett theme-konform # (native tk-Menubar/Popups lassen sich unter Windows nicht einfaerben). - self._open_pop = None self._menus = { "Datei": [ ("Vorschau ansehen", self.vorschau_zeigen), @@ -163,72 +163,16 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, ("Rechnungsnummer…", self.dlg_nummer), ("Speicherort der Rechnungen…", self.dlg_speicherort), ("Gemeinsamer Ordner (Nummernbuch)…", self.dlg_gemeinsam), + ("-", None), + ("Darstellung…", self.dlg_darstellung), ], "Hilfe": [("Info", self._info)], } - bar = tk.Frame(self, bg=self.col_bg) - bar.pack(side="top", fill="x") - for text, items in self._menus.items(): - lbl = tk.Label(bar, text=text, bg=self.col_bg, fg=self.col_fg, padx=8, pady=3) - lbl.pack(side="left") - lbl.bind("", lambda e, w=lbl: w.configure(bg=self.col_sel)) - lbl.bind("", lambda e, w=lbl: w.configure(bg=self.col_bg)) - lbl.bind("", lambda e, b=lbl, it=items: self._menu_popup(b, it)) - ttk.Separator(self, orient="horizontal").pack(side="top", fill="x") + self.menue = menueleiste.Menueleiste(self, self._menus, farben=self) # bind statt bind_all: sonst feuert Strg+P auch aus einem offenen # Dialog heraus und schreibt im Formular dahinter eine Rechnung. self.bind("", lambda e: self.pdf_erstellen()) - def _menu_popup(self, anchor, items): - if self._open_pop: # offenes Menu zu -> Toggle - self._close_pop() - return - pop = tk.Toplevel(self) - pop.overrideredirect(True) - pop.configure(bg=self.col_line) # 1px Rahmen = col_line statt weiss - inner = tk.Frame(pop, bg=self.col_field) - inner.pack(padx=1, pady=1) - for label, cmd in items: - if label == "-": - tk.Frame(inner, bg=self.col_line, height=1).pack(fill="x", pady=3) - continue - it = tk.Label(inner, text=label, bg=self.col_field, fg=self.col_fg, - anchor="w", padx=16, pady=5) - it.pack(fill="x") - it.bind("", lambda e, w=it: w.configure(bg=self.col_sel)) - it.bind("", lambda e, w=it: w.configure(bg=self.col_field)) - it.bind("", lambda e, c=cmd: self._run_menu(c)) - pop.update_idletasks() - pop.geometry(f"+{anchor.winfo_rootx()}+{anchor.winfo_rooty() + anchor.winfo_height()}") - self._open_pop = pop - pop.grab_set() - pop.bind("", self._maybe_close_pop, add="+") - pop.bind("", lambda e: self._close_pop()) - self._dark_titlebar(pop) - - def _maybe_close_pop(self, event): - pop = self._open_pop - if not pop: - return - if (event.x_root < pop.winfo_rootx() or event.x_root > pop.winfo_rootx() + pop.winfo_width() - or event.y_root < pop.winfo_rooty() or event.y_root > pop.winfo_rooty() + pop.winfo_height()): - self._close_pop() - - def _run_menu(self, cmd): - self._close_pop() - if cmd: - cmd() - - def _close_pop(self): - if getattr(self, "_open_pop", None): - try: - self._open_pop.grab_release() - self._open_pop.destroy() - except tk.TclError: - pass - self._open_pop = None - - # ------------------------------------------------------- Arbeitsflaeche def _build_flaeche(self): """Die Kaesten und der Knopf, mit dem man sie verschieben darf. @@ -504,6 +448,134 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self._render_positionszeilen() + # ------------------------------------------------------- Darstellung + def _oberflaeche_neu(self): + """Die ganze Oberflaeche neu zeichnen - fuer den Wechsel hell/dunkel. + + WARUM NEU BAUEN UND NICHT UMFAERBEN + ----------------------------------- + Die Farben stehen an ueber sechzig Stellen fest in den Widgets + (tk.Label mit bg=..., Streifen der Leistungsliste, Kopfzeilen der + Kaesten). Sie einzeln nachzuziehen hiesse, ein Verzeichnis aller + eingefaerbten Widgets zu fuehren - und wer beim naechsten neuen Widget + vergisst, es einzutragen, hat einen hellen Fleck im dunklen Fenster, + den niemand mehr findet. Neu bauen kann nichts vergessen. + + WAS DABEI ERHALTEN BLEIBT + ------------------------- + Alles Eingetippte. Ein Themenwechsel darf keine halb getippte Rechnung + wegwerfen. + + Dass die Werte an StringVars haengen, reicht dafuer NICHT: die + _build_-Methoden legen ihre Vars selbst an (`self.k_name = + tk.StringVar()`), beim Neubau stehen also neue, leere Vars da. Beim + ersten Versuch waren Kundenname und Rechnungsnummer weg, waehrend die + Mengen blieben - die hatte ich einzeln gesichert. + + Deshalb werden hier ALLE Variablen des Fensters gesichert, nicht eine + Auswahl: durchgegangen wird, was das Objekt an Tk-Variablen traegt. + Wer spaeter ein Feld hinzufuegt, muss nichts eintragen - es ist + automatisch dabei. Eine Liste zum Pflegen waere genau die Sorte, die + man beim naechsten Feld vergisst. + """ + gesichert = {} + for name in dir(self): + if name.startswith("__"): + continue + try: + wert = getattr(self, name) + except Exception: # noqa: BLE001 - Eigenschaften koennen werfen + continue + if isinstance(wert, (tk.StringVar, tk.IntVar, tk.DoubleVar, + tk.BooleanVar)): + try: + gesichert[name] = wert.get() + except tk.TclError: + pass + mengen = {nr: v.get() for nr, v in self.anzahl_vars.items()} + personen = {nr: v.get() for nr, v in self.personen_vars.items()} + blatt = None + try: + blatt = self.blaetter.index(self.blaetter.select()) + except Exception: # noqa: BLE001 - dann eben das erste Blatt + pass + + for kind in self.winfo_children(): + kind.destroy() + self.flaeche = None + self._text_zellen = [] + + self._apply_theme() + self._build_menu() + self._build_summen() + self._build_flaeche() + self._build_kopf() + self._build_positionen() + self.flaeche.anordnen() + + for name, wert in gesichert.items(): + neu = getattr(self, name, None) + if isinstance(neu, (tk.StringVar, tk.IntVar, tk.DoubleVar, + tk.BooleanVar)): + try: + neu.set(wert) + except tk.TclError: + pass + for nr, wert in mengen.items(): + if nr in self.anzahl_vars: + self.anzahl_vars[nr].set(wert) + for nr, wert in personen.items(): + if nr in self.personen_vars: + self.personen_vars[nr].set(wert) + if blatt is not None: + try: + self.blaetter.select(blatt) + except Exception: # noqa: BLE001 + pass + self._buch_anzeigen() + self.recalc() + + def dlg_darstellung(self): + """Hell, dunkel oder wie Windows - und sofort sichtbar.""" + d = tk.Toplevel(self) + d.title("Darstellung") + d.transient(self) + d.resizable(False, False) + self._style_dialog(d) + rahmen = ttk.Frame(d, padding=18) + rahmen.pack(fill="both", expand=True) + ttk.Label(rahmen, text="Darstellung", font=(theme.SCHRIFT_NAME, 11, "bold"), + foreground=self.col_accent).pack(anchor="w") + ttk.Label(rahmen, justify="left", wraplength=340, foreground=self.col_muted, + text="Gilt nur für das Programmfenster. Die Farbe der Rechnung " + "steht unter Einstellungen → Firmendaten – das Blatt " + "gehört dem Kunden, nicht dem Programm.").pack( + anchor="w", pady=(6, 12)) + + gewaehlt = tk.StringVar(value=theme.modus(self.cfg)) + + def uebernehmen(): + neu = gewaehlt.get() + if neu == theme.modus(self.cfg): + return + self.cfg["darstellung"] = neu + config.save_config(self.cfg) + self._oberflaeche_neu() + # Der Dialog gehoert noch zur alten Darstellung - er wird + # mitgefaerbt, sonst steht ein helles Fenster vor einem dunklen. + self._style_dialog(d) + + for wert in theme.MODI: + ttk.Radiobutton(rahmen, text=theme.MODUS_NAMEN[wert], value=wert, + variable=gewaehlt, command=uebernehmen).pack( + anchor="w", pady=3) + + ttk.Separator(rahmen, orient="horizontal").pack(fill="x", pady=(12, 10)) + ttk.Button(rahmen, text="Schließen", width=14, + command=d.destroy).pack(anchor="e") + d.geometry(f"+{self.winfo_rootx() + 120}+{self.winfo_rooty() + 140}") + return d + def _umbruch_nachziehen(self, runde=0, vorige_breite=None): """Den Textumbruch der Leistungsspalte auf ihre echte Breite setzen. @@ -714,7 +786,8 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # Das Programmlogo neben der Marke - klein, immer sichtbar. Es steht # rechts bei "powered by ravokk", weil dort die Kennung des Werkzeugs # sitzt und nicht die des Kunden. - self._kopf_bild = wasserzeichen.kopf(18, master=self) + self._kopf_bild = wasserzeichen.kopf(18, master=self, + dunkel=getattr(self, "_dark_mode", False)) if self._kopf_bild is not None: ttk.Label(status, image=self._kopf_bild).pack(side="right", padx=(0, 6)) status.pack(side="bottom", fill="x") @@ -753,7 +826,8 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, def _wasserzeichen_setzen(self, groesse=240): """Das Programmlogo blass hinter die Arbeitsflaeche legen.""" - bild = wasserzeichen.hole(groesse, 0.06, master=self) + bild = wasserzeichen.hole(groesse, 0.06, master=self, + dunkel=getattr(self, "_dark_mode", False)) if bild is None: return # Die Referenz MUSS bleiben - sonst raeumt Python das Bild weg und Tk @@ -766,7 +840,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, def _fenstersymbol(self): """Das Programmsymbol auf das Fenster legen.""" - return wasserzeichen.symbol_setzen(self) + return wasserzeichen.symbol_setzen(self, dunkel=getattr(self, "_dark_mode", False)) print("[symbol] assets/programm.ico nicht gefunden") return False @@ -1145,7 +1219,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, except Exception as e: # noqa: BLE001 print("[push]", e) finally: - self.after(250, self._push_abholen) + self._wieder(250, self._push_abholen) def _nachtragen(self): """Alles, was schon im Rechnungsordner liegt, ins Buch schreiben. @@ -1398,6 +1472,23 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, return jahr, zaehler, f"{jahr}-A{zaehler:03d}" # ------------------------------------------------- Bedienung ueber die API + def _wieder(self, ms, was): + """Einen sich selbst planenden Timer neu setzen - nur solange es das + Fenster noch gibt. + + Ohne das melden die beiden Dauertimer beim Beenden + `invalid command name ..._api_pumpe`: Tk hat das Fenster samt Callback + schon abgeraeumt, der eingeplante Aufruf laeuft aber noch. Das + stuerzt nichts ab, landet aber als Fehler im Log - und ein Log, in dem + beim normalen Beenden immer zwei Fehler stehen, liest irgendwann + niemand mehr. + """ + try: + if self.winfo_exists(): + self.after(ms, was) + except tk.TclError: + pass # Fenster ist weg - dann gibt es nichts mehr zu tun + def _api_pumpe(self): """Holt Aktionen aus der Warteschlange und fuehrt sie HIER aus. @@ -1407,7 +1498,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, try: self._api_schlange.abarbeiten(self._api_aktion) finally: - self.after(150, self._api_pumpe) + self._wieder(150, self._api_pumpe) def _api_aktion(self, name, daten): """Eine Bedienung ausfuehren. Der Schluessel ist schon geprueft (api.py). diff --git a/assets/programm_dunkel.ico b/assets/programm_dunkel.ico new file mode 100644 index 0000000000000000000000000000000000000000..ce2d86d4d734802cd80009de929e57eaa209bcf9 GIT binary patch literal 58385 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 literal 0 HcmV?d00001 diff --git a/bauen.py b/bauen.py index 5ef69f5..efd4381 100644 --- a/bauen.py +++ b/bauen.py @@ -82,6 +82,15 @@ def main(): for ordner in ("build", "dist", "setup", "release"): shutil.rmtree(os.path.join(HIER, ordner), ignore_errors=True) + # Die aufgehellte Fassung des Symbols fuer die dunkle Darstellung. Sie + # wird HIER erzeugt und nicht erst beim ersten dunklen Start: sonst muesste + # das Programm in seinen eigenen Ordner schreiben duerfen - unter + # "Programme" darf es das nicht. + sys.path.insert(0, HIER) + import wasserzeichen + dunkles = wasserzeichen.symbol_datei_dunkel() + print(f"--- Symbol dunkel: {dunkles or 'FEHLT'}") + lauf([sys.executable, "-m", "PyInstaller", "--noconfirm", f"{stamm}.spec"], f"{stamm} {version.VERSION}") lauf([sys.executable, "-m", "PyInstaller", "--noconfirm", "Updater.spec"], diff --git a/menueleiste.py b/menueleiste.py new file mode 100644 index 0000000..6eb4ce6 --- /dev/null +++ b/menueleiste.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +"""Eine Menueleiste, die sich einfaerben laesst. + +WARUM NICHT DAS MENUE VON TK +---------------------------- +`tk.Menu` ist unter Windows kein Tk-Widget, sondern ein Menue des +Betriebssystems. Es nimmt Farben zwar entgegen, zeichnet aber trotzdem im +Systemgrau - ein weisser Balken ueber einem dunklen Fenster. Sein Befund am +07.09.2026 zum Steuerrechnungstool: *"nur die einstellunden hilfe leiste die +ist noch hell"*. + +Diese Leiste ist deshalb aus gewoehnlichen Labels gebaut: eine Zeile mit den +Titeln, und beim Klick geht ein randloses Toplevel als Klappliste auf. Beides +traegt die Farben des Programms. + +WAS SIE KANN UND WAS NICHT +-------------------------- +Sie kann, was diese beiden Programme brauchen: Titel, Eintraege, Trennlinien. +Sie kann bewusst NICHT: Untermenues, Tastenkuerzel neben dem Eintrag, +Ankreuzfelder. Wer das braucht, baut es hier ein - nicht daneben. + +BENUTZUNG + + self.menue = menueleiste.Menueleiste(self, farben=self, menues={ + "Datei": [("Beenden", self._beenden)], + "Hilfe": [("Info", self._info)], + }) + +`farben` ist das Fenster mit den col_*-Feldern (das ThemeMixin). Ein "-" als +Beschriftung ergibt eine Trennlinie. + +Diese Datei liegt in BEIDEN Programmen gleich. Wer sie aendert, kopiert sie +hinueber. +""" +import tkinter as tk +from tkinter import ttk + + +class Menueleiste(tk.Frame): + def __init__(self, master, menues, farben=None, mit_trennlinie=True): + self.f = farben if farben is not None else master + super().__init__(master, bg=self.f.col_bg) + self.menues = menues + self._offen = None + self.pack(side="top", fill="x") + + for titel, eintraege in menues.items(): + lbl = tk.Label(self, text=titel, bg=self.f.col_bg, fg=self.f.col_fg, + padx=8, pady=3) + lbl.pack(side="left") + lbl.bind("", lambda e, w=lbl: w.configure(bg=self.f.col_sel)) + lbl.bind("", lambda e, w=lbl: w.configure(bg=self.f.col_bg)) + lbl.bind("", + lambda e, b=lbl, it=eintraege: self.aufklappen(b, it)) + + if mit_trennlinie: + ttk.Separator(master, orient="horizontal").pack(side="top", fill="x") + + # ---------------------------------------------------------------- Klappen + def aufklappen(self, anker, eintraege): + if self._offen: # zweiter Klick schliesst wieder + self.zuklappen() + return + pop = tk.Toplevel(self) + pop.overrideredirect(True) + # Der Rahmen ist der Hintergrund des Toplevels, einen Pixel breit - + # sonst zeichnet Windows einen weissen Rand um die Liste. + pop.configure(bg=self.f.col_line) + innen = tk.Frame(pop, bg=self.f.col_field) + innen.pack(padx=1, pady=1) + + for beschriftung, befehl in eintraege: + if beschriftung == "-": + tk.Frame(innen, bg=self.f.col_line, height=1).pack(fill="x", pady=3) + continue + eintrag = tk.Label(innen, text=beschriftung, bg=self.f.col_field, + fg=self.f.col_fg, anchor="w", padx=16, pady=5) + eintrag.pack(fill="x") + eintrag.bind("", + lambda e, w=eintrag: w.configure(bg=self.f.col_sel)) + eintrag.bind("", + lambda e, w=eintrag: w.configure(bg=self.f.col_field)) + eintrag.bind("", lambda e, c=befehl: self._ausfuehren(c)) + + pop.update_idletasks() + pop.geometry(f"+{anker.winfo_rootx()}" + f"+{anker.winfo_rooty() + anker.winfo_height()}") + self._offen = pop + pop.grab_set() + pop.bind("", self._klick_ausserhalb, add="+") + pop.bind("", lambda e: self.zuklappen()) + faerben = getattr(self.f, "_dark_titlebar", None) + if faerben: + faerben(pop) + + def _klick_ausserhalb(self, ereignis): + pop = self._offen + if not pop: + return + if (ereignis.x_root < pop.winfo_rootx() + or ereignis.x_root > pop.winfo_rootx() + pop.winfo_width() + or ereignis.y_root < pop.winfo_rooty() + or ereignis.y_root > pop.winfo_rooty() + pop.winfo_height()): + self.zuklappen() + + def _ausfuehren(self, befehl): + # Erst zuklappen, dann ausfuehren: sonst haelt der grab_set der Liste + # einen Dialog fest, der aus dem Eintrag heraus aufgeht. + self.zuklappen() + if befehl: + befehl() + + def zuklappen(self): + if self._offen: + try: + self._offen.grab_release() + self._offen.destroy() + except tk.TclError: + pass + self._offen = None diff --git a/pruef_darstellung.py b/pruef_darstellung.py new file mode 100644 index 0000000..be96ebd --- /dev/null +++ b/pruef_darstellung.py @@ -0,0 +1,196 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: hell, dunkel, automatisch - und nichts geht dabei verloren. + +Sein Wortlaut vom 07.09.2026: + + "waere nun noch gut das mann in den einstellungen einstellen kann hell + oder dunkel oder automatik das fehlt sollte eigendlich drin sein" + +GEPRUEFT WIRD DREIERLEI + +1. Die Einstellung wirkt. "hell" ist hell, "dunkel" ist dunkel, "auto" folgt + Windows. + +2. Beim Umschalten bleibt jede Eingabe stehen. Das ist der Punkt, an dem es + beim Bauen schiefging: die Mengen der Leistungszeilen hatte ich einzeln + gesichert, Kundenname und Rechnungsnummer nicht - die _build_-Methoden + legen ihre Variablen selbst an, beim Neubau standen also leere da. Wer + waehrend einer halb getippten Rechnung auf dunkel stellt, darf sie nicht + verlieren. + +3. NACH dem Wechsel traegt kein Widget mehr eine Farbe der anderen Palette. + Das ist die eigentliche Falle beim Umfaerben: ein einzelnes vergessenes + Label leuchtet hell im dunklen Fenster, und niemand findet die Stelle + wieder. Deshalb wird der ganze Widget-Baum abgegangen und mit den Farben + der jeweils ANDEREN Palette verglichen. +""" +import json +import os +import shutil +import sys +import tempfile +import time +import tkinter as tk + +QUELLE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, QUELLE) + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +os.chdir(QUELLE) +os.environ["CAMPINGHOF_TEST"] = "1" + +from tkinter import messagebox # noqa: E402 + +messagebox.askyesno = lambda *a, **k: True +for _n in ("showinfo", "showwarning", "showerror"): + setattr(messagebox, _n, lambda *a, **k: None) + +import config # noqa: E402 + +# Auf einer Kopie arbeiten - die echte Konfiguration wird nicht angefasst. +tmp = tempfile.mkdtemp(prefix="darstellung_") +shutil.copy(os.path.join(QUELLE, "config.json"), os.path.join(tmp, "config.json")) +config.CONFIG_PATH = os.path.join(tmp, "config.json") +roh = json.load(open(config.CONFIG_PATH, encoding="utf-8")) +roh["nummer_eingerichtet"] = True +roh.pop("darstellung", None) +json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), + ensure_ascii=False, indent=2) + +import app as A # noqa: E402 +import theme # noqa: E402 + +f = A.RechnungsApp() + + +def pumpen(sekunden=1.0): + ende = time.time() + sekunden + while time.time() < ende: + f.update() + time.sleep(0.02) + + +pumpen(2.0) + +# ---- Ohne Einstellung: automatisch -------------------------------------- +pruefe(theme.modus(f.cfg) == "auto", + f"ohne Eintrag gilt 'auto' ({theme.modus(f.cfg)!r})") +pruefe(f._dark_mode == theme.windows_dark_mode(), + "und folgt damit dem Windows-Theme") + +# ---- Eingaben, die den Wechsel ueberleben muessen ------------------------ +f.k_vorname.set("Erika") +f.k_name.set("Mustermann") +f.k_strasse.set("Musterweg 12") +f.k_plzort.set("04416 Markkleeberg") +f.r_nummer.set("2026-099") +f.r_anreise.set("01.09.2026") +erste = sorted(f.anzahl_vars)[0] +f.anzahl_vars[erste].set("3") +pumpen(0.5) + + +def farben(dunkel): + """Die Palette der einen oder anderen Darstellung, als Menge.""" + merker = f._dark_mode + f.cfg["darstellung"] = "dunkel" if dunkel else "hell" + f._apply_theme() + satz = {getattr(f, n).lower() for n in dir(f) + if n.startswith("col_") and isinstance(getattr(f, n), str)} + f._dark_mode = merker + return satz + + +HELL = farben(False) +DUNKEL = farben(True) +# Was in BEIDEN Paletten vorkommt, taugt nicht als Beweis. +NUR_HELL = HELL - DUNKEL +NUR_DUNKEL = DUNKEL - HELL + + +def fremdfarben(verboten): + """Alle Widgets, die eine Farbe der falschen Palette tragen.""" + treffer = [] + + def durchgehen(w): + for kind in w.winfo_children(): + for eigenschaft in ("bg", "background", "fg", "foreground"): + try: + wert = str(kind.cget(eigenschaft)).lower() + except tk.TclError: + continue + if wert in verboten: + treffer.append((str(kind), eigenschaft, wert)) + durchgehen(kind) + + durchgehen(f) + return treffer + + +# ---- Die drei Modi ------------------------------------------------------ +for wunsch, soll_dunkel in (("hell", False), ("dunkel", True)): + f.cfg["darstellung"] = wunsch + config.save_config(f.cfg) + f._oberflaeche_neu() + pumpen(0.8) + + pruefe(f._dark_mode == soll_dunkel, + f"'{wunsch}' zeichnet {'dunkel' if soll_dunkel else 'hell'} " + f"(Hintergrund {f.col_bg})") + + # Nichts darf verlorengehen. + pruefe(f.k_name.get() == "Mustermann", + f"nach dem Wechsel steht der Kundenname noch da ({f.k_name.get()!r})") + pruefe(f.r_nummer.get() == "2026-099", + f"und die Rechnungsnummer ({f.r_nummer.get()!r})") + pruefe(f.k_plzort.get() == "04416 Markkleeberg", + f"und die Anschrift ({f.k_plzort.get()!r})") + pruefe(f.r_anreise.get() == "01.09.2026", + f"und das Anreisedatum ({f.r_anreise.get()!r})") + pruefe(f.anzahl_vars.get(erste) is not None + and f.anzahl_vars[erste].get() == "3", + "und die eingetragene Menge in der Leistungszeile") + + # Kein Rest der anderen Palette. + reste = fremdfarben(NUR_DUNKEL if not soll_dunkel else NUR_HELL) + pruefe(not reste, + f"in '{wunsch}' ist keine Farbe der anderen Darstellung " + f"uebrig ({reste[:3]})") + +# ---- Zurueck auf automatisch -------------------------------------------- +f.cfg["darstellung"] = "auto" +config.save_config(f.cfg) +f._oberflaeche_neu() +pumpen(0.8) +pruefe(f._dark_mode == theme.windows_dark_mode(), + "'auto' folgt wieder dem Windows-Theme") + +# ---- Und die Einstellung ueberlebt den Neustart ------------------------- +f.cfg["darstellung"] = "hell" +config.save_config(f.cfg) +f.destroy() +f = A.RechnungsApp() +pumpen(2.0) +pruefe(f._dark_mode is False, + "die Einstellung steht beim naechsten Start wieder da") + +try: + f.destroy() +except Exception: # noqa: BLE001 + pass +shutil.rmtree(tmp, ignore_errors=True) + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Hell, dunkel und automatisch wirken - ohne Datenverlust") diff --git a/theme.py b/theme.py index ce12a81..6da642c 100644 --- a/theme.py +++ b/theme.py @@ -5,13 +5,74 @@ Native tk-Menues und -Popups lassen sich unter Windows nicht einfaerben, darum baut das Programm Menueleiste und Dropdowns selbst; hier stehen nur die Farben. """ +import ctypes.wintypes +import os import sys import tkinter as tk from tkinter import font as tkfont from tkinter import messagebox from tkinter import ttk -import config + +# --------------------------------------------------------------------------- +# Diese Datei liegt in BEIDEN Programmen gleich und darf deshalb NICHTS aus +# einem der beiden importieren. Frueher holte sie sich die Ordner und den +# Testlauf-Schalter aus config.py - die gibt es aber nur im Rechnungstool, und +# beim Uebernehmen ins Steuerrechnungstool flog sie beim Import auseinander. +# Die zwei Dinge, die gebraucht werden, stehen jetzt hier. +# --------------------------------------------------------------------------- +def _ordner(): + """Alle Orte, an denen assets/ liegen kann - Quelle wie gepackte EXE.""" + hier = os.path.dirname(os.path.abspath(__file__)) + aus_exe = getattr(sys, "_MEIPASS", "") + neben_exe = (os.path.dirname(os.path.abspath(sys.executable)) + if getattr(sys, "frozen", False) else "") + return [p for p in (aus_exe, neben_exe, hier) if p] + + +def titelleiste_faerben(fenster, dunkel): + """Die Titelleiste des Fensters mit einfaerben (Windows 10 ab 1809). + + Tk kann das nicht - die Leiste mit Symbol, Titel und den drei Knoepfen + gehoert Windows, nicht dem Programm. Windows nimmt dafuer aber einen + Hinweis entgegen: DWMWA_USE_IMMERSIVE_DARK_MODE. Ohne den steht ein weisser + Balken ueber einem dunklen Fenster (sein Befund am 07.09.2026: "der icon + und titel leiste auch ... die sind noch hell"). + + Die Nummer des Attributs hat sich einmal geaendert: 19 in den fruehen + 1809er-Fassungen, 20 seit 2004. Beide werden gesetzt; die falsche wird + ignoriert. + """ + if not sys.platform.startswith("win"): + return False + try: + import ctypes + fenster.update_idletasks() + hwnd = ctypes.windll.user32.GetParent(fenster.winfo_id()) or int(fenster.frame(), 16) + wert = ctypes.c_int(1 if dunkel else 0) + gesetzt = False + for attribut in (20, 19): + ergebnis = ctypes.windll.dwmapi.DwmSetWindowAttribute( + ctypes.wintypes.HWND(hwnd), ctypes.c_int(attribut), + ctypes.byref(wert), ctypes.sizeof(wert)) + gesetzt = gesetzt or ergebnis == 0 + # Den Rahmen neu zeichnen lassen, ohne Groesse, Platz, Reihenfolge oder + # Fokus anzufassen. Ohne das bleibt die Leiste stehen, wie sie war - + # die Umstellung wirkt dann erst beim naechsten Start. + SWP = 0x0001 | 0x0002 | 0x0004 | 0x0020 # NOSIZE|NOMOVE|NOZORDER|FRAMECHANGED + ctypes.windll.user32.SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP) + return gesetzt + except Exception: # noqa: BLE001 - ohne dunkle Titelleiste laeuft es weiter + return False + + +def testlauf(): + """Faehrt gerade ein Pruefstand das Programm? + + Muss mit der Definition in app.py uebereinstimmen - beide Programme + schalten ueber `--test` oder die Umgebungsvariable. + """ + return ("--test" in sys.argv) or os.environ.get("CAMPINGHOF_TEST") == "1" # Schrift: Roboto, so wie in den Web-Oberflaechen. Sie wird NICHT auf dem @@ -35,10 +96,9 @@ def schrift_vorbereiten(): if not sys.platform.startswith("win"): return SCHRIFT_NAME import ctypes - import os FR_PRIVATE = 0x10 geladen = 0 - for basis in (config.BASE_DIR, config.RESOURCE_DIR, os.path.dirname(os.path.abspath(__file__))): + for basis in _ordner(): ordner = os.path.join(basis, "assets", "fonts") if not os.path.isdir(ordner): continue @@ -100,15 +160,48 @@ def windows_dark_mode(): return False +# --------------------------------------------------------------------------- +# Welche Darstellung ist gewuenscht? +# --------------------------------------------------------------------------- +# Drei Moeglichkeiten, gespeichert in der config unter "darstellung": +# +# "auto" - folgt Windows (Voreinstellung, wie es bisher immer war) +# "hell" - immer hell +# "dunkel" - immer dunkel +# +# "auto" ist die Voreinstellung, weil sich das Programm dann verhaelt wie jedes +# andere: wer sein Windows abends auf dunkel stellt, bekommt es auch hier. +MODI = ("auto", "hell", "dunkel") +MODUS_NAMEN = {"auto": "Automatisch (wie Windows)", + "hell": "Hell", + "dunkel": "Dunkel"} + + +def modus(cfg): + """Der eingestellte Modus - immer einer aus MODI.""" + wert = str((cfg or {}).get("darstellung", "auto")).strip().lower() + return wert if wert in MODI else "auto" + + +def ist_dunkel(cfg): + """Soll dunkel gezeichnet werden? Die eine Stelle, die das entscheidet.""" + m = modus(cfg) + if m == "hell": + return False + if m == "dunkel": + return True + return windows_dark_mode() + + class ThemeMixin: """Farben setzen. Erwartet ein tk.Tk als Basis.""" # ----------------------------------------------------------------- Theme def _apply_theme(self): - """Farben passend zum Windows-Theme (hell/dunkel) setzen.""" + """Farben passend zur Einstellung setzen (hell, dunkel oder wie Windows).""" schrift_vorbereiten() # Roboto, sonst Segoe UI - dark = windows_dark_mode() + dark = ist_dunkel(getattr(self, "cfg", None)) self._dark_mode = dark # Die Farben sind die aus seinen anderen Sachen (FiveM-Oberflaechen, # Adminpage, Webseiten): Tuerkis #06C6A4 auf sehr dunklen, gestuften @@ -147,6 +240,15 @@ class ThemeMixin: self.col_zebra = "#e4e8ee" self.configure(bg=self.col_bg) + # Die Titelleiste gehoert Windows - sie muss eigens umgestellt werden. + titelleiste_faerben(self, dark) + # Und das Fenstersymbol: in der dunklen Titelleiste geht die dunkle + # Haelfte des Zeichens sonst unter. Es haengt hier und nicht im + # __init__, damit es beim Umschalten mitgeht - dort wird _apply_theme + # erneut gerufen, das __init__ nicht. + symbol = getattr(self, "_fenstersymbol", None) + if callable(symbol): + symbol() style = ttk.Style(self) try: style.theme_use("clam") @@ -292,6 +394,22 @@ class ThemeMixin: arrowcolor=fg, relief="flat", gripcount=0) style.map(sbs, background=[("active", accent)], troughcolor=[("disabled", bg)]) + # Treeview - die Tabelle des Steuerrechnungstools. Ohne diesen Block + # bleibt sie weiss im dunklen Fenster: ttk zeichnet Listen nicht ueber + # den "."-Grundstil, sondern nur ueber den eigenen. + style.configure("Treeview", background=self.col_card, + fieldbackground=self.col_card, foreground=fg, + bordercolor=self.col_line, rowheight=24, + font=SCHRIFT) + style.configure("Treeview.Heading", background=bg, foreground=accent, + relief="flat", font=(SCHRIFT_NAME, 9, "bold")) + style.map("Treeview.Heading", background=[("active", self.col_sel)]) + style.map("Treeview", + background=[("selected", self.col_sel)], + foreground=[("selected", fg)]) + # Der Rahmen um die Liste - ttk zeichnet ihn sonst im Systemgrau. + style.configure("Treeview.field", bordercolor=self.col_line) + style.configure("TSeparator", background=self.col_line) # Reiter (Campingrechnung / Montage): ohne eigene Farben zeichnet clam den # AKTIVEN Reiter dunkler als die ruhenden - man sieht dann nicht, wo man @@ -307,7 +425,10 @@ class ThemeMixin: # Reiter hell und sieht aus wie der ausgewaehlte. style.configure("TNotebook.Tab", background=bg, lightcolor=bg, darkcolor=bg, foreground=self.col_muted, bordercolor=self.col_line, - padding=(20, 9), font=(SCHRIFT_NAME, 10), borderwidth=1) + # Schmal genug, dass zwoelf Monatsreiter nebeneinander + # passen: bei (20, 9) waren "September" und "Dezember" + # im Steuerrechnungstool abgeschnitten. + padding=(9, 7), font=(SCHRIFT_NAME, 10), borderwidth=1) style.map("TNotebook.Tab", background=[("selected", self.col_card), ("active", mischen(accent, bg, 0.12))], @@ -356,7 +477,7 @@ class ThemeMixin: und Tastatur fest, waehrend nebenan jemand schreibt. """ d.configure(bg=self.col_bg) - if config.testlauf(): + if testlauf(): # Wie das Hauptfenster: neben den Bildschirm, und ohne grab_set - # ein Dialog, der Maus und Tastatur festhaelt, blockiert den # Menschen, der nebenher schreibt. @@ -370,22 +491,16 @@ class ThemeMixin: d.after(20, lambda: self._dark_titlebar(d)) def _dark_titlebar(self, win): - """Windows-Titelleiste des Fensters dunkel machen (nur im Dark-Mode).""" - if not (sys.platform.startswith("win") and getattr(self, "_dark_mode", False)): - return - try: - import ctypes - win.update_idletasks() - hwnd = ctypes.windll.user32.GetParent(win.winfo_id()) - val = ctypes.c_int(1) - for attr in (20, 19): # DWMWA_USE_IMMERSIVE_DARK_MODE (Win11=20, frühes Win10=19) - ctypes.windll.dwmapi.DwmSetWindowAttribute( - hwnd, attr, ctypes.byref(val), ctypes.sizeof(val)) - # Frame neu zeichnen lassen (ohne Flackern/Fokusverlust) - SWP = 0x0001 | 0x0002 | 0x0004 | 0x0020 # NOSIZE|NOMOVE|NOZORDER|FRAMECHANGED - ctypes.windll.user32.SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP) - except Exception as e: # noqa: BLE001 - print("[theme] Titelleiste:", e) + """Die Titelleiste eines Fensters an die Darstellung anpassen. + + Frueher machte diese Methode die Leiste nur DUNKEL und tat sonst + nichts. Solange das Programm der Windows-Einstellung folgte, fiel das + nicht auf - seit man hell und dunkel selbst waehlen kann, sehr wohl: + wer von dunkel auf hell stellte, behielt eine schwarze Titelleiste ueber + einem hellen Fenster. Sie zeigt jetzt in beide Richtungen und ist nur + noch eine Weiterleitung; die Arbeit macht titelleiste_faerben(). + """ + titelleiste_faerben(win, bool(getattr(self, "_dark_mode", False))) class MeldungMixin: @@ -417,7 +532,7 @@ class MeldungMixin: def melden(self, titel, text, art="warnung"): """Eine Meldung mit einem OK-Knopf.""" - if config.testlauf(): + if testlauf(): {"info": messagebox.showinfo, "warnung": messagebox.showwarning, "fehler": messagebox.showerror}.get(art, messagebox.showwarning)(titel, text) @@ -426,7 +541,7 @@ class MeldungMixin: def frage(self, titel, text="", ja="Ja", nein="Nein", vorgabe=True, **_kw): """Ja/Nein. Gibt True oder False zurueck - wie askyesno.""" - if config.testlauf(): + if testlauf(): return bool(messagebox.askyesno(titel, text)) return bool(self._meldungsfenster(titel, text, "frage", knoepfe=(ja, nein), vorgabe=vorgabe)) diff --git a/version.py b/version.py index 7df3ba3..747e13b 100644 --- a/version.py +++ b/version.py @@ -10,11 +10,11 @@ und NUR hier; alles andere (Info-Dialog, Updater, Release) liest sie von hier. Regel ----- Die Nummer wird beim Ausliefern erhoeht und entspricht dem Release-Tag ohne das -"v": Tag `v1.7.1` -> VERSION "1.7.1". Wer das eine ohne das andere aendert, +"v": Tag `v1.8.0` -> VERSION "1.8.0". Wer das eine ohne das andere aendert, baut dem Updater eine Falle. """ -VERSION = "1.7.1" +VERSION = "1.8.0" # Zu welchem Repository dieses Programm gehoert - der Updater sucht dort. REPOSITORY = "TheMockTv/rechnungstool" diff --git a/wasserzeichen.py b/wasserzeichen.py index 935ba0a..e582a93 100644 --- a/wasserzeichen.py +++ b/wasserzeichen.py @@ -45,14 +45,51 @@ def pfad(name): return "" -def symbol_setzen(fenster, melden=print): +def symbol_datei_dunkel(): + """Pfad zur aufgehellten ICO - wird angelegt, wenn sie fehlt. + + Sein Befund am 07.09.2026: *"icon musst wenn es dunkel ist mit ändern auf + das hellere geht sonst mit unter"*. Die dunkle Haelfte des Zeichens liegt + genau auf der Farbe der dunklen Titelleiste. + + `iconbitmap` braucht eine DATEI - ein Bild im Speicher genuegt nicht. + Deshalb wird sie einmal neben die normale gelegt. Gelingt das nicht (kein + Schreibrecht im Programmordner), landet sie im Temp-Ordner; und wenn auch + das nicht geht, bleibt es beim normalen Symbol. + """ + fertig = pfad("programm_dunkel.ico") + if fertig: + return fertig + quelle = pfad("programm_logo.png") + if not quelle: + return "" + ziel = os.path.join(os.path.dirname(quelle), "programm_dunkel.ico") + try: + from PIL import Image + bild = _fuer_dunkel(Image.open(quelle).convert("RGBA")) + groessen = [(g, g) for g in (16, 24, 32, 48, 64, 128, 256)] + try: + bild.save(ziel, sizes=groessen) + except OSError: + import tempfile + ziel = os.path.join(tempfile.gettempdir(), "programm_dunkel.ico") + bild.save(ziel, sizes=groessen) + return ziel + except Exception: # noqa: BLE001 - ohne helles Symbol laeuft es weiter + return "" + + +def symbol_setzen(fenster, melden=print, dunkel=False): """Das Programmsymbol auf ein Fenster legen. True bei Erfolg. Die EXE traegt es ohnehin - das Fenster aber nicht von selbst. Ohne das steht in der Titelleiste das nackte Tk-Symbol, obwohl die Datei ein eigenes hat. + + In der dunklen Darstellung wird die aufgehellte Fassung genommen, sonst + verschwindet die dunkle Haelfte des Zeichens in der dunklen Titelleiste. """ - p = pfad("programm.ico") + p = (symbol_datei_dunkel() if dunkel else "") or pfad("programm.ico") if not p: melden("[symbol] assets/programm.ico nicht gefunden") return False @@ -64,7 +101,45 @@ def symbol_setzen(fenster, melden=print): return False -def hole(groesse=240, deckkraft=0.06, master=None, melden=print): +def _fuer_dunkel(bild): + """Das Logo fuer die dunkle Darstellung aufhellen. + + Sein Befund am 07.09.2026: *"wir muessen mal schauen das wir die svg fuer + das dunkle heller machen weil die geht nun unter"*. + + Gemessen sind es zwei Farben: das Petrol #004860 (Helligkeit 53) und ein + fast schwarzes #181818 (Helligkeit 24). Der zweite Wert liegt genau auf der + Kachelfarbe #15171b - deshalb verschwindet die Haelfte des Zeichens. + + Umgestellt wird nur die HELLIGKEIT, Farbton und Saettigung bleiben: sonst + waere es nicht mehr sein Logo, sondern ein anderes. Aus dunkel wird hell, + aus hell dunkel (L -> 1-L), und weil eine reine Umkehr das kraeftige Petrol + fast weiss werden liesse, wird sie auf 0.78 gedeckelt. + + Die Kanten (halbdurchsichtige Punkte aus dem Skalieren) gehen denselben Weg + - deshalb Pixel fuer Pixel und nicht ein Farbtausch mit Toleranz. + """ + import colorsys + bild = bild.convert("RGBA") + punkte = list(bild.getdata()) + neu = [] + zwischen = {} + for r, g, b, a in punkte: + if a == 0: + neu.append((r, g, b, a)) + continue + schluessel = (r, g, b) + if schluessel not in zwischen: + h, l, s2 = colorsys.rgb_to_hls(r / 255, g / 255, b / 255) + hell = min(1.0 - l, 0.78) + r2, g2, b2 = colorsys.hls_to_rgb(h, hell, s2) + zwischen[schluessel] = (int(r2 * 255), int(g2 * 255), int(b2 * 255)) + neu.append(zwischen[schluessel] + (a,)) + bild.putdata(neu) + return bild + + +def hole(groesse=240, deckkraft=0.06, master=None, melden=print, dunkel=False): """Das Logo blass als PhotoImage - oder None. `deckkraft` 0..1, klein halten. Ein Wasserzeichen, das man LIEST, stoert @@ -77,7 +152,7 @@ def hole(groesse=240, deckkraft=0.06, master=None, melden=print): fenster = master if master is not None else tk._default_root if fenster is None: return None - schluessel = (id(fenster), groesse, round(deckkraft, 3)) + schluessel = (id(fenster), groesse, round(deckkraft, 3), bool(dunkel)) if schluessel in _lager: return _lager[schluessel] p = pfad("programm_logo.png") @@ -87,6 +162,8 @@ def hole(groesse=240, deckkraft=0.06, master=None, melden=print): try: from PIL import Image, ImageTk bild = Image.open(p).convert("RGBA").resize((groesse, groesse), Image.LANCZOS) + if dunkel: + bild = _fuer_dunkel(bild) bild.putalpha(bild.getchannel("A").point(lambda w: int(w * deckkraft))) fertig = ImageTk.PhotoImage(bild, master=fenster) except Exception as e: # noqa: BLE001 - ein Wasserzeichen darf nichts blockieren @@ -96,11 +173,11 @@ def hole(groesse=240, deckkraft=0.06, master=None, melden=print): return fertig -def kopf(hoehe=28, master=None, melden=print): +def kopf(hoehe=28, master=None, melden=print, dunkel=False): """Das Logo fuer die Kopfzeile - volle Deckkraft, kleine Hoehe. Getrennt von hole(): dort geht es um ein blasses Wasserzeichen, hier um ein Erkennungszeichen. Zwei Zwecke, zwei Funktionen - sonst haette eine davon einen Schalter, den man beim Lesen nachschlagen muss. """ - return hole(hoehe, 1.0, master=master, melden=melden) + return hole(hoehe, 1.0, master=master, melden=melden, dunkel=dunkel) From adbb035cf114282ffe15a6ce7d2087dc3ae433b3 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 00:41:35 +0200 Subject: [PATCH 26/34] Pruefstaende auf den zweiten Monitor, Desktop-Verknuepfung mit Symbol Seine Ansagen "teste links auf dem 1080p monitor nicht mehr auf dem main ... weil da schau ich nun video" "und das steuertool hat noch kein installer und die rechnungstool hat das icon nicht auf dem desktop etc selbe beim steuertool" Pruefplatz Der Platz fuer Pruefstandsfenster lag bei "Bildschirmbreite + 20", also RECHTS neben dem Hauptmonitor. Bei ihm steht der zweite Monitor aber LINKS (x = -1920), und rechts ist gar nichts: die Fenster gingen ins Leere. Sie liefen, waren aber nirgends zu sehen - das hat beim Bildermachen einige Zeit gekostet, ehe es auffiel. theme.pruefplatz() sucht jetzt den nicht-primaeren Monitor und liefert dessen Ecke. Gibt es keinen, bleibt es beim alten Verhalten. Das Steuerrechnungstool hatte ueberhaupt keine Sonderposition - dessen Pruefstandsfenster gingen mitten auf den Hauptbildschirm auf. Verknuepfungen Der Haken "Verknuepfung auf dem Desktop" ist jetzt vorgesetzt statt abgewaehlt, und jede Verknuepfung traegt IconFilename ausdruecklich. Ohne das erbt sie ihr Symbol vom UPDATER - und Windows zeigte an ihrer Stelle das nackte Standardsymbol. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- Installer.iss | 11 +++++++--- app.py | 3 ++- theme.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/Installer.iss b/Installer.iss index 86f6ce7..f4e7025 100644 --- a/Installer.iss +++ b/Installer.iss @@ -68,8 +68,11 @@ AppComments=Erprobungsfassung. Benutzung auf eigene Gefahr. Name: "deutsch"; MessagesFile: "compiler:Languages\German.isl" [Tasks] +; Kein "unchecked": der Haken ist vorgesetzt. Er hatte nach dem +; Installieren kein Symbol auf dem Desktop und musste das Programm +; suchen (07.09.2026). Wer es nicht will, nimmt den Haken heraus. Name: "desktopicon"; Description: "Verknüpfung auf dem Desktop anlegen"; \ - GroupDescription: "Zusätzliche Verknüpfungen:"; Flags: unchecked + GroupDescription: "Zusätzliche Verknüpfungen:" [Files] ; Der Updater - das ist, was der Benutzer startet. @@ -80,9 +83,11 @@ Source: "dist\{#ExeProgramm}"; DestDir: "{app}"; Flags: ignoreversion [Icons] ; Beide Verknuepfungen zeigen auf den UPDATER, nicht auf das Programm. -Name: "{group}\{#Name}"; Filename: "{app}\{#ExeUpdater}" +; IconFilename ausdruecklich: ohne das erbt die Verknuepfung das Symbol vom +; UPDATER, und Windows zeigte an ihrer Stelle das nackte Standardsymbol. +Name: "{group}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; IconFilename: "{app}\{#ExeProgramm}" Name: "{group}\{#Name} deinstallieren"; Filename: "{uninstallexe}" -Name: "{userdesktop}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; Tasks: desktopicon +Name: "{userdesktop}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; IconFilename: "{app}\{#ExeProgramm}"; Tasks: desktopicon [Run] Filename: "{app}\{#ExeUpdater}"; Description: "{#Name} jetzt starten"; \ diff --git a/app.py b/app.py index b2f9dcf..e2c9186 100644 --- a/app.py +++ b/app.py @@ -89,7 +89,8 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # dem zweiten Monitor, wenn einer da ist) - sichtbar, aber nicht im # Weg. Unsichtbar machen waere falsch: dann sieht niemand mehr, was # der Pruefstand eigentlich tut. - self.geometry(f"+{self.winfo_screenwidth() + 20}+40") + self.geometry(theme.pruefplatz() + or f"+{self.winfo_screenwidth() + 20}+40") try: # Kein Eintrag in der Taskleiste: das Fenster liegt neben # dem Bildschirm, und ein Eintrag, den man anklickt, ohne diff --git a/theme.py b/theme.py index 6da642c..25502ef 100644 --- a/theme.py +++ b/theme.py @@ -66,6 +66,61 @@ def titelleiste_faerben(fenster, dunkel): return False +def pruefplatz(): + """Wo ein Pruefstand seine Fenster aufmachen soll: "+x+y" oder "". + + Seine Ansage am 07.09.2026: *"teste links auf dem 1080p monitor nicht mehr + auf dem main ... weil da schau ich nun video"*. + + Vorher lag der Platz bei `Bildschirmbreite + 20` - also RECHTS neben dem + Hauptmonitor. Bei ihm steht der zweite Monitor aber LINKS (x = -1920), und + rechts ist gar nichts: die Fenster gingen ins Leere. Sie liefen zwar, waren + aber nirgends zu sehen - das hat beim Bildermachen einige Zeit gekostet. + + Gesucht wird deshalb der nicht-primaere Monitor. Gibt es keinen, bleibt es + beim alten Verhalten (neben den Bildschirm), denn im Weg sein soll ein + Pruefstand auch dann nicht. + """ + if not sys.platform.startswith("win"): + return "" + try: + import ctypes + from ctypes import wintypes + + class RECT(ctypes.Structure): + _fields_ = [("left", ctypes.c_long), ("top", ctypes.c_long), + ("right", ctypes.c_long), ("bottom", ctypes.c_long)] + + class MONITORINFO(ctypes.Structure): + _fields_ = [("cbSize", wintypes.DWORD), ("rcMonitor", RECT), + ("rcWork", RECT), ("dwFlags", wintypes.DWORD)] + + gefunden = [] + + def je_monitor(hmon, hdc, lprect, daten): + info = MONITORINFO() + info.cbSize = ctypes.sizeof(MONITORINFO) + if ctypes.windll.user32.GetMonitorInfoW(hmon, ctypes.byref(info)): + r = info.rcWork + gefunden.append((bool(info.dwFlags & 1), # 1 = MONITORINFOF_PRIMARY + r.left, r.top, r.right - r.left)) + return 1 + + RUECKRUF = ctypes.WINFUNCTYPE(ctypes.c_int, wintypes.HMONITOR, + wintypes.HDC, ctypes.POINTER(RECT), + wintypes.LPARAM) + ctypes.windll.user32.EnumDisplayMonitors(0, 0, RUECKRUF(je_monitor), 0) + # Der breiteste Nebenmonitor - bei mehreren der linkeste. + neben = sorted((m for m in gefunden if not m[0]), + key=lambda m: (-m[3], m[1])) + if neben: + _, x, y, _ = neben[0] + return f"+{x + 30}+{y + 40}" + except Exception: # noqa: BLE001 - dann eben der alte Weg + pass + return "" + + def testlauf(): """Faehrt gerade ein Pruefstand das Programm? @@ -478,10 +533,10 @@ class ThemeMixin: """ d.configure(bg=self.col_bg) if testlauf(): - # Wie das Hauptfenster: neben den Bildschirm, und ohne grab_set - + # Wie das Hauptfenster: auf den zweiten Monitor, und ohne grab_set - # ein Dialog, der Maus und Tastatur festhaelt, blockiert den - # Menschen, der nebenher schreibt. - d.geometry(f"+{d.winfo_screenwidth() + 20}+40") + # Menschen, der nebenher arbeitet. + d.geometry(pruefplatz() or f"+{d.winfo_screenwidth() + 20}+40") d.grab_set = lambda *a, **k: None try: d.attributes("-toolwindow", True) # nicht in die Taskleiste From 688dfb53c4244f79940fa1c60c3a744288ba1cee Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 00:52:58 +0200 Subject: [PATCH 27/34] Popups gehen mittig ueber dem Programmfenster auf Seine Ansage "da gehen noch die popups auf dem video monitor auf" "einfach so programmieren das die popup auf dem fenster mittig vom main fenster auf gehen" Was falsch war An sechs Stellen stand `max(0, x)`. Das sollte verhindern, dass ein Dialog ausserhalb des Bildschirms aufgeht - klemmt aber jede NEGATIVE Koordinate auf null. Bei ihm steht der zweite Monitor links (x = -1920): jedes Popup sprang damit zurueck auf den Hauptbildschirm, obwohl das Programm nebenan lief. Dazu kamen feste Versaetze wie "+120+140", die mit der Fenstergroesse nichts zu tun hatten. theme.mittig(dialog, ueber) Eine Stelle fuer alle Dialoge: mittig ueber dem Elternfenster, etwas oberhalb der Mitte (ein Drittel statt der Haelfte), damit der Blick dort ist und die Mitte des Formulars frei bleibt. Das ist zugleich die Antwort auf die Monitorfrage: steht das Programm auf dem zweiten Bildschirm, geht der Dialog dort auf - ohne dass irgendwo ein Monitor gesucht werden muss. Die Sonderbehandlung im Testlauf konnte deshalb entfallen; geblieben ist dort nur der Verzicht auf grab_set. theme.auf_bildschirm(x, y, breite, hoehe) Begrenzt eine Position auf den GESAMTEN Desktop ueber alle Monitore (SM_*VIRTUALSCREEN) statt auf den Hauptmonitor. Das war die eigentliche Absicht hinter dem alten max(0, ...). Gemessen statt geglaubt: Dialogmitte und Fenstermitte liegen 8 Pixel auseinander (Fensterrahmen), der Dialog liegt innerhalb des Fensters. Steht als Pruefung in pruef_darstellung.py. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 6 ++-- korrektur.py | 2 +- ordnerwahl.py | 3 +- pruef_darstellung.py | 22 ++++++++++++++ pruef_release.py | 10 ++++++- pruef_start_exe.py | 7 ++++- theme.py | 71 +++++++++++++++++++++++++++++++++++++++----- 7 files changed, 106 insertions(+), 15 deletions(-) diff --git a/app.py b/app.py index e2c9186..c26bd2b 100644 --- a/app.py +++ b/app.py @@ -574,7 +574,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, ttk.Separator(rahmen, orient="horizontal").pack(fill="x", pady=(12, 10)) ttk.Button(rahmen, text="Schließen", width=14, command=d.destroy).pack(anchor="e") - d.geometry(f"+{self.winfo_rootx() + 120}+{self.winfo_rooty() + 140}") + theme.mittig(d, self) return d def _umbruch_nachziehen(self, runde=0, vorige_breite=None): @@ -1078,7 +1078,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, d.bind("", lambda _e: d.destroy()) d.update_idletasks() x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) - d.geometry(f"+{max(0, x)}+{self.winfo_rooty() + 110}") + theme.mittig(d, self) d.grab_set() self.wait_window(d) if fertig["ok"]: @@ -1428,7 +1428,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, d.bind("", lambda _e: d.destroy()) d.update_idletasks() x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) - d.geometry(f"+{max(0, x)}+{self.winfo_rooty() + 130}") + theme.mittig(d, self) d.grab_set() self.wait_window(d) return wahl["art"] diff --git a/korrektur.py b/korrektur.py index 45b71e1..cbbdb82 100644 --- a/korrektur.py +++ b/korrektur.py @@ -513,7 +513,7 @@ class KorrekturMixin: d.bind("", lambda _e: d.destroy()) d.update_idletasks() x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) - d.geometry(f"+{max(0, x)}+{self.winfo_rooty() + 110}") + theme.mittig(d, self) d.grab_set() self.wait_window(d) if wahl["art"] == "vorhanden": diff --git a/ordnerwahl.py b/ordnerwahl.py index 6cc89b3..367c470 100644 --- a/ordnerwahl.py +++ b/ordnerwahl.py @@ -106,7 +106,8 @@ class OrdnerWahl(tk.Toplevel): hoehe = max(self.winfo_reqheight(), 300) x = master.winfo_rootx() + max(0, (master.winfo_width() - BREITE) // 2) y = master.winfo_rooty() + 90 - self.geometry(f"{BREITE}x{hoehe}+{max(0, x)}+{max(0, y)}") + self.geometry(f"{BREITE}x{hoehe}") + theme.mittig(self, master) self.minsize(BREITE, hoehe) self.grab_set() self.lift() diff --git a/pruef_darstellung.py b/pruef_darstellung.py index be96ebd..3c076b6 100644 --- a/pruef_darstellung.py +++ b/pruef_darstellung.py @@ -167,6 +167,28 @@ for wunsch, soll_dunkel in (("hell", False), ("dunkel", True)): f"in '{wunsch}' ist keine Farbe der anderen Darstellung " f"uebrig ({reste[:3]})") +# ---- Dialoge gehen mittig ueber dem Programmfenster auf ------------------ +# Seine Ansage: "einfach so programmieren das die popup auf dem fenster mittig +# vom main fenster auf gehen". Das ist zugleich die Antwort auf die +# Monitorfrage - steht das Programm auf dem zweiten Bildschirm, geht der +# Dialog dort auf. Vorher klemmte ein max(0, x) jede negative Koordinate auf +# null und riss die Fenster auf den Hauptmonitor zurueck. +d = f.dlg_darstellung() +pumpen(1.2) +d.update_idletasks() +mitte_dialog = d.winfo_rootx() + d.winfo_width() // 2 +mitte_fenster = f.winfo_rootx() + f.winfo_width() // 2 +pruefe(abs(mitte_dialog - mitte_fenster) <= 30, + f"der Dialog steht mittig ueber dem Fenster " + f"({mitte_dialog} vs. {mitte_fenster})") +pruefe(d.winfo_rootx() >= f.winfo_rootx() - 40 + and d.winfo_rootx() + d.winfo_width() <= f.winfo_rootx() + f.winfo_width() + 40, + "und liegt waagerecht innerhalb des Fensters") +pruefe(d.winfo_rooty() >= f.winfo_rooty() - 40, + "und nicht oberhalb davon") +d.destroy() +pumpen(0.3) + # ---- Zurueck auf automatisch -------------------------------------------- f.cfg["darstellung"] = "auto" config.save_config(f.cfg) diff --git a/pruef_release.py b/pruef_release.py index 0616fa8..6722570 100644 --- a/pruef_release.py +++ b/pruef_release.py @@ -64,7 +64,15 @@ if dieses is None: print("ROT | ohne Release ist der Rest nicht pruefbar") sys.exit(1) -anhaenge = {a.get("name"): a for a in dieses.get("assets") or []} +roh = dieses.get("assets") or [] +anhaenge = {a.get("name"): a for a in roh} +# Doppelte Namen: Forgejo laesst zwei Anhaenge mit demselben Namen zu. Beim +# Ersetzen einer Datei blieb die alte einmal stehen (07.09.2026), und welche +# von beiden der Updater dann laedt, ist Glueckssache - unter Umstaenden die +# alte, mit der falschen Pruefsumme daneben. +doppelt = sorted({a["name"] for a in roh + if sum(1 for b in roh if b["name"] == a["name"]) > 1}) +pruefe(not doppelt, f"kein Anhang haengt doppelt am Release ({doppelt})") print(f" (Anhaenge: {', '.join(sorted(anhaenge)) or 'keine'})") pruefe(version.EXE_NAME in anhaenge, diff --git a/pruef_start_exe.py b/pruef_start_exe.py index 04f02fb..adccc6b 100644 --- a/pruef_start_exe.py +++ b/pruef_start_exe.py @@ -57,7 +57,12 @@ if not os.path.exists(EXE): sys.exit(0) u = ctypes.windll.user32 -p = subprocess.Popen([EXE]) +# Mit --test: dann geht das Fenster auf dem ZWEITEN Monitor auf und nicht +# mitten auf dem Hauptbildschirm, wo gerade jemand arbeitet. Seine Ansage am +# 07.09.2026 - und dieser Pruefstand war der eine, der sie noch nicht befolgte, +# weil er die gebaute EXE ganz normal startet. Sichtbar bleibt das Fenster, +# und genau das wird hier ja geprueft. +p = subprocess.Popen([EXE, "--test"]) print(f" (gestartet: {os.path.basename(EXE)}, PID {p.pid})") RUECKRUF = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM) diff --git a/theme.py b/theme.py index 25502ef..309f261 100644 --- a/theme.py +++ b/theme.py @@ -121,6 +121,63 @@ def pruefplatz(): return "" +def auf_bildschirm(x, y, breite=0, hoehe=0): + """Eine Fensterposition auf den sichtbaren Bereich begrenzen. + + Frueher stand an diesen Stellen `max(0, x)`. Das sollte verhindern, dass + ein Dialog ausserhalb des Bildschirms aufgeht - klemmt aber jede NEGATIVE + Koordinate auf null. Steht der zweite Monitor links (bei ihm x = -1920), + sprang damit jedes Popup zurueck auf den Hauptbildschirm, obwohl das + Programm nebenan lief. Sein Befund am 07.09.2026: *"da gehen noch die + popups auf dem video monitor auf"*. + + Begrenzt wird deshalb auf den GESAMTEN Desktop ueber alle Monitore + (SM_*VIRTUALSCREEN), nicht auf den Hauptmonitor. + """ + if not sys.platform.startswith("win"): + return int(x), int(y) + try: + import ctypes + hole = ctypes.windll.user32.GetSystemMetrics + links, oben = hole(76), hole(77) + rechts, unten = links + hole(78), oben + hole(79) + if breite: + x = min(x, rechts - breite) + if hoehe: + y = min(y, unten - hoehe) + return int(max(links, x)), int(max(oben, y)) + except Exception: # noqa: BLE001 - dann eben ungebremst + return int(x), int(y) + + +def mittig(dialog, ueber): + """Einen Dialog mittig ueber sein Elternfenster setzen. + + Seine Ansage am 07.09.2026: *"einfach so programmieren das die popup auf + dem fenster mittig vom main fenster auf gehen"*. + + Das ist zugleich die Antwort auf die Monitorfrage: steht das Programm auf + dem zweiten Bildschirm, geht der Dialog dort auf - ohne dass irgendwo ein + Monitor gesucht werden muesste. Vorher standen an den Dialogen feste + Versaetze ("+120+140") und ein `max(0, x)`, das jede negative Koordinate + auf null klemmte und die Fenster damit auf den Hauptmonitor zurueckriss. + + Etwas oberhalb der Mitte (ein Drittel statt der Haelfte): so sitzt der + Dialog dort, wo der Blick ohnehin ist, und verdeckt nicht die Mitte des + Formulars darunter. + """ + try: + dialog.update_idletasks() + breite = dialog.winfo_reqwidth() or dialog.winfo_width() + hoehe = dialog.winfo_reqheight() or dialog.winfo_height() + x = ueber.winfo_rootx() + (ueber.winfo_width() - breite) // 2 + y = ueber.winfo_rooty() + (ueber.winfo_height() - hoehe) // 3 + x, y = auf_bildschirm(x, y, breite, hoehe) + dialog.geometry(f"+{x}+{y}") + except tk.TclError: + pass # Fenster schon zu - dann ist die Position gleichgueltig + + def testlauf(): """Faehrt gerade ein Pruefstand das Programm? @@ -532,11 +589,12 @@ class ThemeMixin: und Tastatur fest, waehrend nebenan jemand schreibt. """ d.configure(bg=self.col_bg) + # Mittig ueber dem Programmfenster - und damit automatisch auf dem + # Bildschirm, auf dem das Programm gerade steht. + d.after(1, lambda: mittig(d, self)) if testlauf(): - # Wie das Hauptfenster: auf den zweiten Monitor, und ohne grab_set - - # ein Dialog, der Maus und Tastatur festhaelt, blockiert den - # Menschen, der nebenher arbeitet. - d.geometry(pruefplatz() or f"+{d.winfo_screenwidth() + 20}+40") + # Ohne grab_set: ein Dialog, der Maus und Tastatur festhaelt, + # blockiert den Menschen, der nebenher arbeitet. d.grab_set = lambda *a, **k: None try: d.attributes("-toolwindow", True) # nicht in die Taskleiste @@ -639,10 +697,7 @@ class MeldungMixin: d.bind("", lambda _e: schliessen(False)) d.protocol("WM_DELETE_WINDOW", lambda: schliessen(False)) - d.update_idletasks() - x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) - y = self.winfo_rooty() + 140 - d.geometry(f"+{max(0, x)}+{max(0, y)}") + mittig(d, self) # Nach vorn holen und den Tastaturfokus nehmen. Ohne das kann der Dialog # beim Start hinter dem Hauptfenster liegen - der Nutzer sieht nur ein # Fenster, das nicht reagiert, und haelt es fuer haengen geblieben. From 3790b0a86f73317dcefba8cf1fefb00341a89e5a Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 01:01:13 +0200 Subject: [PATCH 28/34] Logo in den Programmfarben, gross und oben links Seine Ansagen "das dunkel blaue machen wir in unserm tuerkis gruen und die andere seite in weiss ... wenn es dunkel ist, und beim hellen machen wir weiss in dunkel grau" "ist mir zu klein geht unter mach es doch gros oben links weil da ist eh platz" "ja links ist auch gut beim rechnungstool" Farben Statt die Helligkeit umzukehren wird das Zeichen jetzt auf die PROGRAMMfarben gesetzt: das Blaugruen wird Tuerkis (#06C6A4, wie col_accent), die zweite Haelfte weiss im Dunkeln und dunkelgrau im Hellen. Unterschieden wird nach SAETTIGUNG, nicht nach dem genauen Farbwert - so bleibt die Zuordnung richtig, wenn die Vorlage einmal in einem anderen Ton gezeichnet wird, und die weichen Kanten aus dem Skalieren gehen denselben Weg wie die Flaeche, zu der sie gehoeren. Position Es stand klein (18 px) unten in der Statuszeile und ging dort unter. Jetzt 34 px oben links in der Werkzeugleiste - die traegt sonst nur den Knopf "Anordnen", und der sitzt rechts. Im Steuerrechnungstool bleibt es rechts in der Kopfleiste: dort stehen links die Bedienelemente, ein Logo davor wuerde sie alle nach rechts schieben. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 18 ++++++++------ assets/programm_dunkel.ico | Bin 58385 -> 55027 bytes wasserzeichen.py | 47 ++++++++++++++++++++----------------- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/app.py b/app.py index c26bd2b..ae92f8a 100644 --- a/app.py +++ b/app.py @@ -183,6 +183,17 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, """ leiste = ttk.Frame(self, padding=(16, 8, 16, 0)) leiste.pack(side="top", fill="x") + + # Das Programmlogo oben LINKS und gross. Es stand zuerst klein (18 px) + # unten in der Statuszeile - sein Befund am 07.09.2026: "ist mir zu + # klein geht unter mach es doch gros oben links weil da ist eh platz". + # Hier ist wirklich Platz: die Leiste traegt sonst nur den Knopf + # "Anordnen", und der sitzt rechts. + self._kopf_bild = wasserzeichen.kopf( + 34, master=self, dunkel=getattr(self, "_dark_mode", False)) + if self._kopf_bild is not None: + ttk.Label(leiste, image=self._kopf_bild).pack(side="left") + self.werkzeuge = ttk.Frame(leiste) self.werkzeuge.pack(side="right") @@ -784,13 +795,6 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, def _build_summen(self): # Statuszeile ganz unten status = ttk.Frame(self, padding=(12, 2)) - # Das Programmlogo neben der Marke - klein, immer sichtbar. Es steht - # rechts bei "powered by ravokk", weil dort die Kennung des Werkzeugs - # sitzt und nicht die des Kunden. - self._kopf_bild = wasserzeichen.kopf(18, master=self, - dunkel=getattr(self, "_dark_mode", False)) - if self._kopf_bild is not None: - ttk.Label(status, image=self._kopf_bild).pack(side="right", padx=(0, 6)) status.pack(side="bottom", fill="x") ttk.Label(status, text=config.MARKE, foreground=self.col_muted, font=(theme.SCHRIFT_NAME, 8)).pack(side="right") diff --git a/assets/programm_dunkel.ico b/assets/programm_dunkel.ico index ce2d86d4d734802cd80009de929e57eaa209bcf9..56f97f77c2c1968873a646a0ed3acd6845669053 100644 GIT binary patch literal 55027 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 literal 58385 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 diff --git a/wasserzeichen.py b/wasserzeichen.py index e582a93..495d72c 100644 --- a/wasserzeichen.py +++ b/wasserzeichen.py @@ -66,7 +66,7 @@ def symbol_datei_dunkel(): ziel = os.path.join(os.path.dirname(quelle), "programm_dunkel.ico") try: from PIL import Image - bild = _fuer_dunkel(Image.open(quelle).convert("RGBA")) + bild = _umfaerben(Image.open(quelle).convert("RGBA"), True) groessen = [(g, g) for g in (16, 24, 32, 48, 64, 128, 256)] try: bild.save(ziel, sizes=groessen) @@ -101,39 +101,45 @@ def symbol_setzen(fenster, melden=print, dunkel=False): return False -def _fuer_dunkel(bild): - """Das Logo fuer die dunkle Darstellung aufhellen. +# Die Farben des Logos - gemessen, nicht geraten: +# #004860 das dunkle Blaugruen (Wolke, Pfeile) +# #181818 das fast schwarze Grau (Dokument bzw. Paragraphenzeichen) +# +# Seine Ansage am 07.09.2026: *"das dunkel blaue machen wir in unserm tuerkis +# gruen und die andere seite in weiss ... wenn es dunkel ist, und beim hellen +# machen wir weiss in dunkel grau"*. Das Zeichen traegt damit dieselbe Farbe +# wie das Programm - und die zweite Haelfte steht in beiden Darstellungen im +# Kontrast statt unterzugehen. +TUERKIS = (0x06, 0xC6, 0xA4) # die Programmfarbe, wie col_accent +NEUTRAL_DUNKEL = (0xF2, 0xF3, 0xF5) # fast weiss - auf dunklem Grund +NEUTRAL_HELL = (0x33, 0x36, 0x3B) # dunkelgrau - auf hellem Grund - Sein Befund am 07.09.2026: *"wir muessen mal schauen das wir die svg fuer - das dunkle heller machen weil die geht nun unter"*. - Gemessen sind es zwei Farben: das Petrol #004860 (Helligkeit 53) und ein - fast schwarzes #181818 (Helligkeit 24). Der zweite Wert liegt genau auf der - Kachelfarbe #15171b - deshalb verschwindet die Haelfte des Zeichens. +def _umfaerben(bild, dunkel): + """Das Logo auf die Programmfarben umsetzen. - Umgestellt wird nur die HELLIGKEIT, Farbton und Saettigung bleiben: sonst - waere es nicht mehr sein Logo, sondern ein anderes. Aus dunkel wird hell, - aus hell dunkel (L -> 1-L), und weil eine reine Umkehr das kraeftige Petrol - fast weiss werden liesse, wird sie auf 0.78 gedeckelt. + Unterschieden wird nach SAETTIGUNG, nicht nach dem genauen Farbwert: das + Blaugruen ist kraeftig gesaettigt, das Grau gar nicht. So bleibt die + Zuordnung auch dann richtig, wenn die Vorlage einmal in einem anderen Ton + gezeichnet wird - und die weichen Kanten aus dem Skalieren gehen denselben + Weg wie die Flaeche, zu der sie gehoeren. - Die Kanten (halbdurchsichtige Punkte aus dem Skalieren) gehen denselben Weg - - deshalb Pixel fuer Pixel und nicht ein Farbtausch mit Toleranz. + Die Deckkraft bleibt unangetastet; die Form kommt aus dem Alphakanal. """ import colorsys bild = bild.convert("RGBA") + neutral = NEUTRAL_DUNKEL if dunkel else NEUTRAL_HELL punkte = list(bild.getdata()) - neu = [] zwischen = {} + neu = [] for r, g, b, a in punkte: if a == 0: neu.append((r, g, b, a)) continue schluessel = (r, g, b) if schluessel not in zwischen: - h, l, s2 = colorsys.rgb_to_hls(r / 255, g / 255, b / 255) - hell = min(1.0 - l, 0.78) - r2, g2, b2 = colorsys.hls_to_rgb(h, hell, s2) - zwischen[schluessel] = (int(r2 * 255), int(g2 * 255), int(b2 * 255)) + _, _, saettigung = colorsys.rgb_to_hls(r / 255, g / 255, b / 255) + zwischen[schluessel] = TUERKIS if saettigung > 0.25 else neutral neu.append(zwischen[schluessel] + (a,)) bild.putdata(neu) return bild @@ -162,8 +168,7 @@ def hole(groesse=240, deckkraft=0.06, master=None, melden=print, dunkel=False): try: from PIL import Image, ImageTk bild = Image.open(p).convert("RGBA").resize((groesse, groesse), Image.LANCZOS) - if dunkel: - bild = _fuer_dunkel(bild) + bild = _umfaerben(bild, dunkel) bild.putalpha(bild.getchannel("A").point(lambda w: int(w * deckkraft))) fertig = ImageTk.PhotoImage(bild, master=fenster) except Exception as e: # noqa: BLE001 - ein Wasserzeichen darf nichts blockieren From 9794632ae437757d2c8c71adaf9148d652933e11 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 10:43:09 +0200 Subject: [PATCH 29/34] Alles unter ravokk - und ein Deinstallieren laesst nichts liegen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seine Ansagen "gibt es noch das popup install ordner auswaehlen, das stimmt ja nicht" "wie soll das rechnungstool und steuertool wissen wo es ist, das muss in ravokk liegen und dann zusammen, sonst kommt das eine nicht an das andere ran - die sind doch nur ueber die gemeinsame sqlite verbunden und mit api" "es gibt ravokk als main verzeichnis, da liegt config und sqlite drin, und dann gibt es den ordner rechnungstool und steuertool" "ravokk ist meine firma und die programme gehoeren zu der firma" "du solltest die auch mal deinstallieren und neu installieren ... dass der ordner dann leer ist und sauber - will keine tools die unsauber sind" Die Struktur %LOCALAPPDATA%/ravokk/ config.json, journal.sqlite3, Nummernbuch, berichte/ <- Daten Rechnungstool/ <- Programm Steuerrechnungstool/ <- Programm Die Daten liegen NEBEN dem Programm, nicht darin. Nur dadurch koennen beide Forderungen gleichzeitig gelten: der Programmordner wird beim Deinstallieren restlos geleert, und die Belege bleiben zehn Jahre stehen (§ 147 AO). Kein Ordner-Dialog mehr beim ersten Start gemeinsam.standard_ordner() nennt den festen Ort, beide Programme legen ihn selbst an. Gefragt wird nur noch, wer ihn ausdruecklich verschieben will (Menue -> Gemeinsamer Ordner) - etwa auf ein Netzlaufwerk. Der Knopf hiess "Install-Ordner auswaehlen..." und der Text riet zum "Ordner, in dem die Programme liegen". Beides war falsch und seit dem Installer erst recht: die beiden liegen in getrennten Unterordnern, und ein Deinstallieren haette das Nummernbuch mitgenommen. ⚠ Dabei gefunden: das Journal lag im TEMP-Ordner Der Merkzettel der installierten Fassung zeigte auf %TEMP%/abnahme_bst/Daten - haengengeblieben aus einem Abnahmelauf vom 03.09. Windows raeumt den Temp-Ordner automatisch auf; das Journal waere ohne Vorwarnung verschwunden. ablage.py verwirft einen solchen Merkzettel jetzt, statt ihm zu folgen. Uninstaller Er raeumt jetzt auch, was der UPDATER angelegt hat - jede geladene Fassung und installiert.json. Die kannte der Installer nicht; mit jeder Fassung waere eine EXE mehr liegen geblieben. Gemessen vorher: zwei EXEs und der halbe Datenordner. pruef_installation.py Installiert wirklich, legt eine Datei an wie der Updater es taete, deinstalliert und sieht nach: Programmordner leer, Daten unangetastet. Vorhandene Daten werden vorher gesichert und danach zurueckgelegt - ein Pruefstand fasst niemandem seine Buchhaltung an. pruef_gemeinsam_automatisch.py Prueft, dass beide Programme denselben Ordner nennen und dass findet, was das andere eintraegt - ohne dass jemand einen Pfad eingegeben hat. Symbol Das Windows-Symbol ist jetzt eine helle Kachel mit runden Ecken und dem Zeichen darauf, in allen Groessen von 16 bis 256 - "so wie das rustdesk, nur halt alle ecken in der rundung". Ein freigestelltes Logo ging auf einem dunklen Desktop unter. Die zweite, aufgehellte ICO ist damit ueberfluessig; das aufgehellte Logo IM Programm (Kopfzeile, Wasserzeichen) bleibt unveraendert. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- Diagnose.spec | 2 +- Installer.iss | 227 ++++++++++++++++++--------------- Rechnungstool.spec | 2 +- app.py | 22 +++- assets/programm.ico | Bin 51609 -> 43660 bytes assets/programm_dunkel.ico | Bin 55027 -> 0 bytes bauen.py | 13 +- config.py | 47 +++++-- gemeinsam.py | 43 +++++++ ordnerwahl.py | 20 ++- pruef_gemeinsam_automatisch.py | 107 ++++++++++++++++ pruef_installation.py | 185 +++++++++++++++++++++++++++ wasserzeichen.py | 94 ++++++++++---- 13 files changed, 611 insertions(+), 151 deletions(-) delete mode 100644 assets/programm_dunkel.ico create mode 100644 pruef_gemeinsam_automatisch.py create mode 100644 pruef_installation.py diff --git a/Diagnose.spec b/Diagnose.spec index bf199bd..d030d6f 100644 --- a/Diagnose.spec +++ b/Diagnose.spec @@ -9,7 +9,7 @@ a = Analysis( # nur fuer den Prozess geladen (theme.schrift_vorbereiten). Fehlt sie, faellt # das Programm still auf Segoe UI zurueck - dann sieht es beim Kunden anders # aus als hier. - datas=[('assets/programm.ico', 'assets'), ('assets/programm_dunkel.ico', 'assets'), + datas=[('assets/programm.ico', 'assets'), ('assets/programm_logo.png', 'assets'),('assets/logo.png', 'assets'), ('assets/fonts', 'assets/fonts'), # Die Icons (Material Symbols vom Hub) - ohne sie zeigen die Knoepfe diff --git a/Installer.iss b/Installer.iss index f4e7025..dcfb2d5 100644 --- a/Installer.iss +++ b/Installer.iss @@ -1,100 +1,127 @@ -; Installer fuer das Rechnungstool (Inno Setup 6) -; -; ENTSCHEIDUNGEN, DIE HIER STECKEN - und warum -; -------------------------------------------- -; 1. INSTALLATION PRO BENUTZER nach %LOCALAPPDATA%\Programs, NICHT nach -; "Program Files". Grund: der Updater muss die EXE ablegen duerfen. In -; Program Files darf ein normaler Benutzer nicht schreiben - jedes Update -; wuerde an fehlenden Rechten scheitern oder eine Administrator-Abfrage -; erzwingen. Chrome, VS Code, Discord, Teams und Fusion 360 machen es -; genauso, aus demselben Grund. -; -; 2. DIE VERKNUEPFUNG ZEIGT AUF DEN UPDATER, nicht auf das Programm. So schaut -; jeder Start zuerst nach einer neuen Fassung. Der Updater startet danach -; die eigentliche EXE - die ist dabei noch gar nicht in Benutzung und laesst -; sich deshalb problemlos ersetzen. -; -; 3. KEINE DATEN ANFASSEN. Der Installer legt keine Rechnungsordner an, kein -; Journal, kein Nummernbuch - und beim Deinstallieren wird davon nichts -; entfernt. Das Programm schreibt aufbewahrungspflichtige Belege -; (§ 147 AO, zehn Jahre). Ein Deinstallieren darf sie nie mitnehmen. -; -; 4. Der Eintrag unter "Apps & Features" entsteht von selbst - Inno Setup legt -; den Registry-Schluessel unter HKCU an. Da muss niemand von Hand hinein. - -#define Name "Rechnungstool" -#define Herausgeber "ravokk" -#define ExeUpdater "Updater.exe" -#define Webseite "https://git.pcore.de/TheMockTv/rechnungstool" - -[Setup] -AppId={{7F3A9C2E-51D4-4B86-9A17-2C0E8B4D6A31} -AppName={#Name} -AppVersion={#Version} -AppVerName={#Name} {#Version} -AppPublisher={#Herausgeber} -AppPublisherURL={#Webseite} -AppSupportURL={#Webseite}/issues -AppUpdatesURL={#Webseite}/releases - -; --- pro Benutzer, ohne Adminrechte --- -PrivilegesRequired=lowest -; Der Zielordner ist NICHT waehlbar. Wer hier "Programme" auswaehlen -; koennte, braeche sich den Updater: dort darf ein normaler Benutzer -; nicht schreiben. Chrome, Teams und Discord blenden diese Seite aus -; demselben Grund aus. In "Programme" gehoert hoechstens eine -; Verknuepfung - und die liegt ohnehin im Startmenue. -DisableDirPage=yes -DefaultDirName={localappdata}\Programs\{#Name} -DefaultGroupName={#Name} -DisableProgramGroupPage=yes -UsePreviousAppDir=yes - -OutputDir=setup -OutputBaseFilename=Rechnungstool-Setup-{#Version} -Compression=lzma2 -SolidCompression=yes -WizardStyle=modern -; Das Programmsymbol - auch fuer den Installer selbst und den -; Eintrag unter "Apps & Features". -SetupIconFile=assets\programm.ico -UninstallDisplayIcon={app}\{#ExeProgramm} -ArchitecturesInstallIn64BitMode=x64compatible - -; Erprobungsfassung - das steht auch im Programm selbst. -AppComments=Erprobungsfassung. Benutzung auf eigene Gefahr. - -[Languages] -Name: "deutsch"; MessagesFile: "compiler:Languages\German.isl" - -[Tasks] -; Kein "unchecked": der Haken ist vorgesetzt. Er hatte nach dem -; Installieren kein Symbol auf dem Desktop und musste das Programm -; suchen (07.09.2026). Wer es nicht will, nimmt den Haken heraus. -Name: "desktopicon"; Description: "Verknüpfung auf dem Desktop anlegen"; \ - GroupDescription: "Zusätzliche Verknüpfungen:" - -[Files] -; Der Updater - das ist, was der Benutzer startet. -Source: "dist\{#ExeUpdater}"; DestDir: "{app}"; Flags: ignoreversion -; Das Programm selbst, mit der Nummer im Namen. Der Updater erkennt daran, -; was installiert ist, und legt neue Fassungen daneben statt darueber. -Source: "dist\{#ExeProgramm}"; DestDir: "{app}"; Flags: ignoreversion - -[Icons] -; Beide Verknuepfungen zeigen auf den UPDATER, nicht auf das Programm. -; IconFilename ausdruecklich: ohne das erbt die Verknuepfung das Symbol vom -; UPDATER, und Windows zeigte an ihrer Stelle das nackte Standardsymbol. -Name: "{group}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; IconFilename: "{app}\{#ExeProgramm}" -Name: "{group}\{#Name} deinstallieren"; Filename: "{uninstallexe}" -Name: "{userdesktop}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; IconFilename: "{app}\{#ExeProgramm}"; Tasks: desktopicon - -[Run] -Filename: "{app}\{#ExeUpdater}"; Description: "{#Name} jetzt starten"; \ - Flags: nowait postinstall skipifsilent - -[UninstallDelete] -; Nur die Buchfuehrung des Updaters. -; NICHTS von den Daten des Betriebs - keine Rechnungen, kein Journal, kein -; Nummernbuch. Die liegen ohnehin woanders und muessen zehn Jahre bleiben. -Type: files; Name: "{app}\installiert.json" +; Installer fuer das Rechnungstool (Inno Setup 6) +; +; ENTSCHEIDUNGEN, DIE HIER STECKEN - und warum +; -------------------------------------------- +; 1. INSTALLATION PRO BENUTZER nach %LOCALAPPDATA%\Programs, NICHT nach +; "Program Files". Grund: der Updater muss die EXE ablegen duerfen. In +; Program Files darf ein normaler Benutzer nicht schreiben - jedes Update +; wuerde an fehlenden Rechten scheitern oder eine Administrator-Abfrage +; erzwingen. Chrome, VS Code, Discord, Teams und Fusion 360 machen es +; genauso, aus demselben Grund. +; +; 2. DIE VERKNUEPFUNG ZEIGT AUF DEN UPDATER, nicht auf das Programm. So schaut +; jeder Start zuerst nach einer neuen Fassung. Der Updater startet danach +; die eigentliche EXE - die ist dabei noch gar nicht in Benutzung und laesst +; sich deshalb problemlos ersetzen. +; +; 3. KEINE DATEN ANFASSEN. Der Installer legt keine Rechnungsordner an, kein +; Journal, kein Nummernbuch - und beim Deinstallieren wird davon nichts +; entfernt. Das Programm schreibt aufbewahrungspflichtige Belege +; (§ 147 AO, zehn Jahre). Ein Deinstallieren darf sie nie mitnehmen. +; +; 4. Der Eintrag unter "Apps & Features" entsteht von selbst - Inno Setup legt +; den Registry-Schluessel unter HKCU an. Da muss niemand von Hand hinein. + +#define Name "Rechnungstool" +#define Herausgeber "ravokk" +#define ExeUpdater "Updater.exe" +#define Webseite "https://git.pcore.de/TheMockTv/rechnungstool" + +[Setup] +AppId={{7F3A9C2E-51D4-4B86-9A17-2C0E8B4D6A31} +AppName={#Name} +AppVersion={#Version} +AppVerName={#Name} {#Version} +AppPublisher={#Herausgeber} +AppPublisherURL={#Webseite} +AppSupportURL={#Webseite}/issues +AppUpdatesURL={#Webseite}/releases + +; --- pro Benutzer, ohne Adminrechte --- +PrivilegesRequired=lowest +; Der Zielordner ist NICHT waehlbar. Wer hier "Programme" auswaehlen +; koennte, braeche sich den Updater: dort darf ein normaler Benutzer +; nicht schreiben. Chrome, Teams und Discord blenden diese Seite aus +; demselben Grund aus. In "Programme" gehoert hoechstens eine +; Verknuepfung - und die liegt ohnehin im Startmenue. +DisableDirPage=yes +; EIN Verzeichnis fuer beides - seine Ansage am 07.09.2026: +; "es gibt ravokk als main verzeichnis, da liegt config und sqlite +; drin, und dann gibt es den ordner rechnungstool und steuertool" +; +; %LOCALAPPDATA%\ravokk\ +; campinghof-nummernbuch.sqlite3 <- gemeinsam, beide schauen hierher +; Rechnungstool\ <- Programm + Updater +; Steuerrechnungstool\ <- Programm + Updater +; +; Jedes Programm in seinem eigenen Unterordner: die beiden Updater heissen +; gleich und wuerden sich sonst gegenseitig ueberschreiben. +; +; Das Nummernbuch liegt eine Ebene DARUEBER und gehoert keinem der beiden. +; Ein Deinstallieren nimmt es deshalb nicht mit - und wer nur eines der +; Programme installiert, legt es trotzdem am richtigen Ort an +; (gemeinsam.standard_ordner). +DefaultDirName={localappdata}\ravokk\{#Name} +DefaultGroupName={#Name} +DisableProgramGroupPage=yes +UsePreviousAppDir=yes + +OutputDir=setup +OutputBaseFilename=Rechnungstool-Setup-{#Version} +Compression=lzma2 +SolidCompression=yes +WizardStyle=modern +; Das Programmsymbol - auch fuer den Installer selbst und den +; Eintrag unter "Apps & Features". +SetupIconFile=assets\programm.ico +UninstallDisplayIcon={app}\{#ExeProgramm} +ArchitecturesInstallIn64BitMode=x64compatible + +; Erprobungsfassung - das steht auch im Programm selbst. +AppComments=Erprobungsfassung. Benutzung auf eigene Gefahr. + +[Languages] +Name: "deutsch"; MessagesFile: "compiler:Languages\German.isl" + +[Tasks] +; Kein "unchecked": der Haken ist vorgesetzt. Er hatte nach dem +; Installieren kein Symbol auf dem Desktop und musste das Programm +; suchen (07.09.2026). Wer es nicht will, nimmt den Haken heraus. +Name: "desktopicon"; Description: "Verknüpfung auf dem Desktop anlegen"; \ + GroupDescription: "Zusätzliche Verknüpfungen:" + +[Files] +; Der Updater - das ist, was der Benutzer startet. +Source: "dist\{#ExeUpdater}"; DestDir: "{app}"; Flags: ignoreversion +; Das Programm selbst, mit der Nummer im Namen. Der Updater erkennt daran, +; was installiert ist, und legt neue Fassungen daneben statt darueber. +Source: "dist\{#ExeProgramm}"; DestDir: "{app}"; Flags: ignoreversion + +[Icons] +; Beide Verknuepfungen zeigen auf den UPDATER, nicht auf das Programm. +; IconFilename ausdruecklich: ohne das erbt die Verknuepfung das Symbol vom +; UPDATER, und Windows zeigte an ihrer Stelle das nackte Standardsymbol. +Name: "{group}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; IconFilename: "{app}\{#ExeProgramm}" +Name: "{group}\{#Name} deinstallieren"; Filename: "{uninstallexe}" +Name: "{userdesktop}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; IconFilename: "{app}\{#ExeProgramm}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#ExeUpdater}"; Description: "{#Name} jetzt starten"; \ + Flags: nowait postinstall skipifsilent + +[UninstallDelete] +; Was der INSTALLER gelegt hat, raeumt Inno Setup von selbst weg. Hier +; steht, was der UPDATER angelegt hat - davon weiss der Installer nichts: +; -.exe jede geladene Fassung +; installiert.json die Buchfuehrung des Updaters +; Ohne diese Zeilen bleibt der Ordner voller alter EXEs stehen. +; +; NICHT geloescht werden Rechnungen, Journal und Nummernbuch. Die liegen +; ohnehin woanders (%LOCALAPPDATA%/ravokk) und muessen zehn Jahre bleiben +; (§ 147 AO). Deshalb steht hier auch kein 'Type: filesandordirs' auf +; {app} - das waere die bequeme, aber falsche Zeile. +Type: files; Name: "{app}\installiert.json" +Type: files; Name: "{app}\{#Name}-*.exe" +Type: files; Name: "{app}\Updater.exe" +; Zum Schluss den Ordner selbst - aber NUR, wenn er leer ist. +Type: dirifempty; Name: "{app}" \ No newline at end of file diff --git a/Rechnungstool.spec b/Rechnungstool.spec index 9f4a7a6..57d1265 100644 --- a/Rechnungstool.spec +++ b/Rechnungstool.spec @@ -9,7 +9,7 @@ a = Analysis( # nur fuer den Prozess geladen (theme.schrift_vorbereiten). Fehlt sie, faellt # das Programm still auf Segoe UI zurueck - dann sieht es beim Kunden anders # aus als hier. - datas=[('assets/programm.ico', 'assets'), ('assets/programm_dunkel.ico', 'assets'), + datas=[('assets/programm.ico', 'assets'), ('assets/programm_logo.png', 'assets'),('assets/logo.png', 'assets'), ('assets/fonts', 'assets/fonts'), # Die Icons (Material Symbols vom Hub) - ohne sie zeigen die Knoepfe diff --git a/app.py b/app.py index ae92f8a..32fe38f 100644 --- a/app.py +++ b/app.py @@ -922,12 +922,30 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, """ self._buch_oeffnen() if self.buch is None and not config.testlauf(): - self.dlg_gemeinsam(erststart=True) + # Kein Dialog mehr beim ersten Start: der Ordner steht fest und + # ist in beiden Programmen derselbe (gemeinsam.standard_ordner). + # Gefragt wurde frueher - und wer in den zwei Programmen zwei + # verschiedene Pfade eintippte, merkte es erst, wenn eine + # Rechnungsnummer zum zweiten Mal vergeben war. + ordner = gemeinsam.standard_anlegen() + if ordner: + self.cfg["gemeinsam_ordner"] = ordner + config.save_config(self.cfg) + self._buch_oeffnen() + if self.buch is None: + # Nur wenn selbst das nicht geht, wird gefragt. + self.dlg_gemeinsam(erststart=True) self._buch_anzeigen() def dlg_gemeinsam(self, erststart=False): + # Ist noch keiner gesetzt, wird der Rechnungsordner vorgeschlagen: + # den kennen beide Programme, er wird mitgesichert, und er ueberlebt + # ein Deinstallieren. Der Ordner, in dem das Programm liegt, taugt + # dafuer NICHT mehr - seit dem Installer sind das zwei getrennte. ordner = ordnerwahl.ordner_abfragen( - self, "Rechnungstool", str(self.cfg.get("gemeinsam_ordner", "") or "")) + self, "Rechnungstool", + str(self.cfg.get("gemeinsam_ordner", "") or "") + or str(self.cfg.get("output_dir", "") or "")) if not ordner: if erststart: self.melden_warnung( diff --git a/assets/programm.ico b/assets/programm.ico index cae16c942d04f204b66e0d334615784bcbb9b9d2..aed826992e6d67bdaeba529f68595ea0e9ca850d 100644 GIT binary patch literal 43660 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 diff --git a/bauen.py b/bauen.py index efd4381..f3aa6dc 100644 --- a/bauen.py +++ b/bauen.py @@ -82,14 +82,15 @@ def main(): for ordner in ("build", "dist", "setup", "release"): shutil.rmtree(os.path.join(HIER, ordner), ignore_errors=True) - # Die aufgehellte Fassung des Symbols fuer die dunkle Darstellung. Sie - # wird HIER erzeugt und nicht erst beim ersten dunklen Start: sonst muesste - # das Programm in seinen eigenen Ordner schreiben duerfen - unter - # "Programme" darf es das nicht. + # Das Windows-Symbol aus dem Logo bauen: helle Kachel mit runden Ecken, + # Zeichen darauf, in allen Groessen von 16 bis 256. Es wird HIER erzeugt + # und nicht zur Laufzeit - ein installiertes Programm soll nicht in seinen + # eigenen Ordner schreiben muessen. sys.path.insert(0, HIER) import wasserzeichen - dunkles = wasserzeichen.symbol_datei_dunkel() - print(f"--- Symbol dunkel: {dunkles or 'FEHLT'}") + ico = wasserzeichen.symbol_bauen( + os.path.join(HIER, "assets", "programm.ico")) + print(f"--- Symbol: {ico or 'FEHLT'}") lauf([sys.executable, "-m", "PyInstaller", "--noconfirm", f"{stamm}.spec"], f"{stamm} {version.VERSION}") diff --git a/config.py b/config.py index c81f110..d76963d 100644 --- a/config.py +++ b/config.py @@ -42,9 +42,15 @@ def _daten_ordner(): Alles, was das Programm schreibt, liegt darin beieinander - man sieht auf einen Blick, was von ihm stammt, und kann es mitnehmen oder sichern. - 1. neben der EXE ein Unterordner "Daten" - 2. geht das nicht (EXE liegt z.B. unter "Programme"), dann - der Ordner Rechnungstool unter LOCALAPPDATA + 1. der Ordner der Firma: %LOCALAPPDATA%/ravokk + 2. geht das nicht, neben der EXE ein Unterordner "Daten" + 3. und zuletzt der alte eigene Ordner unter LOCALAPPDATA + + Warum unter "ravokk" (07.09.2026): dort liegen beide Programme und das + gemeinsame Nummernbuch beieinander - seine Ansage, *"ravokk ist meine + firma und die programme gehoeren zu der firma"*. Und weil die Daten damit + NEBEN dem Programmordner liegen statt darin, raeumt ein Deinstallieren nur + das Programm weg und laesst die Belege stehen (§ 147 AO). Was schon da ist, wird benutzt; was fehlt, wird angelegt. Lagen die Dateien noch direkt neben der EXE - so war es frueher -, ziehen sie mit um, statt @@ -52,19 +58,34 @@ def _daten_ordner(): """ if not getattr(sys, "frozen", False): return EXE_DIR # aus der Quelle heraus bleibt alles, wo es ist - kandidat = os.path.join(EXE_DIR, "Daten") + heim = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~") + # NEBEN dem Programm, nicht darin: das Programm liegt in + # ravokk/Rechnungstool, die Daten eine Ebene darueber in ravokk. Genau so + # hat er es beschrieben - "da liegt config und sqlite drin, und dann gibt + # es den ordner rechnungstool und steuertool". Nur dadurch kann ein + # Deinstallieren den Programmordner restlos leeren, ohne die Belege + # anzufassen (§ 147 AO). + kandidat = os.path.join(heim, "ravokk") if not _beschreibbar(kandidat): - kandidat = os.path.join(os.environ.get("LOCALAPPDATA", EXE_DIR), "Rechnungstool") + kandidat = os.path.join(EXE_DIR, "Daten") if not _beschreibbar(kandidat): - return EXE_DIR # letzter Ausweg: wie frueher + kandidat = os.path.join(heim, "Rechnungstool") + if not _beschreibbar(kandidat): + return EXE_DIR # letzter Ausweg: wie frueher + # Was an einem frueheren Ort liegt, zieht mit um - sonst faengt das + # Programm ohne Firmendaten, Katalog und Zaehler neu an. for name in ("config.json",): - alt, neu_ = os.path.join(EXE_DIR, name), os.path.join(kandidat, name) - if os.path.exists(alt) and not os.path.exists(neu_): - try: - os.replace(alt, neu_) - print(f"[config] {name} in den Datenordner übernommen") - except OSError: - pass + neu_ = os.path.join(kandidat, name) + for alt in (os.path.join(EXE_DIR, "Daten", name), + os.path.join(EXE_DIR, name), + os.path.join(heim, "Rechnungstool", name)): + if os.path.exists(alt) and not os.path.exists(neu_): + try: + os.replace(alt, neu_) + print(f"[config] {name} aus {alt} übernommen") + break + except OSError: + pass return kandidat diff --git a/gemeinsam.py b/gemeinsam.py index 79abae3..7fc329e 100644 --- a/gemeinsam.py +++ b/gemeinsam.py @@ -90,6 +90,49 @@ FELDER = ("jahr", "datum", "nachname", "vorname", "naechte", "zwischensumme", "freigabe") +def standard_ordner(): + """Wo das Nummernbuch liegt, wenn niemand etwas anderes einstellt. + + WARUM ES DIESEN FESTEN ORT GIBT (07.09.2026) + -------------------------------------------- + Vorher fragte jedes Programm beim ersten Start nach einem Ordner - und der + Nutzer musste in BEIDEN denselben eintragen. Sein Einwand, wortwoertlich: + + "wie soll das rechnungstool und steuertool wissen wo es ist, das muss + im ... ravokk liegen und dann zusammen, sonst kommt das eine nicht an + das andere ran" + + Er hat recht: die beiden sind ueber genau zwei Dinge verbunden - diese + SQLite-Datei und die kleine API, die "hier ist etwas Neues" ruft. Wenn + schon der Ort geraten werden muss, ist die Verbindung nur so gut wie die + Aufmerksamkeit dessen, der zweimal denselben Pfad tippt. Ein falscher + Buchstabe faellt erst auf, wenn eine Rechnungsnummer zum zweiten Mal + vergeben wurde. + + Deshalb: ein fester Ort, den beide von selbst kennen. Gefragt wird nur + noch, wer ihn ausdruecklich verschieben will (Menue -> Gemeinsamer Ordner) - + etwa auf ein Netzlaufwerk, wenn die Programme auf zwei Rechnern laufen. + + LOCALAPPDATA und nicht "Dokumente": dort liegen die Programmdaten ohnehin, + und niemand raeumt den Ordner versehentlich auf. Das Buch ist ein + REGISTER, kein Beleg - geht es verloren, fehlt keine Rechnung, es wird beim + naechsten Einlesen neu gefuellt. + """ + heim = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~") + return os.path.join(heim, "ravokk") + + +def standard_anlegen(): + """Den festen Ordner anlegen und zurueckgeben - oder '' wenn das nicht geht.""" + ordner = standard_ordner() + try: + os.makedirs(ordner, exist_ok=True) + return ordner + except OSError as e: + log.warning("Gemeinsamer Ordner %s liess sich nicht anlegen: %s", ordner, e) + return "" + + def pfad_zur_datei(ordner): """Vollstaendiger Pfad der gemeinsamen Datei in diesem Ordner.""" return os.path.join(ordner or "", DATEINAME) diff --git a/ordnerwahl.py b/ordnerwahl.py index 367c470..ddf6fe0 100644 --- a/ordnerwahl.py +++ b/ordnerwahl.py @@ -6,6 +6,14 @@ Rechnungstool und Steuerjournal fuehren ein gemeinsames Nummernbuch genannt werden - deshalb fragt jedes Programm beim ersten Start danach und sagt ausdruecklich dazu, dass es derselbe sein muss. +⚠ NICHT der Ordner, in dem das Programm liegt. Frueher stand das so im Text +("am besten der Ordner, in dem die Programme liegen") und der Knopf hiess +sogar "Install-Ordner auswaehlen". Seit es einen Installer gibt, geht das gar +nicht mehr: die beiden Programme liegen in ZWEI getrennten Ordnern unter +%LOCALAPPDATA%/Programs, und ein Deinstallieren wuerde das Nummernbuch +mitnehmen. Vorgeschlagen wird deshalb der Ordner, in dem auch die Rechnungen +liegen - den kennen beide Programme ohnehin, und er wird mitgesichert. + Der Weg ist bewusst umstaendlich: auswaehlen, dann OK, dann noch einmal bestaetigen. Ein falscher Ordner faellt sonst erst auf, wenn eine Rechnungsnummer zum zweiten Mal vergeben wurde. @@ -73,7 +81,7 @@ class OrdnerWahl(tk.Toplevel): tk.Label(rahmen, wraplength=breite, justify="left", fg=self._warn, bg=self._bg, font=(theme.SCHRIFT_NAME, 10, "bold"), text="WICHTIG: In BEIDEN Programmen muss derselbe Ordner stehen – am besten " - "der Ordner, in dem die Programme liegen.").grid( + "der Ordner, in dem auch die Rechnungen liegen.").grid( row=2, column=0, sticky="w", pady=(0, 14)) wahl = ttk.Frame(rahmen) @@ -81,8 +89,14 @@ class OrdnerWahl(tk.Toplevel): wahl.columnconfigure(0, weight=1) self.feld = ttk.Entry(wahl, textvariable=self.pfad, state="readonly") self.feld.grid(row=0, column=0, sticky="ew") - ttk.Button(wahl, text="Install-Ordner auswählen…", command=self.waehlen, - width=26).grid(row=0, column=1, sticky="w", padx=(10, 0)) + # "Install-Ordner" hiess der Knopf frueher - das war schon immer + # falsch und ist es seit dem Installer erst recht: hier geht es NICHT + # um den Ordner, in dem das Programm liegt, sondern um den, in dem die + # beiden Programme ihr gemeinsames Nummernbuch fuehren. Sein Befund am + # 07.09.2026: "gibt es noch das popup install ordner auswaehlen, das + # stimmt ja nicht". + ttk.Button(wahl, text="Ordner auswählen…", command=self.waehlen, + width=22).grid(row=0, column=1, sticky="w", padx=(10, 0)) self.stand = tk.Label(rahmen, text="", wraplength=breite, justify="left", bg=self._bg, diff --git a/pruef_gemeinsam_automatisch.py b/pruef_gemeinsam_automatisch.py new file mode 100644 index 0000000..4c9b936 --- /dev/null +++ b/pruef_gemeinsam_automatisch.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: finden sich die beiden Programme von SELBST? + +Sein Einwand vom 07.09.2026, wortwoertlich: + + "wie soll das rechnungstool und steuertool wissen wo es ist, das muss im + ... ravokk liegen und dann zusammen, sonst kommt das eine nicht an das + andere ran - die sind doch nur ueber die gemeinsame sqlite verbunden und + mit api, die sagt hallo da ist was neues" + +Er hat recht: die beiden haengen an genau zwei Faeden - dieser SQLite-Datei +und der kleinen API. Vorher fragte jedes Programm beim ersten Start nach einem +Ordner, und der Nutzer musste in BEIDEN denselben eintragen. Ein Buchstabe +daneben, und jedes Programm fuehrt sein eigenes Buch weiter - auffallen wuerde +das erst, wenn eine Rechnungsnummer zum zweiten Mal vergeben ist +(§ 14 Abs. 4 Nr. 4 UStG). + +GEPRUEFT WIRD + + 1. Beide Programme nennen denselben Standardordner. Das ist die Grundlage; + weichen sie hier ab, hilft alles Weitere nichts. + 2. Der Ordner laesst sich anlegen, und darin entsteht EIN Nummernbuch. + 3. Was das eine eintraegt, findet das andere - ohne dass jemand einen Pfad + eingegeben hat. + +Angefasst wird dabei nichts Echtes: der Standardordner wird ueber die +Umgebungsvariable LOCALAPPDATA auf einen Temp-Ordner umgelenkt. +""" +import os +import shutil +import sys +import tempfile + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +RECHNUNG = r"C:\claude\rechnungstool" +STEUER = r"C:\claude\beherbergungssteuer" + +# ---- 1. Beide Programme meinen denselben Ort ---------------------------- +# Geladen wird jede Fassung EINZELN, damit wirklich die Datei des jeweiligen +# Programms befragt wird und nicht die zufaellig zuerst importierte. +import importlib.util # noqa: E402 + + +def modul_aus(ordner, name): + pfad = os.path.join(ordner, name + ".py") + kennung = f"{name}_{os.path.basename(ordner)}" + spec = importlib.util.spec_from_file_location(kennung, pfad) + m = importlib.util.module_from_spec(spec) + spec.loader.exec_module(m) + return m + + +tmp = tempfile.mkdtemp(prefix="gemeinsam_auto_") +os.environ["LOCALAPPDATA"] = tmp + +g_rechnung = modul_aus(RECHNUNG, "gemeinsam") +g_steuer = modul_aus(STEUER, "gemeinsam") + +a, b = g_rechnung.standard_ordner(), g_steuer.standard_ordner() +pruefe(a == b, f"beide Programme nennen denselben Ordner ({a})") +pruefe(a.startswith(tmp), + "und er haengt an LOCALAPPDATA, nicht an einem festen Pfad im Quelltext") +pruefe(os.path.basename(a) == "ravokk", + f"er heisst 'ravokk', wie er es wollte ({os.path.basename(a)})") + +# ---- 2. Er wird angelegt, und darin liegt EIN Buch ---------------------- +angelegt = g_rechnung.standard_anlegen() +pruefe(bool(angelegt) and os.path.isdir(angelegt), + f"der Ordner wird angelegt ({angelegt})") +pruefe(g_rechnung.DATEINAME == g_steuer.DATEINAME, + f"beide erwarten dieselbe Datei ({g_rechnung.DATEINAME})") +pruefe(g_rechnung.pfad_zur_datei(angelegt) == g_steuer.pfad_zur_datei(angelegt), + "und damit denselben vollen Pfad") + +# ---- 3. Was das eine eintraegt, findet das andere ----------------------- +buch_r = g_rechnung.Nummernbuch(angelegt) +buch_s = g_steuer.Nummernbuch(angelegt) + +buch_r.eintragen("2026-777", jahr=2026, nachname="Probe", quelle="rechnungstool") +gefunden = [n for n in buch_s.nummern(2026) if n == "2026-777"] +pruefe(bool(gefunden), + "was das Rechnungstool eintraegt, sieht das Steuerjournal sofort") + +buch_s.eintragen("2026-778", jahr=2026, nachname="Gegenprobe", quelle="journal") +zurueck = [n for n in buch_r.nummern(2026) if n == "2026-778"] +pruefe(bool(zurueck), "und umgekehrt genauso") + +pruefe(len(os.listdir(angelegt)) >= 1 + and any(n.endswith(".sqlite3") for n in os.listdir(angelegt)), + f"es liegt genau ein Buch dort ({os.listdir(angelegt)})") + +shutil.rmtree(tmp, ignore_errors=True) + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Beide Programme finden dasselbe Nummernbuch ohne Nachfrage") diff --git a/pruef_installation.py b/pruef_installation.py new file mode 100644 index 0000000..7e9719c --- /dev/null +++ b/pruef_installation.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: installieren, deinstallieren - bleibt der Ordner sauber? + +Seine Ansage vom 07.09.2026: + + "du solltest die auch mal deinstallieren und neu installieren von windows + lassen, dass du auch pruefen kannst, dass der ordner dann leer ist und + sauber - will keine tools die unsauber sind" + +Er hatte recht. Gemessen blieb nach dem Deinstallieren liegen: + + Rechnungstool-1.7.1.exe, Rechnungstool-1.8.0.exe <- vom UPDATER geladen + Daten/config.json, Daten/rechnungstool.pid + +Die EXEs kennt der Installer nicht - die hat der Updater abgelegt. Ohne eine +eigene Regel bleiben sie stehen, und mit jeder Fassung wird es eine mehr. + +ZWEI DINGE MUESSEN GLEICHZEITIG STIMMEN +--------------------------------------- +1. Der PROGRAMMordner ist danach restlos weg. +2. Die DATEN sind unangetastet - Rechnungen, Journal, Nummernbuch. Die sind + zehn Jahre aufbewahrungspflichtig (§ 147 AO); ein Deinstallieren darf sie + nie mitnehmen. + +Beides zusammen geht nur, weil die Daten NEBEN dem Programm liegen: + + %LOCALAPPDATA%/ravokk/ <- Daten, gemeinsames Nummernbuch + Rechnungstool/ <- Programm, wird geleert + Steuerrechnungstool/ <- Programm, wird geleert + +Genau so hat er es beschrieben: *"es gibt ravokk als main verzeichnis, da liegt +config und sqlite drin, und dann gibt es den ordner rechnungstool und +steuertool"* - und dazu, warum es so heisst: *"ravokk ist meine firma und die +programme gehoeren zu der firma"*. + +⚠ DIESER PRUEFSTAND INSTALLIERT WIRKLICH. Er laeuft deshalb nur, wenn das +Setup gebaut ist, und er fasst NUR die Programmordner an - vorhandene Daten +werden vorher gesichert und danach zurueckgelegt. +""" +import os +import shutil +import subprocess +import sys +import tempfile +import time + +HIER = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, HIER) + +import version # noqa: E402 + +LOKAL = os.environ.get("LOCALAPPDATA", "") +RAVOKK = os.path.join(LOKAL, "ravokk") +NAME = os.path.splitext(version.EXE_NAME)[0] +PROGRAMMORDNER = os.path.join(RAVOKK, NAME) + +fehler = [] + + +def pruefe(bedingung, text): + zeile = (" OK | " if bedingung else "FEHLER | ") + text + kod = sys.stdout.encoding or "utf-8" + print(zeile.encode(kod, "replace").decode(kod)) + if not bedingung: + fehler.append(text) + + +def setup_datei(): + ordner = os.path.join(HIER, "release") + if not os.path.isdir(ordner): + return "" + for d in sorted(os.listdir(ordner)): + if d.startswith(NAME + "-Setup") and d.endswith(".exe"): + return os.path.join(ordner, d) + return "" + + +def beenden(): + subprocess.run(["powershell", "-NoProfile", "-Command", + "Get-Process | Where-Object { $_.ProcessName -match " + f"'{NAME}|Updater' " + "} | Stop-Process -Force " + "-ErrorAction SilentlyContinue"], capture_output=True) + time.sleep(1.5) + + +def inhalt(ordner): + if not os.path.isdir(ordner): + return [] + gefunden = [] + for wurzel, _, dateien in os.walk(ordner): + for d in dateien: + gefunden.append(os.path.relpath(os.path.join(wurzel, d), ordner)) + return sorted(gefunden) + + +setup = setup_datei() +if not setup: + print(f"UEBERSPRUNGEN | kein Setup in release/ (vorher: python bauen.py)") + sys.exit(0) +if not LOKAL: + print("UEBERSPRUNGEN | kein LOCALAPPDATA") + sys.exit(0) + +# ---- Vorhandene Daten in Sicherheit bringen ----------------------------- +# Hier laeuft echte Software auf einem echten Rechner. Was schon da ist, wird +# beiseitegelegt und hinterher zurueckgestellt - ein Pruefstand darf niemandem +# seine Buchhaltung anfassen. +sicher = tempfile.mkdtemp(prefix="installpruef_") +gesichert = [] +if os.path.isdir(RAVOKK): + for d in os.listdir(RAVOKK): + quelle = os.path.join(RAVOKK, d) + if os.path.isfile(quelle): + shutil.copy2(quelle, os.path.join(sicher, d)) + gesichert.append(d) +print(f" ({len(gesichert)} vorhandene Datei(en) gesichert)") + +beenden() +alter_uninstaller = os.path.join(PROGRAMMORDNER, "unins000.exe") +if os.path.exists(alter_uninstaller): + subprocess.run([alter_uninstaller, "/VERYSILENT", "/SUPPRESSMSGBOXES", + "/NORESTART"], capture_output=True) + time.sleep(6) + +# ---- 1. Installieren ---------------------------------------------------- +e = subprocess.run([setup, "/VERYSILENT", "/SUPPRESSMSGBOXES", "/NORESTART"], + capture_output=True) +time.sleep(5) +pruefe(e.returncode == 0, f"das Setup laeuft durch (Rueckgabe {e.returncode})") +pruefe(os.path.isdir(PROGRAMMORDNER), + f"das Programm landet unter ravokk ({PROGRAMMORDNER})") +dabei = inhalt(PROGRAMMORDNER) +pruefe(any(d.startswith(NAME + "-") for d in dabei), + f"die Programmdatei liegt dort ({dabei})") +pruefe("Updater.exe" in dabei, "und der Updater daneben") + +# ---- 2. Eine Datei anlegen, wie der Updater es taete --------------------- +# So sieht der Ordner aus, nachdem das Programm ein paar Fassungen lang +# gelaufen ist. Genau diese Dateien blieben frueher liegen. +geerbt = os.path.join(PROGRAMMORDNER, f"{NAME}-9.9.9.exe") +with open(geerbt, "wb") as f: + f.write(b"als haette der Updater sie geladen") +with open(os.path.join(PROGRAMMORDNER, "installiert.json"), "w", + encoding="utf-8") as f: + f.write("{}") + +# ---- 3. Eine Datendatei daneben, die ueberleben MUSS --------------------- +probe = os.path.join(RAVOKK, "pruefstand-beleg.txt") +with open(probe, "w", encoding="utf-8") as f: + f.write("steht fuer Rechnungen, Journal und Nummernbuch") + +# ---- 4. Deinstallieren -------------------------------------------------- +beenden() +u = os.path.join(PROGRAMMORDNER, "unins000.exe") +pruefe(os.path.exists(u), "es gibt einen Uninstaller") +if os.path.exists(u): + subprocess.run([u, "/VERYSILENT", "/SUPPRESSMSGBOXES", "/NORESTART"], + capture_output=True) + time.sleep(7) + +uebrig = inhalt(PROGRAMMORDNER) +pruefe(not os.path.isdir(PROGRAMMORDNER), + f"der Programmordner ist danach weg ({uebrig})") +pruefe(not uebrig, + f"und darin liegt nichts mehr - auch keine geladene Fassung ({uebrig})") + +pruefe(os.path.exists(probe), + "die Daten daneben sind unangetastet (Rechnungen, Journal, Nummernbuch)") +pruefe(os.path.isdir(RAVOKK), + "und der Ordner der Firma steht noch") + +# ---- Aufraeumen --------------------------------------------------------- +if os.path.exists(probe): + os.remove(probe) +for d in gesichert: + ziel = os.path.join(RAVOKK, d) + if not os.path.exists(ziel): + os.makedirs(RAVOKK, exist_ok=True) + shutil.copy2(os.path.join(sicher, d), ziel) +shutil.rmtree(sicher, ignore_errors=True) + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Deinstallieren laesst den Programmordner leer - und die Daten stehen") diff --git a/wasserzeichen.py b/wasserzeichen.py index 495d72c..7028eca 100644 --- a/wasserzeichen.py +++ b/wasserzeichen.py @@ -45,37 +45,79 @@ def pfad(name): return "" -def symbol_datei_dunkel(): - """Pfad zur aufgehellten ICO - wird angelegt, wenn sie fehlt. +def kachel(bild, kante, grund=(0xFF, 0xFF, 0xFF), rand=0.16, radius=0.22): + """Das Logo auf eine helle Kachel mit runden Ecken setzen. - Sein Befund am 07.09.2026: *"icon musst wenn es dunkel ist mit ändern auf - das hellere geht sonst mit unter"*. Die dunkle Haelfte des Zeichens liegt - genau auf der Farbe der dunklen Titelleiste. + Seine Ansage am 07.09.2026: *"bei den windows icons kannst du einen + weissen bg setzen hinter die icons, mit abgerundeten ecken, und da das svg + drauf - das geht auf dem desktop unter"*. - `iconbitmap` braucht eine DATEI - ein Bild im Speicher genuegt nicht. - Deshalb wird sie einmal neben die normale gelegt. Gelingt das nicht (kein - Schreibrecht im Programmordner), landet sie im Temp-Ordner; und wenn auch - das nicht geht, bleibt es beim normalen Symbol. + Ein freigestelltes Zeichen ohne Flaeche verschwindet auf einem dunklen + Hintergrundbild - und welchen Hintergrund jemand eingestellt hat, weiss + das Programm nicht. Eine helle Kachel ist auf jedem sichtbar; so machen es + die meisten Programme, und deshalb sieht es auch nicht fremd aus. + + `rand` ist der Abstand zum Kachelrand, `radius` die Eckenrundung - beides + als Anteil der Kantenlaenge, damit es in jeder Groesse gleich aussieht. + Die 22 % entsprechen etwa dem, was Windows fuer Kacheln verwendet. + """ + from PIL import Image, ImageDraw + kante = int(kante) + # In vierfacher Groesse zeichnen und herunterrechnen: sonst werden die + # runden Ecken bei 32 oder 48 Pixeln treppig. + fein = kante * 4 + maske = Image.new("L", (fein, fein), 0) + ImageDraw.Draw(maske).rounded_rectangle( + (0, 0, fein - 1, fein - 1), radius=int(fein * radius), fill=255) + flaeche = Image.new("RGBA", (fein, fein), tuple(grund) + (255,)) + flaeche.putalpha(maske) + + innen = max(1, int(fein * (1 - 2 * rand))) + zeichen = bild.convert("RGBA").resize((innen, innen), Image.LANCZOS) + versatz = (fein - innen) // 2 + flaeche.paste(zeichen, (versatz, versatz), zeichen) + return flaeche.resize((kante, kante), Image.LANCZOS) + + +# Groessen, die eine Windows-ICO enthalten soll. 16 und 24 fuer Titelleiste +# und Listen, 32/48 fuer den Desktop, 256 fuer die grosse Ansicht im Explorer. +ICO_GROESSEN = (16, 24, 32, 48, 64, 128, 256) + + +def symbol_bauen(ziel): + """Die Windows-ICO aus dem Logo erzeugen. Gibt den Pfad zurueck oder ''. + + JEDE Groesse wird als Kachel gebaut: helle Flaeche, runde Ecken, Zeichen + darauf - *"so wie das rustdesk, nur halt alle ecken in der rundung"*. Ein + freigestelltes Logo verschwindet sonst auf einem dunklen + Desktop-Hintergrund. + + Auch die 16 Pixel der Titelleiste: dort ist die Kachel zwar winzig, aber + sichtbar. Ein freigestelltes Zeichen war dort je nach Darstellung mal da + und mal nicht - und ein Symbol, das manchmal fehlt, ist schlechter als + eines, das immer klein ist. + + Bei den kleinsten Groessen wird der Rand knapper gefasst: bliebe der + Abstand anteilig gleich, waere vom Zeichen bei 16 Pixeln fast nichts mehr + uebrig. """ - fertig = pfad("programm_dunkel.ico") - if fertig: - return fertig quelle = pfad("programm_logo.png") if not quelle: return "" - ziel = os.path.join(os.path.dirname(quelle), "programm_dunkel.ico") try: from PIL import Image - bild = _umfaerben(Image.open(quelle).convert("RGBA"), True) - groessen = [(g, g) for g in (16, 24, 32, 48, 64, 128, 256)] - try: - bild.save(ziel, sizes=groessen) - except OSError: - import tempfile - ziel = os.path.join(tempfile.gettempdir(), "programm_dunkel.ico") - bild.save(ziel, sizes=groessen) + roh = Image.open(quelle).convert("RGBA") + bilder = [] + for g in ICO_GROESSEN: + bilder.append(kachel(roh, g, rand=0.10 if g <= 24 else 0.16)) + # Pillow schreibt die uebrigen Groessen selbst aus dem groessten Bild - + # deshalb wird das groesste uebergeben und der Rest angehaengt. + bilder[-1].save(ziel, format="ICO", + sizes=[(g, g) for g in ICO_GROESSEN], + append_images=bilder[:-1]) return ziel - except Exception: # noqa: BLE001 - ohne helles Symbol laeuft es weiter + except Exception as e: # noqa: BLE001 - ohne eigenes Symbol laeuft es weiter + print("[symbol] konnte nicht gebaut werden:", e) return "" @@ -86,10 +128,12 @@ def symbol_setzen(fenster, melden=print, dunkel=False): steht in der Titelleiste das nackte Tk-Symbol, obwohl die Datei ein eigenes hat. - In der dunklen Darstellung wird die aufgehellte Fassung genommen, sonst - verschwindet die dunkle Haelfte des Zeichens in der dunklen Titelleiste. + `dunkel` wird nicht mehr gebraucht und nur noch entgegengenommen, damit + bestehende Aufrufe weiterlaufen: seit das Symbol eine helle Kachel ist, ist + es in jeder Darstellung sichtbar. Vorher gab es dafuer eine zweite, + aufgehellte Datei - die ist mit der Kachel ueberfluessig geworden. """ - p = (symbol_datei_dunkel() if dunkel else "") or pfad("programm.ico") + p = pfad("programm.ico") if not p: melden("[symbol] assets/programm.ico nicht gefunden") return False From b5bf6f401fdc6d6a5344245e614733fa33595f90 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 10:52:00 +0200 Subject: [PATCH 30/34] Windows-Symbol in den Programmfarben Sein Befund: "hast du bei dem windows icon das gleich farbige wie im programm, wo als wasserzeichen gilt, gemacht - weil das schaut blau aus". Er hatte recht: auf der Kachel stand das ROHE Logo mit seinem Petrol #004860, waehrend im Programm (Kopfzeile, Wasserzeichen) laengst die umgefaerbte Fassung laeuft. Zwei Farben fuer dasselbe Zeichen. Jetzt geht das Logo auch fuers Symbol durch _umfaerben() - dieselbe Funktion, dieselben Farben: Tuerkis fuer die Wolke, Dunkelgrau fuer das Zeichen daneben. Die Kachel ist weiss, also gilt die HELLE Fassung. Fassung 1.8.1. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- assets/programm.ico | Bin 43660 -> 43555 bytes version.py | 4 ++-- wasserzeichen.py | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/assets/programm.ico b/assets/programm.ico index aed826992e6d67bdaeba529f68595ea0e9ca850d..f3778ff050c987e2d818bbc6507fb8ef03924461 100644 GIT binary patch literal 43555 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�(g0!@W`Haw+WZh0b|}}6FAB{(Hq-o^*8c}_g|?Y$BuaoQ+e6Kd5fDEqJwUIyR&GB{0;FY$bIjE zouyDCga|kmbZ7IW3AC^bxo4B{h?VJ<6;kTFUw^;Q2s5%>yw7L5cg`g225V>-4>!2sB_djy&n>48suJ^iBZc(1GfAG!at>sb-Wp+u? zmhgB~}hR%oM z9P>+B>9Hvm#rp0#i8%sm*&%IM;cC_88vf1*aS*Z;LN0eQ*c4OrKb5fu!C zSQFG8v6g!MwH|@na{YLLZw4$MT%Wrjh`|!+X`3z$q8oD z^G<_SD-sXC@C|FZ{q04hlrjIpex~s`={x}=vhIcofbl1+^Q&D>;t$v-b~mk|6_eCO zg)$Xa7IrZHqCbj;Tv$visheN=`!1?K5w|FWGSno!Ke=(9!cM`*E>u-jLqY-_Q4W(< z1-uR2pNe>r#L0+0&WD2PHTTSm%+X_Y~Z4+}@XEZ_#vltVL)DAihE;zLU3K>g*cVfBGd-ykLGCo*Q zXE9hG#vE1$qmGvm%m&q0B=jO$8n)Ht_#Q!eSYwodC>sp6_UJ*UJGeoOX>cb_6J)Kl>1^;|`#RbcZ5 znKja%b!2HCKTRwskSz(xAnvJh8LY5LGd)=|Vy793nv z#ynx4ve}gsPZc^ian+>~iCiM>4X1-5ZH%Jd1YZ`{!*3ZL=)05 z5w^wsJYMP;K*wM4zG0X!8_4evI9LnEM~k##{+Zf+WGPTQ+IS}k-v-8CA;ryQ z<4+3e@mbD3WRI6xZTFmYFr$d8sk|+$J|^?p>m*B`{?_Cn@kl^~m_MAkiIM@TjN6hP zX!q@Xw}zDAHEg9|wf`VOEzCCGmYt<{+phW>TuW3zC$2`D(lDW@LYXRFr^k_7P8oHx z|H4#t`HCcoSzu;;lF~_%E=tAU9`zkzSd!w(!-)+r0>r(n69@pr&aI8|8`KLkm1ohq<>Pi?Y4yPWX(G= zq;F@f17LZprp@UDkP}jBWiavqN8f7#E1Q~@^N_Jd1JS~_I2Zg5Nm2!?eYA>@GzNBe zU0UYv8&55pVKv^Y=I(}#zpYX0b7)Gqr-BucnvTBg_GGWY{oJs6F-I{EAF%<*mwhg0(3JE+F1DcY`LqN`oT!BR9>- z;-k*gMqL(p8aU-iTO(Wfz(l=+3se2m)94Y3`M00(qVY)1 z!KH$_q#(dVw*a0dBi;H>FS`x7$AW&$9|fl_(`ua-alKa4P!%9&ukQ1sZd$~TDN2$gW=>KA)|%GYp5Ga+4sPe*Am)crTeqdp^HMbvbbfk+ zX#qtjkh6D{smrj)0H}4n?PLW)J;HAexd_bgbHaoPALmU>)&Mod5jZ*gx~9d7fqK7sKjux( z#i^;^yMnQOgDGQ7#91DvXYZ@iSxx3{!jh}Gc6F>eo#pQ*&6nIt0msy{Z-2%q2*ylc zVJKiN9$%8eu|;Q3L+Xi=R_EagP6blsX$5|@w>wWI1nKZUjE~UhdP8|_v-U@ZGJ&z+ zMNXa|4;y$$DfwM z<64E|WMUkUvM7XLRz%F|cS(2s;0hivCCHNq?-ju*LUXBuJrfb7*A=l@pa zMW}F8U5B!z#?Uqdx_#2gFvG&uQbeolNTF`O)Iz~E1|ue^doFjs$Nxo{Nu|IXKjy(5 z|ANarnA0`MQzCqDSvr~98pH21`x``2prSPQXILq_$!p7yrl}*>m0fy}6u191`?(ol#8oCQWbudBh0TJl*AL=xESXrJAStdLG;F z7awGXUn=KNpOM;VSco}OZ`Ht>Jxnua{dkeI3b<}kHi|pNM?*?gOTolW+Z#wWOlYBl z8<^lFi-#tZTcx*x!-TdQdp=u==QnC`EvYLvcNC{M_nTT|6aM%e|H*G6#)lneHmFO_ z9ek)3o1VTnyY=x==lPlci9L0Qk|awrFdJfxS3GCKcN00d=Gb%HQ7&ckm-YJrQAiR1 zqdp#!M4HSu==CI?Nvk&n6)D=HZNQ0$U6626q<7pjTy#=|!Ua^-E`}c#2}h9$(tVlO zxxzt}-;V@Jc_nbcaw$gCi(*3!a+-)$>E@Cknww8wg>AXCx!KYht1!_%HvbASL@8kx z#*I09UI}Hgm4RoRqaXOsEj}V`OY{p}kQF&UcHA)Pc(T$Q4RE>C=I~uQjT| zpyzYcj#3x-k2Q4XK#+;Q_-nRX0u90lJ(sB@NjT|e1TT3btYKJgE}3uuW9JMfs&Jn_ zmw%?(Y2+SH)ut66O)hhUQ@*6&aqj0HThGT2A?i<}QWgFs8dBFc4)@6lWA>lM-q@p; zd}tKL$)D{XII)&ll66XcemDZ3_qfnVbEV&uHr`(aLyh@Af&>~?SZN`W<*==-`=D#y zO@oYKMd*uZ4u5Ajc4+4b)%QcYt+|^Hvb3{h0?i7f&T#ePpi6ga3R)(Ysxt{cW0E?` zh<9@qrbCs`NMQX_xk6$21-XMoIOiZoV6K+Y?TwN`gK{b_ugLu$QFV;Z_oP?~L|pB? zUjy8ukJ;S%oF9kV(G|oLsocoPuuf^SNjFCquw-me;PFDqWJZPR9wP zi~qA)XJ!YhFKfqW&Yd4Sqe8ADUJNuW%-APT4NOnUEk@QJZ0uly82;CDet*?nk%wz% z0-Kd?57H`_DStk$P&IyOV`8_5tWR-y)So@5@t9hjHx9GrLw2Y{zr*MF?sGBV-fTa*wR7y#OQkuk z#ds%mDjlnYjlie@{D9KRfmu#9*UX!+@2etZ^6n@3yi;ko3OzWdK0?!AYIclL+2ou@ zuQv09e_`*#kFTFYv$U<$Z;9FaMb8{0w^f|>51aNILB1SB4({LeZ+Fj9+sM!*+xrJ} zb{1^0L!#?M%^^KBoC;FfjmcthmjP|vnt|{(EAcZ3-MR z6hgW-XhL`c9CsJ~>RPQBe*JdP-2Mf3=ND4Bc5mMTz^h%3+BF;;ujYK zc;KTXh?e)cf`|`md}^=6eI*zbX->YOi4&H>T}zUDTqgvTlD(Zu48|cOMimyeTfqi; zbRkI1^`ZCwiX}$z-#s-J3kb=lKPuh3@v+<)@cQ8^gpL7O283<4USd}NDOILroLoHS z5~rTY%bvPh0g_Unpej0|3){BMEvCXBUqWp)c&fkanD96y7zs@dsgVAs%J(o&t^s}B z_B3wi6v?K0qv|Vr4JfNAr!2@w2I>$_o2E}R&Y#7NpBQJ4XvCDsI@S$#0zd-c{Uh?dvmxQqh>v^C5B^BJhu4@5~0(Y7c41SB(8QeiGsNVLqk%p-rCb=?k` z)&Kbig`a-Ah#03g&t37ucJnUpsv3Tzl$G}swN zp(gBzOxiWy3|v>z9F~l|l)!3V${+OG{LV>jPy?M#9DSrPIbgwqva#pTNm-W&0}ylF z?~^$UT~D*)icAG&V-~aCLW)=&gAVHfK4~Us+sFmOD}LV|b5(ib#tL2a0yTWbO{&WN%k~ns>KYtBz172rcF){_ba2iX1V&njXnlJQoQHe3hdQ>_$Ry zUpMgQUJ6q27atV6M$$4~Jiufk4EN@wWUCZb?UqAvdFH{ASwSAjl$C8{y zq4vqb68S4M5OnRW__lz?JLH+$s$jL*)sEKe{;z(xjO=3HSx#a3=+`$gjgZ{%F(uxu zO`7rK#rgU2^X{d*m7)XzY;-=8-b7}(SV-i=Ku6z1r###GE|Mk1)b!v+8--OqjpHzjwAN<|RecNJv zf!Zco4GKTg+>QrDeOs>fX{Tw7#+xCLr92FlC?vIxHj70b`r!$O9g#K_k|mBR%XX*ElPFSWhkH9&FUmMh7Fh|PfHq3 z0w<%2`{aJU`a7J!c)ahjjR6e>{l~%#F>#W9oNp7A>Dl^Cd>oni)TBsp^@_ zr$78BkN@s(^#$Hdon=-;XdbnjhMhpjp1^4H@tnxs>V8gX5yltAdQu+g7)~Ti45d(s zy)(b5Ld9nw`a*rkrC3Rlx+kuv6^-Uv*QUi*QH#Hd;+<2iTXTYobX->J+t}3fH}5x6 ze>@e;!rv;UvZ-nEten)dQJSz1VdOF>}rD z!DE8*=T|jFtW?a||Kg54QtLQP~B1`jRmz1bw)}_)(U2tU5rO3Ig zMB`OB<$r`8o%i-M!W?e5qsfqL^c#YED!S&4s{+_w$CU|6EL77uekIt&uWcZJ<~PjZ zN~TBXiC(3Mhce~oZPP2yHl>SwGdQYw$XD_ijqK=9UE1teg|FAiU;8mJ@x1XK5 zYmACA?awP0I?+n)EM#MD@nZJ=tiXiA7T?M%!3;LjqP$(Kk&$yzl@^Z+q`s~(aawO< zxLt6{p-GqD&j3ctT1c{!v73s!Jvd=(veEpzUbaq7dH~q6-WOSpD_{s+6+9n_=0~pJ z4MJ(H?_o##KYWdFUw2tkqO>3%#BdSEA~t}!Gr4_UC@mos{oF$vJ}_^+#4ZQJVW~2% z^Sf=`$SHmO=jc3r_V2Pu;WP(X@Ilbh6-NI{4TTkIb=}B6`dDsTjwssEnk_Z}OK<(@ z%)a5^=nq?2NkiJJS%uoBfXi6&A*!UhklJ4giPMKWjrsg-=kaTf@w$YF8}jS#Q+E{K zt!&Cfr`1AqqA5LfsfX7tyMDGmC6DiM=hrAvRAQELCndENQKLbs(&d)Q+Ad~CU3?x1 zC>hc!qk91F$ftM@x7)>7tC`p+ejryGlgU6Ti0^Z?tEed@%Zf`KFhqBEmFVML`ocHo z))IZSCO#FY(ffSOlm?MzVYff)p7&CKt&U!D8z0!tzI-b^ig&O*gR+wotVy^QiH z5YsOGKPLtt|H&e5oOC8O2uee<`6ei+t+8z>&(FTu8`RuqCpo0T`t!Cd?}0SnSZ16( zJ@_lZjC-FQi^$Dm@6noLqf*0WO#s*SrPG$C?e~o~8=K=@HGzwof~uP^wfku|bgfgJ zr=50tg@eN8%OPBurwz0GZgU*Y*2!ghd#FE-XiD7Ah{}nmUKmDRlWDNFU17f|#afqTsByFQ zOm>n;MXBWgSUevqnZ!DAko+F5Z;>KTx65nb$E~&V-_)L2AuKc@P%+2rgI4Fpe(ruA zOE94lmhM|lhS1~p??0K+qJt+SpS}#k<@r2>|GB{P&u!)x6>*W z=5eQlEPeY^d4(mC`t0PG&Vy%#x_u-XBFRSRV6Jija|45YKOaz#*WksYZBWWi?7wkL z14dfHmp8O&!^(fyly_c=81o;Fh@O;dFqZ1`;l@bqJQElxzCU<*?Vrw+d9tLK_jtS8 zPYZiar;XG4qg5jOQe%j?2-;?g4cWNV0z3IZ>GW(d+;-P`q{*^JIO)Uw=Hl{wN%gT6 zN9I}>d}3iEA>ZmUIrj@coIMrH_Qz}!H%HifKHW;lX?*CO8WYwqu}nvg{V!o!1V|TB z;C+f?&`7Qio_^cmFR^DO7>Mtm(#!?$Z2u1FFVO!no(iJEB5?eKczzmsU8@f=5Np5LVJ8xvYSVoX4w7Z+W{u=>-L3D6)N8zbwfWKUF z2m*^vfwo2(H|EZ1sm&i0f}ZeBQ{o7x9eud%s`$n1XHO*Nv1K9M@G46^<4EP-Azmw# z?Ia%VSx2R+{EjQP;t>^69D8M06m6w~*{@$!kt~V7oNn+$RCocF#W3w#T-1X3+GUnJ zT1>e}-A<;YuY{H6kkU~_AKz}{TGxFM7y+n+;@y4i_%8jy2#5_d^-w_TW7F{M*@W~R zKi_U0<|3%A4gl-t2P3x=Sjn@W5gLRU2X~ERExtAc@Te2mo@E7OEIH_{b~Gi&I2B2{ zW~951p?8h|6Vq`02!OPtdbB65xO`4%h&k(XZftVN6OuxzXECw!YlNwhBcsOTzRNmw z+u%jv$K?RE?l$NPZhO)1>8Xk|^JeWNi8)b{*=wuNQ(R_FFLT;gCD2!YnwxtJk`35a zV4+pTX03p#5z9q^scCSao-HB4``su(3Wa>?xCd)TEH?x6D`6;*^$gQt zl$%@1`uu$HckODkg<$W1A+s4sTGyK=(>qakQiJkVrAyy?0DJ+NHehoQ5B1f_ILC3R zl+(kBFCVGlG4iFi$@F1-eT9jlWg<8-L%E!&K#&kS3#x;OF-OhQG?Xn#7IL|pwqw5fg|zJlx1EM*030l&0T%8_&YYh5n0%a4L?e+pr;k~r@OO-OM=Gf= zvn}5ytpC__^CWGt{n~D{4;z9DZh0v?}5C{{^g6{1T8DJjL0 zMqV;~nOf74Rniz&=Oov`WWuNq4JbLfVj6?yElZExe{vEkE^nbka z52bvBJN0&L3mv7vQ118XG}`Luz=055-)oun3wv!0jfS0V^5q(;4oJC&8J!t>HKf=ksNuieFqxreIYC%!w6>F-HCJz zng~pt=zI*D0|v4sH_9*?@21+D$!LU}w97Y!Q%h@md*-~W``SO{7=4FV_h=w)4j^a zDL!*lp~>cFUudS^MK>E>!qBoLWj1z|b*}#nQkn)Mo(H0|%)6677U6sEGO!OX4{zW9 zU}a)B?&zpX51I_I8$k(pV+OgLX z#R$aT1C`gwA*f;fCy3{$fNGnCk(!Q&hljI-z_-Q$pWZfE(2n_1XW9jtov!EVPnYl| zkM5`O)0$}mk4cXxSw0fy@t>r$Djg>`3d~YSk_{^c$8RXC9CbUR{PAquU{O4Y>3() zf`!|l>)Q#A5t5CtCGU~ipr7xLz4?xgj<$?nh8KxF^%Aa{p+On2)+%b-n@ZzqeqrjQ zqFG($a|FbtTtdy`rsu|nA0c@>^WGV<6WECiU<&!0?B~e}C*}`cVPh;T*3wa*I6nL1p| zO$LwR2je@7=dOxd0ai$ljgKPIP~i(%^>Ckm5cX-tviHJA|xK(-Jt{d#=&|`{tIb8@jnii*?wK2B#1mb9SB~$IdJAh z;>>XdbiYvh*8(t)$l-^;cXJC)Lx(?-GpFh3OVE`R?S1W*ioTXH2UYAYte1uX$Efg; zOmhJ@XIQGKkelp`oYcYk;n= zHw+i&@P8%kMN^;mG-T0!&ubLL`4w|jJk2ZEnIu9Wc-HgrVf?^pg<~JF1PkkFoc2(2(y;QcNlm zA7vwifJbZF4i0RR@L$UI2)Si8VZw})V2YQ-q2i_-e~FFs&O`dX!((f0k|;wlHHd|% zy;uqpbP}pid;278Oz133@^t$ikU9x1DKk*K%1eK#Atb;}t5(mvhkE{S+`j_r`*Wzn ze86+vCF1C@=kE&Es*fMRtliMW+Zs=1gCC3nJn1uLg9@Fg_Zu%JhQaH2P5cE!91nr}DcL z_90{G3*(jh#mZ-%WA$q0?{}Q_%#CcXU$k?K0s{^ejgJ`ewJvP~%7Qk+5exT{!2*i- ze2BQE5jZQ^t!wI^u7mTiC-rf9x~D$LznF(=#ARu)`@aTV2|w3CI$+&zW0g!OTfV$R zF;bbe7p1VObHRKco&Gc4C0;alB3*TdKB29QjyL5~PzP9~Cxw~aW zaDs2BaA=V%TA#KpFD6?~`FLW_@21KcLW z8CO%z?=rv8p7X>QDglMWL0#@WUQ7jYlGI>yb}eEs*4?Nod)3t?#X87hvBo`aaG9W`+k@>cZXGB?B zTdQPcWkDALCD*^V=lzF00u8w?vUu$-1Q%dT12IBSt3R{yanf+vU#k!=^_4nSdYhQ#TX?5d208~ zi5*jI@3obhDlP{J`myoTz^^}boy`{rp{LQ?_b&alXg%71=7G|khc;BtIiD>fOSapf zqrP2*FdZTZoC?cw(REM9i~lNaB~(?vnUNSd(;=Xx-V+PK_aWQD-z6HN2iO;9a@$#* zTyzHNKi|S&v}`%gIn>*?P^6Dro;6>d4SnAj>aHoWy7NGMMJ4RpuY6D3v4b-ii63=l zL3|t$@g!^qv}IdBSS$RgkgD&gpjk?{3V>n8#uUl8-W2bR*h zA2z=RU3NcyN1L-pE*_F4U7v=|b{D#ARpkVytl5zMOyd z{?&L1i4FEo4XWiB@|sdmKIp($ysk9vLS~F|f7wwV6c@fH1PB|=9SuAtCD-4{@`;zQ z8wUX>2Uh{1YK3}Mt(mRwL-4)36ls>7kt;jk6@;{R#ttmB$`-#&gujt;5OrJ$f7EeMQ8 zL+<}J=m_3X!uA!iJ9nm%^s)Tnd^>a>WwIqQN2Bq)%FSKOa4@ytb} zSZT$4kz=tYHwz2wq6zd=pv%apIB9C=*;tWKnAzEbM@@q-E<~;vEwZFS73wa=V3Ery zVdQ>AVVz4&Y5wfVgv&-u!LzVzCA2lrmJUik@b7#Z;%C^smI2FT5#a zIiIRGCE1=BSBgwmYZi(-6Q;k;GsT_75yV%U=d=156G>Uc`(rc zRa?|0D>1l#CxwUm>~~7kCdzXKQbJw!racw9-g8)d7!M9)KmDV*2W_yKdWEni*7{e< zF+r?ToyiNWVpsU$PBOg*|D&_iHy|vukRr$z`pcTV-T5t~!}H~>$N9HJ(`Nw(OT(dF zPrDfdIF|(7@I9Owzi|we@kJ0 z8TW;phy+z`59)9*w}_AYb|e+W{7E8sfmx{pU(*w2QM0`JoEtxueRhnPth+HErt?Fq zJA_|okMbS6ejbrzO=9m8GBohd6QvC`ErsneO>HoK*z(sh7sG}ijsW@h!pICYA+UL z6*G|&))$9w%EYS>;>29`d$O@FSZWI>g<|KAe)^PuYg_Jc#FPLKFyl$ zAR5cfmmweV8oNYiD^}xwW(*hcLSO@KPhX-9MAFFRhg>c_yct{@RvMSSP*C6-Iyirf zXkR!ez;Q;DAQ|y+nHxxtD*F@bGWW|Msw>^r@cY4qqRMIe#5HoH+fF}eC&NyZ&UI; zdX?z&K*_n3u@;{fWJg5f52dYvpn9j+oA4JSt1+hl{z<-(6Ger=;j_|)2K0OI>lQS3 z*=|*(45R zCyEJQh$Tu^DnidVx^^WCTakV{df9e{m8DPQHzZ!t{CPe6SjEf~H+4jxL?{`A54A}L z>(LGiEs2sZy}BkdGM3W#}u0tKGKH{W?99chsE~ z$n42}!Q6>zqlIVsTkXbr{8rrey-p{rw{CFEyoz%1y4tsU}3xiB=_6JsibkGAMhP;&S0K4 zx2!>A;H-~`p5nGZGk?aDxB(Uc2W8F_$;^X(b_kw)9WNZ z-@o7~Z)1|Z1U)QfEPyvzDF3k_vBTE5Rm-r6AX(m)N3m&AWo+6v`WIVY%$Hk3t!g%H zjoL>oOL>q!0CA>cpaCz17nie5f@Q?_+FCjy4i0OEu;0^-4U?mjif(V%>U*;YEewZs zb;%GlL5@il+RvZgqap51dQ>)!^TiS-R{MRC_aDJfJo&jpNsEju=q3?>WLqn8bdHW| zK97=8(Tih(Ik)j_9R($QeC{q?B| zwX$Nnq4~|;V5F})-(4t9D)8wxRjFrEu{3Y~Y~y)FYn(fo^yjyUlT@?rbi45fI3-a)$GwVro} zl$iX@6ci%AYj%cnT(@m~6TaM2$0S!X<3wD#Rl1wh&njJlBDs`B(cwns4Mz=vMt zgqWum(CgTGC{9cE!kshJOb&G_OMZ6{l2I(0Y9Cs-z{u)0jH<*!+_i&SPdUNRtgiPylSQS8t3 zG-Fg(&a_L9f006rMYf8pW}CBeyuzcz>|5_k7=IUC6T@f1^Fd?W19c$o%L*qxBc z4PHk&$rUqPkt)fyJ-I4FaAC#fWUBut*^1KW-C3k~$;68}>CI!Z(J)$M5-Hy4?KNT| zXrCmr{LKvZI3ROONlUR@?&Q;cK%#x!-1mGAUp9xXNZPG}On=6Vs$H?^koC-ukKkj^ z8*pPZtX;jNYjM~m*|yHGA*U>J8jlZHJF5-3;g>H3kZ&x;lj)e>E%?CQwL>aLqS#RdXG&p{u{Xx% z58-Dk;ha($4~_lnWn*H--w(I8@*Fl8Y3dIxZ}@s=F#aQPHtBe0s?gFtL5vgtWP;l0 zuVj`y@iCc1rYJjP#($oL#La;5i!2Q@HbgcEsnO_NpR+F+XFxL3d$^5P;P}2NT?QjOg%7&M55(MOdf8CIPnu zx-eh(YGj^;GN$bfa#{ki`v{(>E{`PhftmEz*6Q2%X?>AQ$ruD7P zkj`c05fFeW&u3#X`UGyG2gUcAPcNA^HF>!?Crm~0LlSKC?>Wv+=G?*gTrR5Bg+NLQ zw<)t>bpZ0TcBJllD1Xmut2v}1a^ijJoiN`6odEMP>MDdlv=H>b)<=75F^ViG3NvjB zH~Sd6Q5wQ0MJ;|SYNHrvQEA04AI=_`^S5*sRZ`yILH&AJ;YkZ`q|o@GwNUbJnDvd< zJ4q^=F(s;AJOiyn8}eDQ4cIhh2{SR6=anC zc9H~{!FP)D4$+Q6ukFOo?3$E&LFINJta!xv*%__>PAsNJ%|k8Q1ONUwUe)%{b?+;k zvYF>Zj3_BW#r9vA^(Y9@#oQcEkXmTLg|c)@WXGJEFUGCX9J<|M&^%1ASV z)0Wb$<~VkapC{t;)P}XbO1{IvM5{-GS2m9d@$hvBbVYHWOpHuV+Zwy>l1+YOKQcjP zgO4nrWhb5`r9pf%=74J^!7bwwIP-Ze1Yb|4^0f%2;{u>l*Wx@DzS)r~#)zfe7cQB0 zpSiC+EI#Y?QBILlTkQmwVpdkd{PMV)BW+AoG%qr=TtTqVAoF(CTHB9YABG2xIdUGT z5l_+(9?zOXKBf506jRZa(EunAl3!r@Gv?EEqj3zlE4Jr`&2M&$*w9G1VK3Fm2!D?v z12=2Ns>x?)gS;dHMg6Q$6JTe$T77OOO*w67z06r+XHci878XuN>?Lhv4ej>|c}a^T z6EO-C60bNq8kC*Pxxp5MEq`C8|HRY8hl4%egRwMf??**QP5_lN**w)kZc!LV3rAKqXjgQEoGg_ z7D=4#D(HP#@R-XlUHLQz_VQjQ;cryH3fEiB?~({2gek2cw)g+K@Iad2gNh>}C7I+; ze^{{xRCxGxf}S%eI(TG~%ZxU1-7>J}bDy6WZiFyWQF_sRp@H{~o7!vu zKEH*r9eVKV%?idG{q98oblsPm@$;yc!1ng|1g>v6VEci$Q52V`6c*l^=HyV6lt0-; z6yDz+O!KfM$IvR0mYfPQt{Zvq%HQ>)E$mgxr^37(Je2x;m5d1=HSCG{)l~Fr_DJed zla|*!IGgqaJ{R#5zd&h_z37YFNKWQ61GvRAk>OnyD&~FN^1_ahTfbTbq6blinq&{_ z{iH$sG65j+!ITYJ7_|L&e1fbVr*P@(#yBY+PIHFSbLMMoTc;lj3gEWn#4`}4yrc5D zIewjjaqO&7MuCk#^6{Y zjp7)u_L}ORnqRuv|1F~R5lZG~3?-Mli|{-B5`?~6WVeBcS1lO1C@J5xMYHMlFPKJ(=8E;vz&T zO8Q-P$0|!c8+rUz^c&>yh5;{4i42d*!Xhz(!I@3h{`$}YB5BIxw$KQ7PlNI<-iYA3 zM{N~vmgb$I?b1nguAX=^X7Oxo8#2?5hDZ&fSKC>TGGKKC6Qe@6PjE~kSw`X{@&#G( z-{xEr7{%OfF@Z6fAVDMR9j7PV0$u`|P6zCZf{V7~>PPOaYj{=76(@C0bBHf??^7Lp z#I6_j&rJqiJdqCc+i{o`$26I2>VR#4%l1o#qUtWE^Od_SBW6-5zabECgXP@}1 zv8#nsTGenTGDq-rIftezQQ#!#Lqp_6|9oh;T3)x6w3D8{(hA+Dg+Kf#w|*_FGAPAQ ztM{(!sm9gjC%!3KjQrqeU!!H{juku3ZoXQAU6*fH_5KFVMISyi?m@z2!d)6W)D;@< zx9wN%2!7K;v@$eeGLWRBhpl21Uyh$4RIY@DG`NN;hI_M1Uh4- zQ2CgL$*Gzn<;IYJA-Q+53i?Bt446Ls5lnA6SW&-T3yZN*gt-YqzlrdI;W#NbH1K`9 zQlcn&MoX%aN1i-H{)>jSe8J8BW{z-0jUM6zF&2xuv=wJxbOM)x^o&Z-MJUSh#JY(( zIXqpZ=SF?QbD@la#zQ+Svi#0BV=A|=)Mfxa@?!}vu{`_lv7x-}6r=^K0=g6z1yCtL z_&){~+j5qDO^+u-P(iig7$1aRSY(-iDrW*WI|3Y%(+E*ZfwWp97?ZE$ji1O%G|i;Q zsHX9Z`ubtQxQ*r2HmYNdKn_0)6qu-3bVWw5+_@)`7;qX}T^*SdF7c%0H9b6m zdvdg@w;9`QBn{rOBLQQM`w|J*G08en3mXS_d1X2?D)-Ke$eAmf>w1MZ7#mu!j|9S& zlHA>@7W`BwCNo6*G<2K5cDilP!#ZrEtI%(-FdQ6<(gf^6umxAFyxGf8{Gf5FFt!9n zHDOH^l}2Z<+2wN&_k?ThlQkX-P)^{J)5_XiMs8*R^8wvw@YA!Gp+6r8uHqI z)qUHp^nE!r1G}7d1Y2UTa8cZB*giLLaUgHxs7T{ITr*+HZd~RkEHrx;&O%xzrg5nd zzjja?hJWZJtf?F8RSHQ(&7RpwJ=}Cp+v34J@sq9zIyd1P9jmUdk$apm#G<&6)rY@W zj{GmONo=tDE)ZzWhwAea0N0*9-BMa_?Y%w6ff~l-pa{n~&je$^Fah{O!~vhq2{||& zF2neG6KO<-z}XC`PIMVB`5VIk=YoUd5mGP>9&;9(ekuGV6<)Ob-tdrP&$QFV@Z>$q z{Pmyz{H$5FU7?hniJc*&&XNT`}vQ9?OOXQ7n$=T&Qg5sjDAYK^9 zMY$*o!xza}Po^^V=Ft`ZAl`<@TNMsLrR6Q->jvSb-#swiX{5|4E+}U(-~)=vFH0vZ z*g4_jqh;=|i^?ogV%DGiSRwN6<7JGS{`?>quB>mvb`|x2mxH}T^6n-xL~dt7EE}Ok zgB7(KPY6edv>_20ovPR!sxVHIw$i0%!#^3ODNCZpmw{guCr!DhFKGML^mp+Xzg&igEH3w@HtT7SX_9tA-yXgMl`k8q1^%h=Tn*NnF5hmNyN_)t39GY! zT%xbN7JXf>dJE(D)QJ`sBF4-qIfLanUW|zxKbDN<1UMd+IVdS<{RJCJ1Z*9d;FF_$ ztuS(3KdMuBS4*L@0q}D#u3V!1DIOf1ruMLCc%n5If8?#S_wH(7ah<#3=R%>ycY@cT z3>;_Jv+1X$D@PC+e$mab7c7VYNH$e#y4qQX%)FoXK{xAQM{_wVSU&HVOtOlz2z;ANEPgF5DcrDWO@Tx=`%n zOT!%(eh2~Mm1IcWY@;T>+Gtf8q~9dr-nF(iwI)uK93mj^l~!M(iCe3X!`5hMwq|NH z;rT3n;Y03)YS_Cl&HnR+i0T#T{G0lkkf~I$N4iI&P@{Z&Ddm{Ux_kY_ZN2cxU)3wu z?Wb=SY(U#~Jr`UvHK1QfW4C(zE*Q+3Y(_$bV5)x05j=f;`o1_|KVWqMyH@+2mm$Vw z`c*|Jiw=aknqY>RjcwOgrSC_MZhav$}pqYqdKRL)eImQ>lG1F_FB;31e@ii|R~i29i)bS;Fhf zzzSNR1h+6YF3st&{JkW;Yw(EBue6I?*PoHJnIh_`Vxpc$pC>lK((v%c8n)rUGpvFZ z<2-STO+mf89e_)pvFJ{sH0*xAmZ^jN+-idrZn+BW1-#tcRXs;U9gLjOJ#@T1d?Kqq z?l4I?W7D%+?K$fqoG$53Oe`yYarIwy)OvI9x1gr5ra|1LEx}fU6ARFjMA{fD4O2}B zSrWr-xKgX?#}Vv2?3z<%)uJi8y*^7mB@t-kkLk7OyxOVOzuFaF;4OI7i${+|Eji(1 zh=15lwQZZ)6WEH2+J&SzJxo@%W?`|5;|Qiv&&|W_x~>H;UGjT1-j{DUa3X{-ax(x0 zuY9Z7z@>7qj&lrd~5=7$Dq3z2mEiZ4+!7_@syKwVr5&?sf6iaCy=vw0GS za$|l7wWWxl?4Cda5l_#5cW#zcv_8@*io*rVU_mY+y2hM@JSR@!%8m;FX8=`w6AnQVINuT#Ao@v}E8*)i377 z?CF_p3QE&7l!yc3DfBxe(Rdz@Mi6bf?b*SUpvt{m`R?!v^{U7sw9~BNaw#jF|HoFv z{`H%+DAU{WKO$sH!A`yoN8jj8kzcXw6sNj`paX59srQLcJS^1I7KBoEvObEE{{F|G z0z;=XkFCEG5oO7q@ER zVIQ?!a?%df&aZEYZ<25OOxbMdlzN}8TrJG`jwdg?%(3nWY4ZVnG@|L z&+kN$f7P#)uKcs;8VAjEG+ce=@PK4|N*#o)x$9#g>wL4&N~X$v1ULhP6Q|HtX|}%T zF31XwyFX(AYN`!)HD40q`JK8+-m$lF_#D#7@g^Y;{;;E>`1RrX`WsE}e+#!ZQ3!6Y%?%esoWVO{IN{09#8OPb2l^n9`?BH|xKDl(NaO-rL}33>3I&LpcP* z@f+S_dt{g*buoHN)*C}J>i*_tbxc2QZLi8ze&S@SzL}Y$n;auM?`n$8c`gt=u;3uB ztwm!~sXIfqW?410V`zQ*!)xUv0fX0tOvAIq|$M>adKy>x~gvBeQuZCWf-accw#or z&r>g#>(0|I7@^VtTbGeY#@;L1g)Y&u53g0`CrU(HO6Dd~R|1wo5@&{*7MC?Yd@ypu zUSDiVIksroJ36WzGT(mr(`$$VO9N?+%*;ll8O&`L2VBt}*Bfb>-I9{ixncf$!VaFd zOX9CwUA5ClZo@J1_y@&DeO{04?VjTb}buK|K7cPTt?&^OD^E7arqXje;2 zpS1pW=!Hy$^DBeE0Zh!;Fo5R=Q{aH@eInaYtd_CDW=Nw2XNTWiQ{ z26JmdCueW5AJprB+0=77tf*d2ch|pX2e2Jx_}Lf~w)f@mwdf0_gZ94&y(Mu~akg;? zqH$306E(*VZw=nZq}BF@dXOo<;z1k(Iy~AC#!%GX9540pxQLF-A^P{$nMcAmU?U;pFmT+^WU#w;;-p;yVv?2+f%Bn={FK1xPX3VoWNEsw8`^0vMT^$(pPua(|`Xk z2cM>3@RKRxE`l2nrmJ|Uh&`_;q#`CSgleAa=#rUJAXkF;)-ycKxU=wTSf|?MI3jTd zEM3t$4~U%Fjvl2@jE9mjxmsTz^mG%lJ+es?F_XtO+EomnE;ua=%J@IJ<|5GV)>_kl z>uwkEs&P~cSn==LCK{r*+J4?H6!@HP%EgH+yHfixRHQojhkn^J*jG7%ph;J%<~5nA zdK+!(?Q^?5y!WA>1heyXe9l^wSla3rmp8y{)ILe{gVkPbYPoprfR z056<$Q(YPRCpv&`q25K?t8Q-1apPReKVCaT@_29-(EjxC$|YW#E` zlk=a=VYqt2aV^s%g%*kcIeWjM^JPUAp z9pIZa644FJG#_Jq7oDB+&9rj1TJF7fC?kQ_W-C4&#L;e!4*1v^zZ*a$AEi8{LV~#& zk^RdHEWq(l+$DBOY;BY%q|nymm+fXS#@+1$63uZcJX&OGr#B4vr6G-UngwK&Z~V-U zo0z=WZuLZO`=Uy@_|sK7jkNw{r7)HzrI0lJ6Qwo4wbPj8`W1Gu~d_I0KLn97OR(I>7NMA_8ogZ&NAJ% zp~VUS%v%L|W*}3JSYJ7lBiMI7ehKTrst&0y$EfqLho=XgGg3f7P9vM9-ovm%Pw}vW zx|bshT}ZM?R{h00fW*fFd=U2cV=EwmtNJDd`-s32;cN_)va~V*&I;rZ<=js2p2P*2 zr<$28$G%RyfXKrl~PDL~F$Q~a$TFuC9Y;jde=X4mOz|H}-$B6NuY z$8rB&;-!!=ObRl0Gka1MF614qmtsi5gar5~z5sMbNel4bb&(qZb{iTz;yuuGmJ19AQ}q z;)9S!l?hz)ekjQ0mlQH|b@o?%+HXt*at{5L!j>-g_9E_oTX2!UGtLaY)9mVO-+*L; z5rLl&+p;Afje`1{2tm9doyim<)l%5k$oUWaC|t;5Ch+AS%{^ylXHtrC{%?>)2Kk?S zTpZVeukssvsJ*&u7=0!h5Tkle6)^3OMKo1HxmEJXS)PFxI38oUi+rNm{96H7q|nF; z)cypbCDZ%0-7GdK;~uJXE0@v){2=ja4uQrEJK!5q^Uarv1;%Y$7vEu3ff+)<5psLyqf8(SDaOoga6Z=IDTOXU0gJ3}Sf= zp^l}AK-T4_w~WB-{%^0c|KT&k%hsaL!pZvak=wwc>d>QE(Zz$@qG&H_z+VG;fp~s# zd1F>W@V6NaSw9m1F!zB2_a07oy=j^eKJ$u04IxFrz4CJk984yZ)}2x#bkY5qy>1Dd6Ao`s$vgAc-N>ok?HOfrS1xPR1RgPK ztL}Ka@_r*DA2^hYdWC5SnK`bc1aXoi4*+`rU@i!=cp|{@S%w2I9$u$JJ~v&qxe|RJ ze=%e|6rB>tx*w8mh(E#{f^1`3RMaz%3IzAN4H$ei$D(~eB5V{UAd>kynDTn=Dy=cT Y!W}(*7II6m^JP?VDB8R9|D$jJ53b?+UH||9 literal 43660 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 O2QTg~lm35N?*9NH VERSION "1.8.0". Wer das eine ohne das andere aendert, +"v": Tag `v1.8.1` -> VERSION "1.8.1". Wer das eine ohne das andere aendert, baut dem Updater eine Falle. """ -VERSION = "1.8.0" +VERSION = "1.8.1" # Zu welchem Repository dieses Programm gehoert - der Updater sucht dort. REPOSITORY = "TheMockTv/rechnungstool" diff --git a/wasserzeichen.py b/wasserzeichen.py index 7028eca..7cf0b51 100644 --- a/wasserzeichen.py +++ b/wasserzeichen.py @@ -107,9 +107,14 @@ def symbol_bauen(ziel): try: from PIL import Image roh = Image.open(quelle).convert("RGBA") + # Dieselben Farben wie IM Programm: Tuerkis fuer die Wolke, Dunkelgrau + # fuer das Zeichen daneben. Vorher stand hier das rohe Logo mit seinem + # Petrol #004860 - sein Befund am 07.09.2026: "das schaut blau aus". + # Die Kachel ist weiss, also gilt die HELLE Fassung (dunkel=False). + zeichen = _umfaerben(roh, dunkel=False) bilder = [] for g in ICO_GROESSEN: - bilder.append(kachel(roh, g, rand=0.10 if g <= 24 else 0.16)) + bilder.append(kachel(zeichen, g, rand=0.10 if g <= 24 else 0.16)) # Pillow schreibt die uebrigen Groessen selbst aus dem groessten Bild - # deshalb wird das groesste uebergeben und der Rest angehaengt. bilder[-1].save(ziel, format="ICO", From 08426b3d9b920476a4979daa5fe94e44147ee043 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 10:57:33 +0200 Subject: [PATCH 31/34] pruef_installation hinterlaesst den Zustand, den er vorfindet War das Programm vorher installiert, ist es danach wieder installiert. Beim ersten Lauf war es das NICHT - danach stand ein deinstalliertes Programm da, und der naechste Schritt (den Updater starten lassen) lief ins Leere. Ein Pruefstand, der aufraeumt, muss auch sich selbst aufraeumen. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- pruef_installation.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pruef_installation.py b/pruef_installation.py index 7e9719c..f789ebc 100644 --- a/pruef_installation.py +++ b/pruef_installation.py @@ -36,6 +36,12 @@ programme gehoeren zu der firma"*. ⚠ DIESER PRUEFSTAND INSTALLIERT WIRKLICH. Er laeuft deshalb nur, wenn das Setup gebaut ist, und er fasst NUR die Programmordner an - vorhandene Daten werden vorher gesichert und danach zurueckgelegt. + +Und er hinterlaesst den Zustand, den er vorgefunden hat: war das Programm +vorher installiert, ist es danach wieder installiert. Beim ersten Lauf war es +das NICHT - danach stand ein deinstalliertes Programm da, und der naechste +Schritt lief ins Leere. Ein Pruefstand, der aufraeumt, muss auch sich selbst +aufraeumen. """ import os import shutil @@ -116,6 +122,7 @@ if os.path.isdir(RAVOKK): print(f" ({len(gesichert)} vorhandene Datei(en) gesichert)") beenden() +war_installiert = os.path.exists(os.path.join(PROGRAMMORDNER, "unins000.exe")) alter_uninstaller = os.path.join(PROGRAMMORDNER, "unins000.exe") if os.path.exists(alter_uninstaller): subprocess.run([alter_uninstaller, "/VERYSILENT", "/SUPPRESSMSGBOXES", @@ -172,6 +179,13 @@ pruefe(os.path.isdir(RAVOKK), # ---- Aufraeumen --------------------------------------------------------- if os.path.exists(probe): os.remove(probe) +if war_installiert: + # So hinterlassen, wie es vorgefunden wurde. + subprocess.run([setup, "/VERYSILENT", "/SUPPRESSMSGBOXES", "/NORESTART"], + capture_output=True) + time.sleep(5) + print(f" (war vorher installiert - wieder eingerichtet: " + f"{os.path.isdir(PROGRAMMORDNER)})") for d in gesichert: ziel = os.path.join(RAVOKK, d) if not os.path.exists(ziel): From 5babfc3e2ecd19918e63c0ac0f812097dd2299ff Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 18:10:40 +0200 Subject: [PATCH 32/34] Zwei echte Fehler aus der Pruefkette behoben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 1. Der Darstellungsdialog zerstoerte sich beim ersten Klick selbst _oberflaeche_neu() loeschte ALLE Kinder des Hauptfensters - und ein tk.Toplevel IST ein Kind. Der offene Dialog wurde also mitgeloescht, die Zeile danach fasste eine Leiche an: _tkinter.TclError: invalid command name ".!toplevel" Die Farbe wechselte zwar und nichts ging verloren, aber das Fenster verschwand beim ersten Klick, jede weitere Umstellung brauchte einen neuen Menueaufruf, und jedes Mal landete ein Traceback im Log. In BEIDEN Programmen. Behoben: fremde Toplevels bleiben stehen. Damit ueberlebt auch ein offener Ordnerwahl- oder Einstellungsdialog den Wechsel. ⚠️ Warum mein Pruefstand es nicht fand: er setzte cfg["darstellung"] von Hand und rief _oberflaeche_neu() direkt - also alles ausser dem Weg, den ein Mensch geht. Den Dialog oeffnete er zwar, mass aber nur dessen Position. pruef_darstellung drueckt jetzt den Radioknopf (.invoke()) und prueft, dass der Dialog danach noch lebt UND dass ein ZWEITER Klick im selben Dialog wirkt - das war vorher unmoeglich. ## 2. Unerreichbarer Code nach einem return _fenstersymbol() hatte zwei Zeilen der alten Inline-Fassung hinter dem return stehen. Rest meines symbol_setzen-Umbaus; per AST ueber alle Dateien beider Ordner belegt (genau ein Treffer). Beides gefunden von der Pruefkette nach R23. Die Aufraeumbefunde derselben Runde (doppelter Code, tote Variablen, 34x dasselbe pruefe()) kommen getrennt - eine Fehlerbehebung soll fuer sich pruefbar bleiben. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- app.py | 15 ++++++++--- pruef_darstellung.py | 60 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/app.py b/app.py index 32fe38f..a921b85 100644 --- a/app.py +++ b/app.py @@ -512,8 +512,19 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, except Exception: # noqa: BLE001 - dann eben das erste Blatt pass + # Fremde Fenster stehen lassen! Ein tk.Toplevel IST ein Kind des + # Hauptfensters - der offene Darstellungsdialog wurde hier bisher + # mitgeloescht, und die Zeile danach fasste eine Leiche an + # ("invalid command name .!toplevel"). Gefunden am 07.09.2026 von der + # Pruefkette, mit dem echten Bedienweg gemessen: Klick auf "Dunkel" + # -> Farbe wechselt, Fenster ist weg, Traceback im Log. + # + # Der Pruefstand hat es nicht gefunden, weil er cfg["darstellung"] von + # Hand setzte und _oberflaeche_neu() direkt rief - also alles ausser + # dem Weg, den ein Mensch geht. for kind in self.winfo_children(): - kind.destroy() + if not isinstance(kind, tk.Toplevel): + kind.destroy() self.flaeche = None self._text_zellen = [] @@ -846,8 +857,6 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, def _fenstersymbol(self): """Das Programmsymbol auf das Fenster legen.""" return wasserzeichen.symbol_setzen(self, dunkel=getattr(self, "_dark_mode", False)) - print("[symbol] assets/programm.ico nicht gefunden") - return False def _hinweis_wenn_sichtbar(self, versuche=0): """Wartet, bis das Fenster gezeichnet ist, und fragt dann. diff --git a/pruef_darstellung.py b/pruef_darstellung.py index 3c076b6..260d444 100644 --- a/pruef_darstellung.py +++ b/pruef_darstellung.py @@ -189,6 +189,66 @@ pruefe(d.winfo_rooty() >= f.winfo_rooty() - 40, d.destroy() pumpen(0.3) +# ---- Der Dialog muss den Klick UEBERLEBEN ------------------------------- +# Gefunden am 07.09.2026 von der Pruefkette: _oberflaeche_neu() loeschte alle +# Kinder des Hauptfensters - und ein Toplevel IST ein Kind. Der offene Dialog +# wurde also beim ersten Klick mitgeloescht, die Zeile danach fasste eine +# Leiche an ("invalid command name .!toplevel"). +# +# Dieser Pruefstand hat es NICHT gefunden, weil er cfg["darstellung"] von Hand +# setzte. Hier wird jetzt der Radioknopf gedrueckt - derselbe Weg, den ein +# Mensch geht. +d = f.dlg_darstellung() +pumpen(1.0) + + +def radioknoepfe(fenster): + """Alle Radiobuttons unterhalb eines Fensters, mit ihrer Beschriftung.""" + treffer = [] + + def durchgehen(w): + for kind in w.winfo_children(): + if kind.winfo_class() == "TRadiobutton": + try: + treffer.append((str(kind.cget("text")), kind)) + except tk.TclError: + pass + durchgehen(kind) + + durchgehen(fenster) + return treffer + + +knoepfe = radioknoepfe(d) +pruefe(len(knoepfe) == len(theme.MODI), + f"der Dialog zeigt alle {len(theme.MODI)} Moeglichkeiten " + f"({[t for t, _ in knoepfe]})") + +ziel = next((w for t, w in knoepfe if t == theme.MODUS_NAMEN["dunkel"]), None) +pruefe(ziel is not None, "der Knopf 'Dunkel' ist da") +if ziel is not None: + ziel.invoke() # der echte Klick + pumpen(1.2) + pruefe(bool(d.winfo_exists()), + "der Dialog lebt nach dem Klick noch") + pruefe(f._dark_mode is True, + f"und die Darstellung ist umgestellt (Hintergrund {f.col_bg})") + # Und noch einmal, denn genau das war vorher unmoeglich: + hell = next((w for t, w in knoepfe if t == theme.MODUS_NAMEN["hell"]), None) + if hell is not None: + try: + hell.invoke() + pumpen(1.0) + pruefe(f._dark_mode is False, + "ein ZWEITER Klick im selben Dialog wirkt auch") + except tk.TclError as e: + pruefe(False, f"der zweite Klick scheiterte ({e})") +try: + d.destroy() +except tk.TclError: + pass +pumpen(0.3) + # ---- Zurueck auf automatisch -------------------------------------------- f.cfg["darstellung"] = "auto" config.save_config(f.cfg) From 2b09d15cd0eb9fe30591e295d7a8297957f0d3fd Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 18:39:03 +0200 Subject: [PATCH 33/34] Aufraeumen nach der Pruefkette: doppelter Code an eine Stelle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Runde vom 07.09.2026 hat neben den zwei echten Fehlern eine Reihe Wiederholungen und stumme Stellen gemeldet. Abgearbeitet in Etappen, jede fuer sich pruefbar - nach jeder liefen beide Pruefketten gruen. * Menueleiste: der Wechsel von einem Titel zum anderen brauchte ZWEI Klicks. Der grab_set der offenen Liste schluckt den ersten, die -Bindung des Titels feuert gar nicht. Das native tk.Menu, das diese Leiste ersetzt hat, wechselte schon beim blossen Ueberfahren - zwei Klicks waren also eine Verschlechterung gegenueber dem, was vorher da war. Die Klappliste wird ausserdem jetzt wie jede andere Position ueber theme.auf_bildschirm() begrenzt; am unteren Fensterrand lief sie vorher hinaus. Neu: pruef_menueleiste.py misst beides ueber echte Klickereignisse. * %LOCALAPPDATA%/ravokk wurde an drei Stellen einzeln ausgerechnet. Jetzt fragen alle gemeinsam.standard_ordner(). Laufen die je auseinander, fuehren die beiden Programme zwei Nummernbuecher - und das faellt erst auf, wenn eine Rechnungsnummer zum zweiten Mal vergeben ist (§ 14 Abs. 4 Nr. 4 UStG). * pruefe() stand 35-mal im Quelltext, in sechs Fassungen -> pruefhelfer.py. Die zwei Ausreisser sind mitgezogen: pruef_bilder.py schrieb ein eigenes Format, pruef_storno_verrechnet.py zaehlte in einer Zahl und konnte am Ende nicht sagen, WAS fehlschlug. * dlg_darstellung() und die drei Handgriffe des Umschaltens standen in beiden app.py fast wortgleich -> ThemeMixin in theme.py. Beide trugen inzwischen denselben langen Kommentar zu demselben Fehler; das war der Beweis, dass es eine Sache ist. Programmspezifisch bleiben der Hinweistext im Dialog (R31) und die Frage, ob die Einstellungen ausdruecklich gespeichert werden muessen. * pruef_gemeinsam_automatisch.py sagte im Text "genau ein Buch" und prueft ">= 1" mit einem any() - eine Pruefung, die nicht rot werden kann. Jetzt == 1, und der Dateiname wird mitgeprueft. Dazu neu: die neun Dateien, die im Kopf zusagen, sie laegen in beiden Programmen gleich, werden byteweise verglichen. Bei hinweis.py stimmte die Zusage seit dem 06.09. nicht mehr - gleicher Inhalt, CRLF gegen LF. * .gitattributes, damit die Zeilenenden nicht von der Maschine abhaengen. Ohne das meldet genau diese Pruefung nach einem frischen Checkout einen Unterschied, den es im Repository gar nicht gibt. * Sechs stumme "except OSError" sagen jetzt, warum sie schweigen duerfen, und einer meldet statt zu schweigen: schlaegt die Uebernahme einer alten config.json fehl, faengt das Programm ohne Firmendaten, Katalog und Zaehler neu an - und der Erfolgsfall schrieb eine Zeile, der Fehlerfall nicht. Die 24 stummen tk.TclError bleiben: dort wird ein Widget angefasst, das gerade zerstoert wurde, und eine Meldung waere Rauschen. * Tote Parameter und Variablen aus dem Umbau des Vortags: symbol_setzen(dunkel=), kachel(grund=, radius=), mit_trennlinie, sechs x/y-Berechnungen, die von theme.mittig() sofort ueberschrieben wurden, vier lokale "import ctypes". 39 Pruefstaende, 0 rot. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- .gitattributes | 23 +++++ api.py | 4 + app.py | 109 ++++--------------- config.py | 14 ++- einzelinstanz.py | 4 + korrektur.py | 1 - menueleiste.py | 69 +++++++++++-- ordnerwahl.py | 2 - pruef_angebot.py | 11 +- pruef_api.py | 11 +- pruef_bilder.py | 9 +- pruef_darstellung.py | 11 +- pruef_doppelte_leistung.py | 11 +- pruef_flaeche.py | 11 +- pruef_freigabe.py | 11 +- pruef_gemeinsam_automatisch.py | 68 +++++++++--- pruef_hinweis.py | 11 +- pruef_installation.py | 11 +- pruef_kernregeln.py | 13 +-- pruef_kette.py | 13 +-- pruef_menueleiste.py | 184 +++++++++++++++++++++++++++++++++ pruef_montage.py | 11 +- pruef_nummernbuch.py | 11 +- pruef_nummernsperre.py | 11 +- pruef_nur_storno.py | 11 +- pruef_release.py | 11 +- pruef_selbstbezug.py | 11 +- pruef_spaltenbreiten.py | 11 +- pruef_start_exe.py | 11 +- pruef_storno.py | 13 +-- pruef_updater.py | 11 +- pruef_vorschau.py | 11 +- pruefhelfer.py | 47 +++++++++ theme.py | 130 +++++++++++++++++++++-- updater.py | 5 + wasserzeichen.py | 21 ++-- 36 files changed, 563 insertions(+), 364 deletions(-) create mode 100644 .gitattributes create mode 100644 pruef_menueleiste.py create mode 100644 pruefhelfer.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e3fff1e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +# Zeilenenden festlegen, damit sie nicht von der Maschine abhaengen. +# +# Neun Dateien liegen in beiden Programmen gleich und werden von Hand +# hinueberkopiert; pruef_gemeinsam_automatisch.py prueft das byteweise. +# Ohne diese Festlegung entscheidet core.autocrlf jeder Maschine einzeln, +# wie eine Datei im Arbeitsverzeichnis aussieht - und dann meldet die +# Pruefung einen Unterschied, den es im Repository gar nicht gibt. +# Genau so stand es am 07.09.2026 bei hinweis.py: gleicher Inhalt, die +# eine Fassung CRLF, die andere LF. +* text=auto +*.py text eol=crlf +*.iss text eol=crlf +*.md text eol=crlf +*.json text eol=crlf + +# Binaeres nie anfassen. +*.png binary +*.ico binary +*.svg text eol=crlf +*.ttf binary +*.exe binary +*.pdf binary +*.sqlite3 binary diff --git a/api.py b/api.py index 98eff1e..196de45 100644 --- a/api.py +++ b/api.py @@ -138,6 +138,10 @@ class _Handler(socketserver.StreamRequestHandler): try: self.wfile.write((json.dumps({"antwort": antwort}) + "\n").encode("utf-8")) except OSError: + # Der Rufer hat die Verbindung schon zugemacht - das ist der + # Normalfall bei "schau_nach", wenn das andere Programm beendet + # wurde, waehrend die Antwort unterwegs war. Die Arbeit ist + # getan; nur die Empfangsbestaetigung geht ins Leere. pass diff --git a/app.py b/app.py index a921b85..c777e88 100644 --- a/app.py +++ b/app.py @@ -476,34 +476,15 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, WAS DABEI ERHALTEN BLEIBT ------------------------- Alles Eingetippte. Ein Themenwechsel darf keine halb getippte Rechnung - wegwerfen. + wegwerfen. Um die Tk-Variablen kuemmert sich variablen_sichern() im + ThemeMixin - dort steht auch, warum ALLE gesichert werden und nicht + eine gepflegte Auswahl. - Dass die Werte an StringVars haengen, reicht dafuer NICHT: die - _build_-Methoden legen ihre Vars selbst an (`self.k_name = - tk.StringVar()`), beim Neubau stehen also neue, leere Vars da. Beim - ersten Versuch waren Kundenname und Rechnungsnummer weg, waehrend die - Mengen blieben - die hatte ich einzeln gesichert. - - Deshalb werden hier ALLE Variablen des Fensters gesichert, nicht eine - Auswahl: durchgegangen wird, was das Objekt an Tk-Variablen traegt. - Wer spaeter ein Feld hinzufuegt, muss nichts eintragen - es ist - automatisch dabei. Eine Liste zum Pflegen waere genau die Sorte, die - man beim naechsten Feld vergisst. + Hier stehen nur die Dinge, die es sonst nirgends gibt: die Mengen und + Personenzahlen der Leistungszeilen (sie haengen an Woerterbuechern, + nicht am Fenster) und das Blatt, das gerade vorn war. """ - gesichert = {} - for name in dir(self): - if name.startswith("__"): - continue - try: - wert = getattr(self, name) - except Exception: # noqa: BLE001 - Eigenschaften koennen werfen - continue - if isinstance(wert, (tk.StringVar, tk.IntVar, tk.DoubleVar, - tk.BooleanVar)): - try: - gesichert[name] = wert.get() - except tk.TclError: - pass + gesichert = self.variablen_sichern() mengen = {nr: v.get() for nr, v in self.anzahl_vars.items()} personen = {nr: v.get() for nr, v in self.personen_vars.items()} blatt = None @@ -512,19 +493,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, except Exception: # noqa: BLE001 - dann eben das erste Blatt pass - # Fremde Fenster stehen lassen! Ein tk.Toplevel IST ein Kind des - # Hauptfensters - der offene Darstellungsdialog wurde hier bisher - # mitgeloescht, und die Zeile danach fasste eine Leiche an - # ("invalid command name .!toplevel"). Gefunden am 07.09.2026 von der - # Pruefkette, mit dem echten Bedienweg gemessen: Klick auf "Dunkel" - # -> Farbe wechselt, Fenster ist weg, Traceback im Log. - # - # Der Pruefstand hat es nicht gefunden, weil er cfg["darstellung"] von - # Hand setzte und _oberflaeche_neu() direkt rief - also alles ausser - # dem Weg, den ein Mensch geht. - for kind in self.winfo_children(): - if not isinstance(kind, tk.Toplevel): - kind.destroy() + self.kinder_loeschen() self.flaeche = None self._text_zellen = [] @@ -536,14 +505,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self._build_positionen() self.flaeche.anordnen() - for name, wert in gesichert.items(): - neu = getattr(self, name, None) - if isinstance(neu, (tk.StringVar, tk.IntVar, tk.DoubleVar, - tk.BooleanVar)): - try: - neu.set(wert) - except tk.TclError: - pass + self.variablen_zuruecksetzen(gesichert) for nr, wert in mengen.items(): if nr in self.anzahl_vars: self.anzahl_vars[nr].set(wert) @@ -558,46 +520,17 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, self._buch_anzeigen() self.recalc() - def dlg_darstellung(self): - """Hell, dunkel oder wie Windows - und sofort sichtbar.""" - d = tk.Toplevel(self) - d.title("Darstellung") - d.transient(self) - d.resizable(False, False) - self._style_dialog(d) - rahmen = ttk.Frame(d, padding=18) - rahmen.pack(fill="both", expand=True) - ttk.Label(rahmen, text="Darstellung", font=(theme.SCHRIFT_NAME, 11, "bold"), - foreground=self.col_accent).pack(anchor="w") - ttk.Label(rahmen, justify="left", wraplength=340, foreground=self.col_muted, - text="Gilt nur für das Programmfenster. Die Farbe der Rechnung " - "steht unter Einstellungen → Firmendaten – das Blatt " - "gehört dem Kunden, nicht dem Programm.").pack( - anchor="w", pady=(6, 12)) + # Der Dialog selbst steht im ThemeMixin (theme.py) - er sah in beiden + # Programmen gleich aus. Verschieden ist nur der Hinweis darin und die + # Frage, ob die Einstellungen ausdruecklich gespeichert werden muessen. + DARSTELLUNG_HINWEIS = ( + "Gilt nur für das Programmfenster. Die Farbe der Rechnung steht unter " + "Einstellungen → Firmendaten – das Blatt gehört dem Kunden, nicht dem " + "Programm.") - gewaehlt = tk.StringVar(value=theme.modus(self.cfg)) - - def uebernehmen(): - neu = gewaehlt.get() - if neu == theme.modus(self.cfg): - return - self.cfg["darstellung"] = neu - config.save_config(self.cfg) - self._oberflaeche_neu() - # Der Dialog gehoert noch zur alten Darstellung - er wird - # mitgefaerbt, sonst steht ein helles Fenster vor einem dunklen. - self._style_dialog(d) - - for wert in theme.MODI: - ttk.Radiobutton(rahmen, text=theme.MODUS_NAMEN[wert], value=wert, - variable=gewaehlt, command=uebernehmen).pack( - anchor="w", pady=3) - - ttk.Separator(rahmen, orient="horizontal").pack(fill="x", pady=(12, 10)) - ttk.Button(rahmen, text="Schließen", width=14, - command=d.destroy).pack(anchor="e") - theme.mittig(d, self) - return d + def _cfg_speichern(self): + """Hier ist die Konfiguration eine config.json und will geschrieben sein.""" + config.save_config(self.cfg) def _umbruch_nachziehen(self, runde=0, vorige_breite=None): """Den Textumbruch der Leistungsspalte auf ihre echte Breite setzen. @@ -856,7 +789,7 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, def _fenstersymbol(self): """Das Programmsymbol auf das Fenster legen.""" - return wasserzeichen.symbol_setzen(self, dunkel=getattr(self, "_dark_mode", False)) + return wasserzeichen.symbol_setzen(self) def _hinweis_wenn_sichtbar(self, versuche=0): """Wartet, bis das Fenster gezeichnet ist, und fragt dann. @@ -1108,7 +1041,6 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, d.protocol("WM_DELETE_WINDOW", d.destroy) d.bind("", lambda _e: d.destroy()) d.update_idletasks() - x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) theme.mittig(d, self) d.grab_set() self.wait_window(d) @@ -1458,7 +1390,6 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, d.protocol("WM_DELETE_WINDOW", d.destroy) d.bind("", lambda _e: d.destroy()) d.update_idletasks() - x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) theme.mittig(d, self) d.grab_set() self.wait_window(d) diff --git a/config.py b/config.py index d76963d..3ae12a8 100644 --- a/config.py +++ b/config.py @@ -58,6 +58,7 @@ def _daten_ordner(): """ if not getattr(sys, "frozen", False): return EXE_DIR # aus der Quelle heraus bleibt alles, wo es ist + import gemeinsam heim = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~") # NEBEN dem Programm, nicht darin: das Programm liegt in # ravokk/Rechnungstool, die Daten eine Ebene darueber in ravokk. Genau so @@ -65,7 +66,8 @@ def _daten_ordner(): # es den ordner rechnungstool und steuertool". Nur dadurch kann ein # Deinstallieren den Programmordner restlos leeren, ohne die Belege # anzufassen (§ 147 AO). - kandidat = os.path.join(heim, "ravokk") + # Gerechnet wird der Pfad nur an EINER Stelle - siehe dort. + kandidat = gemeinsam.standard_ordner() if not _beschreibbar(kandidat): kandidat = os.path.join(EXE_DIR, "Daten") if not _beschreibbar(kandidat): @@ -84,8 +86,14 @@ def _daten_ordner(): os.replace(alt, neu_) print(f"[config] {name} aus {alt} übernommen") break - except OSError: - pass + except OSError as e: + # Nicht abbrechen - der naechste Ort wird noch probiert, + # und zur Not faengt das Programm eben neu an. Aber sagen, + # dass es schiefging: der Erfolgsfall schreibt eine Zeile, + # und wer sie sucht und nicht findet, wuesste sonst nicht, + # ob nichts da war oder ob die Uebernahme misslang. Es geht + # um Firmendaten, Leistungskatalog und Rechnungszaehler. + print(f"[config] {name} aus {alt} NICHT übernommen: {e}") return kandidat diff --git a/einzelinstanz.py b/einzelinstanz.py index cdd10cc..3311efa 100644 --- a/einzelinstanz.py +++ b/einzelinstanz.py @@ -41,6 +41,10 @@ def eigene_pid_merken(): with open(PID_DATEI, "w", encoding="ascii") as f: f.write(str(os.getpid())) except OSError: + # Der Merkzettel ist eine Bequemlichkeit, keine Bedingung: ohne ihn + # findet eine zweite Instanz das laufende Fenster nicht und meldet + # nur, dass das Programm schon laeuft. Daran darf der Start nicht + # scheitern - der Ordner kann schreibgeschuetzt sein. pass def laufende_pid_lesen(): """PID der laufenden Instanz aus dem Merkzettel; None wenn unlesbar.""" diff --git a/korrektur.py b/korrektur.py index cbbdb82..9b5f894 100644 --- a/korrektur.py +++ b/korrektur.py @@ -512,7 +512,6 @@ class KorrekturMixin: d.protocol("WM_DELETE_WINDOW", d.destroy) d.bind("", lambda _e: d.destroy()) d.update_idletasks() - x = self.winfo_rootx() + max(0, (self.winfo_width() - d.winfo_reqwidth()) // 2) theme.mittig(d, self) d.grab_set() self.wait_window(d) diff --git a/menueleiste.py b/menueleiste.py index 6eb4ce6..7b0f578 100644 --- a/menueleiste.py +++ b/menueleiste.py @@ -32,29 +32,32 @@ Beschriftung ergibt eine Trennlinie. Diese Datei liegt in BEIDEN Programmen gleich. Wer sie aendert, kopiert sie hinueber. """ +import theme import tkinter as tk from tkinter import ttk class Menueleiste(tk.Frame): - def __init__(self, master, menues, farben=None, mit_trennlinie=True): + def __init__(self, master, menues, farben=None): self.f = farben if farben is not None else master super().__init__(master, bg=self.f.col_bg) self.menues = menues self._offen = None + self._anker = None # welcher Titel gerade offen ist + self._titel = {} # Label -> Eintraege, fuer den Wechsel im Klick self.pack(side="top", fill="x") for titel, eintraege in menues.items(): lbl = tk.Label(self, text=titel, bg=self.f.col_bg, fg=self.f.col_fg, padx=8, pady=3) lbl.pack(side="left") + self._titel[lbl] = eintraege lbl.bind("", lambda e, w=lbl: w.configure(bg=self.f.col_sel)) lbl.bind("", lambda e, w=lbl: w.configure(bg=self.f.col_bg)) lbl.bind("", lambda e, b=lbl, it=eintraege: self.aufklappen(b, it)) - if mit_trennlinie: - ttk.Separator(master, orient="horizontal").pack(side="top", fill="x") + ttk.Separator(master, orient="horizontal").pack(side="top", fill="x") # ---------------------------------------------------------------- Klappen def aufklappen(self, anker, eintraege): @@ -83,9 +86,15 @@ class Menueleiste(tk.Frame): eintrag.bind("", lambda e, c=befehl: self._ausfuehren(c)) pop.update_idletasks() - pop.geometry(f"+{anker.winfo_rootx()}" - f"+{anker.winfo_rooty() + anker.winfo_height()}") + # Auf den sichtbaren Bereich begrenzen, wie jede andere Position im + # Programm auch. Steht das Fenster am unteren oder rechten Rand, lief + # die Liste sonst hinaus und war nicht mehr zu treffen. + x, y = theme.auf_bildschirm( + anker.winfo_rootx(), anker.winfo_rooty() + anker.winfo_height(), + pop.winfo_reqwidth(), pop.winfo_reqheight()) + pop.geometry(f"+{x}+{y}") self._offen = pop + self._anker = anker pop.grab_set() pop.bind("", self._klick_ausserhalb, add="+") pop.bind("", lambda e: self.zuklappen()) @@ -94,14 +103,53 @@ class Menueleiste(tk.Frame): faerben(pop) def _klick_ausserhalb(self, ereignis): + """Klick neben die Liste: schliessen - und auf einem anderen Titel + gleich dessen Liste aufklappen. + + WARUM DAS HIER STEHT UND NICHT IM LABEL (07.09.2026) + ---------------------------------------------------- + Solange eine Liste offen ist, haelt ihr `grab_set` alle Mausklicks der + Anwendung fest. Die ``-Bindung des Menuetitels feuert dann + gar nicht - der Klick landet hier. Vorher endete er damit beim blossen + Zuklappen, und man musste ein zweites Mal klicken, um von "Datei" zu + "Hilfe" zu kommen. Das native tk.Menu, das diese Leiste ersetzt hat, + wechselte schon beim blossen Ueberfahren; zwei Klicks waren also eine + Verschlechterung gegenueber dem, was vorher da war. + + Ein Klick auf DENSELBEN Titel schliesst weiterhin nur - sonst koennte + man eine Liste nie ueber ihren Titel wieder loswerden. + """ pop = self._offen if not pop: return - if (ereignis.x_root < pop.winfo_rootx() - or ereignis.x_root > pop.winfo_rootx() + pop.winfo_width() - or ereignis.y_root < pop.winfo_rooty() - or ereignis.y_root > pop.winfo_rooty() + pop.winfo_height()): - self.zuklappen() + if (pop.winfo_rootx() <= ereignis.x_root + <= pop.winfo_rootx() + pop.winfo_width() + and pop.winfo_rooty() <= ereignis.y_root + <= pop.winfo_rooty() + pop.winfo_height()): + return # der Klick lag in der Liste + vorher = self._anker + self.zuklappen() + getroffen = self._titel_bei(ereignis.x_root, ereignis.y_root) + if getroffen is not None and getroffen is not vorher: + self.aufklappen(getroffen, self._titel[getroffen]) + + def _titel_bei(self, x_root, y_root): + """Welcher Menuetitel an dieser Bildschirmstelle liegt - oder None. + + Nachgerechnet statt gefragt: `winfo_containing()` waere kuerzer, gibt + aber nichts zurueck, sobald das Fenster einer ANDEREN Anwendung ueber + dem Punkt liegt. Beim Bedienen ist das nie der Fall - beim Pruefen + schon, und dort meldete es dann einen Fehler, den es nicht gibt + (07.09.2026, zwei Pruefstaende liefen gleichzeitig auf demselben + Bildschirmplatz). Wo die eigenen Titel liegen, weiss diese Leiste + selbst; dafuer muss sie das Fenstersystem nicht fragen. + """ + for lbl in self._titel: + x, y = lbl.winfo_rootx(), lbl.winfo_rooty() + if (x <= x_root <= x + lbl.winfo_width() + and y <= y_root <= y + lbl.winfo_height()): + return lbl + return None def _ausfuehren(self, befehl): # Erst zuklappen, dann ausfuehren: sonst haelt der grab_set der Liste @@ -118,3 +166,4 @@ class Menueleiste(tk.Frame): except tk.TclError: pass self._offen = None + self._anker = None diff --git a/ordnerwahl.py b/ordnerwahl.py index ddf6fe0..fa9b5a9 100644 --- a/ordnerwahl.py +++ b/ordnerwahl.py @@ -118,8 +118,6 @@ class OrdnerWahl(tk.Toplevel): # zweiten Spalte ab und der Auswahl-Knopf ist nicht erreichbar. self.update_idletasks() hoehe = max(self.winfo_reqheight(), 300) - x = master.winfo_rootx() + max(0, (master.winfo_width() - BREITE) // 2) - y = master.winfo_rooty() + 90 self.geometry(f"{BREITE}x{hoehe}") theme.mittig(self, master) self.minsize(BREITE, hoehe) diff --git a/pruef_angebot.py b/pruef_angebot.py index 3e11e7c..2349b3d 100644 --- a/pruef_angebot.py +++ b/pruef_angebot.py @@ -32,16 +32,6 @@ QUELLE = r"C:\claude\rechnungstool" JOURNAL = r"C:\claude\beherbergungssteuer" sys.path.insert(0, QUELLE) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - def _reissleine(): print("ABBRUCH | Pruefstand haengt (Zeitgrenze) - vermutlich ein Dialog") @@ -73,6 +63,7 @@ json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=Fal import app as A # noqa: E402 import bestand as BE # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe antworten = {"Fertig": False, "Hausnummer": True} diff --git a/pruef_api.py b/pruef_api.py index 0afaf76..ff8994d 100644 --- a/pruef_api.py +++ b/pruef_api.py @@ -52,6 +52,7 @@ import api # noqa: E402 import app as A # noqa: E402 import gemeinsam # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe def _reissleine(): @@ -63,16 +64,6 @@ _wecker = threading.Timer(120, _reissleine) _wecker.daemon = True _wecker.start() -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - k = sys.stdout.encoding or "utf-8" - print(zeile.encode(k, "replace").decode(k)) - if not bedingung: - fehler.append(text) - messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None # Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. diff --git a/pruef_bilder.py b/pruef_bilder.py index 05b1c1f..f9da725 100644 --- a/pruef_bilder.py +++ b/pruef_bilder.py @@ -30,14 +30,7 @@ shutil.copy(os.path.join(QUELLE, "config.json"), config.CONFIG_PATH) import bilder # noqa: E402 import pdf_renderer # noqa: E402 from berechnung import berechne # noqa: E402 - -fehler = [] - - -def pruefe(bedingung, text): - print(("OK | " if bedingung else "FEHL | ") + text) - if not bedingung: - fehler.append(text) +from pruefhelfer import fehler, pruefe def testbild(pfad, farbe): diff --git a/pruef_darstellung.py b/pruef_darstellung.py index 260d444..d5f8158 100644 --- a/pruef_darstellung.py +++ b/pruef_darstellung.py @@ -35,16 +35,6 @@ import tkinter as tk QUELLE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, QUELLE) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) - os.chdir(QUELLE) os.environ["CAMPINGHOF_TEST"] = "1" @@ -69,6 +59,7 @@ json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), import app as A # noqa: E402 import theme # noqa: E402 +from pruefhelfer import fehler, pruefe f = A.RechnungsApp() diff --git a/pruef_doppelte_leistung.py b/pruef_doppelte_leistung.py index 841ff5d..883ac8d 100644 --- a/pruef_doppelte_leistung.py +++ b/pruef_doppelte_leistung.py @@ -26,16 +26,6 @@ QUELLE = r"C:\claude\rechnungstool" JOURNAL = r"C:\claude\beherbergungssteuer" sys.path.insert(0, QUELLE) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - def _reissleine(): print("ABBRUCH | Pruefstand haengt (Zeitgrenze) - vermutlich ein Dialog") @@ -64,6 +54,7 @@ json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=Fal import app as A # noqa: E402 import bestand as BE # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe antworten = {"Fertig": False, "Hausnummer": True, "Storno erstellt": False, "Angaben zum Kunden": True, "Weicht ab": True} diff --git a/pruef_flaeche.py b/pruef_flaeche.py index b94a565..f3dfdf3 100644 --- a/pruef_flaeche.py +++ b/pruef_flaeche.py @@ -44,6 +44,7 @@ json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=Fal import app as A # noqa: E402 import flaeche as FL # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe def _reissleine(): @@ -55,16 +56,6 @@ _wecker = threading.Timer(120, _reissleine) _wecker.daemon = True _wecker.start() -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - k = sys.stdout.encoding or "utf-8" - print(zeile.encode(k, "replace").decode(k)) - if not bedingung: - fehler.append(text) - messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None # Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. diff --git a/pruef_freigabe.py b/pruef_freigabe.py index 9a663fa..270b1ab 100644 --- a/pruef_freigabe.py +++ b/pruef_freigabe.py @@ -28,16 +28,6 @@ import threading QUELLE = r"C:\claude\rechnungstool" sys.path.insert(0, QUELLE) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) - def _reissleine(): print("ABBRUCH | Pruefstand haengt (Zeitgrenze)") @@ -70,6 +60,7 @@ os.environ["CAMPINGHOF_TEST"] = "1" import app as A # noqa: E402 import gemeinsam # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe antworten = {"Fertig": False, "Hausnummer": True} gefragt = [] diff --git a/pruef_gemeinsam_automatisch.py b/pruef_gemeinsam_automatisch.py index 4c9b936..eab6c13 100644 --- a/pruef_gemeinsam_automatisch.py +++ b/pruef_gemeinsam_automatisch.py @@ -22,6 +22,12 @@ GEPRUEFT WIRD 2. Der Ordner laesst sich anlegen, und darin entsteht EIN Nummernbuch. 3. Was das eine eintraegt, findet das andere - ohne dass jemand einen Pfad eingegeben hat. + 4. Die Dateien, die von sich sagen, sie laegen in beiden Programmen gleich, + sind auch wirklich gleich. + +Diese Datei liegt in BEIDEN Programmen gleich. Wer sie aendert, kopiert sie +hinueber - und sie prueft sich unter Punkt 4 selbst mit, denn sie traegt +denselben Satz wie die anderen. Angefasst wird dabei nichts Echtes: der Standardordner wird ueber die Umgebungsvariable LOCALAPPDATA auf einen Temp-Ordner umgelenkt. @@ -31,16 +37,6 @@ import shutil import sys import tempfile -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) - RECHNUNG = r"C:\claude\rechnungstool" STEUER = r"C:\claude\beherbergungssteuer" @@ -49,6 +45,7 @@ STEUER = r"C:\claude\beherbergungssteuer" # Geladen wird jede Fassung EINZELN, damit wirklich die Datei des jeweiligen # Programms befragt wird und nicht die zufaellig zuerst importierte. import importlib.util # noqa: E402 +from pruefhelfer import fehler, pruefe def modul_aus(ordner, name): @@ -95,9 +92,54 @@ buch_s.eintragen("2026-778", jahr=2026, nachname="Gegenprobe", quelle="journal") zurueck = [n for n in buch_r.nummern(2026) if n == "2026-778"] pruefe(bool(zurueck), "und umgekehrt genauso") -pruefe(len(os.listdir(angelegt)) >= 1 - and any(n.endswith(".sqlite3") for n in os.listdir(angelegt)), - f"es liegt genau ein Buch dort ({os.listdir(angelegt)})") +# GENAU eins - nicht "mindestens eins". Vorher stand hier `>= 1` mit einem +# any(); im Text darueber stand "genau ein Buch". Eine Pruefung, die nicht rot +# werden kann, prueft nichts: laege dort ein zweites Buch, weil eine der +# Fassungen einen anderen Dateinamen bildet, waere sie gruen geblieben - und +# das ist genau der Fall, den dieser Pruefstand abfangen soll. +# +# Die Begleitdateien von SQLite (-wal, -shm) zaehlen nicht mit; sie gehoeren +# zum selben Buch. +buecher = [n for n in os.listdir(angelegt) if n.endswith(".sqlite3")] +pruefe(len(buecher) == 1, + f"es liegt genau EIN Buch dort ({os.listdir(angelegt)})") +pruefe(buecher == [g_rechnung.DATEINAME], + f"und es traegt den Namen, den beide erwarten ({buecher})") + +# ---- 4. Was "in beiden gleich" heisst, ist auch gleich ------------------ +# Neun Dateien tragen im Kopf den Satz, sie laegen in beiden Programmen +# gleich. Das ist eine Zusage an den Naechsten, der eine davon anfasst - und +# geprueft hat sie bis zum 07.09.2026 niemand. Bei hinweis.py stimmte sie da +# schon nicht mehr: gleicher Inhalt, andere Zeilenenden. +# +# Die Liste steht bewusst NICHT hier, sondern wird aus dem Satz selbst +# gelesen. Eine Liste, die jemand von Hand nachfuehren muss, veraltet still +# (und still veraltete Pruefstaende fuehren in die Irre). +MARKE = "Diese Datei liegt in BEIDEN Programmen gleich" + +gemeinsame = sorted(n for n in os.listdir(RECHNUNG) if n.endswith(".py") + and MARKE in open(os.path.join(RECHNUNG, n), + encoding="utf-8").read()) +pruefe(len(gemeinsame) >= 5, + f"{len(gemeinsame)} Dateien sagen von sich, sie seien in beiden gleich") + +for name in gemeinsame: + hier = os.path.join(RECHNUNG, name) + dort = os.path.join(STEUER, name) + if not os.path.isfile(dort): + pruefe(False, f"{name} fehlt im Steuerrechnungstool") + continue + roh_h, roh_d = open(hier, "rb").read(), open(dort, "rb").read() + if roh_h == roh_d: + pruefe(True, f"{name} ist byteweise gleich") + continue + # Nicht gleich - dann wenigstens sagen, WORAN es liegt. Das ist der + # Unterschied zwischen einer Meldung und einer Suche. + if roh_h.replace(b"\r\n", b"\n") == roh_d.replace(b"\r\n", b"\n"): + grund = "nur die Zeilenenden weichen ab" + else: + grund = "der Inhalt weicht ab" + pruefe(False, f"{name}: {grund}") shutil.rmtree(tmp, ignore_errors=True) diff --git a/pruef_hinweis.py b/pruef_hinweis.py index 09eb11c..e37b5ef 100644 --- a/pruef_hinweis.py +++ b/pruef_hinweis.py @@ -31,16 +31,6 @@ import threading QUELLE = r"C:\claude\rechnungstool" sys.path.insert(0, QUELLE) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) - def _reissleine(): print("ABBRUCH | Pruefstand haengt (Zeitgrenze)") @@ -71,6 +61,7 @@ os.environ["CAMPINGHOF_TEST"] = "1" import app as A # noqa: E402 import hinweis as H # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe antworten = {"Fertig": False, "Hausnummer": True} gesehen = [] diff --git a/pruef_installation.py b/pruef_installation.py index f789ebc..55d0d1c 100644 --- a/pruef_installation.py +++ b/pruef_installation.py @@ -54,22 +54,13 @@ HIER = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HIER) import version # noqa: E402 +from pruefhelfer import fehler, pruefe LOKAL = os.environ.get("LOCALAPPDATA", "") RAVOKK = os.path.join(LOKAL, "ravokk") NAME = os.path.splitext(version.EXE_NAME)[0] PROGRAMMORDNER = os.path.join(RAVOKK, NAME) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) - def setup_datei(): ordner = os.path.join(HIER, "release") diff --git a/pruef_kernregeln.py b/pruef_kernregeln.py index 87a8f80..bd5160b 100644 --- a/pruef_kernregeln.py +++ b/pruef_kernregeln.py @@ -53,6 +53,7 @@ from tkinter import messagebox # noqa: E402 # eine Aenderung eine neue Frage eingefuehrt hat), bricht er nach zwei Minuten # von selbst ab, statt ein Fenster offen zu lassen, auf das niemand klickt. import threading as _th +from pruefhelfer import fehler, pruefe def _reissleine(): @@ -66,18 +67,6 @@ _wecker = _th.Timer(120, _reissleine) _wecker.daemon = True _wecker.start() -fehler = [] - - -def pruefe(bedingung, text): - # Die Windows-Konsole ist cp1252 - ein Sonderzeichen im Text darf den Lauf - # nicht mit einem UnicodeEncodeError abbrechen. - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - # ---- Dialoge: jede Frage muss angemeldet sein -------------------------------- antworten = {} diff --git a/pruef_kette.py b/pruef_kette.py index 72e4fed..40c5f73 100644 --- a/pruef_kette.py +++ b/pruef_kette.py @@ -52,6 +52,7 @@ from tkinter import messagebox # noqa: E402 # eine Aenderung eine neue Frage eingefuehrt hat), bricht er nach zwei Minuten # von selbst ab, statt ein Fenster offen zu lassen, auf das niemand klickt. import threading as _th +from pruefhelfer import fehler, pruefe def _reissleine(): @@ -65,18 +66,6 @@ _wecker = _th.Timer(120, _reissleine) _wecker.daemon = True _wecker.start() -fehler = [] - - -def pruefe(bedingung, text): - # Die Windows-Konsole ist cp1252 - ein Sonderzeichen im Text darf den Lauf - # nicht mit einem UnicodeEncodeError abbrechen. - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - antworten = {"Fertig": False, "Storno wirklich": True, "endgültig erstellen": True, diff --git a/pruef_menueleiste.py b/pruef_menueleiste.py new file mode 100644 index 0000000..7013965 --- /dev/null +++ b/pruef_menueleiste.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +"""Pruefstand: die eigene Menueleiste - Wechsel mit EINEM Klick, und am Rand. + +WARUM ES DIESE LEISTE GIBT +-------------------------- +`tk.Menu` ist unter Windows ein Menue des Betriebssystems. Es nimmt Farben +entgegen und zeichnet trotzdem im Systemgrau - ein weisser Balken ueber einem +dunklen Fenster. Sein Befund am 07.09.2026: *"nur die einstellunden hilfe +leiste die ist noch hell"*. Deshalb ist die Leiste aus gewoehnlichen Labels +gebaut. + +WAS HIER GEPRUEFT WIRD + +1. Ein Klick auf einen Titel klappt seine Liste auf, ein zweiter auf denselben + Titel klappt sie wieder zu. + +2. Steht eine Liste offen und man klickt auf einen ANDEREN Titel, klappt + dessen Liste auf - mit EINEM Klick. + + Das ging bis zum 07.09.2026 nicht. Solange eine Liste offen ist, haelt ihr + `grab_set` alle Mausklicks der Anwendung fest; die ``-Bindung des + Menuetitels feuert dann gar nicht. Der Klick landete beim Zuklappen und war + damit verbraucht - man musste ein zweites Mal klicken, um von "Datei" zu + "Hilfe" zu kommen. Das native tk.Menu wechselte schon beim blossen + Ueberfahren; zwei Klicks waren also eine Verschlechterung gegenueber dem, + was ersetzt wurde. + + Geprueft wird das ueber ein echtes Klickereignis auf der offenen Liste, mit + den Bildschirmkoordinaten des anderen Titels - also genau der Weg, den der + grab_set erzwingt. Ein direkter Aufruf von aufklappen() wuerde am Problem + vorbeipruefen. + +3. Die Liste bleibt auf dem Bildschirm. Steht das Fenster am unteren Rand, + lief sie vorher darueber hinaus und war nicht mehr zu treffen: die Position + wurde ungeprueft gesetzt, waehrend jede andere neue Position im Programm + ueber theme.auf_bildschirm() laeuft. + +Diese Datei liegt in BEIDEN Programmen gleich. Wer sie aendert, kopiert sie +hinueber - sonst steht in zwei Programmen zweierlei. +""" +import os +import sys +import time +import tkinter as tk + +QUELLE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, QUELLE) + +import menueleiste # noqa: E402 +import theme # noqa: E402 +from pruefhelfer import fehler, pruefe # noqa: E402 + + +class Fenster(theme.ThemeMixin, tk.Tk): + """Ein nacktes Fenster mit Farben - mehr braucht die Leiste nicht.""" + + def __init__(self): + super().__init__() + self.cfg = {} # theme.modus() will etwas mit .get() + self._apply_theme() + self.title("Pruefstand Menueleiste") + self.geometry("560x320" + theme.pruefplatz()) + + +f = Fenster() +gerufen = [] +f.menue = menueleiste.Menueleiste(f, { + "Datei": [("Neu", lambda: gerufen.append("neu")), ("-", None), + ("Beenden", lambda: gerufen.append("beenden"))], + "Bearbeiten": [("Rueckgaengig", lambda: gerufen.append("rueck"))], + "Hilfe": [("Info", lambda: gerufen.append("info"))], +}) + + +def pumpen(sekunden=0.4): + ende = time.time() + sekunden + while time.time() < ende: + f.update() + time.sleep(0.02) + + +pumpen(1.0) + +titel = {str(w.cget("text")): w for w in f.menue.winfo_children() + if isinstance(w, tk.Label)} +pruefe(set(titel) == {"Datei", "Bearbeiten", "Hilfe"}, + f"alle drei Titel stehen in der Leiste ({sorted(titel)})") + + +def klick_auf_titel(name): + """Auf einen Menuetitel klicken - so, wie es die Maus tut. + + Steht schon eine Liste offen, MUSS das Ereignis an sie gehen: ihr grab_set + faengt jeden Klick der Anwendung ab. Genau das ist der Fall, um den es + unter Punkt 2 geht. + """ + w = titel[name] + x = w.winfo_rootx() + w.winfo_width() // 2 + y = w.winfo_rooty() + w.winfo_height() // 2 + ziel = f.menue._offen or w + if ziel is w: + # Achtung: Tk nennt die Bildschirmkoordinaten beim Erzeugen -rootx + # und -rooty; im Ereignis heissen sie dann x_root und y_root. + w.event_generate("", x=w.winfo_width() // 2, + y=w.winfo_height() // 2, rootx=x, rooty=y) + else: + ziel.event_generate("", x=-1, y=-1, rootx=x, rooty=y) + pumpen(0.4) + + +def offener_titel(): + """Welcher Titel gerade offen ist - oder None.""" + anker = f.menue._anker + if anker is None or not f.menue._offen: + return None + return next((t for t, w in titel.items() if w is anker), "?") + + +# ---- 1. Aufklappen und wieder zuklappen --------------------------------- +klick_auf_titel("Datei") +pruefe(offener_titel() == "Datei", f"'Datei' klappt auf ({offener_titel()})") + +klick_auf_titel("Datei") +pruefe(offener_titel() is None, + f"und derselbe Titel klappt wieder zu ({offener_titel()})") + +# ---- 2. Der Wechsel: EIN Klick ------------------------------------------ +klick_auf_titel("Datei") +pruefe(offener_titel() == "Datei", "'Datei' steht offen") + +klick_auf_titel("Hilfe") +pruefe(offener_titel() == "Hilfe", + f"ein Klick auf 'Hilfe' wechselt hinueber ({offener_titel()})") + +klick_auf_titel("Bearbeiten") +pruefe(offener_titel() == "Bearbeiten", + f"und weiter auf 'Bearbeiten' ({offener_titel()})") + +# Ein Klick irgendwo neben die Leiste schliesst - und oeffnet nichts. +pop = f.menue._offen +pop.event_generate("", x=-1, y=-1, + rootx=f.winfo_rootx() + 300, + rooty=f.winfo_rooty() + 250) +pumpen(0.4) +pruefe(offener_titel() is None, + f"ein Klick daneben schliesst und oeffnet nichts ({offener_titel()})") + +# ---- 3. Ein Eintrag fuehrt seinen Befehl aus ---------------------------- +klick_auf_titel("Hilfe") +eintrag = None +for kind in f.menue._offen.winfo_children(): + for enkel in kind.winfo_children(): + if isinstance(enkel, tk.Label) and str(enkel.cget("text")) == "Info": + eintrag = enkel +eintrag.event_generate("", x=2, y=2) +pumpen(0.4) +pruefe(gerufen == ["info"], f"der Eintrag 'Info' fuehrt seinen Befehl aus ({gerufen})") +pruefe(offener_titel() is None, "und die Liste ist danach zu") + +# ---- 4. Am unteren Bildschirmrand bleibt die Liste sichtbar ------------- +# Das Fenster so weit nach unten schieben, dass unter der Leiste kein Platz +# mehr fuer die Klappliste ist. +links, oben = theme.auf_bildschirm(f.winfo_rootx(), f.winfo_rooty()) +unten = oben + f.winfo_screenheight() +f.geometry(f"560x320+{links}+{unten - 120}") +pumpen(0.6) + +klick_auf_titel("Datei") +pop = f.menue._offen +pruefe(pop is not None, "die Liste geht auch am unteren Rand auf") +if pop is not None: + x, y = pop.winfo_rootx(), pop.winfo_rooty() + hoehe, breite = pop.winfo_height(), pop.winfo_width() + grenze_x, grenze_y = theme.auf_bildschirm(x, y, breite, hoehe) + pruefe((x, y) == (grenze_x, grenze_y), + f"und steht vollstaendig auf dem Bildschirm " + f"(Liste {x},{y} bis {x + breite},{y + hoehe})") + +f.destroy() + +if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) +print("GRUEN | Die Menueleiste wechselt mit einem Klick und bleibt im Bild") diff --git a/pruef_montage.py b/pruef_montage.py index 20d65b3..d2332cd 100644 --- a/pruef_montage.py +++ b/pruef_montage.py @@ -49,6 +49,7 @@ os.environ["CAMPINGHOF_TEST"] = "1" import app as A # noqa: E402 import bestand as BE # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe def _reissleine(): @@ -61,16 +62,6 @@ _wecker = threading.Timer(150, _reissleine) _wecker.daemon = True _wecker.start() -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - # Dialoge automatisch beantworten; jede Frage wird protokolliert. antworten = {"Fertig": False, "endgültig erstellen": True, "Hausnummer": True} diff --git a/pruef_nummernbuch.py b/pruef_nummernbuch.py index 1d83585..4656eca 100644 --- a/pruef_nummernbuch.py +++ b/pruef_nummernbuch.py @@ -23,16 +23,6 @@ import threading TOOL = r"C:\claude\rechnungstool" JOURNAL = r"C:\claude\beherbergungssteuer" -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - def _reissleine(): print("ABBRUCH | Pruefstand haengt (Zeitgrenze)") @@ -66,6 +56,7 @@ sys.path.remove(JOURNAL) from datetime import date # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe messagebox.showinfo = lambda *a, **k: None messagebox.showwarning = lambda *a, **k: None diff --git a/pruef_nummernsperre.py b/pruef_nummernsperre.py index c3efa44..0f2ea49 100644 --- a/pruef_nummernsperre.py +++ b/pruef_nummernsperre.py @@ -22,16 +22,6 @@ import threading QUELLE = r"C:\claude\rechnungstool" sys.path.insert(0, QUELLE) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - def _reissleine(): print("ABBRUCH | Pruefstand haengt (Zeitgrenze)") @@ -65,6 +55,7 @@ json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=Fal import app as A # noqa: E402 import gemeinsam # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe warnungen = [] # Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. diff --git a/pruef_nur_storno.py b/pruef_nur_storno.py index a107881..cb55a78 100644 --- a/pruef_nur_storno.py +++ b/pruef_nur_storno.py @@ -31,16 +31,6 @@ QUELLE = r"C:\claude\rechnungstool" JOURNAL = r"C:\claude\beherbergungssteuer" sys.path.insert(0, QUELLE) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - def _reissleine(): print("ABBRUCH | Pruefstand haengt (Zeitgrenze) - vermutlich ein Dialog") @@ -69,6 +59,7 @@ json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=Fal import app as A # noqa: E402 import bestand as BE # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe # Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. # Geprueft wird er eigens in pruef_hinweis.py. diff --git a/pruef_release.py b/pruef_release.py index 6722570..e8e13a4 100644 --- a/pruef_release.py +++ b/pruef_release.py @@ -39,16 +39,7 @@ sys.path.insert(0, HIER) import updater # noqa: E402 import version # noqa: E402 - -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) +from pruefhelfer import fehler, pruefe try: diff --git a/pruef_selbstbezug.py b/pruef_selbstbezug.py index d8a6e84..32e65d1 100644 --- a/pruef_selbstbezug.py +++ b/pruef_selbstbezug.py @@ -32,19 +32,10 @@ import ast import io import os import sys +from pruefhelfer import fehler, pruefe ORDNER = [r"C:\claude\rechnungstool", r"C:\claude\beherbergungssteuer"] -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) - def fundstellen(quelltext): """Alle Zeilen, in denen `self` steht, ohne dass es eines gibt.""" diff --git a/pruef_spaltenbreiten.py b/pruef_spaltenbreiten.py index f76471d..f3692b9 100644 --- a/pruef_spaltenbreiten.py +++ b/pruef_spaltenbreiten.py @@ -41,16 +41,6 @@ import time QUELLE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, QUELLE) -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) - os.chdir(QUELLE) os.environ["CAMPINGHOF_TEST"] = "1" @@ -72,6 +62,7 @@ for _n in ("showinfo", "showwarning", "showerror"): setattr(messagebox, _n, lambda *a, **k: None) import app as A # noqa: E402 +from pruefhelfer import fehler, pruefe f = A.RechnungsApp() diff --git a/pruef_start_exe.py b/pruef_start_exe.py index adccc6b..1dafd4f 100644 --- a/pruef_start_exe.py +++ b/pruef_start_exe.py @@ -36,16 +36,7 @@ HIER = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HIER) import version # noqa: E402 - -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) +from pruefhelfer import fehler, pruefe stamm, endung = os.path.splitext(version.EXE_NAME) diff --git a/pruef_storno.py b/pruef_storno.py index f121e73..e376883 100644 --- a/pruef_storno.py +++ b/pruef_storno.py @@ -48,6 +48,7 @@ from tkinter import messagebox # noqa: E402 # eine Aenderung eine neue Frage eingefuehrt hat), bricht er nach zwei Minuten # von selbst ab, statt ein Fenster offen zu lassen, auf das niemand klickt. import threading as _th +from pruefhelfer import fehler, pruefe def _reissleine(): @@ -61,18 +62,6 @@ _wecker = _th.Timer(120, _reissleine) _wecker.daemon = True _wecker.start() -fehler = [] - - -def pruefe(bedingung, text): - # Die Windows-Konsole ist cp1252 - ein Sonderzeichen im Text darf den Lauf - # nicht mit einem UnicodeEncodeError abbrechen. - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kodierung = sys.stdout.encoding or "utf-8" - print(zeile.encode(kodierung, "replace").decode(kodierung)) - if not bedingung: - fehler.append(text) - # Dialoge automatisch beantworten; jede Frage wird protokolliert. antworten = {} diff --git a/pruef_updater.py b/pruef_updater.py index 227bc3c..8769853 100644 --- a/pruef_updater.py +++ b/pruef_updater.py @@ -25,16 +25,7 @@ QUELLE = r"C:\claude\rechnungstool" sys.path.insert(0, QUELLE) import updater as U # noqa: E402 - -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - kod = sys.stdout.encoding or "utf-8" - print(zeile.encode(kod, "replace").decode(kod)) - if not bedingung: - fehler.append(text) +from pruefhelfer import fehler, pruefe EXE = "Rechnungstool.exe" diff --git a/pruef_vorschau.py b/pruef_vorschau.py index 77979a6..b607c76 100644 --- a/pruef_vorschau.py +++ b/pruef_vorschau.py @@ -40,6 +40,7 @@ json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=Fal os.environ["CAMPINGHOF_TEST"] = "1" import app as A # noqa: E402 from tkinter import messagebox # noqa: E402 +from pruefhelfer import fehler, pruefe def _reissleine(): @@ -51,16 +52,6 @@ _wecker = _th.Timer(120, _reissleine) _wecker.daemon = True _wecker.start() -fehler = [] - - -def pruefe(bedingung, text): - zeile = (" OK | " if bedingung else "FEHLER | ") + text - k = sys.stdout.encoding or "utf-8" - print(zeile.encode(k, "replace").decode(k)) - if not bedingung: - fehler.append(text) - messagebox.showinfo = messagebox.showwarning = messagebox.showerror = lambda *a, **k: None # Der Erprobungshinweis wird von der pauschalen Antwort unten mit erfasst. diff --git a/pruefhelfer.py b/pruefhelfer.py new file mode 100644 index 0000000..f3e9155 --- /dev/null +++ b/pruefhelfer.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +"""Das Gemeinsame aller Pruefstaende: eine Zeile schreiben und sie merken. + +WARUM ES DIESE DATEI GIBT (07.09.2026) +-------------------------------------- +Die Funktion pruefe() stand 35-mal im Quelltext, in sechs leicht verschiedenen +Fassungen. Keine davon war falsch - aber sie sahen unterschiedlich aus, und +wer 37 Laeufe hintereinander durchsieht, liest dann dreierlei Formen fuer +dieselbe Aussage. Wird an der Ausgabe je etwas geaendert, sind es 35 Stellen. + +BENUTZUNG + + from pruefhelfer import fehler, pruefe + + pruefe(a == b, "beide nennen denselben Ordner") + ... + if fehler: + print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt") + sys.exit(1) + print("GRUEN | ...") + +`fehler` ist eine Liste und wird beim Importieren geteilt - jeder Pruefstand +laeuft in einem eigenen Prozess, sie gehoert also ihm allein. + +Den Abschluss schreibt jeder Pruefstand selbst. Er sieht nur aehnlich aus: +manche raeumen dort noch einen Temp-Ordner ab, manche zaehlen die +fehlgeschlagenen Punkte einzeln auf. Das ist Inhalt, keine Wiederholung. + +Diese Datei liegt in BEIDEN Programmen gleich. Wer sie aendert, kopiert sie +hinueber - sonst steht in zwei Programmen zweierlei. +""" +import sys + +# Alles, was nicht erfuellt war - der Text, nicht nur die Anzahl. Wer am Ende +# nur eine Zahl hat, muss den Lauf noch einmal lesen, um zu wissen, was fehlte. +fehler = [] + + +def pruefe(bedingung, text): + """Eine Zusage pruefen, das Ergebnis melden und Fehlschlaege merken.""" + zeile = (" OK | " if bedingung else "FEHLER | ") + text + # Die Windows-Konsole ist cp1252 - ein Sonderzeichen im Text darf den Lauf + # nicht mit einem UnicodeEncodeError abbrechen. + kodierung = sys.stdout.encoding or "utf-8" + print(zeile.encode(kodierung, "replace").decode(kodierung)) + if not bedingung: + fehler.append(text) diff --git a/theme.py b/theme.py index 309f261..213e2d3 100644 --- a/theme.py +++ b/theme.py @@ -46,7 +46,6 @@ def titelleiste_faerben(fenster, dunkel): if not sys.platform.startswith("win"): return False try: - import ctypes fenster.update_idletasks() hwnd = ctypes.windll.user32.GetParent(fenster.winfo_id()) or int(fenster.frame(), 16) wert = ctypes.c_int(1 if dunkel else 0) @@ -84,16 +83,13 @@ def pruefplatz(): if not sys.platform.startswith("win"): return "" try: - import ctypes - from ctypes import wintypes - class RECT(ctypes.Structure): _fields_ = [("left", ctypes.c_long), ("top", ctypes.c_long), ("right", ctypes.c_long), ("bottom", ctypes.c_long)] class MONITORINFO(ctypes.Structure): - _fields_ = [("cbSize", wintypes.DWORD), ("rcMonitor", RECT), - ("rcWork", RECT), ("dwFlags", wintypes.DWORD)] + _fields_ = [("cbSize", ctypes.wintypes.DWORD), ("rcMonitor", RECT), + ("rcWork", RECT), ("dwFlags", ctypes.wintypes.DWORD)] gefunden = [] @@ -106,9 +102,9 @@ def pruefplatz(): r.left, r.top, r.right - r.left)) return 1 - RUECKRUF = ctypes.WINFUNCTYPE(ctypes.c_int, wintypes.HMONITOR, - wintypes.HDC, ctypes.POINTER(RECT), - wintypes.LPARAM) + RUECKRUF = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.wintypes.HMONITOR, + ctypes.wintypes.HDC, ctypes.POINTER(RECT), + ctypes.wintypes.LPARAM) ctypes.windll.user32.EnumDisplayMonitors(0, 0, RUECKRUF(je_monitor), 0) # Der breiteste Nebenmonitor - bei mehreren der linkeste. neben = sorted((m for m in gefunden if not m[0]), @@ -137,7 +133,6 @@ def auf_bildschirm(x, y, breite=0, hoehe=0): if not sys.platform.startswith("win"): return int(x), int(y) try: - import ctypes hole = ctypes.windll.user32.GetSystemMetrics links, oben = hole(76), hole(77) rechts, unten = links + hole(78), oben + hole(79) @@ -207,7 +202,6 @@ def schrift_vorbereiten(): _schrift_geladen = True if not sys.platform.startswith("win"): return SCHRIFT_NAME - import ctypes FR_PRIVATE = 0x10 geladen = 0 for basis in _ordner(): @@ -615,6 +609,120 @@ class ThemeMixin: """ titelleiste_faerben(win, bool(getattr(self, "_dark_mode", False))) + # ------------------------------------------------ Hell / dunkel umstellen + # Der Hinweistext gehoert dem einzelnen Programm - er sagt etwas ueber + # DIESES Programm. Hier steht nur, was dasteht, wenn ihn niemand setzt. + DARSTELLUNG_HINWEIS = "Gilt nur für das Programmfenster." + + def _cfg_speichern(self): + """Die Einstellungen wegschreiben - falls das noetig ist. + + Im Rechnungstool ist die Konfiguration ein gewoehnliches Woerterbuch + und muss ausdruecklich gespeichert werden. Im Steuerrechnungstool ist + sie eine Ablage, die jeden Schreibzugriff sofort in die + Journaltabelle durchreicht - dort ist hier nichts zu tun. + """ + return + + def variablen_sichern(self): + """Alle Tk-Variablen des Fensters als {Name: Wert}. + + WARUM ALLE UND NICHT EINE AUSWAHL + --------------------------------- + Die _build-Methoden legen ihre Variablen selbst an + (`self.k_name = tk.StringVar()`). Nach dem Neubau stehen also neue, + leere da. Beim ersten Versuch waren Kundenname und Rechnungsnummer + weg, waehrend die Mengen blieben - die hatte ich einzeln gesichert. + + Durchgegangen wird deshalb, was das Objekt an Tk-Variablen traegt. + Wer spaeter ein Feld hinzufuegt, muss nichts eintragen; eine Liste zum + Pflegen waere genau die Sorte, die man beim naechsten Feld vergisst. + """ + gesichert = {} + for name in dir(self): + if name.startswith("__"): + continue + try: + wert = getattr(self, name) + except Exception: # noqa: BLE001 - Eigenschaften koennen werfen + continue + if isinstance(wert, (tk.StringVar, tk.IntVar, tk.DoubleVar, + tk.BooleanVar)): + try: + gesichert[name] = wert.get() + except tk.TclError: + pass + return gesichert + + def variablen_zuruecksetzen(self, gesichert): + """Die gesicherten Werte in die neu gebauten Variablen zurueckgeben.""" + for name, wert in gesichert.items(): + neu = getattr(self, name, None) + if isinstance(neu, (tk.StringVar, tk.IntVar, tk.DoubleVar, + tk.BooleanVar)): + try: + neu.set(wert) + except tk.TclError: + pass + + def kinder_loeschen(self): + """Die Oberflaeche abraeumen - aber keine fremden Fenster. + + Ein tk.Toplevel IST ein Kind des Hauptfensters. Der offene + Darstellungsdialog wurde hier bisher mitgeloescht, und die Zeile + danach fasste eine Leiche an ("invalid command name .!toplevel"). + Gefunden am 07.09.2026 von der Pruefkette, mit dem echten Bedienweg + gemessen: Klick auf "Dunkel" -> Farbe wechselt, Fenster ist weg, + Traceback im Log. + + Der Pruefstand hatte es nicht gefunden, weil er cfg["darstellung"] von + Hand setzte und _oberflaeche_neu() direkt rief - also alles ausser dem + Weg, den ein Mensch geht. Er klickt jetzt. + """ + for kind in self.winfo_children(): + if not isinstance(kind, tk.Toplevel): + kind.destroy() + + def dlg_darstellung(self): + """Hell, dunkel oder wie Windows - und sofort sichtbar.""" + d = tk.Toplevel(self) + d.title("Darstellung") + d.transient(self) + d.resizable(False, False) + self._style_dialog(d) + rahmen = ttk.Frame(d, padding=18) + rahmen.pack(fill="both", expand=True) + ttk.Label(rahmen, text="Darstellung", + font=(SCHRIFT_NAME, 11, "bold"), + foreground=self.col_accent).pack(anchor="w") + ttk.Label(rahmen, justify="left", wraplength=340, + foreground=self.col_muted, + text=self.DARSTELLUNG_HINWEIS).pack(anchor="w", pady=(6, 12)) + + gewaehlt = tk.StringVar(value=modus(self.cfg)) + + def uebernehmen(): + neu = gewaehlt.get() + if neu == modus(self.cfg): + return + self.cfg["darstellung"] = neu + self._cfg_speichern() + self._oberflaeche_neu() + # Der Dialog gehoert noch zur alten Darstellung - er wird + # mitgefaerbt, sonst steht ein helles Fenster vor einem dunklen. + self._style_dialog(d) + + for wert in MODI: + ttk.Radiobutton(rahmen, text=MODUS_NAMEN[wert], value=wert, + variable=gewaehlt, command=uebernehmen).pack( + anchor="w", pady=3) + + ttk.Separator(rahmen, orient="horizontal").pack(fill="x", pady=(12, 10)) + ttk.Button(rahmen, text="Schließen", width=14, + command=d.destroy).pack(anchor="e") + mittig(d, self) + return d + class MeldungMixin: """Eigene Meldungs- und Ja/Nein-Fenster im Theme des Programms. diff --git a/updater.py b/updater.py index 5db2447..836c448 100644 --- a/updater.py +++ b/updater.py @@ -245,6 +245,11 @@ def aufraeumen(ordner, exe_name, behalten=2): os.remove(pfad) weg.append(os.path.basename(pfad)) except OSError: + # Laeuft die alte Fassung noch oder haelt ein Virenscanner die + # Datei, sperrt Windows sie. Das ist kein Grund zum Abbruch: die + # Datei stoert nur, sie schadet nicht, und beim naechsten Mal + # klappt es. Was WEG ist, steht in der Rueckgabe - was nicht weg + # ist, taucht dort nicht auf. pass return weg diff --git a/wasserzeichen.py b/wasserzeichen.py index 7cf0b51..9a73658 100644 --- a/wasserzeichen.py +++ b/wasserzeichen.py @@ -45,7 +45,7 @@ def pfad(name): return "" -def kachel(bild, kante, grund=(0xFF, 0xFF, 0xFF), rand=0.16, radius=0.22): +def kachel(bild, kante, rand=0.16): """Das Logo auf eine helle Kachel mit runden Ecken setzen. Seine Ansage am 07.09.2026: *"bei den windows icons kannst du einen @@ -57,9 +57,9 @@ def kachel(bild, kante, grund=(0xFF, 0xFF, 0xFF), rand=0.16, radius=0.22): das Programm nicht. Eine helle Kachel ist auf jedem sichtbar; so machen es die meisten Programme, und deshalb sieht es auch nicht fremd aus. - `rand` ist der Abstand zum Kachelrand, `radius` die Eckenrundung - beides - als Anteil der Kantenlaenge, damit es in jeder Groesse gleich aussieht. - Die 22 % entsprechen etwa dem, was Windows fuer Kacheln verwendet. + `rand` ist der Abstand zum Kachelrand, als Anteil der Kantenlaenge - so + sieht es in jeder Groesse gleich aus. Die Rundung liegt fest bei 22 %, + etwa dem, was Windows fuer Kacheln verwendet. """ from PIL import Image, ImageDraw kante = int(kante) @@ -68,8 +68,8 @@ def kachel(bild, kante, grund=(0xFF, 0xFF, 0xFF), rand=0.16, radius=0.22): fein = kante * 4 maske = Image.new("L", (fein, fein), 0) ImageDraw.Draw(maske).rounded_rectangle( - (0, 0, fein - 1, fein - 1), radius=int(fein * radius), fill=255) - flaeche = Image.new("RGBA", (fein, fein), tuple(grund) + (255,)) + (0, 0, fein - 1, fein - 1), radius=int(fein * 0.22), fill=255) + flaeche = Image.new("RGBA", (fein, fein), (0xFF, 0xFF, 0xFF, 255)) flaeche.putalpha(maske) innen = max(1, int(fein * (1 - 2 * rand))) @@ -126,17 +126,16 @@ def symbol_bauen(ziel): return "" -def symbol_setzen(fenster, melden=print, dunkel=False): +def symbol_setzen(fenster, melden=print): """Das Programmsymbol auf ein Fenster legen. True bei Erfolg. Die EXE traegt es ohnehin - das Fenster aber nicht von selbst. Ohne das steht in der Titelleiste das nackte Tk-Symbol, obwohl die Datei ein eigenes hat. - `dunkel` wird nicht mehr gebraucht und nur noch entgegengenommen, damit - bestehende Aufrufe weiterlaufen: seit das Symbol eine helle Kachel ist, ist - es in jeder Darstellung sichtbar. Vorher gab es dafuer eine zweite, - aufgehellte Datei - die ist mit der Kachel ueberfluessig geworden. + Frueher gab es dafuer eine zweite, aufgehellte ICO und einen Schalter + `dunkel`. Seit das Symbol eine helle Kachel ist, ist es in jeder + Darstellung sichtbar - beides ist damit weggefallen. """ p = pfad("programm.ico") if not p: From fb04f5ad7482eb6c155109fce6ae690998eb1f31 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 18:41:14 +0200 Subject: [PATCH 34/34] Fassung 1.8.2 Aufraeumrunde nach der Pruefkette. Fuer den Nutzer sichtbar ist ein Punkt: der Wechsel von einem Menuetitel zum anderen braucht nur noch EINEN Klick. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.py b/version.py index 415f3f5..46dcda8 100644 --- a/version.py +++ b/version.py @@ -10,11 +10,11 @@ und NUR hier; alles andere (Info-Dialog, Updater, Release) liest sie von hier. Regel ----- Die Nummer wird beim Ausliefern erhoeht und entspricht dem Release-Tag ohne das -"v": Tag `v1.8.1` -> VERSION "1.8.1". Wer das eine ohne das andere aendert, +"v": Tag `v1.8.2` -> VERSION "1.8.2". Wer das eine ohne das andere aendert, baut dem Updater eine Falle. """ -VERSION = "1.8.1" +VERSION = "1.8.2" # Zu welchem Repository dieses Programm gehoert - der Updater sucht dort. REPOSITORY = "TheMockTv/rechnungstool"