rechnungstool/pruef_dialoge.py
TheMockTv 3ea31b3421 Die Kette steht auf dem Storno-Blatt - kein gemerkter Zustand noetig
Statt einer Zustandsmaschine ("offener Storno" ueber den Neustart retten) traegt
das Storno jetzt einfach beide Nummern:

    Storno zu Rechnung:  2026-002
    Neue Rechnung:       2026-004

und im Text "2026-002 -> 2026-003 -> 2026-004". Damit ist die Kette aus dem
Beleg allein lesbar. Wird das Programm zwischendurch geschlossen, sagt der
Storno, unter welcher Nummer die berichtigte Rechnung gehoert; der Dialog
nennt sie ebenfalls, statt nur "bereits storniert" zu melden.

naechste_freie_nummer_nach() bestimmt die Folgenummer, damit sie nicht von der
Reihenfolge abhaengt, in der der Zaehler mitzieht.

Ausserdem: die Pruefstaende raeumen ihren Wegwerf-Ordner wieder weg, wenn sie
gruen sind. Ein Testlauf hatte 398 Ordner im Temp-Verzeichnis hinterlassen.
Bei Fehlern bleibt der Ordner stehen, damit man hineinsehen kann.

Weitere Funde des Code-Agenten behoben:
- "Kopie von Rechnung_...pdf" und klein geschriebene Dateinamen zaehlen jetzt
  bei der Nummernvergabe mit (vorher galt die Nummer als frei).
- Strg+P feuerte auch aus einem offenen Dialog heraus (bind_all -> bind).

167 Pruefungen gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKvGkdNW1vKdnMPAM9Bp3X
2026-09-02 20:42:31 +02:00

97 lines
3.1 KiB
Python

# -*- coding: utf-8 -*-
"""Pruefstand: geht jeder Dialog ueberhaupt auf?
Klingt banal, ist es nicht: beim Aufteilen von app.py in Module sind zwei
Dialoge stumm kaputtgegangen (fehlende Importe), und kein anderer Pruefstand
hat es gemerkt, weil keiner sie oeffnet. Dieser hier oeffnet ALLE.
Geprueft wird ausserdem, dass jeder Dialog auch wieder zugeht - ein modales
Fenster, das haengenbleibt, sperrt das Programm.
"""
import json
import os
import shutil
import sys
import tempfile
import tkinter as tk
QUELLE = r"C:\claude\rechnungstool"
sys.path.insert(0, QUELLE)
tmp = tempfile.mkdtemp(prefix="dialog_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
json.dump(roh, open(config.CONFIG_PATH, "w", encoding="utf-8"), ensure_ascii=False)
import app as A # noqa: E402
from tkinter import messagebox # noqa: E402
messagebox.showinfo = lambda *a, **k: None
messagebox.showwarning = lambda *a, **k: None
messagebox.showerror = lambda *a, **k: None
messagebox.askyesno = lambda *a, **k: False
fehler = 0
f = A.RechnungsApp()
f.update()
# Damit "Storno"/"Berichtigen" nicht an "nichts zu korrigieren" scheitern:
# eine echte Rechnung in den Wegwerf-Ordner legen.
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[sorted(f.anzahl_vars)[0]].set("2")
f.update()
f.pdf_erstellen()
DIALOGE = ["dlg_steuern", "dlg_katalog", "dlg_firma", "dlg_nummer",
"dlg_storno", "dlg_berichtigen"]
for name in DIALOGE:
offen_vorher = [w for w in f.winfo_children() if isinstance(w, tk.Toplevel)]
try:
getattr(f, name)()
f.update()
except Exception as e: # noqa: BLE001 - genau das wollen wir sehen
print(f"ABSTURZ | {name}: {type(e).__name__}: {e}")
fehler += 1
continue
neu = [w for w in f.winfo_children()
if isinstance(w, tk.Toplevel) and w not in offen_vorher]
if not neu:
print(f"FEHLER | {name}: kein Fenster aufgegangen")
fehler += 1
continue
titel = neu[-1].title()
for w in neu:
w.grab_release()
w.destroy()
f.update()
print(f" OK | {name} -> „{titel}“")
# Der Speicherort-Dialog oeffnet einen Systemdialog - nur die Vorstufe pruefen
try:
f._frage_speicherort_falls_noetig()
f.update()
print(" OK | _frage_speicherort_falls_noetig")
except Exception as e: # noqa: BLE001
print(f"ABSTURZ | _frage_speicherort_falls_noetig: {type(e).__name__}: {e}")
fehler += 1
f.destroy()
# Wegwerf-Ordner nur bei Fehlern behalten - sonst laeuft das Temp-Verzeichnis
# voll. Ein Pruefstand, der 400 Ordner hinterlaesst, ist selbst ein Problem.
if not fehler: # fehler ist hier ein Zaehler
import shutil as _sh
_sh.rmtree(tmp, ignore_errors=True)
print("---")
print("alles gruen" if not fehler else f"{fehler} Fehler")
sys.exit(1 if fehler else 0)