# -*- coding: utf-8 -*- """Zeigt, was die Stornos in einem Journal bewirken. NUR LESEN. python zeig_stornos.py [Pfad zur journal.sqlite3] Ohne Pfad nimmt es den Datenordner, den sich das Programm gemerkt hat. Es wird ausschliesslich gelesen - keine Buchung angelegt, geaendert oder geloescht, kein Scan des Rechnungsordners. Man kann es also bedenkenlos auf das echte Journal loslassen. Ausgegeben wird je Monat: ALT = wie frueher gerechnet wurde (Rechnung + und Storno - stehen beide in der Summe und heben sich gegenseitig auf) JETZT = Storno und die von ihm aufgehobene Rechnung zaehlen gar nicht mit (Berichtigung im Monat der Rechnung) Der Unterschied wird nur dort sichtbar, wo Rechnung und Storno in VERSCHIEDENEN Monaten liegen - genau der Fall, um den es geht. """ import os import sys HIER = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HIER) from modell import MONATE, aufgehobene, eur, summiere # noqa: E402 def journal_pfad(argv): if len(argv) > 1: return argv[1] merker = os.path.join(os.environ.get("LOCALAPPDATA", ""), "Beherbergungssteuer", "datenordner.txt") if os.path.exists(merker): ordner = open(merker, encoding="utf-8").read().strip() if ordner: return os.path.join(ordner, "journal.sqlite3") return os.path.join(HIER, "journal.sqlite3") def main(): pfad = journal_pfad(sys.argv) if not os.path.exists(pfad): print(f"Kein Journal unter {pfad}") print("Pfad angeben: python zeig_stornos.py <...\\journal.sqlite3>") return 2 print(f"Journal: {pfad} (wird nur gelesen)\n") from db import Journal j = Journal(pfad) try: for jahr in sorted(j.jahre() or []): alle = j.buchungen(jahr=jahr) weg = aufgehobene(alle) stornos = [b for b in alle if b.storno_zu] print(f"=== {jahr} === {len(alle)} Buchungen, " f"{len(stornos)} Storno-Beleg(e), " f"{len(weg)} aufgehobene Rechnung(en)") print(f"{'Monat':12s} {'ALT (verrechnet)':>18s} {'JETZT':>14s} " f"{'Unterschied':>14s} Naechte alt/jetzt") for m in range(1, 13): des_monats = [b for b in alle if b.monat == m] if not des_monats: continue alt_g = round(sum(float(b.gezahlt or 0) for b in des_monats), 2) alt_n = sum(int(b.naechte or 0) for b in des_monats) s = summiere(des_monats, weg) marke = " <<<" if abs(alt_g - s.gezahlt) > 0.004 else "" print(f"{MONATE[m-1]:12s} {eur(alt_g):>18s} {eur(s.gezahlt):>14s} " f"{eur(s.gezahlt - alt_g):>14s} {alt_n}/{s.naechte}{marke}") jahr_alt = round(sum(float(b.gezahlt or 0) for b in alle), 2) jahr_neu = summiere(alle, weg) print(f"{'JAHR':12s} {eur(jahr_alt):>18s} {eur(jahr_neu.gezahlt):>14s} " f"{eur(jahr_neu.gezahlt - jahr_alt):>14s} " f"{sum(int(b.naechte or 0) for b in alle)}/{jahr_neu.naechte}") if not stornos: print("\n(keine Stornos in diesem Jahr)\n") continue print("\nDie Storno-Paare im Einzelnen:") for s_ in sorted(stornos, key=lambda b: (b.datum, b.rechnungsnummer)): ziel = [b for b in alle if b.id in weg and b.voll_nummer == s_.storno_zu] z = ziel[0] if ziel else None print(f" Storno {s_.voll_nummer} vom {s_.datum:%d.%m.%Y} " f"({MONATE[s_.monat-1]}) {eur(s_.gezahlt)}, {s_.naechte} Naechte") if z: gleich = "gleicher Monat" if z.monat == s_.monat else \ f"ANDERER Monat: Rechnung in {MONATE[z.monat-1]}" print(f" hebt auf: {z.voll_nummer} vom {z.datum:%d.%m.%Y}, " f"{z.nachname}, {eur(z.gezahlt)}, {z.naechte} Naechte [{gleich}]") else: print(f" ACHTUNG: zu {s_.storno_zu} liegt KEINE Rechnung im Journal - " f"der Storno zieht also einfach ab, ohne dass etwas aufgehoben wird") print() finally: j.schliessen() return 0 if __name__ == "__main__": sys.exit(main())