Doppelte Rechnungen anzeigen (Datei > Doppelte Rechnungen)

Der Altbestand wurde nie geprueft - die Sperre verhindert nur NEUE Dubletten.
Neues Modul duplikate.py findet zwei Sorten, und sie bedeuten nicht dasselbe:

  Nummer doppelt - zwei Geldbelege mit derselben Rechnungsnummer. Der harte
                   Fall (§ 14 Abs. 4 Nr. 4 UStG).
  Inhalt doppelt - gleicher Gast, gleiches Datum, gleicher Betrag unter zwei
                   Nummern. Nur ein Hinweis, kann echt sein.

Der schwierige Teil ist das NICHT-Finden: Storno und berichtigte Rechnung
haben absichtlich eigene Nummern, und ein Berichtigungsblatt traegt sogar die
Nummer der Rechnung, die es berichtigt. Nichts davon ist eine Dublette.

PDFs ohne Kenndaten fallen nicht durch: ihre Nummer wird aus dem Dateinamen
gelesen und sie werden getrennt aufgelistet - das ist genau der ungepruefte
Altbestand.

Beim Start laeuft die Pruefung still mit; liegt etwas vor, steht es rot in der
Statuszeile. Kein Popup beim Hochfahren.

pruef_duplikate.py (12 Pruefungen): Ordner mit dem echten Schlamassel gebaut -
zweimal 2026-013 fuer zwei verschiedene Gaeste, dazu eine saubere Storno-Kette
und ein Berichtigungsblatt, die NICHT gemeldet werden duerfen, ein
inhaltsgleiches Paar und eine fremde PDF. Fenster angesehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKvGkdNW1vKdnMPAM9Bp3X
This commit is contained in:
TheMockTv 2026-09-02 20:08:22 +02:00
parent 1060a6421f
commit 67a09e4085
4 changed files with 323 additions and 2 deletions

10
app.py
View file

@ -35,9 +35,11 @@ from einzelinstanz import (eigene_pid_merken, einzelinstanz_pruefen, fenster_nac
from theme import ThemeMixin
from korrektur import KorrekturMixin
from einstellungen import EinstellungenMixin
from duplikate import DuplikateMixin
class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk):
class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin,
DuplikateMixin, tk.Tk):
def __init__(self):
super().__init__()
self.cfg = config.load_config()
@ -74,6 +76,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk):
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)
self.after(400, self.duplikate_pruefen_beim_start)
# ---------------------------------------------------------------- Menue
@ -86,6 +89,7 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk):
("PDF erstellen", self.pdf_erstellen),
("Formular zurücksetzen", self.reset_formular),
("Ausgabeordner öffnen", self._ordner_oeffnen),
("Doppelte Rechnungen…", self.dlg_duplikate),
("-", None),
("Beenden", self._beenden), # fragt nach, wenn ein Storno offen ist
],
@ -347,6 +351,10 @@ class RechnungsApp(ThemeMixin, KorrekturMixin, EinstellungenMixin, tk.Tk):
status.pack(side="bottom", fill="x")
ttk.Label(status, text="powered by ravokk", foreground=self.col_muted,
font=("Segoe UI", 8)).pack(side="right")
# Meldet sich nur, wenn im Ordner wirklich etwas doppelt liegt.
self.duplikat_hinweis = tk.StringVar(value="")
ttk.Label(status, textvariable=self.duplikat_hinweis, foreground="#b00020",
font=("Segoe UI", 8, "bold")).pack(side="left")
f = ttk.Frame(self, padding=(12, 6, 12, 10))
f.pack(side="bottom", fill="x")