Commit graph

10 commits

Author SHA1 Message Date
TheMockTv
9d7aa1eec7 Darstellung: das Programm hatte ueberhaupt kein Theme
Sein Befund
  "und beim steuertool fehlt das theam in genze oder wird nicht durch die
   automatik gesetzt"
  "nur die einstellunden hilfe leiste die ist noch hell und der icon und
   titel leiste auch"

  Er hatte recht, und zwar wortwoertlich: dieses Programm lief im
  Tk-Standard, mit dreimal fest eingetragenem foreground="black". Es gab hier
  gar keine theme.py.

Gebaut
  theme.py aus dem Rechnungstool uebernommen und dabei von config.py geloest
  - eine Datei, die in BEIDEN Programmen liegt, darf nichts aus einem der
  beiden importieren. Beim ersten Uebernehmen flog sie genau daran beim
  Import auseinander.

  Die Einstellungen liegen hier in der Journal-Tabelle, nicht in einer
  config.json. _einstellungen() ist die Bruecke: etwas mit .get() und []=,
  wie hinweis.py und theme.py es erwarten.

  Menueleiste aus menueleiste.py statt tk.Menu - ein natives Menue laesst
  sich unter Windows nicht einfaerben, das war der letzte helle Rest.
  Treeview-Stil in theme.py ergaenzt (ttk zeichnet Listen nicht ueber den
  Grundstil), Reiter schmaler, damit alle zwoelf Monatsnamen lesbar bleiben.
  Die Summenleisten in gui_monat.py holen ihre Farben jetzt vom Fenster statt
  sie fest zu tragen - sie waren ein weisser Block unten im dunklen Bild.

  Logo und Fenstersymbol werden fuer die dunkle Darstellung aufgehellt.

⚠️ Altfehler behoben: die Meldung des Rechnungstools stand nie
  pruef_wache lief mal gruen und mal rot - je nachdem, wann er hinsah. Das
  war kein Wackler im Pruefstand, sondern sein Symptom: meldet das
  Rechnungstool eine neue Rechnung, laeuft sofort das Einlesen an, und dessen
  Ergebnis landete in derselben Zeile. Der Benutzer sah NIE, dass etwas
  hereingekommen war. melde() kennt jetzt einen Vorrang in Sekunden; die
  Meldung des Rechnungstools bekommt sechs. Dreimal hintereinander stabil
  gruen.

  Ein wackelnder Pruefstand ist keine Nebensache, die man wegdrueckt.

AUFGABE_STEUERSAETZE_DYNAMISCH.md
  Seine naechste Ansage notiert: die festen Saetze sollen raus, dynamisch per
  Tabelle wie im Rechnungstool. Mit dem, worauf dabei zu achten ist - ein
  Satz gilt ab einem DATUM, und die Saetze bereits erfasster Buchungen
  bleiben stehen (§ 147 AO).

Fassung 1.9.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
2026-09-07 00:34:38 +02:00
TheMockTv
379afbd9c1 Amtsbericht: Spalte "Art" mit R/S/B und Legende unter der Tabelle
Sein Einwand: "du musst die markieren als rechnung und storno oder
berichtigung, und das kannst einfach mit buchstaben machen: r fuer
rechnung, s fuer storno, b fuer berichtigung. am footer kannst eine
erklaerung fuer die buchstaben machen."

Er hat recht - ohne die Marke muss man aus der Begruendung raten, was fuer
ein Beleg die Zeile ueberhaupt ist. Mit dem Buchstaben liest sich die
Kette von selbst:

  2026-900  R  storniert mit 2026-901
  2026-901  S  neue Rechnung 2026-902
  2026-902  B  Neuausstellung
  2026-911  S  abgerechnet mit 2026-905     (Doppelungsfall)

Unter der Tabelle steht die Legende: "R = Rechnung, S = Stornorechnung,
B = berichtigte Rechnung (Neuausstellung nach einem Storno)". Bewusst
direkt unter die Tabelle und nicht in die Fusszeile - wer eine einzelne
Zeile prueft, hat sie dann vor Augen und muss nicht blaettern.

Dazu "neu abgerechnet mit" auf "abgerechnet mit" gekuerzt: mit dem S
davor ist das "neu" ueberfluessig, und die Zeile bricht nicht mehr um.
Spaltenbreiten neu verteilt (18/18/9/42/Rest/12/18/9/18 mm).

Erklaerungs-PDF um die Art-Spalte ergaenzt. Pruefkette gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bEsoFUk16DfnNA7MjY36H
2026-09-04 02:29:48 +02:00
TheMockTv
b2d933cb7c Amtsbericht: die Kette zeigt vorwaerts - Storno nennt die neue Rechnung
Sein Fund: "an der storno verweist du auf die alte rechnung, muss aber
lauten neu zu und neue rechnungs nummer. heisst kette ist so: rechnung
storniert weist auf die storno nummer, storno verweist auf neue rechnung.
wer soll denn sonst wissen wo er suchen muss."

Er hat recht: eine Zeile, die nur zurueckzeigt, laesst den Leser stehen.
Jetzt sagt jede Zeile, wo es WEITERGEHT:

  Rechnung   -> "storniert mit 2026-901"
  Storno     -> "neue Rechnung 2026-902"      (Fall A)
             -> "neu abgerechnet mit 2026-343" (Fall B, Doppelung)
             -> "Storno zu 2026-900"           (Fall C / alte Belege ohne Angabe)
  neue R.    -> "Neuausstellung"

Dafuer wandert die Folgenummer aus den PDF-Kenndaten bis ins Journal:
Buchung.folge_nummer + folge_art (neu | vorhanden | ""), gelesen aus
korrektur_nummer/ersatz_vorhanden/nur_storno, zwei neue DB-Spalten, alte
Journale bauen sich wie gehabt selbst um.

An seinen ECHTEN Belegen geprueft: Storno 2026-455 -> folge 2026-369
(vorhanden), 2026-456 -> 2026-343 (vorhanden). Die Angabe steht in den
Kenndaten schon drin, sie wurde bisher nur nicht gelesen.

Fenster und Blatt zeigen dieselben Worte. Erklaerungs-PDF um eine
Kettentabelle ergaenzt. Pruefkette gruen (storno_verrechnet inkl.
September-Blatt, doppelte_leistung, nur_storno).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bEsoFUk16DfnNA7MjY36H
2026-09-04 02:19:49 +02:00
TheMockTv
87d92d15b6 Amtsbericht: eigene Spalte "Grund", und die stornierte Zeile nennt ihren Storno
Zwei Ansagen von ihm, beide am selben Blatt:

1. "weil die nummer hast nur auf der storno selber aber nicht am
   stornierten nummer um die es geht" - die aufgehobene Rechnung stand
   nur als "storniert" da. Jetzt steht dort "storniert mit 2026-901".
   Damit ist das Paar in BEIDE Richtungen lesbar, und das zaehlt vor
   allem dann, wenn der Storno in einem anderen Monat liegt und auf
   diesem Blatt gar nicht auftaucht.

2. "mach eine neue spalte mit grund oder so was" - der Vermerk stand als
   zweite Zeile unter der Rechnungsnummer. Jetzt ist es eine eigene
   Spalte "Grund" zwischen Rechnung und Name, eine Zeile je Buchung.
   Feste Breiten neu verteilt (20/20/34 mm + Rest fuer den Namen), damit
   nichts umbricht.

Dafuer neu: modell.aufhebungen() gibt {id der Rechnung: Storno-Buchung}
statt nur der ids - die Anzeige will auch sagen, WOMIT storniert wurde,
nicht nur DASS. aufgehobene() bleibt als duenne Huelle darueber, damit
zeig_stornos und doppelte_nummern unveraendert weiterlaufen.

Fenster und Blatt zeigen wieder dieselben Worte.

pruef_storno_verrechnet prueft beide Richtungen mit, auch ueber die
Monatsgrenze ("storniert mit 2026-911" im August, der Storno selbst steht
im September). Angesehen: Tabelle als Bild gerendert, alles einzeilig,
auch mit langem Namen. doppelte und berichtigung gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bEsoFUk16DfnNA7MjY36H
2026-09-04 01:38:36 +02:00
TheMockTv
13fe1d97f9 Storno wird wieder VERRECHNET statt weggelassen - seine Entscheidung
Heute Nacht war es andersherum gebaut (v1.6.3): Storno und aufgehobene
Rechnung zaehlten gar nicht mehr mit, die Berichtigung landete im Monat
der Rechnung. Sauber nach § 7 Abs. 5 der Satzung (angemeldet wird die im
Kalendermonat VEREINNAHMTE Steuer), aber nicht das, was er will.

Sein Wort:

    "ich wuerde das wie beim alten lassen, nicht das er der Stadt zu
     wenig gibt"
    "ob er im Sep dann weniger gemacht hat ist doch egal, weil im August
     hat er ja mehr - also gleicht es sich aus, es ist nur ein
     Time-Problem. Aber um was es mir geht: die Steuern sind sauber."

Und er hat recht: der Unterschied ist NUR der Monat, nie das Jahr, und
die Richtung stimmt - zu viel zuerst ist beim Amt nie ein Problem, zu
wenig schon.

Also zurueckgebaut:
- modell.zaehlbar() ist wieder raus, summiere() summiert alle Zeilen mit
  ihrem Vorzeichen. Die Begruendung samt Satzungs-Fundstelle steht im
  Docstring, damit es niemand "repariert" - in EINEM Monat sieht eine
  verrechnete Doppelung naemlich nach einem Fehler aus.
- Amtsbericht zeigt Rechnung und Storno wieder beide, jede in ihrem Monat
  und mit ihrem Vorzeichen. Damit erklaert sich die Meldung von selbst.
- aufgehobene() bleibt, wird aber nur noch fuer die Spalte "Art" und fuer
  die Dubletten-Meldung gebraucht, nicht mehr fuers Rechnen.

Nicht zurueckgebaut (das war eine eigene Ansage): Storno und aufgehobene
Rechnung werden NICHT mehr ausgegraut, sie stehen normal da und sind ueber
die Spalte "Art" gekennzeichnet.

pruef_storno_rechnet_nicht.py ist durch pruef_storno_verrechnet.py
ersetzt: derselbe Aufbau (Fake-Rechnungen in einer echten SQLite, auch
der Fall ueber die Monatsgrenze), aber es haelt jetzt das gewollte
Verhalten fest - August 9 Naechte/117,00, September -4/-52,00, Jahr
5/65,00. Restliche Kette (storno_journal, doppelte, berichtigung,
einzelinstanz, wache) gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bEsoFUk16DfnNA7MjY36H
2026-09-04 01:09:08 +02:00
TheMockTv
448afb3c62 Storno wird nicht mehr mitgerechnet, und nicht mehr ausgegraut
Seine Ansage: "wenn es als storno getagt ist darf der rechner das nicht
mehr rechnen weil es minus ist, die rechnung gibt es nicht mehr" - und
"ausgrauen wuerde ich es nicht, ich wuerde es nur als storno taggen".

Bisher standen Rechnung (+) und Storno (-) beide in der Summe und hoben
sich gegenseitig auf. Naechte, Entgelt und Steuer kamen dabei zwar
richtig heraus, aber:

* die Zahl "Rechnungen" war je Stornofall um ZWEI zu hoch - im Fenster
  wie im Amtsbericht, und
* lag der Storno in einem anderen MONAT als seine Rechnung, stand in
  jedem der beiden Monate die Haelfte der Verrechnung allein da: der
  August meldete eine Uebernachtung zu viel, der September eine zu wenig.
  Erst im Jahr hob sich das wieder auf.

Neu ist modell.zaehlbar(): Storno und die von ihm aufgehobene Rechnung
zaehlen gar nicht mehr mit. summiere() geht durch diesen Filter, das Set
der aufgehobenen Rechnungen wird ueber das ganze JAHR bestimmt und an
Monatsleiste, Jahresleiste und Amtsbericht durchgereicht.

Der Amtsbericht zeigt die beiden Zeilen auch nicht mehr an - die
Rechnung gibt es nicht mehr, und Minuswerte auf dem Blatt fuers Amt
waeren ohne die Gegenzeile nicht erklaerbar.

Im Fenster bleibt alles sichtbar, nur nicht mehr grau: der Hinweis
steht in der Spalte "Art" (Storno zu .../storniert/Neuausstellung).

Pruefstand pruef_storno_rechnet_nicht.py (neu, 22 Pruefungen) legt die
Faelle als Fake-Rechnungen in einer echten SQLite an - auch den Fall
ueber die Monatsgrenze, den echte Daten nicht hergeben - und prueft
Rechenkern, Amtsbericht-PDF und das echte Fenster. Die uebrige
Pruefkette (storno_journal, doppelte, berichtigung, einzelinstanz,
wache) laeuft unveraendert gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bEsoFUk16DfnNA7MjY36H
2026-09-04 00:10:19 +02:00
TheMockTv
0218abaebe 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
2026-09-03 22:43:23 +02:00
TheMockTv
59d2db75af Storno und Berichtigung kommen an, gemeinsames Nummernbuch, kein Bearbeiten mehr
Storno: das Journal zaehlte die Uebernachtungen der aufgehobenen Rechnung
weiter mit (4 - 0 + 3 = 7 statt 3 gemeldeter Naechte). Die Betraege kuerzten
sich, die Naechte nicht. Der Storno traegt jetzt die negative Zahl, und das
Journal kennt Art, Bezug und Datum des Belegs (vier neue Spalten, alte
Journale bauen sich beim Oeffnen um).

Berichtigung: das Blatt wurde nur uebersprungen. Der berichtigte NAME kommt
jetzt in der Buchung an - im Amtsbericht stand sonst weiter der falsche.
Angewandt wird erst am Ende des Scans, das Blatt kann vor seiner Rechnung im
Ordner liegen.

Doppelte Nummern: eine stornierte Rechnung ist keine offene mehr und faellt aus
der Meldung. Zugeordnet wird ueber Nummer + Datum + Empfaenger, nicht ueber die
Nummer allein - bei einer doppelt vergebenen Nummer waere die kein eindeutiger
Bezug, und genau den verlangt § 31 Abs. 5 UStDV. Die Texte nennen jetzt den
Weg: eine der beiden im Rechnungstool stornieren und mit freier Nummer neu
ausstellen (§ 14 Abs. 4 Nr. 4 UStG - jede Nummer nur einmal).

Neue Spalte "Art": Storno zu ..., storniert, Neuausstellung. Aufgehobene Zeilen
stehen grau - geloescht wird nichts.

Gemeinsames Nummernbuch (gemeinsam.py, ordnerwahl.py - in beiden Programmen
dieselbe Datei): eine SQLite in einem Ordner, den beide kennen. Das Journal
traegt seine Nummern ein, auch die aus der Excel-Mappe ohne PDF - genau die
kannte das Rechnungstool nicht und vergab sie ein zweites Mal. Beim ersten
Start wird nach dem Ordner gefragt (auswaehlen, OK, Sicherheitsfrage, bei Nein
zurueck ins Feld); wer ihn nicht hat, kommt mit "Spaeter einrichten" weiter.

Kein Doppelklick zum Bearbeiten mehr (gui_dialoge.py geloescht): wer hier Betrag
oder Nummer verstellt, meldet dem Amt etwas anderes, als auf dem Beleg steht.
Loeschen bleibt.

--test / CAMPINGHOF_TEST=1 unterdrueckt den Erststart-Dialog (Pruefstaende).

Pruefstaende: pruef_storno_journal.py (neu, ueber BEIDE Programme: Storno,
Berichtigung, doppelte Nummer aufloesen), pruef_doppelte, pruef_berichtigung,
pruef_einzelinstanz - alle gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYeAfLtccFrbU3MTj1MMTx
2026-09-03 20:38:38 +02:00
TheMockTv
894bc81c46 Doppelte Rechnungsnummern zeigen, nur ein Fenster, keine Handbuchungen
Doppelte Rechnungsnummern werden ANGEZEIGT statt still mitgeschleppt: rote
Zeile mit Warnzeichen, markierter Monatsreiter, rote Zeile unter der
Jahressumme und eine Liste aller Belege mit Dateinamen. Gerechnet wird ueber
das ganze Jahr - liegt die zweite Rechnung im naechsten Monat, sieht kein
Monat fuer sich eine Dublette, das Amt bekommt sie trotzdem doppelt. Die
Betraege bleiben in allen Summen und im Amtsbericht; gemeldet wird der Fund,
korrigiert wird nichts von allein.

Vorgeschichte: bis v1.2 war die Rechnungsnummer der Schluessel der Tabelle -
die zweite Rechnung ueberschrieb die erste still und fehlte im Amtsbericht.
v1.3 hat den Schluessel auf die PDF-Datei umgestellt, seitdem bleiben beide
Zeilen stehen. Erst jetzt sieht man den Fall auch.

Einzelinstanz aus dem Steuerrechner uebernommen (nur Mutex- und PID-Name
geaendert): zwei Fenster lesen denselben Rechnungsordner in dieselbe
journal.sqlite3 - was das eine loescht, steht im anderen noch da, und wer
dort "PDF fuers Amt" drueckt, meldet einen Stand, den es nicht mehr gibt.
Die Sperre greift vor ablage.daten_ordner() und nur beim echten Start.

"Neue Buchung" ist raus: jede Zeile gehoert zu einer Rechnung aus dem
Rechnungstool. Wer eine Buchung braucht, schreibt die Rechnung. Bestehende
Zeilen lassen sich weiter bearbeiten.

Pruefstaende: pruef_doppelte.py (27 Pruefungen am echten Fenster),
pruef_einzelinstanz.py (echte Prozesse). Beide gruen, dazu Abnahme mit den
Augen an Hauptfenster, Liste und Bearbeiten-Dialog.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYeAfLtccFrbU3MTj1MMTx
2026-09-03 19:47:44 +02:00
TheMockTv
80967de26f Beherbergungssteuer: Steuerjournal aus den Rechnungs-PDFs
Ersetzt die Excel-Mappe des Campinghofs. Die Rechnungs-PDFs des
Rechnungstools sind die Quelle; SQLite ist nur Cache, Excel nur noch
Import des Altbestands. Bericht fuers Amt als PDF im Briefkopf der
Rechnungen (Firmendaten aus der config.json des Rechnungstools).

- pdf_parser: liest Datum, Nummer, Name, Naechte, Zwischensumme, Satz
- db: Journal + Scan mit Cache (Pfad/mtime/Groesse)
- xlsx_io: Import der alten Tabelle, vereinheitlicht Rechnungsnummern
- bericht_pdf: Monats- und Jahresbericht (reportlab)
- GUI: Monatsreiter, Suche, Anhaken + Papierkorb, Kennzahlen-Leiste

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