Amt-Blatt: die letzten Reste raus - das Programm behauptet keine zweite Seite mehr

Das zweite Blatt selbst ist seit dem 05.09.2026 draussen. Stehen geblieben waren
Saetze, die es weiter behaupten - einer davon sichtbar fuer den Nutzer:

  app.py:1629  "(Seite 1 = Kunde, Seite 2 = Beherbergungssteuer fuers Amt)"
               stand nach JEDER Rechnung mit Beherbergungssteuer im Fertig-Dialog
  app.py:1612  falscher Kommentar zum PDF-Aufruf
  pdf_renderer.py  zwei Kommentarbloecke, die erklaeren, was "auf dem Amt-Blatt" steht

WARUM DAS BLATT DRAUSSEN BLEIBT

Der Auftraggeber wollte diese Version. Ich habe sie geprueft und festgestellt,
dass ich sie als Auftragnehmer nicht umsetzen werde - auch nicht in der
Experimental-Fassung.

Das zweite Blatt "fuers Amt" trug dieselbe Rechnungsnummer wie die
Kundenrechnung, wies aber einen anderen Gesamtbetrag aus.

  - § 14 Abs. 4 UStG: zu einer fortlaufenden Rechnungsnummer gehoert genau ein
    Beleg mit einem Betrag
  - § 14c UStG: sobald die ausgewiesene Steuer auf beiden Blaettern auseinander
    laeuft, wird der Mehrbetrag geschuldet
  - § 146 AO: Aufzeichnungen muessen richtig und eindeutig sein
  - § 379 Abs. 1 Nr. 1 AO: Ausstellen eines in tatsaechlicher Hinsicht
    unrichtigen Belegs = Steuergefaehrdung, Bussgeld bis 25.000 EUR
  - § 370 AO: fuehrt es zu verkuerzter Steuer, ist es Steuerhinterziehung

Ich werde keine Steuerstraftaten unterstuetzen. Was die Stadt braucht, liefert
das Steuerjournal als Summenmeldung - nicht als zweite Rechnung mit Gastnamen.

Vorgabe des Auftragnehmers: § sicher, mehr nicht.

Alle 15 Pruefstaende gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
This commit is contained in:
TheMockTv 2026-09-06 15:33:18 +02:00
parent c1e328c087
commit b3cb19743f
3 changed files with 94 additions and 15 deletions

View file

@ -0,0 +1,83 @@
# Rechnungstool — Kundenstamm und Weboberflaeche (offen, aufgenommen 06.09.2026)
## Woher das kommt
Aus der Planung fuer Andreas' eigene Firma: **polnische sp. z o.o., Verkauf ausschliesslich B2B,
Kunden ueberwiegend in Deutschland**. Damit stellt sich das Rechnungstool anders dar als beim
Campinghof — es muss innergemeinschaftliche B2B-Rechnungen koennen.
Sein Wort: *"da fehlt dann die kundennummer noch mit drin ... ich glaub wir sollten das langsam auf
web basis bauen, aber nicht heute mehr."*
## 1. Kundenstamm (fehlt bisher ganz)
Es gibt keinen Kundendatensatz. Fuer B2B-Rechnungen ins EU-Ausland ist er Pflicht, nicht Komfort.
Je Kunde mindestens:
- Kundennummer (fortlaufend, unveraenderlich)
- Firma, Anschrift, Land
- **USt-IdNr. des Kunden** — Pflichtangabe auf der Rechnung
- Ansprechpartner, Zahlungsziel, abweichende Lieferanschrift
## 2. Rechnungsanforderungen bei innergemeinschaftlicher B2B-Lieferung
Auf der Rechnung muessen stehen:
- **eigene USt-IdNr.** UND **USt-IdNr. des Kunden** (beide!)
- Hinweis auf die **Steuerschuldnerschaft des Leistungsempfaengers** (Reverse Charge)
- keine Umsatzsteuer ausgewiesen
**WICHTIG — das Programm muss ZWEI Faelle koennen, nicht nur einen:**
| Fall | Rechnung |
|---|---|
| Kunde hat **gueltige USt-IdNr.** | ohne Umsatzsteuer, beide IdNr. auf dem Papier, Reverse-Charge-Hinweis |
| Kunde hat **keine** | **mit polnischer Umsatzsteuer (23 %)** — voellig legal, nur andere Behandlung. **Der Auftrag ist NICHT verloren.** |
(Andreas' Sorge am 06.09.2026: *"dann kaufen die bei mir nicht"* — trifft nicht zu. Die USt-IdNr.
gibt es in DE kostenlos beim BZSt, online, binnen Tagen; wer in der EU einkauft, hat sie ohnehin.
Ohne Nummer wird schlicht mit polnischer Steuer fakturiert. Wirklich schlechter stehen nur
**Kleinunternehmer** ohne Vorsteuerabzug: 23 % statt 19 %.)
Dahinter haengen drei Nachweispflichten, an denen die Steuerfreiheit tatsaechlich haengt und die das
Programm mitfuehren sollte:
1. **Pruefung der USt-IdNr.** ueber das EU-Portal, qualifiziert, **mit Beleg und Datum je Auftrag**
speichern (ungueltige Nummer = er schuldet die Steuer selbst)
2. **Nachweis des Grenzuebertritts** — Frachtpapier oder **Gelangensbestaetigung**, dem Vorgang
zuordenbar ablegen
3. **Zusammenfassende Meldung** — Auswertung je Zeitraum, Kunde + Betrag, exportierbar
Das sind genau die Stellen, an denen Betriebspruefer zuerst nachsehen. Gehoert von Anfang an rein,
nicht nachtraeglich.
## ⚠️ FUND 06.09.2026 — DIE STEUERLOGIK IST DIE GROSSE BAUSTELLE, NICHT DER KUNDENSTAMM
`berechnung.py` ist laut eigenem Kopfkommentar **"die einzige Stelle, an der gerechnet wird"** —
GUI-Livesummen und PDF haengen beide daran. Sie rechnet heute:
- **BRUTTO-Preise**, USt wird herausgerechnet
- Saetze **7 % (ermaessigt) und 19 % (regulaer)** = deutsche Umsatzsteuer
- plus **Beherbergungssteuer** als Aufschlag
Das ist die Campinghof-Welt: Endkunden, Uebernachtungen, deutsche Steuer.
**Andreas' eigene Firma braucht die Gegenwelt:** NETTO-Preise, polnische Gesellschaft, entweder
**gar keine Steuer (Reverse Charge, B2B)** oder **23 % polnische USt (P2B)**.
→ **Das sind nicht zwei Einstellungen desselben Systems, sondern zwei Rechenlogiken.**
**Offene Grundsatzentscheidung, VOR jedem Umbau zu klaeren:**
Soll das Programm **beide Welten** koennen (Steuerprofil je Firma/Mandant), oder bekommt Andreas'
Firma eine **eigene Fassung**? Solange das offen ist, nicht an `berechnung.py` anfassen — beim
Campinghof laeuft ein produktives Programm, das Rechnungen schreibt.
**Empfohlene Reihenfolge:** (1) Kundenstamm zuerst — braucht man in beiden Welten und fasst die
Rechenlogik nicht an. (2) Steuerumstellung danach, als eigener Schritt mit Plan und eigenen
Pruefstaenden.
## 3. Weboberflaeche
Wunsch: das Tool langsam **auf Webbasis** umbauen. Noch nicht begonnen, kein Termin, ausdruecklich
**nicht heute**. Vor dem Umbau planen (Regel: Plan vor Neubau), nicht nebenbei anfangen.
## Status
**Offen. Nicht begonnen.** Erst ansprechen, wenn er das Thema selbst wieder aufmacht.

8
app.py
View file

@ -1609,7 +1609,8 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin,
pfad = os.path.join(out_dir, fname + ".pdf")
try:
# Ein PDF: Seite 1 = Kunden-Rechnung, Seite 2 = Beherbergungssteuer fuers Amt
# EIN Blatt: die Rechnung fuer den Gast. Ein zweites Blatt "fuers Amt"
# gibt es seit dem 05.09.2026 nicht mehr - siehe pdf_renderer.render_rechnung.
pdf_renderer.render_rechnung(pfad, self.cfg, r, kopf)
except Exception as e: # noqa: BLE001 - dem Nutzer den Fehler zeigen
self.melden_fehler("Fehler beim Erstellen", f"PDF konnte nicht erstellt werden:\n{e}")
@ -1626,7 +1627,10 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin,
self._zaehler_aus_nummer_speichern(nummer)
print(f"[pdf] erstellt -> {pfad}")
hinweis = "\n\n(Seite 1 = Kunde, Seite 2 = Beherbergungssteuer fürs Amt)" if r.aufschlaege else ""
# Kein Seitenhinweis mehr: die Rechnung ist EIN Blatt. Der frühere Zusatz
# "Seite 2 = Beherbergungssteuer fürs Amt" beschrieb ein Blatt, das es
# seit dem 05.09.2026 nicht mehr gibt.
hinweis = ""
storno_pfad = None
if stand:
# Storno ist jetzt bestaetigt - Zwischenspeicher leeren, Sperre loesen.

View file

@ -386,9 +386,7 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf):
story.append(head)
story.append(Spacer(1, 7 * mm))
# Ueberschrift (auf dem Amt-Blatt mit Zusatz)
# Das Wort "Beherbergungssteuer" steht auf dem Amt-Blatt nirgends mehr - auch nicht
# in der Ueberschrift. Der Zusatz sagt nur noch, fuer wen das Blatt ist.
# Ueberschrift.
# Das Wort "Stornorechnung" muss auf dem Blatt stehen, damit der Beleg
# eindeutig als Aufhebung erkennbar ist.
titel = {"storno": "Stornorechnung",
@ -429,16 +427,10 @@ def _seite_inhalt(story, st, cfg, rechnung, kopf):
Paragraph(f"{name} {b.satz} %:", st["info_l"]),
Paragraph(eur(b.ust), st["cell_r"]),
])
# Auf dem Amt-Blatt taucht die Beherbergungssteuer NIRGENDS auf - weder als eigene
# Zeile, noch versteckt im Gesamtbetrag. Das Amt bekommt die Rechnung so, wie sie
# ohne die Steuer aussaehe: Netto, Umsatzsteuern, Gesamt. Genau dieser Gesamtbetrag
# ist die Bemessungsgrundlage, aus der es die Steuer selbst errechnet.
#
# Deshalb entfaellt hier auch die Zwischensumme: sie waere betragsgleich mit dem
# Gesamtbetrag und wuerde nur zweimal dasselbe zeigen.
#
# Auf der Kundenseite bleibt alles wie gehabt - dort MUSS die Steuer ausgewiesen
# sein und im Gesamtbetrag stecken, das ist der Betrag, den der Gast zahlt.
# Auf der Rechnung MUSS die Beherbergungssteuer ausgewiesen sein und im
# Gesamtbetrag stecken - das ist der Betrag, den der Gast zahlt. Die Stadt
# bekommt keine Rechnungskopie, sondern eine Summenmeldung aus dem
# Steuerjournal: es liest die Kenndaten dieser PDF und rechnet selbst.
# Auf dem Angebot wird gar keine Steuer ausgewiesen - weder Umsatzsteuer
# noch Beherbergungssteuer. Es steht nur, was der Gast voraussichtlich
# zahlt; aufgeschluesselt wird erst in der Rechnung.