Im Journal wird nichts mehr von Hand geloescht
Sein Einwand: 'wenn man in der beherbergungstool ein datensatz loescht, bleibt die in der sqlite - oder du patchst es raus, dass man das garnicht mehr loeschen kann'. Beides stimmt. Im gemeinsamen Nummernbuch BLEIBT die Nummer stehen, und das ist richtig: vergeben ist vergeben, die Rechnung liegt beim Gast. Das Loeschen im Journal gehoert dagegen weg - eine Zeile aus einer PDF kaeme beim naechsten Einlesen ohnehin zurueck, eine Zeile aus dem Excel-Altbestand (quelle='xlsx') gibt es dagegen nirgends sonst; die waere fuer immer weg, samt Uebernachtung im Amtsbericht. § 146 Abs. 4 AO verbietet Aenderungen, bei denen der urspruengliche Inhalt nicht mehr feststellbar ist. Raus sind: Papierkorb-Knopf, Entf-Taste, Menuepunkt und die Haken-Spalte, die nur dafuer da war. Damit ist das Monatsblatt reine Anzeige. Der Weg, der bleibt: die PDF aus dem Rechnungsordner nehmen - dann raeumt der Scan die Zeile von selbst weg, und nur dann, wenn das Laufwerk erreichbar ist (ein abgezogenes NAS darf die Buchhaltung nicht leeren). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GYeAfLtccFrbU3MTj1MMTx
This commit is contained in:
parent
c230a27cff
commit
0218abaebe
3 changed files with 25 additions and 114 deletions
78
app.py
78
app.py
|
|
@ -102,7 +102,6 @@ class App(tk.Tk):
|
|||
|
||||
self.bind("<F5>", lambda _e: self.einlesen())
|
||||
self.bind("<Control-f>", lambda _e: self.suchfeld.focus_set())
|
||||
self.bind("<Delete>", lambda _e: self.buchung_loeschen())
|
||||
self.protocol("WM_DELETE_WINDOW", self._beenden)
|
||||
|
||||
self.aktualisieren()
|
||||
|
|
@ -137,7 +136,6 @@ class App(tk.Tk):
|
|||
daten.add_command(label="Rechnungen einlesen (F5)", command=self.einlesen)
|
||||
daten.add_command(label="Alle Rechnungen neu einlesen", command=lambda: self.einlesen(voll=True))
|
||||
daten.add_separator()
|
||||
daten.add_command(label="Markierte Buchung löschen (Entf)", command=self.buchung_loeschen)
|
||||
daten.add_separator()
|
||||
daten.add_command(label="Steuersatz ändern…", command=self.satz_aendern)
|
||||
daten.add_command(label="Firmendaten des Rechnungstools wählen…",
|
||||
|
|
@ -160,9 +158,11 @@ class App(tk.Tk):
|
|||
ttk.Button(leiste, text="Rechnungen einlesen", command=self.einlesen).pack(side="left")
|
||||
ttk.Button(leiste, text="PDF fürs Amt", command=self.bericht_monat).pack(side="left", padx=(6, 0))
|
||||
|
||||
self.papierkorb = ttk.Button(leiste, text="🗑 Löschen", state="disabled",
|
||||
command=self.angehakte_loeschen)
|
||||
self.papierkorb.pack(side="left", padx=(6, 0))
|
||||
# Kein Papierkorb mehr: im Journal wird nichts von Hand geloescht. Eine
|
||||
# Zeile aus einer PDF kaeme beim naechsten Einlesen ohnehin zurueck, eine
|
||||
# Zeile aus dem Excel-Altbestand waere fuer immer weg - samt Uebernachtung
|
||||
# im Amtsbericht (§ 146 Abs. 4 AO). Soll eine Buchung raus, wandert die PDF
|
||||
# aus dem Rechnungsordner; den Rest macht der Scan von selbst.
|
||||
|
||||
ttk.Label(leiste, text="Suche:").pack(side="left", padx=(20, 4))
|
||||
self.suchfeld = ttk.Entry(leiste, textvariable=self.suche, width=22)
|
||||
|
|
@ -175,7 +175,7 @@ class App(tk.Tk):
|
|||
self.blaetter.pack(fill="both", expand=True, padx=10, pady=(0, 6))
|
||||
self.monate = {}
|
||||
for m in range(1, 13):
|
||||
tab = MonatsTab(self.blaetter, m, bei_haken=self.papierkorb_auffrischen)
|
||||
tab = MonatsTab(self.blaetter, m)
|
||||
self.blaetter.add(tab, text=MONATE[m - 1])
|
||||
self.monate[m] = tab
|
||||
self.blaetter.select(min(date.today().month, 12) - 1)
|
||||
|
|
@ -262,7 +262,6 @@ class App(tk.Tk):
|
|||
|
||||
self.jahr_summe.setzen(summiere(sichtbar), sichtbar)
|
||||
self.jahr_wahl.config(values=self._jahre())
|
||||
self.papierkorb_auffrischen()
|
||||
self.ordner_anzeige.config(
|
||||
text=f"Rechnungen: {self.pdf_ordner}" if self.pdf_ordner
|
||||
else "kein Rechnungs-Ordner gewählt (Datei → Rechnungs-Ordner wählen…)")
|
||||
|
|
@ -588,71 +587,6 @@ class App(tk.Tk):
|
|||
"Nicht eingelesen",
|
||||
f"{len(fehler)} Datei(en) sind keine lesbare Rechnung:\n\n{namen}",
|
||||
parent=self)
|
||||
|
||||
# Im Journal wird NICHTS von Hand geaendert - weder angelegt noch bearbeitet.
|
||||
# Jede Zeile gehoert zu einer Rechnung aus dem Rechnungstool; wer hier Betrag
|
||||
# oder Nummer verstellt, meldet dem Amt etwas anderes, als auf dem Beleg
|
||||
# steht, und beim naechsten Einlesen kaeme die Aenderung ohnehin zurueck.
|
||||
# Stimmt eine Rechnung nicht, wird sie im Rechnungstool storniert oder
|
||||
# berichtigt. Loeschen bleibt moeglich (Entf / Papierkorb) - es entfernt nur
|
||||
# die Zeile aus dem Zwischenspeicher, die PDF bleibt liegen.
|
||||
def _markierte(self):
|
||||
return self.monate[self._monat].markierte()
|
||||
|
||||
def buchung_loeschen(self):
|
||||
b = self._markierte()
|
||||
if not b:
|
||||
return
|
||||
if not messagebox.askyesno(
|
||||
"Buchung löschen",
|
||||
f"Rechnung {b.voll_nummer} ({b.nachname}) aus dem Journal löschen?\n\n"
|
||||
"Die PDF-Datei bleibt erhalten – beim nächsten Einlesen "
|
||||
"taucht die Buchung wieder auf.", parent=self):
|
||||
return
|
||||
self.journal.loeschen(b.id)
|
||||
self.aktualisieren()
|
||||
self.melde(f"Buchung {b.voll_nummer} gelöscht")
|
||||
|
||||
# ---- Anhaken + Papierkorb ----------------------------------------------
|
||||
def _angehakte(self):
|
||||
"""Alle angehakten Buchungen – über alle Monate hinweg."""
|
||||
return [b for m in range(1, 13) for b in self.monate[m].angehakte()]
|
||||
|
||||
def papierkorb_auffrischen(self):
|
||||
anzahl = len(self._angehakte())
|
||||
self.papierkorb.config(
|
||||
text=f"🗑 Löschen ({anzahl})" if anzahl else "🗑 Löschen",
|
||||
state="normal" if anzahl else "disabled")
|
||||
|
||||
def angehakte_loeschen(self):
|
||||
angehakt = self._angehakte()
|
||||
if not angehakt:
|
||||
return
|
||||
|
||||
aus_pdf = [b for b in angehakt if b.quelle == "pdf"]
|
||||
namen = "\n".join(f"• {b.datum.strftime('%d.%m.%Y')} {b.voll_nummer} "
|
||||
f"{b.nachname or 'ohne Namen'}" for b in angehakt[:15])
|
||||
if len(angehakt) > 15:
|
||||
namen += f"\n… und {len(angehakt) - 15} weitere"
|
||||
hinweis = ""
|
||||
if aus_pdf:
|
||||
hinweis = (f"\n\n{len(aus_pdf)} davon stammen aus einer Rechnungs-PDF – die Dateien "
|
||||
"bleiben liegen und tauchen beim nächsten Einlesen wieder auf.")
|
||||
|
||||
if not messagebox.askyesno(
|
||||
"Angehakte Buchungen löschen",
|
||||
f"{len(angehakt)} Buchung(en) aus dem Journal löschen?\n\n{namen}{hinweis}",
|
||||
parent=self):
|
||||
return
|
||||
|
||||
for b in angehakt:
|
||||
self.journal.loeschen(b.id)
|
||||
for m in range(1, 13):
|
||||
self.monate[m].haken_loesen()
|
||||
self.aktualisieren()
|
||||
self.papierkorb_auffrischen()
|
||||
self.melde(f"{len(angehakt)} Buchung(en) gelöscht")
|
||||
|
||||
def satz_aendern(self):
|
||||
fenster = tk.Toplevel(self)
|
||||
fenster.title("Steuersatz")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue