Commit graph

9 commits

Author SHA1 Message Date
TheMockTv
1060a6421f Vorgangsnummer: eine Klammer um die ganze Kette
Bisher zeigte jeder Beleg nur auf seinen Vorgaenger (storno_zu, ersetzt,
storno_nummer). Ein zweites Programm musste sich die Kette daraus
zusammensuchen. Jetzt tragen ALLE Blaetter einer Kette dieselbe
Vorgangsnummer - die der ersten Rechnung. Gruppieren heisst dort: nach
"vorgang" sortieren, fertig. Eine normale Rechnung ist ihr eigener Vorgang.

Wichtig fuer den Fall "schon korrigierte Rechnung wird noch einmal
storniert": Storno und Berichtigung uebernehmen den VORGANG der alten
Rechnung, nicht deren Nummer - sonst zerfaellt die Kette in zwei.

Die Einzelbezuege bleiben zusaetzlich stehen, damit man die Reihenfolge
innerhalb der Kette lesen kann.

Neu pruef_kette.py (13 Pruefungen): spielt den schlimmsten Fall durch -
Rechnung, Storno, berichtigte Rechnung, Berichtigung der Anschrift, zweiter
Storno, zweite berichtigte Rechnung. Alle sechs landen unter einem
Schluessel, die Summe der Kette ergibt genau die letzte gueltige Rechnung
(27,30 €), und der Steuerrechner liest davon 5 Geldbelege - das
Berichtigungsblatt zaehlt nicht mit.

148 Pruefungen gruen (100 + 27 + 13 + 8) plus 7 Dialoge.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKvGkdNW1vKdnMPAM9Bp3X
2026-09-02 20:03:17 +02:00
TheMockTv
d67448c58f Funde der drei Agenten: zwei kaputte Dialoge, haengende Flags, scharfe Pruefstaende
REGRESSION aus der Modulaufteilung (Code-Review-Agent):
- einstellungen.py fehlten "berechnung" und "datetime". Menue > Leistungskatalog
  und > Rechnungsnummer stuerzten mit NameError ab und liessen ein leeres,
  modales Fenster stehen. Preise und Nummernkreis waren nicht mehr einstellbar.
  KEIN Pruefstand hat das gemerkt - keiner oeffnete je einen Dialog. Neu:
  pruef_dialoge.py oeffnet ALLE Dialoge und schliesst sie wieder.

HAENGENDE ZWISCHENSPEICHER (derselbe Agent, gemessen):
- "Zuruecksetzen" liess storno_stand/berichtigung_stand stehen. Danach gehoerten
  die Daten eines FREMDEN Gastes zum Storno der alten Rechnung, und die
  Berichtigung schrieb ein Blatt mit Nummer A im Kenndatensatz und Nummer B auf
  dem Blatt. reset_formular fragt jetzt nach und verwirft sauber.
- _neue_nummer_vorschlagen fasst die Nummer nicht mehr an, solange ein Vorgang
  laeuft (traf auch dlg_nummer).
- Fenster schliessen mit offenem Storno fragt jetzt nach (WM_DELETE_WINDOW).
- _storno_verwerfen bricht ab, wenn das PDF nicht geloescht werden kann, statt
  den Zaehler trotzdem zurueckzudrehen.
- Der Storno prueft die Kundenangaben und fragt, wenn die alte Rechnung sie
  nicht hergibt.
- Zaehler nicht speicherbar -> sichtbare Meldung statt Traceback ins Nichts.
- storno.py: v1-Rueckfall nimmt den ersten Satz OHNE extra_blatt.
- EINE Quelle fuer die naechste Nummer: _neue_nummer_vorschlagen benutzt jetzt
  naechste_freie_nummer, der Jahreswechsel steht nur noch dort. Vorher schlug
  das Formular 2026-001 vor, waehrend der Storno-Weg 2025-088 nahm.

PRUEFSTAENDE (Audit-Agent: 16 von 27 eingebauten Fehlern blieben unbemerkt):
- Neu pruef_kernregeln.py (27 Pruefungen) fuer die zwei Regeln, um die es geht:
  Nummer von HAND auf eine vergebene setzen, Zaehler hinter dem Ordner,
  Jahreswechsel, Zaehler nur vorwaerts, Storno ueber den DIALOGKNOPF statt der
  internen Methode, zweite Berichtigung am selben Tag. Der Bestand wird ueber
  SHA256 verglichen - "Datei ist noch da" heisst nicht "unveraendert".
- Der Text des Storno-PDFs wird gelesen: Positionszeile negativ, nicht nur der
  Summenblock.
- Tautologien raus: Selbstvergleich beim storno_datum, all() ueber eine leere
  Liste, "nicht" in einem deutschen Text.
- Unangemeldeter Dialog laesst den Lauf scheitern, statt still "Nein" zu sagen.
- pruef_nummern.py: .PDF gross geschrieben, Rechnung_*.txt, echte Praefix-Falle.
- Gegenprobe: sechs Mutationen eingebaut, die vorher gruen blieben - alle sechs
  werden jetzt rot.

RECHT (Gegenpruefungs-Agent): Zitate praezisiert. § 146 Abs. 4 AO verbietet nur
Aenderungen, bei denen der urspruengliche Inhalt nicht mehr feststellbar ist -
ein protokollierter Storno-Vermerk waere erlaubt, wir verzichten trotzdem
bewusst darauf. Der § 14c-Hinweis bleibt, gilt aber gegenueber Endverbrauchern
nicht (EuGH C-378/21, BMF v. 27.02.2024) - er zielt auf Firmengaeste.

142 Pruefungen gruen (100 + 27 + 8 + 7).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKvGkdNW1vKdnMPAM9Bp3X
2026-09-02 19:57:31 +02:00
TheMockTv
d3962ec8d1 Berichtigen: zweiter Knopf im Storno-Popup, alles haengt an einem Flag
Fuer Rechnungen, bei denen nur die Kundenangaben falsch sind - falsche
Betraege bleiben der Storno-Weg.

- Kein eigener Dialog: das Storno-Popup hat jetzt zwei Knoepfe. "Nur
  berichtigen" laedt die Rechnung ins Formular, sperrt die Nummer und setzt
  ein Flag; "PDF erstellen" schreibt daraus das berichtigte Blatt.
- Die Rechnung behaelt Nummer, Datum und Betraege; dazu kommt "Berichtigt am".
  Der Zaehler bleibt stehen - das Blatt verbraucht keine Nummer.
- Ueberschrift "Berichtigte Rechnung", darunter die vollstaendige Rechnung,
  darunter der Bezug nach § 31 Abs. 5 UStDV und der Satz, dass es KEINE
  zusaetzliche Leistung und keine zweite Rechnung ist. Ohne den kann ein
  zweites Blatt mit ausgewiesener USt die Steuer nach § 14c UStG ein zweites
  Mal ausloesen.
- Kenndaten des Blattes tragen Nullen und "art": "berichtigung". Damit zaehlt
  ein Programm, das die Art nicht kennt, 0,00 € statt den Umsatz doppelt; der
  Steuerrechner ueberspringt es ganz (einnahmen.py).
- Dateiname "Berichtigte Rechnung_JJJJ-MM-TT_<Nummer>.pdf".

pruef_storno.py: 100 Pruefungen gruen, darunter der ganze Berichtigungsweg
inklusive Text auf dem Blatt und Gegenprobe mit dem Steuerrechner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKvGkdNW1vKdnMPAM9Bp3X
2026-09-02 19:32:24 +02:00
TheMockTv
790ac4c0f6 Storno statt Ueberschreiben: Rechnungskette 005 -> Storno -> Korrektur
Eine ausgestellte Rechnung darf nicht geaendert und nicht geloescht werden
(§ 146 Abs. 4 AO), und jede Nummer gibt es nur einmal (§ 14 Abs. 4 Nr. 4
UStG). Korrigiert wird deshalb ueber ein eigenes Dokument mit neuer Nummer,
das sich auf die alte bezieht (§ 31 Abs. 5 UStDV).

- Knopf "Rechnung stornieren": alte Nummer waehlen, Programm liest deren PDF
  und schreibt eine Stornorechnung mit eigener neuer Nummer, Betraege
  negativ, mit Bezug auf Nummer und Datum der alten Rechnung.
- Danach steht das Formular auf der naechsten Nummer, gefuellt aus der alten
  Rechnung; die Nummer ist gesperrt. "PDF erstellen" fragt noch einmal nach
  und legt bei Nein das Storno-PDF wieder weg - dann bleibt allein das
  Original stehen.
- Die alte Rechnung wird nie angefasst.
- Metadaten v3: art / storno_zu / ersetzt / storno_nummer, dazu Anschrift und
  Positionen, damit eine Rechnung wieder ins Formular geladen werden kann.
  Alle Felder aus v1/v2 bleiben unveraendert - daran haengt das Steuerjournal.
- Zaehler laeuft nur noch vorwaerts; eine vergebene Nummer wird nicht mehr
  ueberschrieben, sondern die naechste freie angeboten.
- Combobox im Storno-Dialog blieb leer: die StringVar hing nur an einer
  lokalen Variable und wurde weggeraeumt. Jetzt ohne textvariable.

Prueflauf (pruef_storno.py, 36 Pruefungen gruen): echte PDFs in einem
Wegwerf-Ordner, danach liest der Steuerrechner den Ordner - 001 + Storno +
Korrektur ergeben genau die berichtigte Rechnung, kein Beleg unsicher.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKvGkdNW1vKdnMPAM9Bp3X
2026-09-02 19:06:45 +02:00
TheMockTv
a0cfc31ae6 Kenndaten-Metadaten v2: USt-Aufteilung je Satz
Der Steuerrechner braucht Brutto->Netto je Steuersatz; auf einer Rechnung
stecken 7 % (Uebernachtung) und 19 % (Waesche, Gas, Rad) gemischt drin, und
die Aufteilung stand bisher nur im Fliesstext.

Neu in /Subject: netto_gesamt, ust_gesamt, ust_bloecke[{satz,netto,ust,brutto}].
Alle Felder der Version 1 bleiben unveraendert - am zwischensumme/steuer_satz/
steuer_betrag haengt der Import des Steuerjournals.

Verifiziert an einer gemischten Testrechnung (7 % + 19 %): Summe der Bloecke
= Zwischensumme = netto_gesamt + ust_gesamt; Steuerjournal liest die v2-PDF
unveraendert ein.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TxFbNUnzkEk7FRFcZQoepm
2026-08-01 12:33:53 +02:00
TheMockTv
b5799a60a1 Amt-Blatt strikt vom Kundenblatt trennen
Auf dem Blatt fuers Amt taucht die Beherbergungssteuer nirgends mehr auf - auch
nicht versteckt im Gesamtbetrag (der zeigt jetzt die Summe OHNE die Steuer, also
genau die Bemessungsgrundlage). Die Zwischensumme entfaellt dort, sie waere
betragsgleich. Ebenso raus: Bankverbindung und Steuernummer im Fuss, und das Wort
"Beherbergungssteuer" in der Ueberschrift.

Die Kundenseite bleibt vollstaendig: Steuer ausgewiesen, im Gesamtbetrag enthalten,
Bankverbindung im Fuss - das ist die Rechnung, die der Gast bezahlt.

Damit Kopf und Fuss die Seiten unterscheiden koennen, wird das PDF zweimal gebaut:
der erste Lauf ermittelt nur, auf welcher Seite das Amt-Blatt beginnt. Auf "Seite 2
ist das Amt" zu wetten waere falsch, sobald die Kundenrechnung ueber eine Seite
laeuft - dann stuende die Bankverbindung auf dem Amt-Blatt und fehlte beim Kunden.
2026-07-13 21:06:08 +02:00
TheMockTv
5388203e56 Amtsblatt: Beherbergungssteuer nicht mehr ausweisen
Auf Seite 2 (Kopie fuers Amt) stehen nur noch die Umsatzsteuersaetze,
die Zwischensumme als Bemessungsgrundlage und der Gesamtbetrag. Die Zeile
"zzgl. Beherbergungssteuer" und der Satzungs-Hinweis entfallen dort - das
Amt rechnet die Steuer selbst aus der Zwischensumme.

Die Kundenseite bleibt unveraendert, und die Kenndaten in den PDF-Metadaten
(steuer_satz, steuer_betrag) bleiben erhalten - daran haengt das Steuerjournal.
2026-07-13 20:47:04 +02:00
TheMockTv
0c83f9d821 Vor- und Nachname getrennt + Kenndaten in die PDF-Metadaten
Bisher gab es nur ein Feld "Name / Firma". Stand in der Anrede etwas,
war die Anrede die erste Zeile des Adressblocks - das Steuerjournal hat
sie als Namen gelesen.

- Kundenblock hat jetzt "Vorname (optional)" und "Nachname / Firma".
  Auf der Rechnung stehen beide wie gewohnt in einer Zeile.
- Die Kenndaten der Rechnung (Nummer, Datum, Nachname, Naechte,
  Zwischensumme, Steuersatz und -betrag) stehen zusaetzlich als JSON in
  den PDF-Metadaten. Das Steuerjournal liest sie von dort und muss
  nichts mehr aus dem Fliesstext raten. Der Ausdruck aendert sich nicht.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:45:53 +02:00
TheMockTv
dc170a9d9c Rechnungstool Campinghof - Rechnungen als PDF statt Excel-Vorlage
Desktop-Programm (Python/Tkinter): Kundendaten + Leistungen eingeben,
druckfertige PDF-Rechnung im Briefkopf des Betriebs. Optionale
Beherbergungssteuer wird eigen ausgewiesen und bekommt ein zweites
Blatt fuers Amt.

Firmendaten, Preise und Steuersaetze stehen in der config.json neben
dem Programm (nicht im Repo) und werden im Menue "Einstellungen"
gepflegt. Im Code stehen nur Platzhalter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:18:38 +02:00