diff --git a/Beherbergungssteuer.exe b/Beherbergungssteuer.exe index 5ddd36a..3bc47cd 100644 Binary files a/Beherbergungssteuer.exe and b/Beherbergungssteuer.exe differ diff --git a/bericht_pdf.py b/bericht_pdf.py index 23fe6aa..0cca167 100644 --- a/bericht_pdf.py +++ b/bericht_pdf.py @@ -198,6 +198,23 @@ def _ort(firma): # ------------------------------------------------------------- Monat -------- +def _art_kuerzel(b) -> str: + """Ein Buchstabe je Beleg - seine Ansage vom 04.09.2026: *"du musst die + markieren als rechnung und storno oder berichtigung, und das kannst einfach + mit buchstaben machen"*. Ohne die Marke muss man aus der Begruendung raten, + was fuer ein Beleg die Zeile ueberhaupt ist. + + R = Rechnung + S = Stornorechnung + B = berichtigte Rechnung (die Neuausstellung nach einem Storno) + """ + if b.storno_zu or b.art == "storno": + return "S" + if b.art == "korrektur": + return "B" + return "R" + + def _art_text(b, weg) -> str: """Was in der Rechnungsspalte unter der Nummer steht. @@ -211,7 +228,7 @@ def _art_text(b, weg) -> str: # Ein Storno, der nur zurueckzeigt, laesst den Leser stehen ("wer soll # denn sonst wissen, wo er suchen muss" - 04.09.2026). if b.folge_nummer and b.folge_art == "vorhanden": - return f"neu abgerechnet mit {b.folge_nummer}" + return f"abgerechnet mit {b.folge_nummer}" if b.folge_nummer: return f"neue Rechnung {b.folge_nummer}" if b.folge_art == "" and b.art == "storno" and not b.folge_nummer: @@ -250,13 +267,15 @@ def render_monat(pfad, firma, jahr: int, monat: int, buchungen): # Eigene Spalte "Grund" statt einer zweiten Zeile unter der Nummer - seine # Ansage vom 04.09.2026: "mach eine neue spalte mit grund oder so was". - kopf = ["Datum", "Rechnung", "Begründung", "Name", "Nächte", "Entgelt", "Satz", "Steuer"] - stile = ["th", "th", "th_l", "th_l", "th", "th", "th", "th"] + kopf = ["Datum", "Rechnung", "Art", "Begründung", "Name", + "Nächte", "Entgelt", "Satz", "Steuer"] + stile = ["th", "th", "th", "th_l", "th_l", "th", "th", "th", "th"] daten = [[Paragraph(k, st[s_]) for k, s_ in zip(kopf, stile)]] for b in liste: daten.append([ Paragraph(b.datum.strftime("%d.%m.%Y"), st["zelle_c"]), Paragraph(b.voll_nummer, st["zelle_c"]), + Paragraph(f'{_art_kuerzel(b)}', st["zelle_c"]), Paragraph(_art_text(b, weg), st["zelle"]), Paragraph(b.nachname, st["zelle"]), Paragraph(str(b.naechte), st["zelle_c"]), @@ -267,7 +286,7 @@ def render_monat(pfad, firma, jahr: int, monat: int, buchungen): if len(daten) == 1: daten.append([Paragraph("", st["zelle_c"]), Paragraph("(keine Buchungen in diesem Monat)", st["zelle"]), - "", "", "", "", "", ""]) + "", "", "", "", "", "", ""]) # Namensspalte nur so breit wie der breiteste Name (Rest der Tabelle ist fest) breiteste = max([stringWidth(b.nachname, "Helvetica", 8.5) for b in liste] @@ -278,11 +297,11 @@ def render_monat(pfad, firma, jahr: int, monat: int, buchungen): # raum ein, da kannst locker zeile begruendung setzen"*. Also enger gestellt # und der Begruendung so viel gegeben, dass "storniert mit 2026-901" in EINE # Zeile passt - in normaler Schriftgroesse, nicht kleingedruckt. - name_w = min(max(breiteste + 6 * mm, 22 * mm), CONTENT_W - 142 * mm) + name_w = min(max(breiteste + 6 * mm, 22 * mm), CONTENT_W - 144 * mm) tabelle = Table(daten, repeatRows=1, hAlign="LEFT", - colWidths=[19 * mm, 19 * mm, 44 * mm, name_w, - 12 * mm, 19 * mm, 10 * mm, 19 * mm]) + colWidths=[18 * mm, 18 * mm, 9 * mm, 42 * mm, name_w, + 12 * mm, 18 * mm, 9 * mm, 18 * mm]) tabelle.setStyle(TableStyle([ ("BACKGROUND", (0, 0), (-1, 0), GREY_BG), ("LINEBELOW", (0, 0), (-1, 0), 0.8, ACCENT), @@ -294,6 +313,14 @@ def render_monat(pfad, firma, jahr: int, monat: int, buchungen): ("RIGHTPADDING", (0, 0), (-1, -1), 3), ])) story.append(tabelle) + # Legende zu den Buchstaben - direkt unter der Tabelle, damit sie beim Lesen + # da ist und nicht auf der naechsten Seite. Wer nur eine Zeile prueft, muss + # nicht raten, was fuer ein Beleg sie ist. + story.append(Spacer(1, 1.5 * mm)) + story.append(Paragraph( + "Art: R = Rechnung · S = Stornorechnung · B = berichtigte Rechnung " + "(Neuausstellung nach einem Storno). Die Spalte Begründung nennt den Beleg, " + "bei dem es weitergeht.", st["klein"])) _summenblock(story, st, s, satz_text) story.append(Spacer(1, 3 * mm)) diff --git a/doku_aenderungen_pdf.py b/doku_aenderungen_pdf.py index 7bc9ffa..ae3a39a 100644 --- a/doku_aenderungen_pdf.py +++ b/doku_aenderungen_pdf.py @@ -207,16 +207,20 @@ def bauen(pfad, cfg): "Begründung, und zwar als Kette, die vorwärts zeigt – jede Zeile sagt, wo es " "weitergeht:") s.append(tabelle([ - ["Zeile im Bericht", "Begründung", "Bedeutung"], - ["die aufgehobene Rechnung", "storniert mit 2026-901", + ["Art", "Zeile im Bericht", "Begründung", "Bedeutung"], + ["R", "die aufgehobene Rechnung", "storniert mit 2026-901", "hier steht, welcher Beleg sie aufhebt"], - ["die Stornorechnung", "neue Rechnung 2026-902", + ["S", "die Stornorechnung", "neue Rechnung 2026-902", "hier steht, unter welcher Nummer die Leistung jetzt abgerechnet ist"], - ["die Stornorechnung im Doppelungsfall", "neu abgerechnet mit 2026-343", + ["S", "Stornorechnung im Doppelungsfall", "abgerechnet mit 2026-343", "die Leistung war bereits abgerechnet – das ist die Rechnung, die bleibt"], - ["die neue Rechnung", "Neuausstellung", + ["B", "die berichtigte Rechnung", "Neuausstellung", "sie ersetzt die aufgehobene"], - ], st, [45 * mm, 47 * mm, CONTENT_W - 92 * mm])) + ], st, [9 * mm, 40 * mm, 40 * mm, CONTENT_W - 89 * mm])) + s.append(Spacer(1, 1 * mm)) + P("Die Spalte Art markiert jeden Beleg mit einem Buchstaben – R Rechnung, " + "S Stornorechnung, B berichtigte Rechnung. Die Erklärung dazu steht auf jedem " + "Blatt unter der Tabelle.", "klein") s.append(Spacer(1, 2 * mm)) P("So findet man von jedem Beleg aus den nächsten, auch wenn Rechnung und Storno in " "verschiedenen Monaten liegen und gar nicht auf demselben Blatt stehen.") diff --git a/gui_monat.py b/gui_monat.py index eaefa91..43ecd6d 100644 --- a/gui_monat.py +++ b/gui_monat.py @@ -155,7 +155,7 @@ class MonatsTab(ttk.Frame): if b.storno_zu: # Kette vorwaerts: Rechnung -> Storno -> die Rechnung, die gilt. if b.folge_nummer and b.folge_art == "vorhanden": - art_text = f"neu abgerechnet mit {b.folge_nummer}" + art_text = f"abgerechnet mit {b.folge_nummer}" elif b.folge_nummer: art_text = f"neue Rechnung {b.folge_nummer}" else: diff --git a/pruef_storno_verrechnet.py b/pruef_storno_verrechnet.py index d131433..394cc40 100644 --- a/pruef_storno_verrechnet.py +++ b/pruef_storno_verrechnet.py @@ -157,9 +157,13 @@ pruefe("neue Rechnung 2026-902" in text, pfad_sep = os.path.join(tmp, "September.pdf") bericht_pdf.render_monat(pfad_sep, firma_lib.lade(), JAHR, 9, alle) text_sep = " ".join((PdfReader(pfad_sep).pages[0].extract_text() or "").split()) -pruefe("neu abgerechnet mit 2026-905" in text_sep, +pruefe("abgerechnet mit 2026-905" in text_sep, "und beim Doppelungsfall zeigt er auf die Rechnung, die bleibt") pruefe("-52,00" in text_sep, "der September traegt weiter seinen Minusbetrag") +# Die Buchstaben-Marke: ohne sie muss man aus der Begruendung raten, was fuer ein +# Beleg die Zeile ist ("du musst die markieren als rechnung und storno"). +pruefe("R = Rechnung" in text and "S = Stornorechnung" in text, + "unter der Tabelle steht die Erklaerung der Buchstaben") pruefe("Neuausstellung" in text, "die neue Rechnung ist als Neuausstellung beschriftet") # ---------------------------------------------------------------------------