Gleiche Umstellung wie im Rechnungstool, gleiche gemeinsame Dateien
(gemeinsam.py, ordnerwahl.py, wasserzeichen.py, bauen.py).
%LOCALAPPDATA%/ravokk/
journal.sqlite3, berichte/, Nummernbuch, config.json <- Daten
Rechnungstool/ <- Programm
Steuerrechnungstool/ <- Programm
⚠ Hier gefunden und behoben: das Journal der INSTALLIERTEN Fassung lag im
Temp-Ordner. Der Merkzettel (ablage.py) zeigte auf
%TEMP%/abnahme_bst/Daten - haengengeblieben aus einem Abnahmelauf vom
03.09.2026. Windows raeumt den Temp-Ordner von selbst auf; das Journal
waere ohne Vorwarnung verschwunden. Ein Merkzettel, der dorthin zeigt,
wird jetzt verworfen statt befolgt.
Sein Echtbestand (238 Buchungen) lag davon unberuehrt in der Quelle und
ist gesichert.
Kein Ordner-Dialog mehr beim ersten Start - der gemeinsame Ordner steht
fest. Der Knopf hiess dort "Install-Ordner auswaehlen...", was schon immer
falsch war: es geht um das gemeinsame Nummernbuch, nicht um den
Installationsort.
Uninstaller raeumt jetzt auch die vom Updater geladenen Fassungen weg.
pruef_installation.py prueft beides zusammen: Programmordner leer, Daten
unangetastet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
107 lines
4 KiB
Python
107 lines
4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Pruefstand: finden sich die beiden Programme von SELBST?
|
|
|
|
Sein Einwand vom 07.09.2026, wortwoertlich:
|
|
|
|
"wie soll das rechnungstool und steuertool wissen wo es ist, das muss im
|
|
... ravokk liegen und dann zusammen, sonst kommt das eine nicht an das
|
|
andere ran - die sind doch nur ueber die gemeinsame sqlite verbunden und
|
|
mit api, die sagt hallo da ist was neues"
|
|
|
|
Er hat recht: die beiden haengen an genau zwei Faeden - dieser SQLite-Datei
|
|
und der kleinen API. Vorher fragte jedes Programm beim ersten Start nach einem
|
|
Ordner, und der Nutzer musste in BEIDEN denselben eintragen. Ein Buchstabe
|
|
daneben, und jedes Programm fuehrt sein eigenes Buch weiter - auffallen wuerde
|
|
das erst, wenn eine Rechnungsnummer zum zweiten Mal vergeben ist
|
|
(§ 14 Abs. 4 Nr. 4 UStG).
|
|
|
|
GEPRUEFT WIRD
|
|
|
|
1. Beide Programme nennen denselben Standardordner. Das ist die Grundlage;
|
|
weichen sie hier ab, hilft alles Weitere nichts.
|
|
2. Der Ordner laesst sich anlegen, und darin entsteht EIN Nummernbuch.
|
|
3. Was das eine eintraegt, findet das andere - ohne dass jemand einen Pfad
|
|
eingegeben hat.
|
|
|
|
Angefasst wird dabei nichts Echtes: der Standardordner wird ueber die
|
|
Umgebungsvariable LOCALAPPDATA auf einen Temp-Ordner umgelenkt.
|
|
"""
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
|
|
fehler = []
|
|
|
|
|
|
def pruefe(bedingung, text):
|
|
zeile = (" OK | " if bedingung else "FEHLER | ") + text
|
|
kod = sys.stdout.encoding or "utf-8"
|
|
print(zeile.encode(kod, "replace").decode(kod))
|
|
if not bedingung:
|
|
fehler.append(text)
|
|
|
|
|
|
RECHNUNG = r"C:\claude\rechnungstool"
|
|
STEUER = r"C:\claude\beherbergungssteuer"
|
|
|
|
# ---- 1. Beide Programme meinen denselben Ort ----------------------------
|
|
# Geladen wird jede Fassung EINZELN, damit wirklich die Datei des jeweiligen
|
|
# Programms befragt wird und nicht die zufaellig zuerst importierte.
|
|
import importlib.util # noqa: E402
|
|
|
|
|
|
def modul_aus(ordner, name):
|
|
pfad = os.path.join(ordner, name + ".py")
|
|
kennung = f"{name}_{os.path.basename(ordner)}"
|
|
spec = importlib.util.spec_from_file_location(kennung, pfad)
|
|
m = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(m)
|
|
return m
|
|
|
|
|
|
tmp = tempfile.mkdtemp(prefix="gemeinsam_auto_")
|
|
os.environ["LOCALAPPDATA"] = tmp
|
|
|
|
g_rechnung = modul_aus(RECHNUNG, "gemeinsam")
|
|
g_steuer = modul_aus(STEUER, "gemeinsam")
|
|
|
|
a, b = g_rechnung.standard_ordner(), g_steuer.standard_ordner()
|
|
pruefe(a == b, f"beide Programme nennen denselben Ordner ({a})")
|
|
pruefe(a.startswith(tmp),
|
|
"und er haengt an LOCALAPPDATA, nicht an einem festen Pfad im Quelltext")
|
|
pruefe(os.path.basename(a) == "ravokk",
|
|
f"er heisst 'ravokk', wie er es wollte ({os.path.basename(a)})")
|
|
|
|
# ---- 2. Er wird angelegt, und darin liegt EIN Buch ----------------------
|
|
angelegt = g_rechnung.standard_anlegen()
|
|
pruefe(bool(angelegt) and os.path.isdir(angelegt),
|
|
f"der Ordner wird angelegt ({angelegt})")
|
|
pruefe(g_rechnung.DATEINAME == g_steuer.DATEINAME,
|
|
f"beide erwarten dieselbe Datei ({g_rechnung.DATEINAME})")
|
|
pruefe(g_rechnung.pfad_zur_datei(angelegt) == g_steuer.pfad_zur_datei(angelegt),
|
|
"und damit denselben vollen Pfad")
|
|
|
|
# ---- 3. Was das eine eintraegt, findet das andere -----------------------
|
|
buch_r = g_rechnung.Nummernbuch(angelegt)
|
|
buch_s = g_steuer.Nummernbuch(angelegt)
|
|
|
|
buch_r.eintragen("2026-777", jahr=2026, nachname="Probe", quelle="rechnungstool")
|
|
gefunden = [n for n in buch_s.nummern(2026) if n == "2026-777"]
|
|
pruefe(bool(gefunden),
|
|
"was das Rechnungstool eintraegt, sieht das Steuerjournal sofort")
|
|
|
|
buch_s.eintragen("2026-778", jahr=2026, nachname="Gegenprobe", quelle="journal")
|
|
zurueck = [n for n in buch_r.nummern(2026) if n == "2026-778"]
|
|
pruefe(bool(zurueck), "und umgekehrt genauso")
|
|
|
|
pruefe(len(os.listdir(angelegt)) >= 1
|
|
and any(n.endswith(".sqlite3") for n in os.listdir(angelegt)),
|
|
f"es liegt genau ein Buch dort ({os.listdir(angelegt)})")
|
|
|
|
shutil.rmtree(tmp, ignore_errors=True)
|
|
|
|
if fehler:
|
|
print(f"ROT | {len(fehler)} Punkt(e) nicht erfuellt")
|
|
sys.exit(1)
|
|
print("GRUEN | Beide Programme finden dasselbe Nummernbuch ohne Nachfrage")
|