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
This commit is contained in:
parent
31bb0c600b
commit
dbe95e1ec6
6 changed files with 319 additions and 31 deletions
50
app.py
50
app.py
|
|
@ -10,6 +10,7 @@ Start: Doppelklick auf "Beherbergungssteuer starten.bat" oder `python app.py`
|
|||
"""
|
||||
|
||||
import os
|
||||
import queue
|
||||
import sys
|
||||
import logging
|
||||
from datetime import date
|
||||
|
|
@ -42,6 +43,7 @@ if __name__ == "__main__":
|
|||
_wurzel.destroy()
|
||||
sys.exit(0)
|
||||
|
||||
import api
|
||||
import db
|
||||
import gemeinsam
|
||||
import ordnerwahl
|
||||
|
|
@ -82,6 +84,9 @@ class App(tk.Tk):
|
|||
|
||||
self.journal = db.Journal(JOURNAL)
|
||||
self.buch = None # gemeinsames Nummernbuch, siehe gemeinsam.py
|
||||
# Der eigene kleine Server. Klopft das Rechnungstool an, wird sofort
|
||||
# nachgesehen - ohne auf den naechsten Durchgang der Wache zu warten.
|
||||
self.api = api.MiniApi("journal", self._push_empfangen)
|
||||
self.satz = float(self.journal.hole("satz", str(STANDARD_SATZ)))
|
||||
self.pdf_ordner = self.journal.hole("pdf_ordner", "")
|
||||
self.jahr = tk.IntVar(value=int(self.journal.hole("jahr", str(date.today().year))))
|
||||
|
|
@ -107,6 +112,8 @@ class App(tk.Tk):
|
|||
# Beide Programme laufen nebeneinander: schreibt das Rechnungstool eine
|
||||
# Rechnung, meldet es das hier herein - siehe _wache_jetzt().
|
||||
self._briefkasten_stand = "?" # "?" = noch nicht nachgesehen
|
||||
self._push_kasten = queue.Queue() # Zettel aus dem API-Faden
|
||||
self.after(250, self._push_abholen)
|
||||
self._nachricht_stand = 0 # bis hierher sind Meldungen gelesen
|
||||
self.after(600, self._wache)
|
||||
# Beim Zurueckklicken sofort nachsehen statt zwei Sekunden zu warten.
|
||||
|
|
@ -338,18 +345,43 @@ class App(tk.Tk):
|
|||
self._buch_oeffnen()
|
||||
if self.buch is None:
|
||||
return
|
||||
try:
|
||||
self.buch.anmelden("journal", os.getpid(), os.path.basename(sys.executable))
|
||||
except Exception as e: # noqa: BLE001
|
||||
log.warning("Anmeldung fehlgeschlagen: %s", e)
|
||||
# Die Mini-API aufmachen und mit Port und PID ins Telefonbuch: daran
|
||||
# sieht das Rechnungstool, dass jemand zuhoert, und kann anklopfen.
|
||||
self.api.starten(self.buch)
|
||||
if not self.api.port:
|
||||
try:
|
||||
self.buch.anmelden("journal", os.getpid(),
|
||||
os.path.basename(sys.executable))
|
||||
except Exception as e: # noqa: BLE001
|
||||
log.warning("Anmeldung fehlgeschlagen: %s", e)
|
||||
|
||||
def _abmelden(self):
|
||||
if self.buch is None:
|
||||
return
|
||||
self.api.stoppen(self.buch)
|
||||
|
||||
def _push_empfangen(self):
|
||||
"""Ruft die API aus IHREM Faden - Tkinter darf man von dort nicht anfassen.
|
||||
|
||||
Also nur einen Zettel in die Warteschlange legen; das Fenster holt ihn
|
||||
gleich ab (_push_abholen).
|
||||
"""
|
||||
self._push_kasten.put(1)
|
||||
|
||||
def _push_abholen(self):
|
||||
"""Im Fenster-Faden: liegt ein Zettel da, sofort in der SQLite nachsehen."""
|
||||
try:
|
||||
self.buch.abmelden("journal")
|
||||
except Exception as e: # noqa: BLE001 - beim Schliessen nichts erzwingen
|
||||
log.debug("Abmelden fehlgeschlagen: %s", e)
|
||||
geklopft = False
|
||||
while True:
|
||||
try:
|
||||
self._push_kasten.get_nowait()
|
||||
geklopft = True
|
||||
except queue.Empty:
|
||||
break
|
||||
if geklopft:
|
||||
self._wache_jetzt()
|
||||
except Exception as e: # noqa: BLE001 - darf das Fenster nie umwerfen
|
||||
log.warning("Push: %s", e)
|
||||
finally:
|
||||
self.after(250, self._push_abholen)
|
||||
|
||||
def _buch_oeffnen(self):
|
||||
ordner = self.journal.hole("gemeinsam_ordner", "")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue