beherbergungssteuer/firma.py
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

64 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
Firmendaten für den Briefkopf des Amts-Berichts.
Sie stehen bereits in der `config.json` des Rechnungstools von dort werden sie
gelesen, damit Rechnung und Steuerbericht garantiert denselben Kopf tragen und
nichts doppelt gepflegt werden muss.
Wird das Rechnungstool nicht gefunden, greift ein neutraler Ersatz und der
Bericht wird trotzdem gedruckt (nur ohne Logo/Bankzeile).
"""
import os
import json
import logging
log = logging.getLogger("bst.firma")
SUCHPFADE = [
r"C:\claude\rechnungstool\config.json",
os.path.join(os.path.expanduser("~"), "Documents", "rechnungstool", "config.json"),
]
ERSATZ = {
"name": "Campinghof Bartl",
"untertitel": "Camping & Ferienwohnung am Markkleeberger See",
"absender": "Campinghof Bartl - Bornaer Chaussee 36 - 04416 Markkleeberg OT Wachau",
"inhaber": "", "bank": "", "iban": "", "bic": "",
"homepage": "", "email": "", "telefon": "", "steuernummer": "", "logo": "",
}
def config_pfad(gespeichert: str = "") -> str:
"""Erster gefundener Pfad zur config.json des Rechnungstools ('' = keiner)."""
for p in ([gespeichert] if gespeichert else []) + SUCHPFADE:
if p and os.path.isfile(p):
return os.path.abspath(p)
return ""
def lade(gespeichert: str = "") -> dict:
"""Firmendaten laden. Der Logo-Pfad wird absolut gemacht."""
pfad = config_pfad(gespeichert)
if not pfad:
log.warning("config.json des Rechnungstools nicht gefunden Ersatz-Briefkopf")
return dict(ERSATZ)
try:
with open(pfad, encoding="utf-8") as f:
cfg = json.load(f)
except Exception as e: # noqa: BLE001 - kaputte/fremde Datei
log.warning("config.json nicht lesbar (%s): %s", pfad, e)
return dict(ERSATZ)
daten = dict(ERSATZ)
daten.update(cfg.get("firma", {}))
logo = str(daten.get("logo") or "").strip()
if logo and not os.path.isabs(logo):
kandidat = os.path.join(os.path.dirname(pfad), logo)
daten["logo"] = kandidat if os.path.exists(kandidat) else ""
log.info("Firmendaten aus %s", pfad)
return daten