Commit graph

13 commits

Author SHA1 Message Date
TheMockTv
c230a27cff Angebote werden nicht gebucht - doppelt gesichert
Das Rechnungstool schreibt jetzt unverbindliche Angebote (frueher Proforma).
Uebersprungen werden sie zuerst ueber die Kenndaten (art=angebot, die
ueberleben auch ein Umbenennen) und, falls die einmal fehlen, ueber Dateiname
und Unterordner ('Angebot_...' bzw. 'Angebote/') - sein Vorschlag: 'kann er ja
am dateinamen festmachen, steht ja dann rechnung oder angebot'. Eine echte
Rechnung wird davon nicht erfasst, das prueft pruef_angebot.py mit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYeAfLtccFrbU3MTj1MMTx
2026-09-03 21:41:14 +02:00
TheMockTv
dbe95e1ec6 Mini-API, Push vom Rechnungstool, Proforma wird nicht gebucht
Das Journal macht beim Start einen winzigen Server auf 127.0.0.1 auf und traegt
Port und PID in die gemeinsame SQLite ein (Tabelle "laeuft"). Das Rechnungstool
sieht daran, dass jemand zuhoert, und klopft nach jeder Rechnung an: "schau in
die sqlite". Dann wird sofort nachgelesen, statt bis zum naechsten Durchgang zu
warten. Faellt die API aus, findet die Wache die Meldung trotzdem - ein os.stat
auf die eine Datei, alle zwei Sekunden und sofort beim Zurueckklicken.

Die Proforma-Rechnung wird NICHT gebucht: keine_buchung() kennt jetzt
Berichtigung und Proforma. Der Scan fragt wieder keine_buchung() - seit dem
Berichtigungs-Umbau tat er das nicht mehr, und die Proforma waere als Buchung
im Journal gelandet (der Pruefstand hat es gefunden).

Pruefstand pruef_wache.py: 31 Pruefungen ueber BEIDE Programme - Anmeldung mit
PID, ping ("hallo, bin noch da"), genau eine Datei im gemeinsamen Ordner, Push
nach Rechnung und nach Storno, Einlesen samt Anzeige, Rueckfallebene ohne API,
tote PID wird weggeraeumt, kein Melden an ein geschlossenes Journal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYeAfLtccFrbU3MTj1MMTx
2026-09-03 21:24:12 +02:00
TheMockTv
31bb0c600b Neue Rechnungen tauchen von selbst auf - das Journal hoert auf die gemeinsame SQLite
Stehen beide Programme offen und wird im Rechnungstool eine Rechnung
geschrieben, erscheint sie hier ohne Zutun. Das Journal traegt sich dafuer beim
Start mit seiner PID in der gemeinsamen SQLite ein (Tabelle "laeuft") und traegt
sich beim Schliessen wieder aus; das Rechnungstool sieht daran, dass jemand
zuhoert, und legt eine Zeile in die Tabelle "nachrichten".

Nachgesehen wird nur dort - erst ein os.stat auf die eine Datei, und nur wenn
sich etwas geruehrt hat, wird sie geoeffnet. Kein Absuchen des
Rechnungsordners, kein Server, kein Port. Beim Zurueckklicken ins Fenster wird
sofort nachgesehen statt zwei Sekunden zu warten.

Die Wache faengt jeden Fehler ab und stirbt nie - ein Netzlaufwerk, das kurz
weg ist, darf das Fenster nicht lahmlegen.

⚠ Ein Denkfehler daraus gleich behoben: der erste Blick nach dem Start merkt
sich den Stand AUCH dann, wenn es die Datei noch gar nicht gibt. Sonst galt die
erste Meldung danach als "schon gesehen" und wurde verschluckt.

Pruefstand pruef_wache.py (faehrt BEIDE Programme): 23 Pruefungen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYeAfLtccFrbU3MTj1MMTx
2026-09-03 21:02:24 +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
9e564466c7 Der Fund der Dubletten steht auch im Log
Der Amtsbericht wird aus diesen Zeilen gebaut - es muss spaeter nachvollziehbar
sein, wann eine doppelt vergebene Nummer zuerst dastand. Eine Zeile je
Auffrischung, mit Jahr, Anzahl und den Nummern.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYeAfLtccFrbU3MTj1MMTx
2026-09-03 19:51:14 +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
de71fce64f Eigener Datenordner (ablage.py)
Als EXE lagen Journal, Berichte und Log bisher direkt neben der EXE. Damit
laesst sich das Programm nicht in einen Ordner legen, in den Windows nicht
schreiben laesst - und beim Sichern uebersieht man leicht die Haelfte.

Jetzt: beim ersten Start ein Ordner "Daten" neben der EXE, alles darin. Geht
das nicht, weicht es nach LOCALAPPDATA aus. Was schon neben der EXE lag, zieht
mit um - sonst waere das Journal ploetzlich leer.

Ist der gemerkte Ordner nicht erreichbar (Stick ab, NAS aus), wird NICHTS
geaendert und der Merkzettel bleibt stehen: morgen steckt der Stick wieder
dran und alles ist da, wo es war.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKvGkdNW1vKdnMPAM9Bp3X
2026-09-02 21:44:51 +02:00
TheMockTv
65eec9937a Storno und Berichtigung: das Journal darf die Buchung nicht verlieren
Das Rechnungstool schreibt seit heute auch Storno- und Berichtigungsblaetter in
denselben Ordner. Zwei Fehler, die daraus entstanden waeren - beide still:

1. Ein Berichtigungsblatt (§ 31 Abs. 5 UStDV) traegt die Nummer DER RECHNUNG,
   die es berichtigt, und lauter Nullen. Unter dem alten Schluessel
   (jahr, rechnungsnummer) hat es die echte Buchung ueberschrieben - im
   Amtsbericht fehlte die Uebernachtung dann. Wird jetzt uebersprungen
   (pdf_parser.keine_buchung), in beiden Scannern.
2. Der Schluessel ist jetzt die DATEI. Zwei Rechnungen mit derselben Nummer -
   der Altbestand, bevor das Rechnungstool eine Sperre bekam - ueberschrieben
   sich sonst gegenseitig. Bestehende Journale werden beim Oeffnen einmalig
   umgebaut, in einer Transaktion, mit Rueckfall auf den alten Stand.
   Buchungen von Hand (kein PDF-Pfad) bleiben davon unberuehrt.

Stornos zaehlen weiter mit - sie sind negativ und heben die Uebernachtung im
Bericht genau so auf, wie es sein soll.

pruef_berichtigung.py (neu): schreibt mit dem echten Renderer des
Rechnungstools eine Rechnung, ein Berichtigungsblatt dazu und zwei Rechnungen
mit derselben Nummer, liest sie ein und prueft das Ergebnis in der Tabelle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKvGkdNW1vKdnMPAM9Bp3X
2026-09-02 21:39:41 +02:00
TheMockTv
700ddc3bd1 Fusszeile raus - sie ragte in die Tabelle
Der Briefkopf-Fuss (Bank, Steuernummer, Inhaber, Homepage, E-Mail, Telefon) wurde
oberhalb des unteren Seitenrands gezeichnet und lief damit in den Textbereich. Auf
vollen Seiten stand er quer ueber der letzten Tabellenzeile. Die Kontaktdaten waren
zudem Platzhalter (example.de).

Es bleibt die Seitenzahl, bewusst unterhalb von MARGIN_BOT.
2026-07-13 20:59:20 +02:00
TheMockTv
7c66a669b4 Amtsbericht ohne Bankverbindung und Steuernummer
Die Fusszeile druckte Bankname, IBAN, BIC und Steuernummer. In einer Meldung
ans Amt haben die nichts verloren - es zieht nichts ein und ueberweist nichts.
Es bleiben Inhaber (wer meldet) und die Kontaktdaten fuer Rueckfragen; leere
Felder werden uebersprungen. Auf der Rechnung bleibt alles unveraendert.
2026-07-13 20:47:04 +02:00
TheMockTv
6a8cb0849f Nachname aus den PDF-Metadaten, Anrede nicht mehr als Name lesen
Der Parser nahm die erste Zeile unter "Rechnung an:" als Namen. Steht im
Rechnungstool eine Anrede, war das "Herr" statt "Mustermann".

- Neue Rechnungen: Kenndaten kommen aus den PDF-Metadaten (JSON), inkl.
  getrenntem Nachnamen. Nichts wird mehr geraten.
- Alte Rechnungen ohne Metadaten: der Adressblock wird gesammelt, reine
  Anrede-Zeilen (Herr/Frau/Familie/Firma) werden uebersprungen, fuehrende
  Anreden abgeschnitten.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:45:55 +02:00
TheMockTv
2b7990b1b6 Firmendaten portabel suchen + Menuepunkt zum Auswaehlen
Die config.json des Rechnungstools wurde nur unter dem festen
Entwicklungspfad gesucht - als EXE auf einem anderen Rechner haette der
Bericht keinen Briefkopf bekommen. Jetzt: neben dem Programm, im
Nachbarordner, in Dokumente, und ueber "Daten -> Firmendaten waehlen".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:22:17 +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